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
This commit is contained in:
Per Bothner 2004-02-11 07:29:30 -08:00 committed by Per Bothner
parent 8914b65e21
commit 12f9df4ec5
14 changed files with 423 additions and 187 deletions

View File

@ -1,3 +1,82 @@
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>
* config/rs6000/altivec.md (*movv4si_internal): At least one

View File

@ -42,9 +42,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "splay-tree.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. */
static int header_time, body_time;
static splay_tree file_info_tree;
@ -194,28 +191,27 @@ static void
cb_line_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const cpp_token *token,
int parsing_args)
{
if (token->type == CPP_EOF || parsing_args)
return;
input_line = SOURCE_LINE (map, token->line);
if (token->type != CPP_EOF && !parsing_args)
{
source_location loc = token->src_loc;
const struct line_map *map = linemap_lookup (&line_table, loc);
input_line = SOURCE_LINE (map, loc);
}
}
void
fe_file_change (const struct line_map *new_map)
{
if (new_map == NULL)
{
map = NULL;
return;
}
return;
if (new_map->reason == LC_ENTER)
{
/* Don't stack the main buffer on the input stack;
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;
push_srcloc (new_map->to_file, 1);
@ -250,20 +246,20 @@ fe_file_change (const struct line_map *new_map)
in_system_header = new_map->sysp != 0;
input_filename = new_map->to_file;
input_line = new_map->to_line;
map = new_map;
/* Hook for C++. */
extract_interface_info ();
}
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
unknown pragmas in system headers unless an explicit
-Wunknown-pragmas has been given. */
if (warn_unknown_pragmas > in_system_header)
{
const struct line_map *map = linemap_lookup (&line_table, loc);
const unsigned char *space, *name;
const cpp_token *s;
@ -277,25 +273,27 @@ cb_def_pragma (cpp_reader *pfile, unsigned int line)
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);
}
}
/* #define callback for DWARF and DWARF2 debug info. */
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));
}
/* #undef callback for DWARF and DWARF2 debug info. */
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)
{
(*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));
}

View File

