Commit 12f9df4e by Per Bothner Committed by Per Bothner

Represent column numbers using line-map's source_location.

	The "next available source_location" is now managed internally by
	line-maps.c rather than by clients.
	* line-map.h (struct line_map):  New field column_bits.
	<from_line>:  Rename field to start_location.
	(struct line_maps):  New fields highest_location and max_column_hint.
	(linemap_check_files_exited):  New declaration.
	(linemap_line_start):  New declaration.
	(linemap_add):  Remove from_line parameter; use highest_location field.
	(SOURCE_LINE, LAST_SOURCE_LINE):  Modify to use column_bits.
	(SOURCE_COLUMN, LAST_SOURCE_LINE_LOCATION):  New macros.
	(CURRENT_LINE_MAP):  Remove macro.
	(linemap_position_for_column):  New inline function.
	* line-map.c (linemap_init):  Clear new fields.
	(linemap_check_files_exited):  New function, extracted from ...
	(linemap_free):  Use linemap_check_files_exited.
	(linemap_add):  Remove from_line parameter.  Various updates.
	(linemap_line_start):  New function.
	(linemap_lookeup):  Update for new field names.
	* cpphash.h (struct cpp_reader) <map>:  Field removed.  Because
	linemap_position_for_column may unpredictably change the current map,
	it is cleaner and simpler for us to not cache it in cpp_reader.
	(struct cpp_buffer):  New sysp field.
	Changed warned_cplusplus_comments and from_stage3 to bitfields.
	* cppinit.c (cpp_read_min_file):  pfile->map no longer exists.
	* cpplib.c (do_line, do_linemarker, _cpp_do_file_change):  Get
	current map using linemap_lookup.
	(do_linemarker):  Also set buffer's sysp field.
	(destringize_and_run):  No longer need to decrement current line.
	* cppfiles.c (_cpp_stack_file):  Set sysp from and in buffer.
	(search_path_head, open_file_failed):  Use buffer's sysp.
	(cpp_make_system_header):  Get current map using linemap_lookup.
	Also set buffer's sysp flag.
	* cppmacro.c (_cpp_builtin_macro_text):  Likewise use linemap_lookup.
	* cpphash.h (CPP_INCREMENT_LINE):  New macro.
	(struct cpp_buffer):  Moved fields saved_cur, saved_rlimit to ...
	(struct cpp_reader):  ... and adding saved_line_base field.
	* cpptrad.c (_cpp_overlay_buffer, _cpp_remove_overlay):
	Update accordingly.  Don't adjust line.
	(_cpp_scan_out_logical_line):  Use CPP_INCREMENT_LINE.
	* cpphash.c (CPP_IN_SYSTEM_HEADER):  Replaced macro by ...
	(cpp_in_system_header):  ... new inline function, using buffer's sysp.
	* cpperror.c (_cpp_begin_message):  Update to use cpp_in_system_header.
	* cpplex.c (_cpp_lex_direct):  Likewise.
	* cppmacro.c (_cpp_builtin_macro_text):  Likewise.
	* cppmacro.c (_cpp_create_definition):  Use buffer's sysp field.
	* cpplib.h (struct cpp_token):  Rename line field to src_loc.
	Remove col field as it is now subsumed by src_loc.
	* cpperror.c:  Update various field, parameter, and macro names.
	(print_location):  If col==0, try SOURCE_COLUMN of line.
	(cpp_error):  Use cur_token's src_loc field, rather than line+col.
	* cpplib.c (do_diagnostic):  Token's src_loc fields replaces line+col.
	* cpplex.c (_cpp_process_line_notes, _cpp_lex_direct,
	_cpp_skip_block_comment):  Use CPP_INCREMENT_LINE.
	(_cpp_temp_token):  Replace cpp_token's line+col fields by src_loc.
	(_cpp_get_fresh_line):  Don't need to adjust line for missing newline.
	(_cpp_lex_direct):  Use linemap_position_for_column.
	* c-ppoutput.c (maybe_print_line, print_line):  Don't take map
	parameter.  Instead get it from the line_table global.  Adjust callers.
	(print):  Remove map field.  Replace line field to src_line.
	(init_pp_output, account_for_newlines, maybe_print_line):  Adjust.
	(cb_line_change):  Use SOURCE_COLUMN.  Minor optimizations.
	(pp_file_change):  Use MAIN_FILE_P since we cannot checked print.map.
	Use LAST_SOURCE_LINE_LOCATION to "catch up" after #include.
	* cpptrad.c (copy_comment):  Rename variable.
	* c-lex.c (map):  Remove static variable, for same reason we removed
	cpp_reader's map field.
	(cb_line_change, cb_def_pragma, cb_define, cb_undef):  Hence we need
	to call linemap_lookup.
	(cb_line_change):  Token's line field replaced by src_loc.
	(fe_file_change):  Use MAINFILE_P and LAST_SOURCE_LINE macros.
	Don't save new_map.

	* cpphash.h, cpperror.c, cpplib.h:  Some renames of fileline to
	source_location.

