mirror of git://gcc.gnu.org/git/gcc.git
line-map.c: New.
* line-map.c: New. * line-map.h: New. * Makefile.in (line-map.o): New. (LIBCPP_OBJS, LIBCPP_DEPS): Update. * c-lex.c (cb_file_change): Update for new cpp_file_change structure. * cpperror.c (print_containing_files): Similarly. (print_location): Update. Don't output a space before _Pragma. * cppfiles.c (stack_include_file): Set to line 1 immediately. (stack_include_filee, cpp_make_system_header): Update. (_cpp_execute_include): Get logical line number right for calling as-yet-unterminated #include. * cpphash.h (struct cpp_reader): Add line_maps. (_cpp_do_file_change): Update. * cppinit.c (cpp_create_reader): Initialize line maps. (cpp_destroy): Destroy line maps. (cpp_start_read): Get logical line number right. * cpplex.c (parse_string): Only warn once for multi-line strings. Use boolean variable for null warning. * cpplib.c (_cpp_handle_directive): End the directive if it isn't already. (do_include_common): End the directive early. (do_line): Don't warn about out-of-range lines in preprocessed source. Update. Remove unused variables. (_cpp_do_file_change): Update for new line mapping. (pragma_cb): New typedef. (cpp_register_pragma): Stop looking ahead before calling the handler. Clean up. (do_pragma_system_header): End directive early. (cpp_get_line_maps): New. (cpp_pop_buffer): Fudge logical line. Update. * cpplib.h: Include line-map.h (enum cpp_fc_reason): Remove. (struct cpp_file_change): Update. (cpp_get_line_maps): New. * cppmain.c (struct_printer): New member map. (cb_file_change): Update for new mappings. * fix-header.c (cb_file_change): Similarly. testsuite: * gcc.dg/cpp/19951025-1.c: Update. From-SVN: r44584
This commit is contained in:
parent
6ff02a9579
commit
d82fc1085f
|
@ -1,3 +1,43 @@
|
||||||
|
2001-08-03 Neil Booth <neil@cat.daikokuya.demon.co.uk>
|
||||||
|
|
||||||
|
* line-map.c: New.
|
||||||
|
* line-map.h: New.
|
||||||
|
* Makefile.in (line-map.o): New.
|
||||||
|
(LIBCPP_OBJS, LIBCPP_DEPS): Update.
|
||||||
|
* c-lex.c (cb_file_change): Update for new cpp_file_change structure.
|
||||||
|
* cpperror.c (print_containing_files): Similarly.
|
||||||
|
(print_location): Update. Don't output a space before _Pragma.
|
||||||
|
* cppfiles.c (stack_include_file): Set to line 1 immediately.
|
||||||
|
(stack_include_filee, cpp_make_system_header): Update.
|
||||||
|
(_cpp_execute_include): Get logical line number right for calling
|
||||||
|
as-yet-unterminated #include.
|
||||||
|
* cpphash.h (struct cpp_reader): Add line_maps.
|
||||||
|
(_cpp_do_file_change): Update.
|
||||||
|
* cppinit.c (cpp_create_reader): Initialize line maps.
|
||||||
|
(cpp_destroy): Destroy line maps.
|
||||||
|
(cpp_start_read): Get logical line number right.
|
||||||
|
* cpplex.c (parse_string): Only warn once for multi-line strings.
|
||||||
|
Use boolean variable for null warning.
|
||||||
|
* cpplib.c (_cpp_handle_directive): End the directive if it isn't
|
||||||
|
already.
|
||||||
|
(do_include_common): End the directive early.
|
||||||
|
(do_line): Don't warn about out-of-range lines in preprocessed
|
||||||
|
source. Update. Remove unused variables.
|
||||||
|
(_cpp_do_file_change): Update for new line mapping.
|
||||||
|
(pragma_cb): New typedef.
|
||||||
|
(cpp_register_pragma): Stop looking ahead before calling the
|
||||||
|
handler. Clean up.
|
||||||
|
(do_pragma_system_header): End directive early.
|
||||||
|
(cpp_get_line_maps): New.
|
||||||
|
(cpp_pop_buffer): Fudge logical line. Update.
|
||||||
|
* cpplib.h: Include line-map.h
|
||||||
|
(enum cpp_fc_reason): Remove.
|
||||||
|
(struct cpp_file_change): Update.
|
||||||
|
(cpp_get_line_maps): New.
|
||||||
|
* cppmain.c (struct_printer): New member map.
|
||||||
|
(cb_file_change): Update for new mappings.
|
||||||
|
* fix-header.c (cb_file_change): Similarly.
|
||||||
|
|
||||||
2001-08-02 Nick Clifton <nickc@cambridge.redhat.com>
|
2001-08-02 Nick Clifton <nickc@cambridge.redhat.com>
|
||||||
|
|
||||||
* Makefile.in (libgcc.mk): Define mkinstalldirs.
|
* Makefile.in (libgcc.mk): Define mkinstalldirs.
|
||||||
|
|
|
@ -1324,6 +1324,8 @@ stringpool.o: stringpool.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(OBSTACK_H) \
|
||||||
|
|
||||||
hashtable.o: hashtable.c hashtable.h $(CONFIG_H) $(SYSTEM_H) $(OBSTACK_H)
|
hashtable.o: hashtable.c hashtable.h $(CONFIG_H) $(SYSTEM_H) $(OBSTACK_H)
|
||||||
|
|
||||||
|
line-map.o: line-map.c line-map.h $(CONFIG_H) $(SYSTEM_H)
|
||||||
|
|
||||||
ggc-none.o: ggc-none.c $(GCONFIG_H) $(SYSTEM_H) $(GGC_H)
|
ggc-none.o: ggc-none.c $(GCONFIG_H) $(SYSTEM_H) $(GGC_H)
|
||||||
$(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
|
$(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
|
||||||
|
|
||||||
|
@ -1933,9 +1935,10 @@ PREPROCESSOR_DEFINES = \
|
||||||
|
|
||||||
LIBCPP_OBJS = cpplib.o cpplex.o cppmacro.o cppexp.o cppfiles.o \
|
LIBCPP_OBJS = cpplib.o cpplex.o cppmacro.o cppexp.o cppfiles.o \
|
||||||
cpphash.o cpperror.o cppinit.o cppdefault.o \
|
cpphash.o cpperror.o cppinit.o cppdefault.o \
|
||||||
hashtable.o mkdeps.o prefix.o version.o mbchar.o
|
hashtable.o line-map.o mkdeps.o prefix.o version.o mbchar.o
|
||||||
|
|
||||||
LIBCPP_DEPS = cpplib.h cpphash.h hashtable.h intl.h $(OBSTACK_H) $(SYSTEM_H)
|
LIBCPP_DEPS = cpplib.h cpphash.h line-map.h hashtable.h intl.h \
|
||||||
|
$(OBSTACK_H) $(SYSTEM_H)
|
||||||
|
|
||||||
# Most of the other archives built/used by this makefile are for
|
# Most of the other archives built/used by this makefile are for
|
||||||
# targets. This one is strictly for the host.
|
# targets. This one is strictly for the host.
|
||||||
|
|
26
gcc/c-lex.c
26
gcc/c-lex.c
|
@ -241,16 +241,20 @@ cb_file_change (pfile, fc)
|
||||||
cpp_reader *pfile ATTRIBUTE_UNUSED;
|
cpp_reader *pfile ATTRIBUTE_UNUSED;
|
||||||
const cpp_file_change *fc;
|
const cpp_file_change *fc;
|
||||||
{
|
{
|
||||||
if (fc->reason == FC_ENTER)
|
unsigned int from_line = SOURCE_LINE (fc->map - 1, fc->line - 1);
|
||||||
|
|
||||||
|
if (fc->reason == LC_ENTER)
|
||||||
{
|
{
|
||||||
/* Don't stack the main buffer on the input stack;
|
/* Don't stack the main buffer on the input stack;
|
||||||
we already did in compile_file. */
|
we already did in compile_file. */
|
||||||
if (fc->from.filename)
|
if (MAIN_FILE_P (fc->map))
|
||||||
|
main_input_filename = fc->map->to_file;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
lineno = fc->from.lineno;
|
lineno = from_line;
|
||||||
push_srcloc (fc->to.filename, 1);
|
push_srcloc (fc->map->to_file, 1);
|
||||||
input_file_stack->indent_level = indent_level;
|
input_file_stack->indent_level = indent_level;
|
||||||
(*debug_hooks->start_source_file) (fc->from.lineno, fc->to.filename);
|
(*debug_hooks->start_source_file) (lineno, fc->map->to_file);
|
||||||
#ifndef NO_IMPLICIT_EXTERN_C
|
#ifndef NO_IMPLICIT_EXTERN_C
|
||||||
if (c_header_level)
|
if (c_header_level)
|
||||||
++c_header_level;
|
++c_header_level;
|
||||||
|
@ -261,10 +265,8 @@ cb_file_change (pfile, fc)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
|
||||||
main_input_filename = fc->to.filename;
|
|
||||||
}
|
}
|
||||||
else if (fc->reason == FC_LEAVE)
|
else if (fc->reason == LC_LEAVE)
|
||||||
{
|
{
|
||||||
/* Popping out of a file. */
|
/* Popping out of a file. */
|
||||||
if (input_file_stack->next)
|
if (input_file_stack->next)
|
||||||
|
@ -288,16 +290,16 @@ cb_file_change (pfile, fc)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
pop_srcloc ();
|
pop_srcloc ();
|
||||||
(*debug_hooks->end_source_file) (input_file_stack->line);
|
(*debug_hooks->end_source_file) (from_line);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
error ("leaving more files than we entered");
|
error ("leaving more files than we entered");
|
||||||
}
|
}
|
||||||
|
|
||||||
update_header_times (fc->to.filename);
|
update_header_times (fc->map->to_file);
|
||||||
in_system_header = fc->sysp != 0;
|
in_system_header = fc->sysp != 0;
|
||||||
input_filename = fc->to.filename;
|
input_filename = fc->map->to_file;
|
||||||
lineno = fc->to.lineno; /* Do we need this? */
|
lineno = SOURCE_LINE (fc->map, fc->line); /* Do we need this? */
|
||||||
|
|
||||||
/* Hook for C++. */
|
/* Hook for C++. */
|
||||||
extract_interface_info ();
|
extract_interface_info ();
|
||||||
|
|
|
@ -29,7 +29,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#include "cpphash.h"
|
#include "cpphash.h"
|
||||||
#include "intl.h"
|
#include "intl.h"
|
||||||
|
|
||||||
static void print_containing_files PARAMS ((cpp_buffer *));
|
static void print_containing_files PARAMS ((struct line_map *,
|
||||||
|
struct line_map *));
|
||||||
static void print_location PARAMS ((cpp_reader *,
|
static void print_location PARAMS ((cpp_reader *,
|
||||||
const char *,
|
const char *,
|
||||||
const cpp_lexer_pos *));
|
const cpp_lexer_pos *));
|
||||||
|
@ -42,21 +43,25 @@ static void print_location PARAMS ((cpp_reader *,
|
||||||
/* Print the file names and line numbers of the #include
|
/* Print the file names and line numbers of the #include
|
||||||
commands which led to the current file. */
|
commands which led to the current file. */
|
||||||
static void
|
static void
|
||||||
print_containing_files (ip)
|
print_containing_files (map_array, map)
|
||||||
cpp_buffer *ip;
|
struct line_map *map_array;
|
||||||
|
struct line_map *map;
|
||||||
{
|
{
|
||||||
int first = 1;
|
int first = 1;
|
||||||
|
|
||||||
/* Find the other, outer source files. */
|
for (;;)
|
||||||
for (ip = ip->prev; ip; ip = ip->prev)
|
|
||||||
{
|
{
|
||||||
|
if (MAIN_FILE_P (map))
|
||||||
|
break;
|
||||||
|
map = &map_array[map->included_from];
|
||||||
|
|
||||||
if (first)
|
if (first)
|
||||||
{
|
{
|
||||||
first = 0;
|
first = 0;
|
||||||
/* The current line in each outer source file is now the
|
/* The current line in each outer source file is now the
|
||||||
same as the line of the #include. */
|
same as the line of the #include. */
|
||||||
fprintf (stderr, _("In file included from %s:%u"),
|
fprintf (stderr, _("In file included from %s:%u"),
|
||||||
ip->nominal_fname, CPP_BUF_LINE (ip));
|
map->to_file, LAST_SOURCE_LINE (map));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* Translators note: this message is used in conjunction
|
/* Translators note: this message is used in conjunction
|
||||||
|
@ -72,8 +77,9 @@ print_containing_files (ip)
|
||||||
The trailing comma is at the beginning of this message,
|
The trailing comma is at the beginning of this message,
|
||||||
and the trailing colon is not translated. */
|
and the trailing colon is not translated. */
|
||||||
fprintf (stderr, _(",\n from %s:%u"),
|
fprintf (stderr, _(",\n from %s:%u"),
|
||||||
ip->nominal_fname, CPP_BUF_LINE (ip));
|
map->to_file, LAST_SOURCE_LINE (map));
|
||||||
}
|
}
|
||||||
|
|
||||||
fputs (":\n", stderr);
|
fputs (":\n", stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,19 +106,24 @@ print_location (pfile, filename, pos)
|
||||||
line = 0;
|
line = 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
struct line_map *map;
|
||||||
|
|
||||||
|
line = pfile->line;
|
||||||
if (type == BUF_PRAGMA)
|
if (type == BUF_PRAGMA)
|
||||||
{
|
{
|
||||||
buffer = buffer->prev;
|
buffer = buffer->prev;
|
||||||
line = CPP_BUF_LINE (buffer);
|
|
||||||
col = CPP_BUF_COL (buffer);
|
col = CPP_BUF_COL (buffer);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
map = lookup_line (&pfile->line_maps, line);
|
||||||
|
if (pos == 0)
|
||||||
{
|
{
|
||||||
if (pos == 0)
|
pos = cpp_get_line (pfile);
|
||||||
pos = cpp_get_line (pfile);
|
line = SOURCE_LINE (map, line);
|
||||||
line = pos->line;
|
|
||||||
col = pos->col;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
line = pos->line;
|
||||||
|
col = pos->col;
|
||||||
|
|
||||||
if (col == 0)
|
if (col == 0)
|
||||||
col = 1;
|
col = 1;
|
||||||
|
@ -121,7 +132,7 @@ print_location (pfile, filename, pos)
|
||||||
if (buffer->prev && ! buffer->include_stack_listed)
|
if (buffer->prev && ! buffer->include_stack_listed)
|
||||||
{
|
{
|
||||||
buffer->include_stack_listed = 1;
|
buffer->include_stack_listed = 1;
|
||||||
print_containing_files (buffer);
|
print_containing_files (pfile->line_maps.maps, map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,14 +140,15 @@ print_location (pfile, filename, pos)
|
||||||
filename = buffer->nominal_fname;
|
filename = buffer->nominal_fname;
|
||||||
|
|
||||||
if (line == 0)
|
if (line == 0)
|
||||||
fprintf (stderr, "%s: ", filename);
|
fprintf (stderr, "%s:", filename);
|
||||||
else if (CPP_OPTION (pfile, show_column) == 0)
|
else if (CPP_OPTION (pfile, show_column) == 0)
|
||||||
fprintf (stderr, "%s:%u: ", filename, line);
|
fprintf (stderr, "%s:%u:", filename, line);
|
||||||
else
|
else
|
||||||
fprintf (stderr, "%s:%u:%u: ", filename, line, col);
|
fprintf (stderr, "%s:%u:%u:", filename, line, col);
|
||||||
|
|
||||||
if (type == BUF_PRAGMA)
|
if (type == BUF_PRAGMA)
|
||||||
fprintf (stderr, "_Pragma: ");
|
fprintf (stderr, "_Pragma:");
|
||||||
|
fputc (' ', stderr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -338,7 +338,7 @@ stack_include_file (pfile, inc)
|
||||||
|
|
||||||
/* Generate the call back. */
|
/* Generate the call back. */
|
||||||
fp->lineno = 0;
|
fp->lineno = 0;
|
||||||
_cpp_do_file_change (pfile, FC_ENTER, 0, 0);
|
_cpp_do_file_change (pfile, LC_ENTER);
|
||||||
fp->lineno = 1;
|
fp->lineno = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,8 +579,7 @@ cpp_make_system_header (pfile, syshdr, externc)
|
||||||
if (syshdr)
|
if (syshdr)
|
||||||
flags = 1 + (externc != 0);
|
flags = 1 + (externc != 0);
|
||||||
pfile->buffer->sysp = flags;
|
pfile->buffer->sysp = flags;
|
||||||
_cpp_do_file_change (pfile, FC_RENAME, pfile->buffer->nominal_fname,
|
_cpp_do_file_change (pfile, LC_RENAME);
|
||||||
pfile->buffer->lineno);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Report on all files that might benefit from a multiple include guard.
|
/* Report on all files that might benefit from a multiple include guard.
|
||||||
|
@ -681,6 +680,7 @@ _cpp_execute_include (pfile, header, type)
|
||||||
pfile->system_include_depth++;
|
pfile->system_include_depth++;
|
||||||
|
|
||||||
stack_include_file (pfile, inc);
|
stack_include_file (pfile, inc);
|
||||||
|
pfile->line++; /* Fake the '\n' at the end of #include. */
|
||||||
|
|
||||||
if (type == IT_IMPORT)
|
if (type == IT_IMPORT)
|
||||||
_cpp_never_reread (inc);
|
_cpp_never_reread (inc);
|
||||||
|
|
|
@ -249,6 +249,7 @@ struct cpp_reader
|
||||||
/* Source line tracking. Subtract pseudo_newlines from the actual
|
/* Source line tracking. Subtract pseudo_newlines from the actual
|
||||||
line number to get the line number of preprocessed output. Used
|
line number to get the line number of preprocessed output. Used
|
||||||
for escaped newlines and macro args that cross multiple lines. */
|
for escaped newlines and macro args that cross multiple lines. */
|
||||||
|
struct line_maps line_maps;
|
||||||
unsigned int line;
|
unsigned int line;
|
||||||
unsigned int pseudo_newlines;
|
unsigned int pseudo_newlines;
|
||||||
|
|
||||||
|
@ -439,8 +440,7 @@ extern void _cpp_define_builtin PARAMS ((cpp_reader *, const char *));
|
||||||
extern void _cpp_do__Pragma PARAMS ((cpp_reader *));
|
extern void _cpp_do__Pragma PARAMS ((cpp_reader *));
|
||||||
extern void _cpp_init_directives PARAMS ((cpp_reader *));
|
extern void _cpp_init_directives PARAMS ((cpp_reader *));
|
||||||
extern void _cpp_init_internal_pragmas PARAMS ((cpp_reader *));
|
extern void _cpp_init_internal_pragmas PARAMS ((cpp_reader *));
|
||||||
extern void _cpp_do_file_change PARAMS ((cpp_reader *, enum cpp_fc_reason,
|
extern void _cpp_do_file_change PARAMS ((cpp_reader *, enum lc_reason));
|
||||||
const char *, unsigned int));
|
|
||||||
|
|
||||||
/* Utility routines and macros. */
|
/* Utility routines and macros. */
|
||||||
#define DSC(str) (const U_CHAR *)str, sizeof str - 1
|
#define DSC(str) (const U_CHAR *)str, sizeof str - 1
|
||||||
|
|
|
@ -496,6 +496,9 @@ cpp_create_reader (table, lang)
|
||||||
be needed. */
|
be needed. */
|
||||||
pfile->deps = deps_init ();
|
pfile->deps = deps_init ();
|
||||||
|
|
||||||
|
/* Initialise the line map. */
|
||||||
|
init_line_maps (&pfile->line_maps);
|
||||||
|
|
||||||
/* Initialize lexer state. */
|
/* Initialize lexer state. */
|
||||||
pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
|
pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
|
||||||
|
|
||||||
|
@ -585,6 +588,8 @@ cpp_destroy (pfile)
|
||||||
free (context);
|
free (context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free_line_maps (&pfile->line_maps);
|
||||||
|
|
||||||
result = pfile->errors;
|
result = pfile->errors;
|
||||||
free (pfile);
|
free (pfile);
|
||||||
|
|
||||||
|
@ -941,6 +946,11 @@ cpp_start_read (pfile, fname)
|
||||||
p = q;
|
p = q;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This was zero when the initial buffer was stacked; so we must
|
||||||
|
make up for a non-existent new line, as well as the intervening
|
||||||
|
macro definitions, by setting it to 1. */
|
||||||
|
pfile->line = 1;
|
||||||
|
|
||||||
/* The -imacros files can be scanned now, but the -include files
|
/* The -imacros files can be scanned now, but the -include files
|
||||||
have to be pushed onto the buffer stack and processed later,
|
have to be pushed onto the buffer stack and processed later,
|
||||||
otherwise cppmain.c won't see the tokens. include_head was built
|
otherwise cppmain.c won't see the tokens. include_head was built
|
||||||
|
|
19
gcc/cpplex.c
19
gcc/cpplex.c
|
@ -657,7 +657,7 @@ parse_string (pfile, token, terminator)
|
||||||
cpp_pool *pool = &pfile->ident_pool;
|
cpp_pool *pool = &pfile->ident_pool;
|
||||||
unsigned char *dest, *limit;
|
unsigned char *dest, *limit;
|
||||||
cppchar_t c;
|
cppchar_t c;
|
||||||
unsigned int nulls = 0;
|
bool warned_nulls = false, warned_multi = false;
|
||||||
|
|
||||||
dest = POOL_FRONT (pool);
|
dest = POOL_FRONT (pool);
|
||||||
limit = POOL_LIMIT (pool);
|
limit = POOL_LIMIT (pool);
|
||||||
|
@ -707,7 +707,12 @@ parse_string (pfile, token, terminator)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpp_pedwarn (pfile, "multi-line string literals are deprecated");
|
if (!warned_multi)
|
||||||
|
{
|
||||||
|
warned_multi = true;
|
||||||
|
cpp_pedwarn (pfile, "multi-line string literals are deprecated");
|
||||||
|
}
|
||||||
|
|
||||||
if (pfile->mlstring_pos.line == 0)
|
if (pfile->mlstring_pos.line == 0)
|
||||||
pfile->mlstring_pos = pfile->lexer_pos;
|
pfile->mlstring_pos = pfile->lexer_pos;
|
||||||
|
|
||||||
|
@ -715,10 +720,10 @@ parse_string (pfile, token, terminator)
|
||||||
*dest++ = '\n';
|
*dest++ = '\n';
|
||||||
goto have_char;
|
goto have_char;
|
||||||
}
|
}
|
||||||
else if (c == '\0')
|
else if (c == '\0' && !warned_nulls)
|
||||||
{
|
{
|
||||||
if (nulls++ == 0)
|
warned_nulls = true;
|
||||||
cpp_warning (pfile, "null character(s) preserved in literal");
|
cpp_warning (pfile, "null character(s) preserved in literal");
|
||||||
}
|
}
|
||||||
|
|
||||||
*dest++ = c;
|
*dest++ = c;
|
||||||
|
@ -914,8 +919,8 @@ _cpp_lex_token (pfile, result)
|
||||||
bol = 1;
|
bol = 1;
|
||||||
pfile->lexer_pos.output_line = buffer->lineno;
|
pfile->lexer_pos.output_line = buffer->lineno;
|
||||||
/* This is a new line, so clear any white space flag.
|
/* This is a new line, so clear any white space flag.
|
||||||
Newlines in arguments are white space (6.10.3.10);
|
Newlines in arguments are white space (6.10.3.10);
|
||||||
parse_arg takes care of that. */
|
parse_arg takes care of that. */
|
||||||
result->flags &= ~(PREV_WHITE | AVOID_LPASTE);
|
result->flags &= ~(PREV_WHITE | AVOID_LPASTE);
|
||||||
goto next_char;
|
goto next_char;
|
||||||
}
|
}
|
||||||
|
|
103
gcc/cpplib.c
103
gcc/cpplib.c
|
@ -379,7 +379,8 @@ _cpp_handle_directive (pfile, indented)
|
||||||
cpp_token_as_text (pfile, &dname));
|
cpp_token_as_text (pfile, &dname));
|
||||||
}
|
}
|
||||||
|
|
||||||
end_directive (pfile, skip);
|
if (pfile->state.in_directive)
|
||||||
|
end_directive (pfile, skip);
|
||||||
return skip;
|
return skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -623,7 +624,7 @@ do_include_common (pfile, type)
|
||||||
{
|
{
|
||||||
check_eol (pfile);
|
check_eol (pfile);
|
||||||
/* Get out of macro context, if we are. */
|
/* Get out of macro context, if we are. */
|
||||||
skip_rest_of_line (pfile);
|
end_directive (pfile, 1);
|
||||||
if (pfile->cb.include)
|
if (pfile->cb.include)
|
||||||
(*pfile->cb.include) (pfile, pfile->directive->name, &header);
|
(*pfile->cb.include) (pfile, pfile->directive->name, &header);
|
||||||
|
|
||||||
|
@ -713,9 +714,7 @@ do_line (pfile)
|
||||||
cpp_reader *pfile;
|
cpp_reader *pfile;
|
||||||
{
|
{
|
||||||
cpp_buffer *buffer = pfile->buffer;
|
cpp_buffer *buffer = pfile->buffer;
|
||||||
const char *filename = buffer->nominal_fname;
|
enum lc_reason reason = LC_RENAME;
|
||||||
unsigned int lineno = buffer->lineno;
|
|
||||||
enum cpp_fc_reason reason = FC_RENAME;
|
|
||||||
unsigned long new_lineno;
|
unsigned long new_lineno;
|
||||||
unsigned int cap;
|
unsigned int cap;
|
||||||
cpp_token token;
|
cpp_token token;
|
||||||
|
@ -733,7 +732,8 @@ do_line (pfile)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CPP_PEDANTIC (pfile) && (new_lineno == 0 || new_lineno > cap))
|
if (CPP_PEDANTIC (pfile) && ! pfile->state.line_extension
|
||||||
|
&& (new_lineno == 0 || new_lineno > cap))
|
||||||
cpp_pedwarn (pfile, "line number out of range");
|
cpp_pedwarn (pfile, "line number out of range");
|
||||||
|
|
||||||
cpp_get_token (pfile, &token);
|
cpp_get_token (pfile, &token);
|
||||||
|
@ -751,12 +751,12 @@ do_line (pfile)
|
||||||
flag = read_flag (pfile, flag);
|
flag = read_flag (pfile, flag);
|
||||||
if (flag == 1)
|
if (flag == 1)
|
||||||
{
|
{
|
||||||
reason = FC_ENTER;
|
reason = LC_ENTER;
|
||||||
flag = read_flag (pfile, flag);
|
flag = read_flag (pfile, flag);
|
||||||
}
|
}
|
||||||
else if (flag == 2)
|
else if (flag == 2)
|
||||||
{
|
{
|
||||||
reason = FC_LEAVE;
|
reason = LC_LEAVE;
|
||||||
flag = read_flag (pfile, flag);
|
flag = read_flag (pfile, flag);
|
||||||
}
|
}
|
||||||
if (flag == 3)
|
if (flag == 3)
|
||||||
|
@ -767,7 +767,7 @@ do_line (pfile)
|
||||||
sysp = 2, read_flag (pfile, flag);
|
sysp = 2, read_flag (pfile, flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reason == FC_ENTER)
|
if (reason == LC_ENTER)
|
||||||
{
|
{
|
||||||
/* Fake a buffer stack for diagnostics. */
|
/* Fake a buffer stack for diagnostics. */
|
||||||
cpp_push_buffer (pfile, 0, 0, BUF_FAKE, fname);
|
cpp_push_buffer (pfile, 0, 0, BUF_FAKE, fname);
|
||||||
|
@ -775,7 +775,7 @@ do_line (pfile)
|
||||||
_cpp_fake_include (pfile, fname);
|
_cpp_fake_include (pfile, fname);
|
||||||
buffer = pfile->buffer;
|
buffer = pfile->buffer;
|
||||||
}
|
}
|
||||||
else if (reason == FC_LEAVE)
|
else if (reason == LC_LEAVE)
|
||||||
{
|
{
|
||||||
if (buffer->type != BUF_FAKE)
|
if (buffer->type != BUF_FAKE)
|
||||||
cpp_warning (pfile, "file \"%s\" left but not entered",
|
cpp_warning (pfile, "file \"%s\" left but not entered",
|
||||||
|
@ -808,49 +808,36 @@ do_line (pfile)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Our line number is incremented after the directive is processed. */
|
end_directive (pfile, 1);
|
||||||
buffer->lineno = new_lineno - 1;
|
buffer->lineno = new_lineno - 1;
|
||||||
_cpp_do_file_change (pfile, reason, filename, lineno);
|
_cpp_do_file_change (pfile, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Arrange the file_change callback. */
|
/* Arrange the file_change callback. It is assumed that the next line
|
||||||
|
is given by incrementing buffer->lineno and pfile->line. */
|
||||||
void
|
void
|
||||||
_cpp_do_file_change (pfile, reason, from_file, from_lineno)
|
_cpp_do_file_change (pfile, reason)
|
||||||
cpp_reader *pfile;
|
cpp_reader *pfile;
|
||||||
enum cpp_fc_reason reason;
|
enum lc_reason reason;
|
||||||
const char *from_file;
|
|
||||||
unsigned int from_lineno;
|
|
||||||
{
|
{
|
||||||
|
cpp_buffer *buffer;
|
||||||
|
struct line_map *map;
|
||||||
|
|
||||||
|
buffer = pfile->buffer;
|
||||||
|
map = add_line_map (&pfile->line_maps, reason,
|
||||||
|
pfile->line + 1, buffer->nominal_fname, buffer->lineno + 1);
|
||||||
|
|
||||||
if (pfile->cb.file_change)
|
if (pfile->cb.file_change)
|
||||||
{
|
{
|
||||||
cpp_file_change fc;
|
cpp_file_change fc;
|
||||||
cpp_buffer *buffer = pfile->buffer;
|
|
||||||
|
fc.map = map;
|
||||||
|
fc.line = pfile->line + 1;
|
||||||
fc.reason = reason;
|
fc.reason = reason;
|
||||||
fc.to.filename = buffer->nominal_fname;
|
|
||||||
fc.to.lineno = buffer->lineno + 1;
|
|
||||||
fc.sysp = buffer->sysp;
|
fc.sysp = buffer->sysp;
|
||||||
fc.externc = CPP_OPTION (pfile, cplusplus) && buffer->sysp == 2;
|
fc.externc = CPP_OPTION (pfile, cplusplus) && buffer->sysp == 2;
|
||||||
|
|
||||||
/* Caller doesn't need to handle FC_ENTER. */
|
(*pfile->cb.file_change) (pfile, &fc);
|
||||||
if (reason == FC_ENTER)
|
|
||||||
{
|
|
||||||
if (buffer->prev)
|
|
||||||
{
|
|
||||||
from_file = buffer->prev->nominal_fname;
|
|
||||||
from_lineno = buffer->prev->lineno;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
from_file = 0;
|
|
||||||
}
|
|
||||||
/* Special case for file "foo.i" with "# 1 foo.c" on first line. */
|
|
||||||
else if (reason == FC_RENAME && ! buffer->prev
|
|
||||||
&& pfile->directive_pos.line == 1)
|
|
||||||
from_file = 0;
|
|
||||||
|
|
||||||
fc.from.filename = from_file;
|
|
||||||
fc.from.lineno = from_lineno;
|
|
||||||
pfile->cb.file_change (pfile, &fc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -915,6 +902,7 @@ do_ident (pfile)
|
||||||
|
|
||||||
/* Sub-handlers for the pragmas needing treatment here.
|
/* Sub-handlers for the pragmas needing treatment here.
|
||||||
They return 1 if the token buffer is to be popped, 0 if not. */
|
They return 1 if the token buffer is to be popped, 0 if not. */
|
||||||
|
typedef void (*pragma_cb) PARAMS ((cpp_reader *));
|
||||||
struct pragma_entry
|
struct pragma_entry
|
||||||
{
|
{
|
||||||
struct pragma_entry *next;
|
struct pragma_entry *next;
|
||||||
|
@ -922,7 +910,7 @@ struct pragma_entry
|
||||||
size_t len;
|
size_t len;
|
||||||
int isnspace;
|
int isnspace;
|
||||||
union {
|
union {
|
||||||
void (*handler) PARAMS ((cpp_reader *));
|
pragma_cb handler;
|
||||||
struct pragma_entry *space;
|
struct pragma_entry *space;
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
@ -932,7 +920,7 @@ cpp_register_pragma (pfile, space, name, handler)
|
||||||
cpp_reader *pfile;
|
cpp_reader *pfile;
|
||||||
const char *space;
|
const char *space;
|
||||||
const char *name;
|
const char *name;
|
||||||
void (*handler) PARAMS ((cpp_reader *));
|
pragma_cb handler;
|
||||||
{
|
{
|
||||||
struct pragma_entry **x, *new;
|
struct pragma_entry **x, *new;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
@ -1014,9 +1002,9 @@ static void
|
||||||
do_pragma (pfile)
|
do_pragma (pfile)
|
||||||
cpp_reader *pfile;
|
cpp_reader *pfile;
|
||||||
{
|
{
|
||||||
|
pragma_cb handler = NULL;
|
||||||
const struct pragma_entry *p;
|
const struct pragma_entry *p;
|
||||||
cpp_token tok;
|
cpp_token tok;
|
||||||
int drop = 0;
|
|
||||||
|
|
||||||
p = pfile->pragmas;
|
p = pfile->pragmas;
|
||||||
pfile->state.prevent_expansion++;
|
pfile->state.prevent_expansion++;
|
||||||
|
@ -1041,8 +1029,7 @@ do_pragma (pfile)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(*p->u.handler) (pfile);
|
handler = p->u.handler;
|
||||||
drop = 1;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1050,10 +1037,12 @@ do_pragma (pfile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cpp_stop_lookahead (pfile, drop);
|
cpp_stop_lookahead (pfile, handler != NULL);
|
||||||
pfile->state.prevent_expansion--;
|
pfile->state.prevent_expansion--;
|
||||||
|
|
||||||
if (!drop && pfile->cb.def_pragma)
|
if (handler)
|
||||||
|
(*handler) (pfile);
|
||||||
|
else if (pfile->cb.def_pragma)
|
||||||
(*pfile->cb.def_pragma) (pfile);
|
(*pfile->cb.def_pragma) (pfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1119,9 +1108,11 @@ do_pragma_system_header (pfile)
|
||||||
if (buffer->prev == 0)
|
if (buffer->prev == 0)
|
||||||
cpp_warning (pfile, "#pragma system_header ignored outside include file");
|
cpp_warning (pfile, "#pragma system_header ignored outside include file");
|
||||||
else
|
else
|
||||||
cpp_make_system_header (pfile, 1, 0);
|
{
|
||||||
|
check_eol (pfile);
|
||||||
check_eol (pfile);
|
end_directive (pfile, 1);
|
||||||
|
cpp_make_system_header (pfile, 1, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the modified date of the current include file against a specified
|
/* Check the modified date of the current include file against a specified
|
||||||
|
@ -1763,6 +1754,14 @@ cpp_get_callbacks (pfile)
|
||||||
return &pfile->cb;
|
return &pfile->cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The line map set. */
|
||||||
|
struct line_maps *
|
||||||
|
cpp_get_line_maps (pfile)
|
||||||
|
cpp_reader *pfile;
|
||||||
|
{
|
||||||
|
return &pfile->line_maps;
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy the given callbacks structure to our own. */
|
/* Copy the given callbacks structure to our own. */
|
||||||
void
|
void
|
||||||
cpp_set_callbacks (pfile, cb)
|
cpp_set_callbacks (pfile, cb)
|
||||||
|
@ -1875,8 +1874,8 @@ cpp_pop_buffer (pfile)
|
||||||
if (pfile->directive == &dtable[T_LINE])
|
if (pfile->directive == &dtable[T_LINE])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
_cpp_do_file_change (pfile, FC_LEAVE, buffer->nominal_fname,
|
pfile->line--; /* We have a '\n' at the end of #include. */
|
||||||
buffer->lineno);
|
_cpp_do_file_change (pfile, LC_LEAVE);
|
||||||
if (pfile->buffer->type == BUF_FILE)
|
if (pfile->buffer->type == BUF_FILE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
17
gcc/cpplib.h
17
gcc/cpplib.h
|
@ -25,6 +25,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include "hashtable.h"
|
#include "hashtable.h"
|
||||||
|
#include "line-map.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -386,21 +387,12 @@ struct cpp_options
|
||||||
unsigned char help_only;
|
unsigned char help_only;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This structure is passed to the call back when changing file. */
|
|
||||||
enum cpp_fc_reason {FC_ENTER = 0, FC_LEAVE, FC_RENAME};
|
|
||||||
|
|
||||||
struct cpp_file_loc
|
|
||||||
{
|
|
||||||
const char *filename;
|
|
||||||
unsigned int lineno;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct cpp_file_change cpp_file_change;
|
typedef struct cpp_file_change cpp_file_change;
|
||||||
struct cpp_file_change
|
struct cpp_file_change
|
||||||
{
|
{
|
||||||
struct cpp_file_loc from; /* Line of #include or #line. */
|
struct line_map *map; /* Line map to use until next callback. */
|
||||||
struct cpp_file_loc to; /* Line after #include or #line, or start. */
|
unsigned int line; /* Logical line number of next line. */
|
||||||
enum cpp_fc_reason reason; /* Reason for change. */
|
enum lc_reason reason; /* Reason for change. */
|
||||||
unsigned char sysp; /* Nonzero if system header. */
|
unsigned char sysp; /* Nonzero if system header. */
|
||||||
unsigned char externc; /* Nonzero if wrapper needed. */
|
unsigned char externc; /* Nonzero if wrapper needed. */
|
||||||
};
|
};
|
||||||
|
@ -510,6 +502,7 @@ extern int cpp_destroy PARAMS ((cpp_reader *));
|
||||||
through the pointer returned from cpp_get_callbacks, or set them
|
through the pointer returned from cpp_get_callbacks, or set them
|
||||||
with cpp_set_callbacks. */
|
with cpp_set_callbacks. */
|
||||||
extern cpp_options *cpp_get_options PARAMS ((cpp_reader *));
|
extern cpp_options *cpp_get_options PARAMS ((cpp_reader *));
|
||||||
|
extern struct line_maps *cpp_get_line_maps PARAMS ((cpp_reader *));
|
||||||
extern cpp_callbacks *cpp_get_callbacks PARAMS ((cpp_reader *));
|
extern cpp_callbacks *cpp_get_callbacks PARAMS ((cpp_reader *));
|
||||||
extern void cpp_set_callbacks PARAMS ((cpp_reader *, cpp_callbacks *));
|
extern void cpp_set_callbacks PARAMS ((cpp_reader *, cpp_callbacks *));
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ struct printer
|
||||||
const char *syshdr_flags; /* system header flags, if any. */
|
const char *syshdr_flags; /* system header flags, if any. */
|
||||||
unsigned int lineno; /* line currently being written. */
|
unsigned int lineno; /* line currently being written. */
|
||||||
unsigned char printed; /* nonzero if something output at lineno. */
|
unsigned char printed; /* nonzero if something output at lineno. */
|
||||||
|
struct line_map *map; /* logical to physical line mappings. */
|
||||||
};
|
};
|
||||||
|
|
||||||
int main PARAMS ((int, char **));
|
int main PARAMS ((int, char **));
|
||||||
|
@ -402,10 +403,11 @@ cb_file_change (pfile, fc)
|
||||||
const cpp_file_change *fc;
|
const cpp_file_change *fc;
|
||||||
{
|
{
|
||||||
/* Bring current file to correct line (except first file). */
|
/* Bring current file to correct line (except first file). */
|
||||||
if (fc->reason == FC_ENTER && fc->from.filename)
|
if (fc->reason == LC_ENTER && !MAIN_FILE_P (fc->map))
|
||||||
maybe_print_line (fc->from.lineno);
|
maybe_print_line (SOURCE_LINE (fc->map - 1, fc->line - 1));
|
||||||
|
|
||||||
print.last_fname = fc->to.filename;
|
print.map = fc->map;
|
||||||
|
print.last_fname = fc->map->to_file;
|
||||||
if (fc->externc)
|
if (fc->externc)
|
||||||
print.syshdr_flags = " 3 4";
|
print.syshdr_flags = " 3 4";
|
||||||
else if (fc->sysp)
|
else if (fc->sysp)
|
||||||
|
@ -417,10 +419,10 @@ cb_file_change (pfile, fc)
|
||||||
{
|
{
|
||||||
const char *flags = "";
|
const char *flags = "";
|
||||||
|
|
||||||
print.lineno = fc->to.lineno;
|
print.lineno = SOURCE_LINE (fc->map, fc->line);
|
||||||
if (fc->reason == FC_ENTER)
|
if (fc->reason == LC_ENTER)
|
||||||
flags = " 1";
|
flags = " 1";
|
||||||
else if (fc->reason == FC_LEAVE)
|
else if (fc->reason == LC_LEAVE)
|
||||||
flags = " 2";
|
flags = " 2";
|
||||||
|
|
||||||
if (! options->no_line_commands)
|
if (! options->no_line_commands)
|
||||||
|
@ -428,6 +430,8 @@ cb_file_change (pfile, fc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Copy a #pragma directive to the preprocessed output. LINE is the
|
||||||
|
line of the current source file, not the logical line. */
|
||||||
static void
|
static void
|
||||||
cb_def_pragma (pfile)
|
cb_def_pragma (pfile)
|
||||||
cpp_reader *pfile;
|
cpp_reader *pfile;
|
||||||
|
|
|
@ -603,7 +603,7 @@ cb_file_change (pfile, fc)
|
||||||
const cpp_file_change *fc;
|
const cpp_file_change *fc;
|
||||||
{
|
{
|
||||||
/* Just keep track of current file name. */
|
/* Just keep track of current file name. */
|
||||||
cur_file = fc->to.filename;
|
cur_file = fc->map->to_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
/* Map logical line numbers to (source file, line number) pairs.
|
||||||
|
Copyright (C) 2001
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2, or (at your option) any
|
||||||
|
later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
In other words, you are welcome to use, share and improve this program.
|
||||||
|
You are forbidden to forbid anyone else to use, share and improve
|
||||||
|
what you give them. Help stamp out software-hoarding! */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "line-map.h"
|
||||||
|
|
||||||
|
/* Initialize a line map set. */
|
||||||
|
|
||||||
|
void
|
||||||
|
init_line_maps (set)
|
||||||
|
struct line_maps *set;
|
||||||
|
{
|
||||||
|
set->maps = 0;
|
||||||
|
set->allocated = 0;
|
||||||
|
set->used = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free a line map set. */
|
||||||
|
|
||||||
|
void free_line_maps (set)
|
||||||
|
struct line_maps *set;
|
||||||
|
{
|
||||||
|
if (set->maps)
|
||||||
|
free (set->maps);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add a mapping of logical source line to physical source file and
|
||||||
|
line number. Ther text pointed to by TO_FILE must have a lifetime
|
||||||
|
at least as long as the final call to lookup_line ().
|
||||||
|
|
||||||
|
FROM_LINE should be monotonic increasing across calls to this
|
||||||
|
function. */
|
||||||
|
|
||||||
|
struct line_map *
|
||||||
|
add_line_map (set, reason, from_line, to_file, to_line)
|
||||||
|
struct line_maps *set;
|
||||||
|
enum lc_reason reason;
|
||||||
|
unsigned int from_line;
|
||||||
|
const char *to_file;
|
||||||
|
unsigned int to_line;
|
||||||
|
{
|
||||||
|
struct line_map *map;
|
||||||
|
|
||||||
|
if (set->used && from_line < set->maps[set->used - 1].from_line)
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
if (set->used == set->allocated)
|
||||||
|
{
|
||||||
|
set->allocated = 2 * set->allocated + 256;
|
||||||
|
set->maps = (struct line_map *)
|
||||||
|
xrealloc (set->maps, set->allocated * sizeof (struct line_map));
|
||||||
|
}
|
||||||
|
|
||||||
|
map = &set->maps[set->used];
|
||||||
|
map->from_line = from_line;
|
||||||
|
map->to_file = to_file;
|
||||||
|
map->to_line = to_line;
|
||||||
|
|
||||||
|
if (set->used == 0)
|
||||||
|
map->included_from = -1;
|
||||||
|
else if (reason == LC_ENTER)
|
||||||
|
map->included_from = set->used - 1;
|
||||||
|
else if (reason == LC_RENAME)
|
||||||
|
map->included_from = map[-1].included_from;
|
||||||
|
else if (reason == LC_LEAVE)
|
||||||
|
{
|
||||||
|
if (map[-1].included_from < 0)
|
||||||
|
abort ();
|
||||||
|
map->included_from = set->maps[map[-1].included_from].included_from;
|
||||||
|
}
|
||||||
|
|
||||||
|
set->used++;
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Translate a logical line number into a (source file, line) pair. */
|
||||||
|
|
||||||
|
struct line_map *
|
||||||
|
lookup_line (set, line)
|
||||||
|
struct line_maps *set;
|
||||||
|
unsigned int line;
|
||||||
|
{
|
||||||
|
unsigned int md, mn = 0, mx = set->used;
|
||||||
|
|
||||||
|
if (mx == 0)
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
while (mx - mn > 1)
|
||||||
|
{
|
||||||
|
md = (mn + mx) / 2;
|
||||||
|
if (set->maps[md].from_line > line)
|
||||||
|
mx = md;
|
||||||
|
else
|
||||||
|
mn = md;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &set->maps[mn];
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
/* Map logical line numbers to (source file, line number) pairs.
|
||||||
|
Copyright (C) 2001
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2, or (at your option) any
|
||||||
|
later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
In other words, you are welcome to use, share and improve this program.
|
||||||
|
You are forbidden to forbid anyone else to use, share and improve
|
||||||
|
what you give them. Help stamp out software-hoarding! */
|
||||||
|
|
||||||
|
#ifndef GCC_LINE_MAP_H
|
||||||
|
#define GCC_LINE_MAP_H
|
||||||
|
|
||||||
|
/* The logical line FROM_LINE maps to physical source file TO_FILE at
|
||||||
|
line TO_LINE, and subsequently one-to-one until the next line_map
|
||||||
|
structure in the set. */
|
||||||
|
struct line_map
|
||||||
|
{
|
||||||
|
const char *to_file;
|
||||||
|
unsigned int to_line;
|
||||||
|
unsigned int from_line;
|
||||||
|
int included_from;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Contains a sequence of chronological line_map structures. */
|
||||||
|
struct line_maps
|
||||||
|
{
|
||||||
|
struct line_map *maps;
|
||||||
|
unsigned int allocated;
|
||||||
|
unsigned int used;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Reason for adding a line change with add_line_map (). */
|
||||||
|
enum lc_reason {LC_ENTER = 0, LC_LEAVE, LC_RENAME};
|
||||||
|
|
||||||
|
/* Initialize a line map set. */
|
||||||
|
extern void init_line_maps
|
||||||
|
PARAMS ((struct line_maps *));
|
||||||
|
|
||||||
|
/* Free a line map set. */
|
||||||
|
extern void free_line_maps
|
||||||
|
PARAMS ((struct line_maps *));
|
||||||
|
|
||||||
|
/* Add a mapping of logical source line to physical source file and
|
||||||
|
line number. Ther text pointed to by TO_FILE must have a lifetime
|
||||||
|
at least as long as the final call to lookup_line ().
|
||||||
|
|
||||||
|
FROM_LINE should be monotonic increasing across calls to this
|
||||||
|
function. */
|
||||||
|
extern struct line_map *add_line_map
|
||||||
|
PARAMS ((struct line_maps *, enum lc_reason,
|
||||||
|
unsigned int from_line, const char *to_file, unsigned int to_line));
|
||||||
|
|
||||||
|
/* Given a logical line, returns the map from which the corresponding
|
||||||
|
(source file, line) pair can be deduced. */
|
||||||
|
extern struct line_map *lookup_line
|
||||||
|
PARAMS ((struct line_maps *, unsigned int));
|
||||||
|
|
||||||
|
/* Converts a map and logical line to source line. */
|
||||||
|
#define SOURCE_LINE(MAP, LINE) ((LINE) + (MAP)->to_line - (MAP)->from_line)
|
||||||
|
|
||||||
|
/* Returns the last source line within a map. This is the (last) line
|
||||||
|
of the #include, or other directive, that caused a map change. */
|
||||||
|
#define LAST_SOURCE_LINE(MAP) SOURCE_LINE (MAP, (MAP)[1].from_line - 1)
|
||||||
|
|
||||||
|
#define MAIN_FILE_P(MAP) ((MAP)->included_from < 0)
|
||||||
|
|
||||||
|
#endif /* !GCC_LINE_MAP_H */
|
|
@ -1,3 +1,7 @@
|
||||||
|
2001-08-02 Neil Booth <neil@daikokuya.demon.co.uk>
|
||||||
|
|
||||||
|
* gcc.dg/cpp/19951025-1.c: Update.
|
||||||
|
|
||||||
2001-08-02 Jeffrey Oldham <oldham@codesourcery.com>
|
2001-08-02 Jeffrey Oldham <oldham@codesourcery.com>
|
||||||
|
|
||||||
* g77.dg/ff90-1.f (s): Fix reference of variable z,
|
* g77.dg/ff90-1.f (s): Fix reference of variable z,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* { dg-do preprocess } */
|
/* { dg-do preprocess } */
|
||||||
/* { dg-error "include expects" "" { target *-*-* } 4 } */
|
/* { dg-error "include expects" "" { target *-*-* } 5 } */
|
||||||
/* { dg-error "newline at end" "" { target *-*-* } 4 } */
|
/* { dg-error "newline at end" "" { target *-*-* } 5 } */
|
||||||
#include /\
|
#include /\
|
||||||
|
|
Loading…
Reference in New Issue