@ -32,10 +32,9 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
static struct
{
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 *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. */
} print;
@ -45,8 +44,8 @@ static void scan_translation_unit_trad (cpp_reader *);
static void account_for_newlines (const unsigned char *, size_t);
static int dump_macro (cpp_reader *, cpp_hashnode *, void *);
static void print_line (const struct line_map *, fileline, const char *);
static void maybe_print_line (const struct line_map *, fileline);
static void print_line (source_location, const char *);
static void maybe_print_line (source_location);
/* Callback routines for the parser. Most of these are active only
in specific modes. */
@ -112,13 +111,12 @@ init_pp_output (FILE *out_stream)
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 linemarker to be output by maybe_print_line. */
print.line = (fileline) -1;
print.src_line = -1;
print.printed = 0;
print.prev = 0;
print.map = 0;
print.outf = out_stream;
}
@ -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
account_for_newlines (const unsigned char *str, size_t len)
{
while (len--)
if (*str++ == '\n')
print.line++;
print.src_line++;
}
/* Writes out a traditionally preprocessed file. */
@ -187,7 +185,7 @@ scan_translation_unit_trad (cpp_reader *pfile)
while (_cpp_read_logical_line_trad (pfile))
{
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);
print.printed = 1;
if (!CPP_OPTION (pfile, discard_comments))
@ -199,52 +197,56 @@ scan_translation_unit_trad (cpp_reader *pfile)
different line to the current one, output the required newlines or
a line marker, and return 1. Otherwise return 0. */
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. */
if (print.printed)
{
putc ('\n', print.outf);
print.line++;
print.src_line++;
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);
print.line++;
print.src_line++;
}
}
else
print_line (map, line, "");
print_line (src_loc, "");
}
/* Output a line marker for logical line LINE. Special flags are "1"
or "2" indicating entering or leaving a file. */
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. */
if (print.printed)
putc ('\n', print.outf);
print.printed = 0;
print.line = line;
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);
unsigned char *to_file_quoted = alloca (to_file_len * 4 + 1);
unsigned char *p;
print.src_line = SOURCE_LINE (map, src_loc);
/* cpp_quote_string does not nul-terminate, so we have to do it
ourselves. */
p = cpp_quote_string (to_file_quoted,
(unsigned char *)map->to_file, to_file_len);
*p = '\0';
fprintf (print.outf, "# %u \"%s\"%s",
SOURCE_LINE (map, print.line),
fprintf (print.outf, "# %u \"%s\"%s", print.src_line,
to_file_quoted, special_flags);
if (map->sysp == 2)
@ -262,10 +264,12 @@ static void
cb_line_change (cpp_reader *pfile, const cpp_token *token,
int parsing_args)
{
source_location src_loc = token->src_loc;
if (token->type == CPP_EOF || parsing_args)
return;
maybe_print_line (print.map, token->line);
maybe_print_line (src_loc);
print.prev = 0;
print.source = 0;
@ -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. */
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;
if (token->col > 2)
{
unsigned int spaces = token->col - 2;
while (spaces--)
putc (' ', print.outf);
}
while (-- spaces >= 0)
putc (' ', print.outf);
}
}
@ -291,15 +293,15 @@ static void
cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line,
const cpp_string *str)
{
maybe_print_line (print.map, line);
maybe_print_line (line);
fprintf (print.outf, "#ident \"%s\"\n", str->text);
print.line++;
print.src_line++;
}
static void
cb_define (cpp_reader *pfile, fileline line, cpp_hashnode *node)
{
maybe_print_line (print.map, line);
maybe_print_line (line);
fputs ("#define ", print.outf);
/* 'D' is whole definition; 'N' is name only. */
@ -310,28 +312,28 @@ cb_define (cpp_reader *pfile, fileline line, cpp_hashnode *node)
fputs ((const char *) NODE_NAME (node), print.outf);
putc ('\n', print.outf);
print.line++;
print.src_line++;
}
static void
cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line,
cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line,
cpp_hashnode *node)
{
maybe_print_line (print.map, line);
maybe_print_line (line);
fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
print.line++;
print.src_line++;
}
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)
{
maybe_print_line (print.map, line);
maybe_print_line (line);
if (angle_brackets)
fprintf (print.outf, "#%s <%s>\n", dir, header);
else
fprintf (print.outf, "#%s \"%s\"\n", dir, header);
print.line++;
print.src_line++;
}
/* 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)
}
/* 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
pointing to freed memory, and so must not be dereferenced. */
described in MAP. */
void
pp_file_change (const struct line_map *map)
@ -365,37 +366,37 @@ pp_file_change (const struct line_map *map)
if (map != NULL)
{
/* First time? */
if (print.map == NULL)
if (MAIN_FILE_P (map))
{
/* Avoid printing foo.i when the main file is foo.c. */
if (!cpp_get_options (parse_in)->preprocessed)
print_line (map, map->from_line, flags);
print_line (map->start_location, flags);
}
else
{
/* Bring current file to correct line when entering a new file. */
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)
flags = " 1";
else if (map->reason == LC_LEAVE)
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. */
static void
cb_def_pragma (cpp_reader *pfile, fileline line)
{
maybe_print_line (print.map, line);
maybe_print_line (line);
fputs ("#pragma ", print.outf);
cpp_output_line (pfile, print.outf);
print.line++;
print.src_line++;
}
/* Dump out the hash table. */
@ -408,7 +409,7 @@ dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED)
fputs ((const char *) cpp_macro_definition (pfile, node),
print.outf);
putc ('\n', print.outf);
print.line++;
print.src_line++;
}
return 1;

View File