From-SVN: r77663
parent 8914b65e
2004-02-11 Per Bothner <per@bothner.com>
Represent column numbers using line-map's source_location.
The "next available source_location" is now managed internally by
line-maps.c rather than by clients.
* line-map.h (struct line_map): New field column_bits.
<from_line>: Rename field to start_location.
(struct line_maps): New fields highest_location and max_column_hint.
(linemap_check_files_exited): New declaration.
(linemap_line_start): New declaration.
(linemap_add): Remove from_line parameter; use highest_location field.
(SOURCE_LINE, LAST_SOURCE_LINE): Modify to use column_bits.
(SOURCE_COLUMN, LAST_SOURCE_LINE_LOCATION): New macros.
(CURRENT_LINE_MAP): Remove macro.
(linemap_position_for_column): New inline function.
* line-map.c (linemap_init): Clear new fields.
(linemap_check_files_exited): New function, extracted from ...
(linemap_free): Use linemap_check_files_exited.
(linemap_add): Remove from_line parameter. Various updates.
(linemap_line_start): New function.
(linemap_lookeup): Update for new field names.
* cpphash.h (struct cpp_reader) <map>: Field removed. Because
linemap_position_for_column may unpredictably change the current map,
it is cleaner and simpler for us to not cache it in cpp_reader.
(struct cpp_buffer): New sysp field.
Changed warned_cplusplus_comments and from_stage3 to bitfields.
* cppinit.c (cpp_read_min_file): pfile->map no longer exists.
* cpplib.c (do_line, do_linemarker, _cpp_do_file_change): Get
current map using linemap_lookup.
(do_linemarker): Also set buffer's sysp field.
(destringize_and_run): No longer need to decrement current line.
* cppfiles.c (_cpp_stack_file): Set sysp from and in buffer.
(search_path_head, open_file_failed): Use buffer's sysp.
(cpp_make_system_header): Get current map using linemap_lookup.
Also set buffer's sysp flag.
* cppmacro.c (_cpp_builtin_macro_text): Likewise use linemap_lookup.
* cpphash.h (CPP_INCREMENT_LINE): New macro.
(struct cpp_buffer): Moved fields saved_cur, saved_rlimit to ...
(struct cpp_reader): ... and adding saved_line_base field.
* cpptrad.c (_cpp_overlay_buffer, _cpp_remove_overlay):
Update accordingly. Don't adjust line.
(_cpp_scan_out_logical_line): Use CPP_INCREMENT_LINE.
* cpphash.c (CPP_IN_SYSTEM_HEADER): Replaced macro by ...
(cpp_in_system_header): ... new inline function, using buffer's sysp.
* cpperror.c (_cpp_begin_message): Update to use cpp_in_system_header.
* cpplex.c (_cpp_lex_direct): Likewise.
* cppmacro.c (_cpp_builtin_macro_text): Likewise.
* cppmacro.c (_cpp_create_definition): Use buffer's sysp field.
* cpplib.h (struct cpp_token): Rename line field to src_loc.
Remove col field as it is now subsumed by src_loc.
* cpperror.c: Update various field, parameter, and macro names.
(print_location): If col==0, try SOURCE_COLUMN of line.
(cpp_error): Use cur_token's src_loc field, rather than line+col.
* cpplib.c (do_diagnostic): Token's src_loc fields replaces line+col.
* cpplex.c (_cpp_process_line_notes, _cpp_lex_direct,
_cpp_skip_block_comment): Use CPP_INCREMENT_LINE.
(_cpp_temp_token): Replace cpp_token's line+col fields by src_loc.
(_cpp_get_fresh_line): Don't need to adjust line for missing newline.
(_cpp_lex_direct): Use linemap_position_for_column.
* c-ppoutput.c (maybe_print_line, print_line): Don't take map
parameter. Instead get it from the line_table global. Adjust callers.
(print): Remove map field. Replace line field to src_line.
(init_pp_output, account_for_newlines, maybe_print_line): Adjust.
(cb_line_change): Use SOURCE_COLUMN. Minor optimizations.
(pp_file_change): Use MAIN_FILE_P since we cannot checked print.map.
Use LAST_SOURCE_LINE_LOCATION to "catch up" after #include.
* cpptrad.c (copy_comment): Rename variable.
* c-lex.c (map): Remove static variable, for same reason we removed
cpp_reader's map field.
(cb_line_change, cb_def_pragma, cb_define, cb_undef): Hence we need
to call linemap_lookup.
(cb_line_change): Token's line field replaced by src_loc.
(fe_file_change): Use MAINFILE_P and LAST_SOURCE_LINE macros.
Don't save new_map.
* cpphash.h, cpperror.c, cpplib.h: Some renames of fileline to
source_location.
2004-02-11 Hartmut Penner <hpenner@de.ibm.com> 2004-02-11 Hartmut Penner <hpenner@de.ibm.com>
* config/rs6000/altivec.md (*movv4si_internal): At least one * config/rs6000/altivec.md (*movv4si_internal): At least one
......
...@@ -42,9 +42,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -42,9 +42,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "splay-tree.h" #include "splay-tree.h"
#include "debug.h" #include "debug.h"
/* The current line map. */
static const struct line_map *map;
/* We may keep statistics about how long which files took to compile. */ /* We may keep statistics about how long which files took to compile. */
static int header_time, body_time; static int header_time, body_time;
static splay_tree file_info_tree; static splay_tree file_info_tree;
...@@ -194,28 +191,27 @@ static void ...@@ -194,28 +191,27 @@ static void
cb_line_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const cpp_token *token, cb_line_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const cpp_token *token,
int parsing_args) int parsing_args)
{ {
if (token->type == CPP_EOF || parsing_args) if (token->type != CPP_EOF && !parsing_args)
return; {
source_location loc = token->src_loc;
input_line = SOURCE_LINE (map, token->line); const struct line_map *map = linemap_lookup (&line_table, loc);
input_line = SOURCE_LINE (map, loc);
}
} }
void void
fe_file_change (const struct line_map *new_map) fe_file_change (const struct line_map *new_map)
{ {
if (new_map == NULL) if (new_map == NULL)
{ return;
map = NULL;
return;
}
if (new_map->reason == LC_ENTER) if (new_map->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 (map != NULL) if (! MAIN_FILE_P (new_map))
{ {
int included_at = SOURCE_LINE (new_map - 1, new_map->from_line - 1); int included_at = LAST_SOURCE_LINE (new_map - 1);
input_line = included_at; input_line = included_at;
push_srcloc (new_map->to_file, 1); push_srcloc (new_map->to_file, 1);
...@@ -250,20 +246,20 @@ fe_file_change (const struct line_map *new_map) ...@@ -250,20 +246,20 @@ fe_file_change (const struct line_map *new_map)
in_system_header = new_map->sysp != 0; in_system_header = new_map->sysp != 0;
input_filename = new_map->to_file; input_filename = new_map->to_file;
input_line = new_map->to_line; input_line = new_map->to_line;
map = new_map;
/* Hook for C++. */ /* Hook for C++. */
extract_interface_info (); extract_interface_info ();
} }
static void static void
cb_def_pragma (cpp_reader *pfile, unsigned int line) cb_def_pragma (cpp_reader *pfile, source_location loc)
{ {
/* Issue a warning message if we have been asked to do so. Ignore /* Issue a warning message if we have been asked to do so. Ignore
unknown pragmas in system headers unless an explicit unknown pragmas in system headers unless an explicit
-Wunknown-pragmas has been given. */ -Wunknown-pragmas has been given. */
if (warn_unknown_pragmas > in_system_header) if (warn_unknown_pragmas > in_system_header)
{ {
const struct line_map *map = linemap_lookup (&line_table, loc);
const unsigned char *space, *name; const unsigned char *space, *name;
const cpp_token *s; const cpp_token *s;
...@@ -277,25 +273,27 @@ cb_def_pragma (cpp_reader *pfile, unsigned int line) ...@@ -277,25 +273,27 @@ cb_def_pragma (cpp_reader *pfile, unsigned int line)
name = cpp_token_as_text (pfile, s); name = cpp_token_as_text (pfile, s);
} }
input_line = SOURCE_LINE (map, line); input_line = SOURCE_LINE (map, loc);
warning ("ignoring #pragma %s %s", space, name); warning ("ignoring #pragma %s %s", space, name);
} }
} }
/* #define callback for DWARF and DWARF2 debug info. */ /* #define callback for DWARF and DWARF2 debug info. */
static void static void
cb_define (cpp_reader *pfile, unsigned int line, cpp_hashnode *node) cb_define (cpp_reader *pfile, source_location loc, cpp_hashnode *node)
{ {
(*debug_hooks->define) (SOURCE_LINE (map, line), const struct line_map *map = linemap_lookup (&line_table, loc);
(*debug_hooks->define) (SOURCE_LINE (map, loc),
(const char *) cpp_macro_definition (pfile, node)); (const char *) cpp_macro_definition (pfile, node));
} }
/* #undef callback for DWARF and DWARF2 debug info. */ /* #undef callback for DWARF and DWARF2 debug info. */
static void static void
cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, unsigned int line, cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location loc,
cpp_hashnode *node) cpp_hashnode *node)
{ {
(*debug_hooks->undef) (SOURCE_LINE (map, line), const struct line_map *map = linemap_lookup (&line_table, loc);
(*debug_hooks->undef) (SOURCE_LINE (map, loc),
(const char *) NODE_NAME (node)); (const char *) NODE_NAME (node));
} }
......
...@@ -32,10 +32,9 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ ...@@ -32,10 +32,9 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
static struct static struct
{ {
FILE *outf; /* Stream to write to. */ FILE *outf; /* Stream to write to. */
const struct line_map *map; /* Logical to physical line mappings. */
const cpp_token *prev; /* Previous token. */ const cpp_token *prev; /* Previous token. */
const cpp_token *source; /* Source token for spacing. */ const cpp_token *source; /* Source token for spacing. */
fileline line; /* Line currently being written. */ int src_line; /* Line number currently being written. */
unsigned char printed; /* Nonzero if something output at line. */ unsigned char printed; /* Nonzero if something output at line. */
} print; } print;
...@@ -45,8 +44,8 @@ static void scan_translation_unit_trad (cpp_reader *); ...@@ -45,8 +44,8 @@ static void scan_translation_unit_trad (cpp_reader *);
static void account_for_newlines (const unsigned char *, size_t); static void account_for_newlines (const unsigned char *, size_t);
static int dump_macro (cpp_reader *, cpp_hashnode *, void *); static int dump_macro (cpp_reader *, cpp_hashnode *, void *);
static void print_line (const struct line_map *, fileline, const char *); static void print_line (source_location, const char *);
static void maybe_print_line (const struct line_map *, fileline); static void maybe_print_line (source_location);
/* Callback routines for the parser. Most of these are active only /* Callback routines for the parser. Most of these are active only
in specific modes. */ in specific modes. */
...@@ -112,13 +111,12 @@ init_pp_output (FILE *out_stream) ...@@ -112,13 +111,12 @@ init_pp_output (FILE *out_stream)
cb->undef = cb_undef; cb->undef = cb_undef;
} }
/* Initialize the print structure. Setting print.line to -1 here is /* Initialize the print structure. Setting print.src_line to -1 here is
a trick to guarantee that the first token of the file will cause a trick to guarantee that the first token of the file will cause
a linemarker to be output by maybe_print_line. */ a linemarker to be output by maybe_print_line. */
print.line = (fileline) -1; print.src_line = -1;
print.printed = 0; print.printed = 0;
print.prev = 0; print.prev = 0;
print.map = 0;
print.outf = out_stream; print.outf = out_stream;
} }
...@@ -171,13 +169,13 @@ scan_translation_unit (cpp_reader *pfile) ...@@ -171,13 +169,13 @@ scan_translation_unit (cpp_reader *pfile)
} }
} }
/* Adjust print.line for newlines embedded in output. */ /* Adjust print.src_line for newlines embedded in output. */
static void static void
account_for_newlines (const unsigned char *str, size_t len) account_for_newlines (const unsigned char *str, size_t len)
{ {
while (len--) while (len--)
if (*str++ == '\n') if (*str++ == '\n')
print.line++; print.src_line++;
} }
/* Writes out a traditionally preprocessed file. */ /* Writes out a traditionally preprocessed file. */
...@@ -187,7 +185,7 @@ scan_translation_unit_trad (cpp_reader *pfile) ...@@ -187,7 +185,7 @@ scan_translation_unit_trad (cpp_reader *pfile)
while (_cpp_read_logical_line_trad (pfile)) while (_cpp_read_logical_line_trad (pfile))
{ {
size_t len = pfile->out.cur - pfile->out.base; size_t len = pfile->out.cur - pfile->out.base;
maybe_print_line (print.map, pfile->out.first_line); maybe_print_line (pfile->out.first_line);
fwrite (pfile->out.base, 1, len, print.outf); fwrite (pfile->out.base, 1, len, print.outf);
print.printed = 1; print.printed = 1;
if (!CPP_OPTION (pfile, discard_comments)) if (!CPP_OPTION (pfile, discard_comments))
...@@ -199,52 +197,56 @@ scan_translation_unit_trad (cpp_reader *pfile) ...@@ -199,52 +197,56 @@ scan_translation_unit_trad (cpp_reader *pfile)
different line to the current one, output the required newlines or different line to the current one, output the required newlines or
a line marker, and return 1. Otherwise return 0. */ a line marker, and return 1. Otherwise return 0. */
static void static void
maybe_print_line (const struct line_map *map, fileline line) maybe_print_line (source_location src_loc)
{ {
const struct line_map *map = linemap_lookup (&line_table, src_loc);
int src_line = SOURCE_LINE (map, src_loc);
/* End the previous line of text. */ /* End the previous line of text. */
if (print.printed) if (print.printed)
{ {
putc ('\n', print.outf); putc ('\n', print.outf);
print.line++; print.src_line++;
print.printed = 0; print.printed = 0;
} }
if (line >= print.line && line < print.line + 8) if (src_line >= print.src_line && src_line < print.src_line + 8)
{ {
while (line > print.line) while (src_line > print.src_line)
{ {
putc ('\n', print.outf); putc ('\n', print.outf);
print.line++; print.src_line++;
} }
} }
else else
print_line (map, line, ""); print_line (src_loc, "");
} }
/* Output a line marker for logical line LINE. Special flags are "1" /* Output a line marker for logical line LINE. Special flags are "1"
or "2" indicating entering or leaving a file. */ or "2" indicating entering or leaving a file. */
static void static void
print_line (const struct line_map *map, fileline line, const char *special_flags) print_line (source_location src_loc, const char *special_flags)
{ {
/* End any previous line of text. */ /* End any previous line of text. */
if (print.printed) if (print.printed)
putc ('\n', print.outf); putc ('\n', print.outf);
print.printed = 0; print.printed = 0;
print.line = line;
if (!flag_no_line_commands) if (!flag_no_line_commands)
{ {
const struct line_map *map = linemap_lookup (&line_table, src_loc);
size_t to_file_len = strlen (map->to_file); size_t to_file_len = strlen (map->to_file);
unsigned char *to_file_quoted = alloca (to_file_len * 4 + 1); unsigned char *to_file_quoted = alloca (to_file_len * 4 + 1);
unsigned char *p; unsigned char *p;
print.src_line = SOURCE_LINE (map, src_loc);
/* cpp_quote_string does not nul-terminate, so we have to do it /* cpp_quote_string does not nul-terminate, so we have to do it
ourselves. */ ourselves. */
p = cpp_quote_string (to_file_quoted, p = cpp_quote_string (to_file_quoted,
(unsigned char *)map->to_file, to_file_len); (unsigned char *)map->to_file, to_file_len);
*p = '\0'; *p = '\0';
fprintf (print.outf, "# %u \"%s\"%s", fprintf (print.outf, "# %u \"%s\"%s", print.src_line,
SOURCE_LINE (map, print.line),
to_file_quoted, special_flags); to_file_quoted, special_flags);
if (map->sysp == 2) if (map->sysp == 2)
...@@ -262,10 +264,12 @@ static void ...@@ -262,10 +264,12 @@ static void
cb_line_change (cpp_reader *pfile, const cpp_token *token, cb_line_change (cpp_reader *pfile, const cpp_token *token,
int parsing_args) int parsing_args)
{ {
source_location src_loc = token->src_loc;
if (token->type == CPP_EOF || parsing_args) if (token->type == CPP_EOF || parsing_args)
return; return;
maybe_print_line (print.map, token->line); maybe_print_line (src_loc);
print.prev = 0; print.prev = 0;
print.source = 0; print.source = 0;
...@@ -276,14 +280,12 @@ cb_line_change (cpp_reader *pfile, const cpp_token *token, ...@@ -276,14 +280,12 @@ cb_line_change (cpp_reader *pfile, const cpp_token *token,
ought to care. Some things do care; the fault lies with them. */ ought to care. Some things do care; the fault lies with them. */
if (!CPP_OPTION (pfile, traditional)) if (!CPP_OPTION (pfile, traditional))
{ {
const struct line_map *map = linemap_lookup (&line_table, src_loc);
int spaces = SOURCE_COLUMN (map, src_loc) - 2;
print.printed = 1; print.printed = 1;
if (token->col > 2)
{
unsigned int spaces = token->col - 2;
while (spaces--) while (-- spaces >= 0)
putc (' ', print.outf); putc (' ', print.outf);
}
} }
} }
...@@ -291,15 +293,15 @@ static void ...@@ -291,15 +293,15 @@ static void
cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line, cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line,
const cpp_string *str) const cpp_string *str)
{ {
maybe_print_line (print.map, line); maybe_print_line (line);
fprintf (print.outf, "#ident \"%s\"\n", str->text); fprintf (print.outf, "#ident \"%s\"\n", str->text);
print.line++; print.src_line++;
} }
static void static void
cb_define (cpp_reader *pfile, fileline line, cpp_hashnode *node) cb_define (cpp_reader *pfile, fileline line, cpp_hashnode *node)
{ {
maybe_print_line (print.map, line); maybe_print_line (line);
fputs ("#define ", print.outf); fputs ("#define ", print.outf);
/* 'D' is whole definition; 'N' is name only. */ /* 'D' is whole definition; 'N' is name only. */
...@@ -310,28 +312,28 @@ cb_define (cpp_reader *pfile, fileline line, cpp_hashnode *node) ...@@ -310,28 +312,28 @@ cb_define (cpp_reader *pfile, fileline line, cpp_hashnode *node)
fputs ((const char *) NODE_NAME (node), print.outf); fputs ((const char *) NODE_NAME (node), print.outf);
putc ('\n', print.outf); putc ('\n', print.outf);
print.line++; print.src_line++;
} }
static void static void
cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line, cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line,
cpp_hashnode *node) cpp_hashnode *node)
{ {
maybe_print_line (print.map, line); maybe_print_line (line);
fprintf (print.outf, "#undef %s\n", NODE_NAME (node)); fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
print.line++; print.src_line++;
} }
static void static void
cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line, cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line,
const unsigned char *dir, const char *header, int angle_brackets) const unsigned char *dir, const char *header, int angle_brackets)
{ {
maybe_print_line (print.map, line); maybe_print_line (line);
if (angle_brackets) if (angle_brackets)
fprintf (print.outf, "#%s <%s>\n", dir, header); fprintf (print.outf, "#%s <%s>\n", dir, header);
else else
fprintf (print.outf, "#%s \"%s\"\n", dir, header); fprintf (print.outf, "#%s \"%s\"\n", dir, header);
print.line++; print.src_line++;
} }
/* Callback called when -fworking-director and -E to emit working /* Callback called when -fworking-director and -E to emit working
...@@ -351,8 +353,7 @@ pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir) ...@@ -351,8 +353,7 @@ pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir)
} }
/* The file name, line number or system header flags have changed, as /* The file name, line number or system header flags have changed, as
described in MAP. From this point on, the old print.map might be described in MAP. */
pointing to freed memory, and so must not be dereferenced. */
void void
pp_file_change (const struct line_map *map) pp_file_change (const struct line_map *map)
...@@ -365,37 +366,37 @@ pp_file_change (const struct line_map *map) ...@@ -365,37 +366,37 @@ pp_file_change (const struct line_map *map)
if (map != NULL) if (map != NULL)
{ {
/* First time? */ /* First time? */
if (print.map == NULL) if (MAIN_FILE_P (map))
{ {
/* Avoid printing foo.i when the main file is foo.c. */ /* Avoid printing foo.i when the main file is foo.c. */
if (!cpp_get_options (parse_in)->preprocessed) if (!cpp_get_options (parse_in)->preprocessed)
print_line (map, map->from_line, flags); print_line (map->start_location, flags);
} }
else else
{ {
/* Bring current file to correct line when entering a new file. */ /* Bring current file to correct line when entering a new file. */
if (map->reason == LC_ENTER) if (map->reason == LC_ENTER)
maybe_print_line (map - 1, map->from_line - 1); {
const struct line_map *from = INCLUDED_FROM (&line_table, map);
maybe_print_line (LAST_SOURCE_LINE_LOCATION (from));
}
if (map->reason == LC_ENTER) if (map->reason == LC_ENTER)
flags = " 1"; flags = " 1";
else if (map->reason == LC_LEAVE) else if (map->reason == LC_LEAVE)
flags = " 2"; flags = " 2";
print_line (map, map->from_line, flags); print_line (map->start_location, flags);
} }
} }
print.map = map;
} }
/* Copy a #pragma directive to the preprocessed output. */ /* Copy a #pragma directive to the preprocessed output. */
static void static void
cb_def_pragma (cpp_reader *pfile, fileline line) cb_def_pragma (cpp_reader *pfile, fileline line)
{ {
maybe_print_line (print.map, line); maybe_print_line (line);
fputs ("#pragma ", print.outf); fputs ("#pragma ", print.outf);
cpp_output_line (pfile, print.outf); cpp_output_line (pfile, print.outf);
print.line++; print.src_line++;
} }
/* Dump out the hash table. */ /* Dump out the hash table. */
...@@ -408,7 +409,7 @@ dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED) ...@@ -408,7 +409,7 @@ dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED)
fputs ((const char *) cpp_macro_definition (pfile, node), fputs ((const char *) cpp_macro_definition (pfile, node),
print.outf); print.outf);
putc ('\n', print.outf); putc ('\n', print.outf);
print.line++; print.src_line++;
} }
return 1; return 1;
......
...@@ -29,14 +29,14 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -29,14 +29,14 @@ 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_location (cpp_reader *, fileline, unsigned int); static void print_location (cpp_reader *, source_location, unsigned int);
/* Print the logical file location (LINE, COL) in preparation for a /* Print the logical file location (LINE, COL) in preparation for a
diagnostic. Outputs the #include chain if it has changed. A line diagnostic. Outputs the #include chain if it has changed. A line
of zero suppresses the include stack, and outputs the program name of zero suppresses the include stack, and outputs the program name
instead. */ instead. */
static void static void
print_location (cpp_reader *pfile, fileline line, unsigned int col) print_location (cpp_reader *pfile, source_location line, unsigned int col)
{ {
if (line == 0) if (line == 0)
fprintf (stderr, "%s: ", progname); fprintf (stderr, "%s: ", progname);
...@@ -50,7 +50,11 @@ print_location (cpp_reader *pfile, fileline line, unsigned int col) ...@@ -50,7 +50,11 @@ print_location (cpp_reader *pfile, fileline line, unsigned int col)
lin = SOURCE_LINE (map, line); lin = SOURCE_LINE (map, line);
if (col == 0) if (col == 0)
col = 1; {
col = SOURCE_COLUMN (map, line);
if (col == 0)
col = 1;
}
if (lin == 0) if (lin == 0)
fprintf (stderr, "%s:", map->to_file); fprintf (stderr, "%s:", map->to_file);
...@@ -64,13 +68,18 @@ print_location (cpp_reader *pfile, fileline line, unsigned int col) ...@@ -64,13 +68,18 @@ print_location (cpp_reader *pfile, fileline line, unsigned int col)
} }
/* Set up for a diagnostic: print the file and line, bump the error /* Set up for a diagnostic: print the file and line, bump the error
counter, etc. LINE is the logical line number; zero means to print counter, etc. SRC_LOC is the logical line number; zero means to print
at the location of the previously lexed token, which tends to be at the location of the previously lexed token, which tends to be
the correct place by default. Returns 0 if the error has been the correct place by default. The column number can be specified either
suppressed. */ using COLUMN or (if COLUMN==0) extracting SOURCE_COLUMN from SRC_LOC.
(This may seem redundant, but is useful when pre-scanning (cleaning) a line,
when we haven't yet verified whether the current line_map has a
big enough max_column_hint.)
Returns 0 if the error has been suppressed. */
int int
_cpp_begin_message (cpp_reader *pfile, int code, fileline line, _cpp_begin_message (cpp_reader *pfile, int code,
unsigned int column) source_location src_loc, unsigned int column)
{ {
int level = CPP_DL_EXTRACT (code); int level = CPP_DL_EXTRACT (code);
...@@ -78,7 +87,7 @@ _cpp_begin_message (cpp_reader *pfile, int code, fileline line, ...@@ -78,7 +87,7 @@ _cpp_begin_message (cpp_reader *pfile, int code, fileline line,
{ {
case CPP_DL_WARNING: case CPP_DL_WARNING:
case CPP_DL_PEDWARN: case CPP_DL_PEDWARN:
if (CPP_IN_SYSTEM_HEADER (pfile) if (cpp_in_system_header (pfile)
&& ! CPP_OPTION (pfile, warn_system_headers)) && ! CPP_OPTION (pfile, warn_system_headers))
return 0; return 0;
/* Fall through. */ /* Fall through. */
...@@ -105,7 +114,7 @@ _cpp_begin_message (cpp_reader *pfile, int code, fileline line, ...@@ -105,7 +114,7 @@ _cpp_begin_message (cpp_reader *pfile, int code, fileline line,
break; break;
} }
print_location (pfile, line, column); print_location (pfile, src_loc, column);
if (CPP_DL_WARNING_P (level)) if (CPP_DL_WARNING_P (level))
fputs (_("warning: "), stderr); fputs (_("warning: "), stderr);
else if (level == CPP_DL_ICE) else if (level == CPP_DL_ICE)
...@@ -125,8 +134,7 @@ _cpp_begin_message (cpp_reader *pfile, int code, fileline line, ...@@ -125,8 +134,7 @@ _cpp_begin_message (cpp_reader *pfile, int code, fileline line,
void void
cpp_error (cpp_reader * pfile, int level, const char *msgid, ...) cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
{ {
fileline line; source_location src_loc;
unsigned int column;
va_list ap; va_list ap;
va_start (ap, msgid); va_start (ap, msgid);
...@@ -134,18 +142,16 @@ cpp_error (cpp_reader * pfile, int level, const char *msgid, ...) ...@@ -134,18 +142,16 @@ cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
if (CPP_OPTION (pfile, traditional)) if (CPP_OPTION (pfile, traditional))
{ {
if (pfile->state.in_directive) if (pfile->state.in_directive)
line = pfile->directive_line; src_loc = pfile->directive_line;
else else
line = pfile->line; src_loc = pfile->line;
column = 0;
} }
else else
{ {
line = pfile->cur_token[-1].line; src_loc = pfile->cur_token[-1].src_loc;
column = pfile->cur_token[-1].col;
} }
if (_cpp_begin_message (pfile, level, line, column)) if (_cpp_begin_message (pfile, level, src_loc, 0))
v_message (msgid, ap); v_message (msgid, ap);
va_end (ap); va_end (ap);
...@@ -154,14 +160,14 @@ cpp_error (cpp_reader * pfile, int level, const char *msgid, ...) ...@@ -154,14 +160,14 @@ cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
/* Print an error at a specific location. */ /* Print an error at a specific location. */
void void
cpp_error_with_line (cpp_reader *pfile, int level, cpp_error_with_line (cpp_reader *pfile, int level,
fileline line, unsigned int column, source_location src_loc, unsigned int column,
const char *msgid, ...) const char *msgid, ...)
{ {
va_list ap; va_list ap;
va_start (ap, msgid); va_start (ap, msgid);
if (_cpp_begin_message (pfile, level, line, column)) if (_cpp_begin_message (pfile, level, src_loc, column))
v_message (msgid, ap); v_message (msgid, ap);
va_end (ap); va_end (ap);
......
...@@ -640,8 +640,10 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) ...@@ -640,8 +640,10 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
if (!should_stack_file (pfile, file, import)) if (!should_stack_file (pfile, file, import))
return false; return false;
sysp = MAX ((pfile->map ? pfile->map->sysp : 0), if (pfile->buffer == NULL || file->dir == NULL)
(file->dir ? file->dir->sysp : 0)); sysp = 0;
else
sysp = MAX (pfile->buffer->sysp, file->dir->sysp);
/* Add the file to the dependencies on its first inclusion. */ /* Add the file to the dependencies on its first inclusion. */
if (CPP_OPTION (pfile, deps.style) > !!sysp && !file->stack_count) if (CPP_OPTION (pfile, deps.style) > !!sysp && !file->stack_count)
...@@ -658,6 +660,7 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) ...@@ -658,6 +660,7 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
buffer = cpp_push_buffer (pfile, file->buffer, file->st.st_size, buffer = cpp_push_buffer (pfile, file->buffer, file->st.st_size,
CPP_OPTION (pfile, preprocessed)); CPP_OPTION (pfile, preprocessed));
buffer->file = file; buffer->file = file;
buffer->sysp = sysp;
/* Initialize controlling macro state. */ /* Initialize controlling macro state. */
pfile->mi_valid = true; pfile->mi_valid = true;
...@@ -707,7 +710,8 @@ search_path_head (cpp_reader *pfile, const char *fname, int angle_brackets, ...@@ -707,7 +710,8 @@ search_path_head (cpp_reader *pfile, const char *fname, int angle_brackets,
else if (pfile->quote_ignores_source_dir) else if (pfile->quote_ignores_source_dir)
dir = pfile->quote_include; dir = pfile->quote_include;
else else
return make_cpp_dir (pfile, dir_name_of_file (file), pfile->map->sysp); return make_cpp_dir (pfile, dir_name_of_file (file),
pfile->buffer ? pfile->buffer->sysp : 0);
if (dir == NULL) if (dir == NULL)
cpp_error (pfile, CPP_DL_ERROR, cpp_error (pfile, CPP_DL_ERROR,
...@@ -756,7 +760,7 @@ _cpp_stack_include (cpp_reader *pfile, const char *fname, int angle_brackets, ...@@ -756,7 +760,7 @@ _cpp_stack_include (cpp_reader *pfile, const char *fname, int angle_brackets,
static void static void
open_file_failed (cpp_reader *pfile, _cpp_file *file) open_file_failed (cpp_reader *pfile, _cpp_file *file)
{ {
int sysp = pfile->map ? pfile->map->sysp: 0; int sysp = pfile->line > 1 && pfile->buffer ? pfile->buffer->sysp : 0;
bool print_dep = CPP_OPTION (pfile, deps.style) > !!sysp; bool print_dep = CPP_OPTION (pfile, deps.style) > !!sysp;
errno = file->err_no; errno = file->err_no;
...@@ -936,12 +940,14 @@ void ...@@ -936,12 +940,14 @@ void
cpp_make_system_header (cpp_reader *pfile, int syshdr, int externc) cpp_make_system_header (cpp_reader *pfile, int syshdr, int externc)
{ {
int flags = 0; int flags = 0;
const struct line_map *map = linemap_lookup (pfile->line_table, pfile->line);
/* 1 = system header, 2 = system header to be treated as C. */ /* 1 = system header, 2 = system header to be treated as C. */
if (syshdr) if (syshdr)
flags = 1 + (externc != 0); flags = 1 + (externc != 0);
_cpp_do_file_change (pfile, LC_RENAME, pfile->map->to_file, pfile->buffer->sysp = flags;
SOURCE_LINE (pfile->map, pfile->line), flags); _cpp_do_file_change (pfile, LC_RENAME, map->to_file,
SOURCE_LINE (map, pfile->line), flags);
} }
/* Allow the client to change the current file. Used by the front end /* Allow the client to change the current file. Used by the front end
......
...@@ -64,6 +64,13 @@ typedef unsigned char uchar; ...@@ -64,6 +64,13 @@ typedef unsigned char uchar;
#define CPP_BUF_COLUMN(BUF, CUR) ((CUR) - (BUF)->line_base) #define CPP_BUF_COLUMN(BUF, CUR) ((CUR) - (BUF)->line_base)
#define CPP_BUF_COL(BUF) CPP_BUF_COLUMN(BUF, (BUF)->cur) #define CPP_BUF_COL(BUF) CPP_BUF_COLUMN(BUF, (BUF)->cur)
#define CPP_INCREMENT_LINE(PFILE, COLS_HINT) do { \
const struct line_map *map \
= linemap_lookup (PFILE->line_table, PFILE->line); \
unsigned int line = SOURCE_LINE (map, PFILE->line) + 1; \
PFILE->line = linemap_line_start (PFILE->line_table, line, COLS_HINT); \
} while (0)
/* Maximum nesting of cpp_buffers. We use a static limit, partly for /* Maximum nesting of cpp_buffers. We use a static limit, partly for
efficiency, and partly to limit runaway recursion. */ efficiency, and partly to limit runaway recursion. */
#define CPP_STACK_MAX 200 #define CPP_STACK_MAX 200
...@@ -296,24 +303,25 @@ struct cpp_buffer ...@@ -296,24 +303,25 @@ struct cpp_buffer
The warning happens only for C89 extended mode with -pedantic on, The warning happens only for C89 extended mode with -pedantic on,
or for -Wtraditional, and only once per file (otherwise it would or for -Wtraditional, and only once per file (otherwise it would
be far too noisy). */ be far too noisy). */
unsigned char warned_cplusplus_comments; unsigned int warned_cplusplus_comments : 1;
/* True if we don't process trigraphs and escaped newlines. True /* True if we don't process trigraphs and escaped newlines. True
for preprocessed input, command line directives, and _Pragma for preprocessed input, command line directives, and _Pragma
buffers. */ buffers. */
unsigned char from_stage3; unsigned int from_stage3 : 1;
/* Nonzero means that the directory to start searching for "" /* Nonzero means that the directory to start searching for ""
include files has been calculated and stored in "dir" below. */ include files has been calculated and stored in "dir" below. */
unsigned char search_cached; unsigned char search_cached;
/* One for a system header, two for a C system header file that therefore
needs to be extern "C" protected in C++, and zero otherwise. */
unsigned char sysp;
/* The directory of the this buffer's file. Its NAME member is not /* The directory of the this buffer's file. Its NAME member is not
allocated, so we don't need to worry about freeing it. */ allocated, so we don't need to worry about freeing it. */
struct cpp_dir dir; struct cpp_dir dir;
/* Used for buffer overlays by cpptrad.c. */
const uchar *saved_cur, *saved_rlimit;
/* Descriptor for converting from the input character set to the /* Descriptor for converting from the input character set to the
source character set. */ source character set. */
struct cset_converter input_cset_desc; struct cset_converter input_cset_desc;
...@@ -335,7 +343,6 @@ struct cpp_reader ...@@ -335,7 +343,6 @@ struct cpp_reader
/* Source line tracking. */ /* Source line tracking. */
struct line_maps *line_table; struct line_maps *line_table;
const struct line_map *map;
fileline line; fileline line;
/* The line of the '#' of the current directive. */ /* The line of the '#' of the current directive. */
...@@ -455,6 +462,9 @@ struct cpp_reader ...@@ -455,6 +462,9 @@ struct cpp_reader
fileline first_line; fileline first_line;
} out; } out;
/* Used for buffer overlays by cpptrad.c. */
const uchar *saved_cur, *saved_rlimit, *saved_line_base;
/* Used to save the original line number during traditional /* Used to save the original line number during traditional
preprocessing. */ preprocessing. */
unsigned int saved_line; unsigned int saved_line;
...@@ -493,12 +503,18 @@ extern unsigned char _cpp_trigraph_map[UCHAR_MAX + 1]; ...@@ -493,12 +503,18 @@ extern unsigned char _cpp_trigraph_map[UCHAR_MAX + 1];
/* Macros. */ /* Macros. */
#define CPP_IN_SYSTEM_HEADER(PFILE) ((PFILE)->map && (PFILE)->map->sysp) static inline int cpp_in_system_header (cpp_reader *);
static inline int
cpp_in_system_header (cpp_reader *pfile)
{
return pfile->buffer ? pfile->buffer->sysp : 0;
}
#define CPP_PEDANTIC(PF) CPP_OPTION (PF, pedantic) #define CPP_PEDANTIC(PF) CPP_OPTION (PF, pedantic)
#define CPP_WTRADITIONAL(PF) CPP_OPTION (PF, warn_traditional) #define CPP_WTRADITIONAL(PF) CPP_OPTION (PF, warn_traditional)
/* In cpperror.c */ /* In cpperror.c */
extern int _cpp_begin_message (cpp_reader *, int, fileline, unsigned int); extern int _cpp_begin_message (cpp_reader *, int,
source_location, unsigned int);
/* In cppmacro.c */ /* In cppmacro.c */
extern void _cpp_free_definition (cpp_hashnode *); extern void _cpp_free_definition (cpp_hashnode *);
......
...@@ -479,7 +479,7 @@ cpp_read_main_file (cpp_reader *pfile, const char *fname) ...@@ -479,7 +479,7 @@ cpp_read_main_file (cpp_reader *pfile, const char *fname)
if (CPP_OPTION (pfile, preprocessed)) if (CPP_OPTION (pfile, preprocessed))
{ {
read_original_filename (pfile); read_original_filename (pfile);
fname = pfile->map->to_file; fname = pfile->line_table->maps[pfile->line_table->used-1].to_file;
} }
return fname; return fname;
} }
......
...@@ -282,7 +282,7 @@ _cpp_process_line_notes (cpp_reader *pfile, int in_comment) ...@@ -282,7 +282,7 @@ _cpp_process_line_notes (cpp_reader *pfile, int in_comment)
} }
buffer->line_base = note->pos; buffer->line_base = note->pos;
pfile->line++; CPP_INCREMENT_LINE (pfile, 0);
} }
else if (_cpp_trigraph_map[note->type]) else if (_cpp_trigraph_map[note->type])
{ {
...@@ -349,12 +349,16 @@ _cpp_skip_block_comment (cpp_reader *pfile) ...@@ -349,12 +349,16 @@ _cpp_skip_block_comment (cpp_reader *pfile)
} }
else if (c == '\n') else if (c == '\n')
{ {
unsigned int cols;
buffer->cur = cur - 1; buffer->cur = cur - 1;
_cpp_process_line_notes (pfile, true); _cpp_process_line_notes (pfile, true);
if (buffer->next_line >= buffer->rlimit) if (buffer->next_line >= buffer->rlimit)
return true; return true;
_cpp_clean_line (pfile); _cpp_clean_line (pfile);
pfile->line++;
cols = buffer->next_line - buffer->line_base;
CPP_INCREMENT_LINE (pfile, cols);
cur = buffer->cur; cur = buffer->cur;
} }
} }
...@@ -680,8 +684,7 @@ _cpp_temp_token (cpp_reader *pfile) ...@@ -680,8 +684,7 @@ _cpp_temp_token (cpp_reader *pfile)
} }
result = pfile->cur_token++; result = pfile->cur_token++;
result->line = old->line; result->src_loc = old->src_loc;
result->col = old->col;
return result; return result;
} }
...@@ -772,7 +775,7 @@ _cpp_get_fresh_line (cpp_reader *pfile) ...@@ -772,7 +775,7 @@ _cpp_get_fresh_line (cpp_reader *pfile)
{ {
/* Only warn once. */ /* Only warn once. */
buffer->next_line = buffer->rlimit; buffer->next_line = buffer->rlimit;
cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line - 1, cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line,
CPP_BUF_COLUMN (buffer, buffer->cur), CPP_BUF_COLUMN (buffer, buffer->cur),
"no newline at end of file"); "no newline at end of file");
} }
...@@ -822,7 +825,7 @@ _cpp_lex_direct (cpp_reader *pfile) ...@@ -822,7 +825,7 @@ _cpp_lex_direct (cpp_reader *pfile)
if (!pfile->state.in_directive) if (!pfile->state.in_directive)
{ {
/* Tell the compiler the line number of the EOF token. */ /* Tell the compiler the line number of the EOF token. */
result->line = pfile->line; result->src_loc = pfile->line;
result->flags = BOL; result->flags = BOL;
} }
return result; return result;
...@@ -839,17 +842,19 @@ _cpp_lex_direct (cpp_reader *pfile) ...@@ -839,17 +842,19 @@ _cpp_lex_direct (cpp_reader *pfile)
} }
buffer = pfile->buffer; buffer = pfile->buffer;
update_tokens_line: update_tokens_line:
result->line = pfile->line; result->src_loc = pfile->line;
skipped_white: skipped_white:
if (buffer->cur >= buffer->notes[buffer->cur_note].pos if (buffer->cur >= buffer->notes[buffer->cur_note].pos
&& !pfile->overlaid_buffer) && !pfile->overlaid_buffer)
{ {
_cpp_process_line_notes (pfile, false); _cpp_process_line_notes (pfile, false);
result->line = pfile->line; result->src_loc = pfile->line;
} }
c = *buffer->cur++; c = *buffer->cur++;
result->col = CPP_BUF_COLUMN (buffer, buffer->cur);
result->src_loc = linemap_position_for_column (pfile->line_table,
CPP_BUF_COLUMN (buffer, buffer->cur));
switch (c) switch (c)
{ {
...@@ -859,7 +864,8 @@ _cpp_lex_direct (cpp_reader *pfile) ...@@ -859,7 +864,8 @@ _cpp_lex_direct (cpp_reader *pfile)
goto skipped_white; goto skipped_white;
case '\n': case '\n':
pfile->line++; if (buffer->cur < buffer->rlimit)
CPP_INCREMENT_LINE (pfile, 0);
buffer->need_line = true; buffer->need_line = true;
goto fresh_line; goto fresh_line;
...@@ -916,7 +922,7 @@ _cpp_lex_direct (cpp_reader *pfile) ...@@ -916,7 +922,7 @@ _cpp_lex_direct (cpp_reader *pfile)
cpp_error (pfile, CPP_DL_ERROR, "unterminated comment"); cpp_error (pfile, CPP_DL_ERROR, "unterminated comment");
} }
else if (c == '/' && (CPP_OPTION (pfile, cplusplus_comments) else if (c == '/' && (CPP_OPTION (pfile, cplusplus_comments)
|| CPP_IN_SYSTEM_HEADER (pfile))) || cpp_in_system_header (pfile)))
{ {
/* Warn about comments only if pedantically GNUC89, and not /* Warn about comments only if pedantically GNUC89, and not
in system headers. */ in system headers. */
......
...@@ -777,8 +777,9 @@ strtoul_for_line (const uchar *str, unsigned int len, long unsigned int *nump) ...@@ -777,8 +777,9 @@ strtoul_for_line (const uchar *str, unsigned int len, long unsigned int *nump)
static void static void
do_line (cpp_reader *pfile) do_line (cpp_reader *pfile)
{ {
const struct line_map *map = linemap_lookup (pfile->line_table, pfile->line);
const cpp_token *token; const cpp_token *token;
const char *new_file = pfile->map->to_file; const char *new_file = map->to_file;
unsigned long new_lineno; unsigned long new_lineno;
/* C99 raised the minimum limit on #line numbers. */ /* C99 raised the minimum limit on #line numbers. */
...@@ -816,7 +817,7 @@ do_line (cpp_reader *pfile) ...@@ -816,7 +817,7 @@ do_line (cpp_reader *pfile)
skip_rest_of_line (pfile); skip_rest_of_line (pfile);
_cpp_do_file_change (pfile, LC_RENAME, new_file, new_lineno, _cpp_do_file_change (pfile, LC_RENAME, new_file, new_lineno,
pfile->map->sysp); map->sysp);
} }
/* Interpret the # 44 "file" [flags] notation, which has slightly /* Interpret the # 44 "file" [flags] notation, which has slightly
...@@ -825,10 +826,11 @@ do_line (cpp_reader *pfile) ...@@ -825,10 +826,11 @@ do_line (cpp_reader *pfile)
static void static void
do_linemarker (cpp_reader *pfile) do_linemarker (cpp_reader *pfile)
{ {
const struct line_map *map = linemap_lookup (pfile->line_table, pfile->line);
const cpp_token *token; const cpp_token *token;
const char *new_file = pfile->map->to_file; const char *new_file = map->to_file;
unsigned long new_lineno; unsigned long new_lineno;
unsigned int new_sysp = pfile->map->sysp; unsigned int new_sysp = map->sysp;
enum lc_reason reason = LC_RENAME; enum lc_reason reason = LC_RENAME;
int flag; int flag;
...@@ -876,6 +878,7 @@ do_linemarker (cpp_reader *pfile) ...@@ -876,6 +878,7 @@ do_linemarker (cpp_reader *pfile)
flag = read_flag (pfile, flag); flag = read_flag (pfile, flag);
if (flag == 4) if (flag == 4)
new_sysp = 2; new_sysp = 2;
pfile->buffer->sysp = new_sysp;
} }
check_eol (pfile); check_eol (pfile);
...@@ -900,11 +903,15 @@ _cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason, ...@@ -900,11 +903,15 @@ _cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason,
const char *to_file, unsigned int file_line, const char *to_file, unsigned int file_line,
unsigned int sysp) unsigned int sysp)
{ {
pfile->map = linemap_add (pfile->line_table, reason, sysp, const struct line_map *map = linemap_add (pfile->line_table, reason, sysp,
pfile->line, to_file, file_line); to_file, file_line);
if (map == NULL)
pfile->line = 0;
else
pfile->line = linemap_line_start (pfile->line_table, map->to_line, 127);
if (pfile->cb.file_change) if (pfile->cb.file_change)
pfile->cb.file_change (pfile, pfile->map); pfile->cb.file_change (pfile, map);
} }
/* Report a warning or error detected by the program we are /* Report a warning or error detected by the program we are
...@@ -912,9 +919,7 @@ _cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason, ...@@ -912,9 +919,7 @@ _cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason,
static void static void
do_diagnostic (cpp_reader *pfile, int code, int print_dir) do_diagnostic (cpp_reader *pfile, int code, int print_dir)
{ {
if (_cpp_begin_message (pfile, code, if (_cpp_begin_message (pfile, code, pfile->cur_token[-1].src_loc, 0))
pfile->cur_token[-1].line,
pfile->cur_token[-1].col))
{ {
if (print_dir) if (print_dir)
fprintf (stderr, "#%s ", pfile->directive->name); fprintf (stderr, "#%s ", pfile->directive->name);
...@@ -1340,7 +1345,6 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in) ...@@ -1340,7 +1345,6 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in)
pfile->context = saved_context; pfile->context = saved_context;
pfile->cur_token = saved_cur_token; pfile->cur_token = saved_cur_token;
pfile->cur_run = saved_cur_run; pfile->cur_run = saved_cur_run;
pfile->line--;
} }
/* See above comment. For the moment, we'd like /* See above comment. For the moment, we'd like
...@@ -1903,13 +1907,6 @@ cpp_get_callbacks (cpp_reader *pfile) ...@@ -1903,13 +1907,6 @@ cpp_get_callbacks (cpp_reader *pfile)
return &pfile->cb; return &pfile->cb;
} }
/* The line map set. */
const struct line_maps *
cpp_get_line_maps (cpp_reader *pfile)
{
return pfile->line_table;
}
/* Copy the given callbacks structure to our own. */ /* Copy the given callbacks structure to our own. */
void void
cpp_set_callbacks (cpp_reader *pfile, cpp_callbacks *cb) cpp_set_callbacks (cpp_reader *pfile, cpp_callbacks *cb)
......
...@@ -174,8 +174,7 @@ struct cpp_string ...@@ -174,8 +174,7 @@ struct cpp_string
occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts. */ occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts. */
struct cpp_token struct cpp_token
{ {
fileline line; /* Logical line of first char of token. */ source_location src_loc; /* Location of first char of token. */
unsigned short col; /* Column of first char of token. */
ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT; /* token type */ ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT; /* token type */
unsigned char flags; /* flags - see above */ unsigned char flags; /* flags - see above */
...@@ -527,7 +526,6 @@ extern void cpp_set_include_chains (cpp_reader *, cpp_dir *, cpp_dir *, int); ...@@ -527,7 +526,6 @@ extern void cpp_set_include_chains (cpp_reader *, cpp_dir *, cpp_dir *, int);
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 (cpp_reader *); extern cpp_options *cpp_get_options (cpp_reader *);
extern const struct line_maps *cpp_get_line_maps (cpp_reader *);
extern cpp_callbacks *cpp_get_callbacks (cpp_reader *); extern cpp_callbacks *cpp_get_callbacks (cpp_reader *);
extern void cpp_set_callbacks (cpp_reader *, cpp_callbacks *); extern void cpp_set_callbacks (cpp_reader *, cpp_callbacks *);
...@@ -685,7 +683,7 @@ extern void cpp_errno (cpp_reader *, int, const char *msgid); ...@@ -685,7 +683,7 @@ extern void cpp_errno (cpp_reader *, int, const char *msgid);
/* Same as cpp_error, except additionally specifies a position as a /* Same as cpp_error, except additionally specifies a position as a
(translation unit) physical line and physical column. If the line is (translation unit) physical line and physical column. If the line is
zero, then no location is printed. */ zero, then no location is printed. */
extern void cpp_error_with_line (cpp_reader *, int, fileline, unsigned, extern void cpp_error_with_line (cpp_reader *, int, source_location, unsigned,
const char *msgid, ...) ATTRIBUTE_PRINTF_5; const char *msgid, ...) ATTRIBUTE_PRINTF_5;
/* In cpplex.c */ /* In cpplex.c */
......
...@@ -116,6 +116,7 @@ static const char * const monthnames[] = ...@@ -116,6 +116,7 @@ static const char * const monthnames[] =
const uchar * const uchar *
_cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
{ {
const struct line_map *map;
const uchar *result = NULL; const uchar *result = NULL;
unsigned int number = 1; unsigned int number = 1;
...@@ -132,7 +133,7 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) ...@@ -132,7 +133,7 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
unsigned int len; unsigned int len;
const char *name; const char *name;
uchar *buf; uchar *buf;
const struct line_map *map = pfile->map; map = linemap_lookup (pfile->line_table, pfile->line);
if (node->value.builtin == BT_BASE_FILE) if (node->value.builtin == BT_BASE_FILE)
while (! MAIN_FILE_P (map)) while (! MAIN_FILE_P (map))
...@@ -157,14 +158,15 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) ...@@ -157,14 +158,15 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
break; break;
case BT_SPECLINE: case BT_SPECLINE:
map = linemap_lookup (pfile->line_table, pfile->line);
/* If __LINE__ is embedded in a macro, it must expand to the /* If __LINE__ is embedded in a macro, it must expand to the
line of the macro's invocation, not its definition. line of the macro's invocation, not its definition.
Otherwise things like assert() will not work properly. */ Otherwise things like assert() will not work properly. */
if (CPP_OPTION (pfile, traditional)) if (CPP_OPTION (pfile, traditional))
number = pfile->line; number = pfile->line;
else else
number = pfile->cur_token[-1].line; number = pfile->cur_token[-1].src_loc;
number = SOURCE_LINE (pfile->map, number); number = SOURCE_LINE (map, number);
break; break;
/* __STDC__ has the value 1 under normal circumstances. /* __STDC__ has the value 1 under normal circumstances.
...@@ -174,7 +176,7 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) ...@@ -174,7 +176,7 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
value 0. */ value 0. */
case BT_STDC: case BT_STDC:
{ {
if (CPP_IN_SYSTEM_HEADER (pfile) if (cpp_in_system_header (pfile)
&& CPP_OPTION (pfile, stdc_0_in_system_headers) && CPP_OPTION (pfile, stdc_0_in_system_headers)
&& !CPP_OPTION (pfile,std)) && !CPP_OPTION (pfile,std))
number = 0; number = 0;
...@@ -1488,7 +1490,7 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node) ...@@ -1488,7 +1490,7 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
macro->count = 0; macro->count = 0;
macro->fun_like = 0; macro->fun_like = 0;
/* To suppress some diagnostics. */ /* To suppress some diagnostics. */
macro->syshdr = pfile->map->sysp != 0; macro->syshdr = pfile->buffer && pfile->buffer->sysp != 0;
if (CPP_OPTION (pfile, traditional)) if (CPP_OPTION (pfile, traditional))
ok = _cpp_create_trad_definition (pfile, macro); ok = _cpp_create_trad_definition (pfile, macro);
......
...@@ -148,7 +148,7 @@ static const uchar * ...@@ -148,7 +148,7 @@ static const uchar *
copy_comment (cpp_reader *pfile, const uchar *cur, int in_define) copy_comment (cpp_reader *pfile, const uchar *cur, int in_define)
{ {
bool unterminated, copy = false; bool unterminated, copy = false;
unsigned int from_line = pfile->line; source_location src_loc = pfile->line;
cpp_buffer *buffer = pfile->buffer; cpp_buffer *buffer = pfile->buffer;
buffer->cur = cur; buffer->cur = cur;
...@@ -158,7 +158,7 @@ copy_comment (cpp_reader *pfile, const uchar *cur, int in_define) ...@@ -158,7 +158,7 @@ copy_comment (cpp_reader *pfile, const uchar *cur, int in_define)
unterminated = _cpp_skip_block_comment (pfile); unterminated = _cpp_skip_block_comment (pfile);
if (unterminated) if (unterminated)
cpp_error_with_line (pfile, CPP_DL_ERROR, from_line, 0, cpp_error_with_line (pfile, CPP_DL_ERROR, src_loc, 0,
"unterminated comment"); "unterminated comment");
/* Comments in directives become spaces so that tokens are properly /* Comments in directives become spaces so that tokens are properly
...@@ -268,13 +268,14 @@ _cpp_overlay_buffer (cpp_reader *pfile, const uchar *start, size_t len) ...@@ -268,13 +268,14 @@ _cpp_overlay_buffer (cpp_reader *pfile, const uchar *start, size_t len)
cpp_buffer *buffer = pfile->buffer; cpp_buffer *buffer = pfile->buffer;
pfile->overlaid_buffer = buffer; pfile->overlaid_buffer = buffer;
buffer->saved_cur = buffer->cur; pfile->saved_cur = buffer->cur;
buffer->saved_rlimit = buffer->rlimit; pfile->saved_rlimit = buffer->rlimit;
/* Prevent the ISO lexer from scanning a fresh line. */ pfile->saved_line_base = buffer->next_line;
pfile->saved_line = pfile->line--; pfile->saved_line = pfile->line;
buffer->need_line = false; buffer->need_line = false;
buffer->cur = start; buffer->cur = start;
buffer->line_base = start;
buffer->rlimit = start + len; buffer->rlimit = start + len;
} }
...@@ -284,12 +285,12 @@ _cpp_remove_overlay (cpp_reader *pfile) ...@@ -284,12 +285,12 @@ _cpp_remove_overlay (cpp_reader *pfile)
{ {
cpp_buffer *buffer = pfile->overlaid_buffer; cpp_buffer *buffer = pfile->overlaid_buffer;
buffer->cur = buffer->saved_cur; buffer->cur = pfile->saved_cur;
buffer->rlimit = buffer->saved_rlimit; buffer->rlimit = pfile->saved_rlimit;
buffer->line_base = pfile->saved_line_base;
buffer->need_line = true; buffer->need_line = true;
pfile->overlaid_buffer = NULL; pfile->overlaid_buffer = NULL;
pfile->line = pfile->saved_line;
} }
/* Reads a logical line into the output buffer. Returns TRUE if there /* Reads a logical line into the output buffer. Returns TRUE if there
...@@ -404,7 +405,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro) ...@@ -404,7 +405,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro)
pfile->out.cur = out - 1; pfile->out.cur = out - 1;
pfile->buffer->cur = cur; pfile->buffer->cur = cur;
pfile->buffer->need_line = true; pfile->buffer->need_line = true;
pfile->line++; CPP_INCREMENT_LINE (pfile, 0);
if ((lex_state == ls_fun_open || lex_state == ls_fun_close) if ((lex_state == ls_fun_open || lex_state == ls_fun_close)
&& !pfile->state.in_directive && !pfile->state.in_directive
...@@ -605,7 +606,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro) ...@@ -605,7 +606,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro)
/* Null directive. Ignore it and don't invalidate /* Null directive. Ignore it and don't invalidate
the MI optimization. */ the MI optimization. */
pfile->buffer->need_line = true; pfile->buffer->need_line = true;
pfile->line++; CPP_INCREMENT_LINE (pfile, 0);
result = false; result = false;
goto done; goto done;
} }
......
...@@ -39,8 +39,24 @@ linemap_init (struct line_maps *set) ...@@ -39,8 +39,24 @@ linemap_init (struct line_maps *set)
set->trace_includes = false; set->trace_includes = false;
set->depth = 0; set->depth = 0;
set->cache = 0; set->cache = 0;
set->highest_location = 0;
set->max_column_hint = 0;
} }
/* Check for and warn about line_maps entered but not exited. */
void
linemap_check_files_exited (struct line_maps *set)
{
struct line_map *map;
/* Depending upon whether we are handling preprocessed input or
not, this can be a user error or an ICE. */
for (map = &set->maps[set->used - 1]; ! MAIN_FILE_P (map);
map = INCLUDED_FROM (set, map))
fprintf (stderr, "line-map.c: file \"%s\" entered but not left\n",
map->to_file);
}
/* Free a line map set. */ /* Free a line map set. */
void void
...@@ -48,14 +64,7 @@ linemap_free (struct line_maps *set) ...@@ -48,14 +64,7 @@ linemap_free (struct line_maps *set)
{ {
if (set->maps) if (set->maps)
{ {
struct line_map *map; linemap_check_files_exited (set);
/* Depending upon whether we are handling preprocessed input or
not, this can be a user error or an ICE. */
for (map = CURRENT_LINE_MAP (set); ! MAIN_FILE_P (map);
map = INCLUDED_FROM (set, map))
fprintf (stderr, "line-map.c: file \"%s\" entered but not left\n",
map->to_file);
free (set->maps); free (set->maps);
} }
...@@ -72,16 +81,17 @@ linemap_free (struct line_maps *set) ...@@ -72,16 +81,17 @@ linemap_free (struct line_maps *set)
FROM_LINE should be monotonic increasing across calls to this FROM_LINE should be monotonic increasing across calls to this
function. A call to this function can relocate the previous set of function. A call to this function can relocate the previous set of
A call to this function can relocate the previous set of
maps, so any stored line_map pointers should not be used. */ maps, so any stored line_map pointers should not be used. */
const struct line_map * const struct line_map *
linemap_add (struct line_maps *set, enum lc_reason reason, linemap_add (struct line_maps *set, enum lc_reason reason,
unsigned int sysp, source_location from_line, unsigned int sysp, const char *to_file, unsigned int to_line)
const char *to_file, unsigned int to_line)
{ {
struct line_map *map; struct line_map *map;
source_location start_location = set->highest_location + 1;
if (set->used && from_line < set->maps[set->used - 1].from_line) if (set->used && start_location < set->maps[set->used - 1].start_location)
abort (); abort ();
if (set->used == set->allocated) if (set->used == set->allocated)
...@@ -131,17 +141,20 @@ linemap_add (struct line_maps *set, enum lc_reason reason, ...@@ -131,17 +141,20 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
if (error || to_file == NULL) if (error || to_file == NULL)
{ {
to_file = from->to_file; to_file = from->to_file;
to_line = LAST_SOURCE_LINE (from) + 1; to_line = SOURCE_LINE (from, from[1].start_location);
sysp = from->sysp; sysp = from->sysp;
} }
} }
map->reason = reason; map->reason = reason;
map->sysp = sysp; map->sysp = sysp;
map->from_line = from_line; map->start_location = start_location;
map->to_file = to_file; map->to_file = to_file;
map->to_line = to_line; map->to_line = to_line;
set->cache = set->used++; set->cache = set->used++;
map->column_bits = 0;
set->highest_location = start_location;
set->max_column_hint = 0;
if (reason == LC_ENTER) if (reason == LC_ENTER)
{ {
...@@ -161,6 +174,59 @@ linemap_add (struct line_maps *set, enum lc_reason reason, ...@@ -161,6 +174,59 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
return map; return map;
} }
source_location
linemap_line_start (struct line_maps *set, unsigned int to_line,
unsigned int max_column_hint)
{
struct line_map *map = &set->maps[set->used - 1];
source_location highest = set->highest_location;
source_location r;
unsigned int last_line = SOURCE_LINE (map, highest);
int line_delta = to_line - last_line;
bool add_map = false;
if (line_delta < 0
|| (line_delta > 10 && line_delta * map->column_bits > 1000)
|| (max_column_hint >= (1U << map->column_bits))
|| (max_column_hint <= 80 && map->column_bits >= 10))
{
add_map = true;
}
else
max_column_hint = set->max_column_hint;
if (add_map)
{
int column_bits;
if (max_column_hint > 1000000 || highest > 0xC0000000)
{
max_column_hint = 0;
if (highest >0xF0000000)
return 0;
column_bits = 0;
}
else
{
column_bits = 7;
while (max_column_hint >= (1U << column_bits))
column_bits++;
max_column_hint = 1U << column_bits;
}
if (line_delta < 0
|| last_line != map->to_line
|| SOURCE_COLUMN (map, highest) >= (1U << column_bits))
map = (struct line_map*) linemap_add (set, LC_RENAME, map->sysp,
map->to_file, to_line);
map->column_bits = column_bits;
r = map->start_location;
}
else
r = highest - SOURCE_COLUMN (map, highest)
+ (line_delta << map->column_bits);
if (r > set->highest_location)
set->highest_location = r;
set->max_column_hint = max_column_hint;
return r;
}
/* Given a logical line, returns the map from which the corresponding /* Given a logical line, returns the map from which the corresponding
(source file, line) pair can be deduced. Since the set is built (source file, line) pair can be deduced. Since the set is built
chronologically, the logical lines are monotonic increasing, and so chronologically, the logical lines are monotonic increasing, and so
...@@ -177,9 +243,9 @@ linemap_lookup (struct line_maps *set, source_location line) ...@@ -177,9 +243,9 @@ linemap_lookup (struct line_maps *set, source_location line)
cached = &set->maps[mn]; cached = &set->maps[mn];
/* We should get a segfault if no line_maps have been added yet. */ /* We should get a segfault if no line_maps have been added yet. */
if (line >= cached->from_line) if (line >= cached->start_location)
{ {
if (mn + 1 == mx || line < cached[1].from_line) if (mn + 1 == mx || line < cached[1].start_location)
return cached; return cached;
} }
else else
...@@ -191,7 +257,7 @@ linemap_lookup (struct line_maps *set, source_location line) ...@@ -191,7 +257,7 @@ linemap_lookup (struct line_maps *set, source_location line)
while (mx - mn > 1) while (mx - mn > 1)
{ {
md = (mn + mx) / 2; md = (mn + mx) / 2;
if (set->maps[md].from_line > line) if (set->maps[md].start_location > line)
mx = md; mx = md;
else else
mn = md; mn = md;
......
...@@ -30,28 +30,35 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -30,28 +30,35 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
(e.g. a #line directive in C). */ (e.g. a #line directive in C). */
enum lc_reason {LC_ENTER = 0, LC_LEAVE, LC_RENAME}; enum lc_reason {LC_ENTER = 0, LC_LEAVE, LC_RENAME};
/* A logical line number, i,e, an "index" into a line_map. */ /* A logical line/column number, i.e. an "index" into a line_map. */
/* Long-term, we want to use this to replace struct location_s (in input.h), /* Long-term, we want to use this to replace struct location_s (in input.h),
and effectively typedef source_location location_t. */ and effectively typedef source_location location_t. */
typedef unsigned int source_location; typedef unsigned int source_location;
typedef source_location fileline; /* deprecated name */ typedef source_location fileline; /* deprecated name */
/* The logical line FROM_LINE maps to physical source file TO_FILE at /* Physical source file TO_FILE at line TO_LINE at column 0 is represented
line TO_LINE, and subsequently one-to-one until the next line_map by the logical START_LOCATION. TO_LINE+L at column C is represented by
structure in the set. INCLUDED_FROM is an index into the set that START_LOCATION+(L*(1<<column_bits))+C, as long as C<(1<<column_bits),
gives the line mapping at whose end the current one was included. and the result_location is less than the next line_map's start_location.
File(s) at the bottom of the include stack have this set to -1. (The top line is line 1 and the leftmost column is column 1; line/column 0
REASON is the reason for creation of this line map, SYSP is one for means "entire file/line" or "unknown line/column" or "not applicable".)
a system header, two for a C system header file that therefore INCLUDED_FROM is an index into the set that gives the line mapping
needs to be extern "C" protected in C++, and zero otherwise. */ at whose end the current one was included. File(s) at the bottom
of the include stack have this set to -1. REASON is the reason for
creation of this line map, SYSP is one for a system header, two for
a C system header file that therefore needs to be extern "C"
protected in C++, and zero otherwise. */
struct line_map struct line_map
{ {
const char *to_file; const char *to_file;
unsigned int to_line; unsigned int to_line;
source_location from_line; source_location start_location;
int included_from; int included_from;
ENUM_BITFIELD (lc_reason) reason : CHAR_BIT; ENUM_BITFIELD (lc_reason) reason : CHAR_BIT;
/* The sysp field isn't really needed now that it's in cpp_buffer. */
unsigned char sysp; unsigned char sysp;
/* Number of the low-order source_location bits used for a column number. */
unsigned int column_bits : 8;
}; };
/* A set of chronological line_map structures. */ /* A set of chronological line_map structures. */
...@@ -73,6 +80,13 @@ struct line_maps ...@@ -73,6 +80,13 @@ struct line_maps
/* If true, prints an include trace a la -H. */ /* If true, prints an include trace a la -H. */
bool trace_includes; bool trace_includes;
/* Highest source_location "given out". */
source_location highest_location;
/* The maximum column number we can quickly allocate. Higher numbers
may require allocating a new line_map. */
unsigned int max_column_hint;
}; };
/* Initialize a line map set. */ /* Initialize a line map set. */
...@@ -81,6 +95,19 @@ extern void linemap_init (struct line_maps *); ...@@ -81,6 +95,19 @@ extern void linemap_init (struct line_maps *);
/* Free a line map set. */ /* Free a line map set. */
extern void linemap_free (struct line_maps *); extern void linemap_free (struct line_maps *);
/* Check for and warn about line_maps entered but not exited. */
extern void linemap_check_files_exited (struct line_maps *);
/* Return a source_location for the start (i.e. column==0) of
(physical) line TO_LINE in the current source file (as in the
most recent linemap_add). MAX_COLUMN_HINT is the highest column
number we expect to use in this line (but it does not change
the highest_location). */
extern source_location linemap_line_start
(struct line_maps *, unsigned int, unsigned int);
/* Add a mapping of logical source line to physical source file and /* Add a mapping of logical source line to physical source file and
line number. line number.
...@@ -90,12 +117,12 @@ extern void linemap_free (struct line_maps *); ...@@ -90,12 +117,12 @@ extern void linemap_free (struct line_maps *);
TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their
natural values considering the file we are returning to. natural values considering the file we are returning to.
FROM_LINE should be monotonic increasing across calls to this START_LOCATION should be monotonic increasing across calls to this
function. A call to this function can relocate the previous set of function. A call to this function can relocate the previous set of
maps, so any stored line_map pointers should not be used. */ maps, so any stored line_map pointers should not be used. */
extern const struct line_map *linemap_add extern const struct line_map *linemap_add
(struct line_maps *, enum lc_reason, unsigned int sysp, (struct line_maps *, enum lc_reason, unsigned int sysp,
source_location from_line, const char *to_file, unsigned int to_line); const char *to_file, unsigned int to_line);
/* Given a logical line, returns the map from which the corresponding /* Given a logical line, returns the map from which the corresponding
(source file, line) pair can be deduced. */ (source file, line) pair can be deduced. */
...@@ -108,12 +135,21 @@ extern const struct line_map *linemap_lookup ...@@ -108,12 +135,21 @@ extern const struct line_map *linemap_lookup
extern void linemap_print_containing_files (struct line_maps *, extern void linemap_print_containing_files (struct line_maps *,
const struct line_map *); const struct line_map *);
/* Converts a map and logical line to source line. */ /* Converts a map and a source_location to source line. */
#define SOURCE_LINE(MAP, LINE) ((LINE) + (MAP)->to_line - (MAP)->from_line) #define SOURCE_LINE(MAP, LINE) \
((((LINE) - (MAP)->start_location) >> (MAP)->column_bits) + (MAP)->to_line)
#define SOURCE_COLUMN(MAP, LINE) \
(((LINE) - (MAP)->start_location) & ((1 << (MAP)->column_bits) - 1))
/* Returns the last source line within a map. This is the (last) 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. */ 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 LAST_SOURCE_LINE(MAP) \
SOURCE_LINE (MAP, LAST_SOURCE_LINE_LOCATION (MAP))
#define LAST_SOURCE_LINE_LOCATION(MAP) \
((((MAP)[1].start_location - 2 - (MAP)->start_location) \
& ~((1 << (MAP)->column_bits) - 1)) \
+ (MAP)->start_location)
/* Returns the map a given map was included from. */ /* Returns the map a given map was included from. */
#define INCLUDED_FROM(SET, MAP) (&(SET)->maps[(MAP)->included_from]) #define INCLUDED_FROM(SET, MAP) (&(SET)->maps[(MAP)->included_from])
...@@ -121,8 +157,32 @@ extern void linemap_print_containing_files (struct line_maps *, ...@@ -121,8 +157,32 @@ extern void linemap_print_containing_files (struct line_maps *,
/* Nonzero if the map is at the bottom of the include stack. */ /* Nonzero if the map is at the bottom of the include stack. */
#define MAIN_FILE_P(MAP) ((MAP)->included_from < 0) #define MAIN_FILE_P(MAP) ((MAP)->included_from < 0)
/* The current line map. Saves a call to lookup_line if the caller is /* Get a source position that for the same line as the most recent
sure he is in the scope of the current map. */ linemap_line_start, but with the specified TO_COLUMN column number. */
#define CURRENT_LINE_MAP(MAPS) ((MAPS)->maps + (MAPS)->used - 1)
static inline source_location
linemap_position_for_column (struct line_maps *set, unsigned int to_column)
{
struct line_map *map = &set->maps[set->used - 1];
source_location r = set->highest_location;
if (__builtin_expect (to_column > set->max_column_hint, 0))
{
if (r >= 0xC000000 || to_column > 1000000) /* FIXME */
{
/* Running low on source_locations - disable column numbers. */
return r - SOURCE_COLUMN (map, r);
}
else
{
r = linemap_line_start (set, SOURCE_LINE (map, r), to_column + 50);
map = &set->maps[set->used - 1];
r = set->highest_location;
}
}
r = r - SOURCE_COLUMN (map, r) + to_column;
if (r >= set->highest_location)
set->highest_location = r;
return r;
}
#endif /* !GCC_LINE_MAP_H */ #endif /* !GCC_LINE_MAP_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment