* line-map.h (struct line_maps): New field highest_line.
(linemap_position_for_column): Make non-inline function.
(LINEMAP_POSITION_FOR_COLUMN): New macro.
* line-map.c (linemap_init): Clear highest_line field.
(linemap_add): Set highest_line field.
(linemap_line_start): Minor optimization - use highest_line field.
Reduce maximum column hint to 10000. Update highest_line field.
(linemap_position_for_column): Moved from line-map.h. Optimize a bit.
* cpphash.h (struct cpp_reader): Remove line field - instead use
line_table->highest_line.
(saved_line): Remove unused field.
(CPP_INCREMENT_FILE): Don't do linemap_lookup - just use newest map.
Use line_table's highest_line field instead of cpp_reader's line.
* cpplib.c (start_directive): Likewise use highest_line field.
(do_line, do_linemarker): Likewise just use newest map.
(_cpp_do_file_change): Don't need to set cpp_reader's line field.
* cpperror.c (cpp_error): Likewise use highest_line field.
* cppfiles.c (open_file_failed: Likewise.
(cpp_make_system_header): Likewise use newest map and highest_line.
* cppinit.c (cpp_create_reader): Don't initialize removed field.
* cpplex.c (_cpp_process_line_notes, _cpp_skip_block_comment,
skip_line_comment, skip_whitespace, _cpp_get_fresh_line,
_cpp_lex_direct): Likewise use highest_line.
(_cpp_lex_direct): Use new LINEMAP_POSITION_FOR_COLUMN macro.
* cppmacro.c (_cpp_builtin_macro_text): Likewise use highest_line,
and use newest map.
* cpppch.c (cpp_read_state): Don't save+restore cpp_reader's line.
* cpptrad.c (_cpp_overlay_buffer): Don't save cpp_reader's line.
(copy_comment, _cpp_scan_out_logical_line): Likewise use highest_line.
From-SVN: r81074
+2004-04-22 Per Bothner <per@bothner.com>
+
+ * line-map.h (struct line_maps): New field highest_line.
+ (linemap_position_for_column): Make non-inline function.
+ (LINEMAP_POSITION_FOR_COLUMN): New macro.
+ * line-map.c (linemap_init): Clear highest_line field.
+ (linemap_add): Set highest_line field.
+ (linemap_line_start): Minor optimization - use highest_line field.
+ Reduce maximum column hint to 10000. Update highest_line field.
+ (linemap_position_for_column): Moved from line-map.h. Optimize a bit.
+ * cpphash.h (struct cpp_reader): Remove line field - instead use
+ line_table->highest_line.
+ (saved_line): Remove unused field.
+ (CPP_INCREMENT_FILE): Don't do linemap_lookup - just use newest map.
+ Use line_table's highest_line field instead of cpp_reader's line.
+ * cpplib.c (start_directive): Likewise use highest_line field.
+ (do_line, do_linemarker): Likewise just use newest map.
+ (_cpp_do_file_change): Don't need to set cpp_reader's line field.
+ * cpperror.c (cpp_error): Likewise use highest_line field.
+ * cppfiles.c (open_file_failed: Likewise.
+ (cpp_make_system_header): Likewise use newest map and highest_line.
+ * cppinit.c (cpp_create_reader): Don't initialize removed field.
+ * cpplex.c (_cpp_process_line_notes, _cpp_skip_block_comment,
+ skip_line_comment, skip_whitespace, _cpp_get_fresh_line,
+ _cpp_lex_direct): Likewise use highest_line.
+ (_cpp_lex_direct): Use new LINEMAP_POSITION_FOR_COLUMN macro.
+ * cppmacro.c (_cpp_builtin_macro_text): Likewise use highest_line,
+ and use newest map.
+ * cpppch.c (cpp_read_state): Don't save+restore cpp_reader's line.
+ * cpptrad.c (_cpp_overlay_buffer): Don't save cpp_reader's line.
+ (copy_comment, _cpp_scan_out_logical_line): Likewise use highest_line.
+
2004-04-23 Alan Modra <amodra@bigpond.net.au>
PR bootstrap/14992
if (pfile->state.in_directive)
src_loc = pfile->directive_line;
else
- src_loc = pfile->line;
+ src_loc = pfile->line_table->highest_line;
}
else
{
static void
open_file_failed (cpp_reader *pfile, _cpp_file *file)
{
- int sysp = pfile->line > 1 && pfile->buffer ? pfile->buffer->sysp : 0;
+ int sysp = pfile->line_table->highest_line > 1 && pfile->buffer ? pfile->buffer->sysp : 0;
bool print_dep = CPP_OPTION (pfile, deps.style) > !!sysp;
errno = file->err_no;
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);
+ const struct line_maps *line_table = pfile->line_table;
+ const struct line_map *map = &line_table->maps[line_table->used-1];
/* 1 = system header, 2 = system header to be treated as C. */
if (syshdr)
flags = 1 + (externc != 0);
pfile->buffer->sysp = flags;
_cpp_do_file_change (pfile, LC_RENAME, map->to_file,
- SOURCE_LINE (map, pfile->line), flags);
+ SOURCE_LINE (map, pfile->line_table->highest_line), flags);
}
/* Allow the client to change the current file. Used by the front end
#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); \
+ const struct line_maps *line_table = PFILE->line_table; \
+ const struct line_map *map = &line_table->maps[line_table->used-1]; \
+ unsigned int line = SOURCE_LINE (map, line_table->highest_line); \
+ linemap_line_start (PFILE->line_table, line + 1, COLS_HINT); \
} while (0)
/* Maximum nesting of cpp_buffers. We use a static limit, partly for
/* Source line tracking. */
struct line_maps *line_table;
- fileline line;
/* The line of the '#' of the current directive. */
fileline directive_line;
/* 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;
-
/* A saved list of the defined macros, for dependency checking
of precompiled headers. */
struct cpp_savedstate *savedstate;
other entries are correct zero-initialized. */
pfile->no_search_path.name = (char *) "";
- /* Initialize the line map. Start at logical line 1, so we can use
- a line number of zero for special states. */
+ /* Initialize the line map. */
pfile->line_table = line_table;
- pfile->line = 1;
/* Initialize lexer state. */
pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
if (note->type == '\\' || note->type == ' ')
{
if (note->type == ' ' && !in_comment)
- cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line, col,
+ cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line_table->highest_line, col,
"backslash and newline separated by space");
if (buffer->next_line > buffer->rlimit)
{
- cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line, col,
+ cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line_table->highest_line, col,
"backslash-newline at end of file");
/* Prevent "no newline at end of file" warning. */
buffer->next_line = buffer->rlimit;
&& (!in_comment || warn_in_comment (pfile, note)))
{
if (CPP_OPTION (pfile, trigraphs))
- cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line, col,
+ cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line_table->highest_line, col,
"trigraph ??%c converted to %c",
note->type,
(int) _cpp_trigraph_map[note->type]);
else
{
cpp_error_with_line
- (pfile, CPP_DL_WARNING, pfile->line, col,
+ (pfile, CPP_DL_WARNING, pfile->line_table->highest_line, col,
"trigraph ??%c ignored, use -trigraphs to enable",
note->type);
}
{
buffer->cur = cur;
cpp_error_with_line (pfile, CPP_DL_WARNING,
- pfile->line, CPP_BUF_COL (buffer),
+ pfile->line_table->highest_line, CPP_BUF_COL (buffer),
"\"/*\" within comment");
}
}
skip_line_comment (cpp_reader *pfile)
{
cpp_buffer *buffer = pfile->buffer;
- unsigned int orig_line = pfile->line;
+ unsigned int orig_line = pfile->line_table->highest_line;
while (*buffer->cur != '\n')
buffer->cur++;
_cpp_process_line_notes (pfile, true);
- return orig_line != pfile->line;
+ return orig_line != pfile->line_table->highest_line;
}
/* Skips whitespace, saving the next non-whitespace character. */
else if (c == '\0')
saw_NUL = true;
else if (pfile->state.in_directive && CPP_PEDANTIC (pfile))
- cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line,
+ cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line_table->highest_line,
CPP_BUF_COL (buffer),
"%s in preprocessing directive",
c == '\f' ? "form feed" : "vertical tab");
{
/* Only warn once. */
buffer->next_line = buffer->rlimit;
- cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line,
+ cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line_table->highest_line,
CPP_BUF_COLUMN (buffer, buffer->cur),
"no newline at end of file");
}
if (!pfile->state.in_directive)
{
/* Tell the compiler the line number of the EOF token. */
- result->src_loc = pfile->line;
+ result->src_loc = pfile->line_table->highest_line;
result->flags = BOL;
}
return result;
}
buffer = pfile->buffer;
update_tokens_line:
- result->src_loc = pfile->line;
+ result->src_loc = pfile->line_table->highest_line;
skipped_white:
if (buffer->cur >= buffer->notes[buffer->cur_note].pos
&& !pfile->overlaid_buffer)
{
_cpp_process_line_notes (pfile, false);
- result->src_loc = pfile->line;
+ result->src_loc = pfile->line_table->highest_line;
}
c = *buffer->cur++;
- result->src_loc = linemap_position_for_column (pfile->line_table,
- CPP_BUF_COLUMN (buffer, buffer->cur));
+ LINEMAP_POSITION_FOR_COLUMN (result->src_loc, pfile->line_table,
+ CPP_BUF_COLUMN (buffer, buffer->cur));
switch (c)
{
pfile->state.save_comments = 0;
/* Some handlers need the position of the # for diagnostics. */
- pfile->directive_line = pfile->line;
+ pfile->directive_line = pfile->line_table->highest_line;
}
/* Called when leaving a directive, _Pragma or command-line directive. */
static void
do_line (cpp_reader *pfile)
{
- const struct line_map *map = linemap_lookup (pfile->line_table, pfile->line);
+ const struct line_maps *line_table = pfile->line_table;
+ const struct line_map *map = &line_table->maps[line_table->used - 1];
const cpp_token *token;
const char *new_file = map->to_file;
unsigned long new_lineno;
static void
do_linemarker (cpp_reader *pfile)
{
- const struct line_map *map = linemap_lookup (pfile->line_table, pfile->line);
+ const struct line_maps *line_table = pfile->line_table;
+ const struct line_map *map = &line_table->maps[line_table->used - 1];
const cpp_token *token;
const char *new_file = map->to_file;
unsigned long new_lineno;
{
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 (map != NULL)
+ linemap_line_start (pfile->line_table, map->to_line, 127);
if (pfile->cb.file_change)
pfile->cb.file_change (pfile, map);
unsigned int len;
const char *name;
uchar *buf;
- map = linemap_lookup (pfile->line_table, pfile->line);
+ map = linemap_lookup (pfile->line_table, pfile->line_table->highest_line);
if (node->value.builtin == BT_BASE_FILE)
while (! MAIN_FILE_P (map))
break;
case BT_SPECLINE:
- map = linemap_lookup (pfile->line_table, pfile->line);
+ map = &pfile->line_table->maps[pfile->line_table->used-1];
/* 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;
+ number = pfile->line_table->highest_line;
else
number = pfile->cur_token[-1].src_loc;
number = SOURCE_LINE (map, number);
struct lexer_state old_state;
struct save_macro_item *d;
size_t i, mac_count;
- int saved_line = r->line;
/* Restore spec_nodes, which will be full of references to the old
hashtable entries and so will now be invalid. */
}
r->state = old_state;
- r->line = saved_line;
free (defn);
defn = NULL;
copy_comment (cpp_reader *pfile, const uchar *cur, int in_define)
{
bool unterminated, copy = false;
- source_location src_loc = pfile->line;
+ source_location src_loc = pfile->line_table->highest_line;
cpp_buffer *buffer = pfile->buffer;
buffer->cur = cur;
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;
CUR (pfile->context) = pfile->buffer->cur;
RLIMIT (pfile->context) = pfile->buffer->rlimit;
pfile->out.cur = pfile->out.base;
- pfile->out.first_line = pfile->line;
+ pfile->out.first_line = pfile->line_table->highest_line;
/* start_of_input_line is needed to make sure that directives really,
really start at the first character of the line. */
start_of_input_line = pfile->buffer->cur;
{
maybe_start_funlike (pfile, node, out_start, &fmacro);
lex_state = ls_fun_open;
- fmacro.line = pfile->line;
+ fmacro.line = pfile->line_table->highest_line;
continue;
}
else if (!recursive_macro (pfile, node))
set->depth = 0;
set->cache = 0;
set->highest_location = 0;
+ set->highest_line = 0;
set->max_column_hint = 0;
}
set->cache = set->used++;
map->column_bits = 0;
set->highest_location = start_location;
+ set->highest_line = start_location;
set->max_column_hint = 0;
if (reason == LC_ENTER)
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);
+ unsigned int last_line = SOURCE_LINE (map, set->highest_line);
int line_delta = to_line - last_line;
bool add_map = false;
if (line_delta < 0
if (add_map)
{
int column_bits;
- if (max_column_hint > 1000000 || highest > 0xC0000000)
+ if (max_column_hint > 100000 || highest > 0xC0000000)
{
max_column_hint = 0;
if (highest >0xF0000000)
else
r = highest - SOURCE_COLUMN (map, highest)
+ (line_delta << map->column_bits);
+ set->highest_line = r;
if (r > set->highest_location)
set->highest_location = r;
set->max_column_hint = max_column_hint;
return r;
}
+source_location
+linemap_position_for_column (struct line_maps *set, unsigned int to_column)
+{
+ source_location r = set->highest_line;
+ if (to_column >= set->max_column_hint)
+ {
+ if (r >= 0xC000000 || to_column > 100000)
+ {
+ /* Running low on source_locations - disable column numbers. */
+ return r;
+ }
+ else
+ {
+ struct line_map *map = &set->maps[set->used - 1];
+ r = linemap_line_start (set, SOURCE_LINE (map, r), to_column + 50);
+ }
+ }
+ r = r + to_column;
+ if (r >= set->highest_location)
+ set->highest_location = r;
+ 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
/* Highest source_location "given out". */
source_location highest_location;
+ /* Start of line of highest source_location "given out". */
+ source_location highest_line;
+
/* The maximum column number we can quickly allocate. Higher numbers
may require allocating a new line_map. */
unsigned int max_column_hint;
/* Nonzero if the map is at the bottom of the include stack. */
#define MAIN_FILE_P(MAP) ((MAP)->included_from < 0)
-/* Get a source position that for the same line as the most recent
+/* Set LOC to a source position that is 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;
-}
-
+#define LINEMAP_POSITION_FOR_COLUMN(LOC, SET, TO_COLUMN) { \
+ unsigned int to_column = (TO_COLUMN); \
+ struct line_maps *set = (SET); \
+ if (__builtin_expect (to_column >= set->max_column_hint, 0)) \
+ (LOC) = linemap_position_for_column (set, to_column); \
+ else { \
+ source_location r = set->highest_line; \
+ r = r + to_column; \
+ if (r >= set->highest_location) \
+ set->highest_location = r; \
+ (LOC) = r; \
+ }}
+
+
+extern source_location
+linemap_position_for_column (struct line_maps *set, unsigned int to_column);
#endif /* !GCC_LINE_MAP_H */