@ -29,14 +29,14 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "cpphash.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
diagnostic. Outputs the #include chain if it has changed. A line
of zero suppresses the include stack, and outputs the program name
instead. */
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)
fprintf (stderr, "%s: ", progname);
@ -50,7 +50,11 @@ print_location (cpp_reader *pfile, fileline line, unsigned int col)
lin = SOURCE_LINE (map, line);
if (col == 0)
col = 1;
{
col = SOURCE_COLUMN (map, line);
if (col == 0)
col = 1;
}
if (lin == 0)
fprintf (stderr, "%s:", map->to_file);
@ -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
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
the correct place by default. Returns 0 if the error has been
suppressed. */
the correct place by default. The column number can be specified either
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
_cpp_begin_message (cpp_reader *pfile, int code, fileline line,
unsigned int column)
_cpp_begin_message (cpp_reader *pfile, int code,
source_location src_loc, unsigned int column)
{
int level = CPP_DL_EXTRACT (code);
@ -78,7 +87,7 @@ _cpp_begin_message (cpp_reader *pfile, int code, fileline line,
{
case CPP_DL_WARNING:
case CPP_DL_PEDWARN:
if (CPP_IN_SYSTEM_HEADER (pfile)
if (cpp_in_system_header (pfile)
&& ! CPP_OPTION (pfile, warn_system_headers))
return 0;
/* Fall through. */
@ -105,7 +114,7 @@ _cpp_begin_message (cpp_reader *pfile, int code, fileline line,
break;
}
print_location (pfile, line, column);
print_location (pfile, src_loc, column);
if (CPP_DL_WARNING_P (level))
fputs (_("warning: "), stderr);
else if (level == CPP_DL_ICE)
@ -125,8 +134,7 @@ _cpp_begin_message (cpp_reader *pfile, int code, fileline line,
void
cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
{
fileline line;
unsigned int column;
source_location src_loc;
va_list ap;
va_start (ap, msgid);
@ -134,18 +142,16 @@ cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
if (CPP_OPTION (pfile, traditional))
{
if (pfile->state.in_directive)
line = pfile->directive_line;
src_loc = pfile->directive_line;
else
line = pfile->line;
column = 0;
src_loc = pfile->line;
}
else
{
line = pfile->cur_token[-1].line;
column = pfile->cur_token[-1].col;
src_loc = pfile->cur_token[-1].src_loc;
}
if (_cpp_begin_message (pfile, level, line, column))
if (_cpp_begin_message (pfile, level, src_loc, 0))
v_message (msgid, ap);
va_end (ap);
@ -154,14 +160,14 @@ cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
/* Print an error at a specific location. */
void
cpp_error_with_line (cpp_reader *pfile, int level,
fileline line, unsigned int column,
source_location src_loc, unsigned int column,
const char *msgid, ...)
{
va_list ap;
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);
va_end (ap);

View File

@ -640,8 +640,10 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
if (!should_stack_file (pfile, file, import))
return false;
sysp = MAX ((pfile->map ? pfile->map->sysp : 0),
(file->dir ? file->dir->sysp : 0));
if (pfile->buffer == NULL || file->dir == NULL)
sysp = 0;
else
sysp = MAX (pfile->buffer->sysp, file->dir->sysp);
/* Add the file to the dependencies on its first inclusion. */
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)
buffer = cpp_push_buffer (pfile, file->buffer, file->st.st_size,
CPP_OPTION (pfile, preprocessed));
buffer->file = file;
buffer->sysp = sysp;
/* Initialize controlling macro state. */
pfile->mi_valid = true;
@ -707,7 +710,8 @@ search_path_head (cpp_reader *pfile, const char *fname, int angle_brackets,
else if (pfile->quote_ignores_source_dir)
dir = pfile->quote_include;
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)
cpp_error (pfile, CPP_DL_ERROR,
@ -756,7 +760,7 @@ _cpp_stack_include (cpp_reader *pfile, const char *fname, int angle_brackets,
static void
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;
errno = file->err_no;
@ -936,12 +940,14 @@ void
cpp_make_system_header (cpp_reader *pfile, int syshdr, int externc)
{
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. */
if (syshdr)
flags = 1 + (externc != 0);
_cpp_do_file_change (pfile, LC_RENAME, pfile->map->to_file,
SOURCE_LINE (pfile->map, pfile->line), flags);
pfile->buffer->sysp = 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

View File

@ -64,6 +64,13 @@ typedef unsigned char uchar;
#define CPP_BUF_COLUMN(BUF, CUR) ((CUR) - (BUF)->line_base)
#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
efficiency, and partly to limit runaway recursion. */
#define CPP_STACK_MAX 200
@ -296,24 +303,25 @@ struct cpp_buffer
The warning happens only for C89 extended mode with -pedantic on,
or for -Wtraditional, and only once per file (otherwise it would
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
for preprocessed input, command line directives, and _Pragma
buffers. */
unsigned char from_stage3;
unsigned int from_stage3 : 1;
/* Nonzero means that the directory to start searching for ""
include files has been calculated and stored in "dir" below. */
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
allocated, so we don't need to worry about freeing it. */
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
source character set. */
struct cset_converter input_cset_desc;
@ -335,7 +343,6 @@ struct cpp_reader
/* Source line tracking. */
struct line_maps *line_table;
const struct line_map *map;
fileline line;
/* The line of the '#' of the current directive. */
@ -455,6 +462,9 @@ struct cpp_reader
fileline first_line;
} 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
preprocessing. */
unsigned int saved_line;
@ -493,12 +503,18 @@ extern unsigned char _cpp_trigraph_map[UCHAR_MAX + 1];
/* 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_WTRADITIONAL(PF) CPP_OPTION (PF, warn_traditional)
/* 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 */
extern void _cpp_free_definition (cpp_hashnode *);

View File

@ -479,7 +479,7 @@ cpp_read_main_file (cpp_reader *pfile, const char *fname)
if (CPP_OPTION (pfile, preprocessed))
{
read_original_filename (pfile);
fname = pfile->map->to_file;
fname = pfile->line_table->maps[pfile->line_table->used-1].to_file;
}
return fname;
}

View File

@ -282,7 +282,7 @@ _cpp_process_line_notes (cpp_reader *pfile, int in_comment)
}
buffer->line_base = note->pos;
pfile->line++;
CPP_INCREMENT_LINE (pfile, 0);
}
else if (_cpp_trigraph_map[note->type])
{
@ -349,12 +349,16 @@ _cpp_skip_block_comment (cpp_reader *pfile)
}
else if (c == '\n')
{
unsigned int cols;
buffer->cur = cur - 1;
_cpp_process_line_notes (pfile, true);
if (buffer->next_line >= buffer->rlimit)
return true;
_cpp_clean_line (pfile);
pfile->line++;
cols = buffer->next_line - buffer->line_base;
CPP_INCREMENT_LINE (pfile, cols);
cur = buffer->cur;
}
}
@ -680,8 +684,7 @@ _cpp_temp_token (cpp_reader *pfile)
}
result = pfile->cur_token++;
result->line = old->line;
result->col = old->col;
result->src_loc = old->src_loc;
return result;
}
@ -772,7 +775,7 @@ _cpp_get_fresh_line (cpp_reader *pfile)
{
/* Only warn once. */
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),
"no newline at end of file");
}
@ -822,7 +825,7 @@ _cpp_lex_direct (cpp_reader *pfile)
if (!pfile->state.in_directive)
{
/* Tell the compiler the line number of the EOF token. */
result->line = pfile->line;
result->src_loc = pfile->line;
result->flags = BOL;
}
return result;
@ -839,17 +842,19 @@ _cpp_lex_direct (cpp_reader *pfile)
}
buffer = pfile->buffer;
update_tokens_line:
result->line = pfile->line;
result->src_loc = pfile->line;
skipped_white:
if (buffer->cur >= buffer->notes[buffer->cur_note].pos
&& !pfile->overlaid_buffer)
{
_cpp_process_line_notes (pfile, false);
result->line = pfile->line;
result->src_loc = pfile->line;
}
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)
{
@ -859,7 +864,8 @@ _cpp_lex_direct (cpp_reader *pfile)
goto skipped_white;
case '\n':
pfile->line++;
if (buffer->cur < buffer->rlimit)
CPP_INCREMENT_LINE (pfile, 0);
buffer->need_line = true;
goto fresh_line;
@ -916,7 +922,7 @@ _cpp_lex_direct (cpp_reader *pfile)
cpp_error (pfile, CPP_DL_ERROR, "unterminated comment");
}
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
in system headers. */

