aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog79
-rw-r--r--gcc/c-lex.c38
-rw-r--r--gcc/c-ppoutput.c99
-rw-r--r--gcc/cpperror.c46
-rw-r--r--gcc/cppfiles.c18
-rw-r--r--gcc/cpphash.h32
-rw-r--r--gcc/cppinit.c2
-rw-r--r--gcc/cpplex.c28
-rw-r--r--gcc/cpplib.c33
-rw-r--r--gcc/cpplib.h6
-rw-r--r--gcc/cppmacro.c12
-rw-r--r--gcc/cpptrad.c23
-rw-r--r--gcc/line-map.c98
-rw-r--r--gcc/line-map.h96
14 files changed, 423 insertions, 187 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4dab854..2921e53 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/c-lex.c b/gcc/c-lex.c
index aba571f..cbd5573 100644
--- a/gcc/c-lex.c
+++ b/gcc/c-lex.c
@@ -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));
}
diff --git a/gcc/c-ppoutput.c b/gcc/c-ppoutput.c
index 6b5aa99..2d32445 100644
--- a/gcc/c-ppoutput.c
+++ b/gcc/c-ppoutput.c
@@ -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;
diff --git a/gcc/cpperror.c b/gcc/cpperror.c
index 776f6e8..d572380 100644
--- a/gcc/cpperror.c
+++ b/gcc/cpperror.c
@@ -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);
diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c
index c886c89..862be9f 100644
--- a/gcc/cppfiles.c
+++ b/gcc/cppfiles.c
@@ -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
diff --git a/gcc/cpphash.h b/gcc/cpphash.h
index 6606746..d704c09 100644
--- a/gcc/cpphash.h
+++ b/gcc/cpphash.h
@@ -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 *);
diff --git a/gcc/cppinit.c b/gcc/cppinit.c
index 0fc9c68..ed91b0e 100644
--- a/gcc/cppinit.c
+++ b/gcc/cppinit.c
@@ -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;
}
diff --git a/gcc/cpplex.c b/gcc/cpplex.c
index 783732f..c53a9965 100644
--- a/gcc/cpplex.c
+++ b/gcc/cpplex.c
@@ -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. */
diff --git a/gcc/cpplib.c b/gcc/cpplib.c
index fa16859..3165351 100644
--- a/gcc/cpplib.c
+++ b/gcc/cpplib.c
@@ -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)
diff --git a/gcc/cpplib.h b/gcc/cpplib.h
index fd512b6..1183821 100644
--- a/gcc/cpplib.h
+++ b/gcc/cpplib.h
@@ -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 */
diff --git a/gcc/cppmacro.c b/gcc/cppmacro.c
index c797100..f396a9d 100644
--- a/gcc/cppmacro.c
+++ b/gcc/cppmacro.c
@@ -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);
diff --git a/gcc/cpptrad.c b/gcc/cpptrad.c
index 6315b10..f6dc99d 100644
--- a/gcc/cpptrad.c
+++ b/gcc/cpptrad.c
@@ -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;
}
diff --git a/gcc/line-map.c b/gcc/line-map.c
index be8cf27..a7398bb 100644
--- a/gcc/line-map.c
+++ b/gcc/line-map.c
@@ -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;
diff --git a/gcc/line-map.h b/gcc/line-map.h
index 2780583..6f09fcf 100644
--- a/gcc/line-map.h
+++ b/gcc/line-map.h
@@ -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 */