View File

@ -777,8 +777,9 @@ strtoul_for_line (const uchar *str, unsigned int len, long unsigned int *nump)
static void
do_line (cpp_reader *pfile)
{
const struct line_map *map = linemap_lookup (pfile->line_table, pfile->line);
const cpp_token *token;
const char *new_file = pfile->map->to_file;
const char *new_file = map->to_file;
unsigned long new_lineno;
/* C99 raised the minimum limit on #line numbers. */
@ -816,7 +817,7 @@ do_line (cpp_reader *pfile)
skip_rest_of_line (pfile);
_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
@ -825,10 +826,11 @@ do_line (cpp_reader *pfile)
static void
do_linemarker (cpp_reader *pfile)
{
const struct line_map *map = linemap_lookup (pfile->line_table, pfile->line);
const cpp_token *token;
const char *new_file = pfile->map->to_file;
const char *new_file = map->to_file;
unsigned long new_lineno;
unsigned int new_sysp = pfile->map->sysp;
unsigned int new_sysp = map->sysp;
enum lc_reason reason = LC_RENAME;
int flag;
@ -876,6 +878,7 @@ do_linemarker (cpp_reader *pfile)
flag = read_flag (pfile, flag);
if (flag == 4)
new_sysp = 2;
pfile->buffer->sysp = new_sysp;
}
check_eol (pfile);
@ -900,11 +903,15 @@ _cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason,
const char *to_file, unsigned int file_line,
unsigned int sysp)
{
pfile->map = linemap_add (pfile->line_table, reason, sysp,
pfile->line, to_file, file_line);
const struct line_map *map = linemap_add (pfile->line_table, reason, sysp,
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)
pfile->cb.file_change (pfile, pfile->map);
pfile->cb.file_change (pfile, map);
}
/* 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,
static void
do_diagnostic (cpp_reader *pfile, int code, int print_dir)
{
if (_cpp_begin_message (pfile, code,
pfile->cur_token[-1].line,
pfile->cur_token[-1].col))
if (_cpp_begin_message (pfile, code, pfile->cur_token[-1].src_loc, 0))
{
if (print_dir)
fprintf (stderr, "#%s ", pfile->directive->name);
@ -1340,7 +1345,6 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in)
pfile->context = saved_context;
pfile->cur_token = saved_cur_token;
pfile->cur_run = saved_cur_run;
pfile->line--;
}
/* See above comment. For the moment, we'd like
@ -1903,13 +1907,6 @@ cpp_get_callbacks (cpp_reader *pfile)
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. */
void
cpp_set_callbacks (cpp_reader *pfile, cpp_callbacks *cb)

View File

@ -174,8 +174,7 @@ struct cpp_string
occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts. */
struct cpp_token
{
fileline line; /* Logical line of first char of token. */
unsigned short col; /* Column of first char of token. */
source_location src_loc; /* Location of first char of token. */
ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT; /* token type */
unsigned char flags; /* flags - see above */
@ -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
with cpp_set_callbacks. */
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 void cpp_set_callbacks (cpp_reader *, cpp_callbacks *);
@ -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
(translation unit) physical line and physical column. If the line is
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;
/* In cpplex.c */

View File

@ -116,6 +116,7 @@ static const char * const monthnames[] =
const uchar *
_cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
{
const struct line_map *map;
const uchar *result = NULL;
unsigned int number = 1;
@ -132,7 +133,7 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
unsigned int len;
const char *name;
uchar *buf;
const struct line_map *map = pfile->map;
map = linemap_lookup (pfile->line_table, pfile->line);
if (node->value.builtin == BT_BASE_FILE)
while (! MAIN_FILE_P (map))
@ -157,14 +158,15 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
break;
case BT_SPECLINE:
map = linemap_lookup (pfile->line_table, pfile->line);
/* If __LINE__ is embedded in a macro, it must expand to the
line of the macro's invocation, not its definition.
Otherwise things like assert() will not work properly. */
if (CPP_OPTION (pfile, traditional))
number = pfile->line;
else
number = pfile->cur_token[-1].line;
number = SOURCE_LINE (pfile->map, number);
number = pfile->cur_token[-1].src_loc;
number = SOURCE_LINE (map, number);
break;
/* __STDC__ has the value 1 under normal circumstances.
@ -174,7 +176,7 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
value 0. */
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,std))
number = 0;
@ -1488,7 +1490,7 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
macro->count = 0;
macro->fun_like = 0;
/* To suppress some diagnostics. */
macro->syshdr = pfile->map->sysp != 0;
macro->syshdr = pfile->buffer && pfile->buffer->sysp != 0;
if (CPP_OPTION (pfile, traditional))
ok = _cpp_create_trad_definition (pfile, macro);

View File

@ -148,7 +148,7 @@ static const uchar *
copy_comment (cpp_reader *pfile, const uchar *cur, int in_define)
{
bool unterminated, copy = false;
unsigned int from_line = pfile->line;
source_location src_loc = pfile->line;
cpp_buffer *buffer = pfile->buffer;
buffer->cur = cur;
@ -158,7 +158,7 @@ copy_comment (cpp_reader *pfile, const uchar *cur, int in_define)
unterminated = _cpp_skip_block_comment (pfile);
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");
/* 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)
cpp_buffer *buffer = pfile->buffer;
pfile->overlaid_buffer = buffer;
buffer->saved_cur = buffer->cur;
buffer->saved_rlimit = buffer->rlimit;
/* Prevent the ISO lexer from scanning a fresh line. */
pfile->saved_line = pfile->line--;
pfile->saved_cur = buffer->cur;
pfile->saved_rlimit = buffer->rlimit;
pfile->saved_line_base = buffer->next_line;
pfile->saved_line = pfile->line;
buffer->need_line = false;
buffer->cur = start;
buffer->line_base = start;
buffer->rlimit = start + len;
}
@ -284,12 +285,12 @@ _cpp_remove_overlay (cpp_reader *pfile)
{
cpp_buffer *buffer = pfile->overlaid_buffer;
buffer->cur = buffer->saved_cur;
buffer->rlimit = buffer->saved_rlimit;
buffer->cur = pfile->saved_cur;
buffer->rlimit = pfile->saved_rlimit;
buffer->line_base = pfile->saved_line_base;
buffer->need_line = true;
pfile->overlaid_buffer = NULL;
pfile->line = pfile->saved_line;
}
/* 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)
pfile->out.cur = out - 1;
pfile->buffer->cur = cur;
pfile->buffer->need_line = true;
pfile->line++;
CPP_INCREMENT_LINE (pfile, 0);
if ((lex_state == ls_fun_open || lex_state == ls_fun_close)
&& !pfile->state.in_directive
@ -605,7 +606,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro)
/* Null directive. Ignore it and don't invalidate
the MI optimization. */
pfile->buffer->need_line = true;
pfile->line++;
CPP_INCREMENT_LINE (pfile, 0);
result = false;
goto done;
}

View File

@ -39,8 +39,24 @@ linemap_init (struct line_maps *set)
set->trace_includes = false;
set->depth = 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. */
void
@ -48,14 +64,7 @@ linemap_free (struct line_maps *set)
{
if (set->maps)
{
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 = 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);
linemap_check_files_exited (set);
free (set->maps);
}
@ -72,16 +81,17 @@ linemap_free (struct line_maps *set)
FROM_LINE should be monotonic increasing across calls to this
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. */
const struct line_map *
linemap_add (struct line_maps *set, enum lc_reason reason,
unsigned int sysp, source_location from_line,
const char *to_file, unsigned int to_line)
unsigned int sysp, const char *to_file, unsigned int to_line)
{
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 ();
if (set->used == set->allocated)
@ -131,17 +141,20 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
if (error || to_file == NULL)
{
to_file = from->to_file;
to_line = LAST_SOURCE_LINE (from) + 1;
to_line = SOURCE_LINE (from, from[1].start_location);
sysp = from->sysp;
}
}
map->reason = reason;
map->sysp = sysp;
map->from_line = from_line;
map->start_location = start_location;
map->to_file = to_file;
map->to_line = to_line;
set->cache = set->used++;
map->column_bits = 0;
set->highest_location = start_location;
set->max_column_hint = 0;
if (reason == LC_ENTER)
{
@ -161,6 +174,59 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
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
(source file, line) pair can be deduced. Since the set is built
chronologically, the logical lines are monotonic increasing, and so
@ -177,9 +243,9 @@ linemap_lookup (struct line_maps *set, source_location line)
cached = &set->maps[mn];
/* 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;
}
else
@ -191,7 +257,7 @@ linemap_lookup (struct line_maps *set, source_location line)
while (mx - mn > 1)
{
md = (mn + mx) / 2;
if (set->maps[md].from_line > line)
if (set->maps[md].start_location > line)
mx = md;
else
mn = md;

View File

@ -30,28 +30,35 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
(e.g. a #line directive in C). */
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),
and effectively typedef source_location location_t. */
typedef unsigned int source_location;
typedef source_location fileline; /* deprecated name */
/* 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. INCLUDED_FROM is an index into the set that
gives the line mapping 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. */
/* Physical source file TO_FILE at line TO_LINE at column 0 is represented
by the logical START_LOCATION. TO_LINE+L at column C is represented by
START_LOCATION+(L*(1<<column_bits))+C, as long as C<(1<<column_bits),
and the result_location is less than the next line_map's start_location.
(The top line is line 1 and the leftmost column is column 1; line/column 0
means "entire file/line" or "unknown line/column" or "not applicable".)
INCLUDED_FROM is an index into the set that gives the line mapping
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
{
const char *to_file;
unsigned int to_line;
source_location from_line;
source_location start_location;
int included_from;
ENUM_BITFIELD (lc_reason) reason : CHAR_BIT;
/* The sysp field isn't really needed now that it's in cpp_buffer. */
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. */
@ -73,6 +80,13 @@ struct line_maps
/* If true, prints an include trace a la -H. */
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. */
@ -81,6 +95,19 @@ extern void linemap_init (struct line_maps *);
/* Free a line map set. */
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
line number.
@ -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
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
maps, so any stored line_map pointers should not be used. */
extern const struct line_map *linemap_add
(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
(source file, line) pair can be deduced. */
@ -108,12 +135,21 @@ extern const struct line_map *linemap_lookup
extern void linemap_print_containing_files (struct line_maps *,
const struct line_map *);
/* Converts a map and logical line to source line. */
#define SOURCE_LINE(MAP, LINE) ((LINE) + (MAP)->to_line - (MAP)->from_line)
/* Converts a map and a source_location to source 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
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. */
#define INCLUDED_FROM(SET, MAP) (&(SET)->maps[(MAP)->included_from])
@ -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. */
#define MAIN_FILE_P(MAP) ((MAP)->included_from < 0)
/* The current line map. Saves a call to lookup_line if the caller is
sure he is in the scope of the current map. */
#define CURRENT_LINE_MAP(MAPS) ((MAPS)->maps + (MAPS)->used - 1)
/* Get a source position that for the same line as the most recent
linemap_line_start, but with the specified TO_COLUMN column number. */
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 */