aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Booth <neil@daikokuya.demon.co.uk>2001-08-05 17:31:25 +0000
committerNeil Booth <neil@gcc.gnu.org>2001-08-05 17:31:25 +0000
commit67821e3a9e007c34a85bbc3b934031b57eafc903 (patch)
tree37a35ef3c394621edd2c84f886dcc1310e94c38d
parent8125d7e9ad4f1525e0e703f7610fd47cc628f047 (diff)
downloadgcc-67821e3a9e007c34a85bbc3b934031b57eafc903.zip
gcc-67821e3a9e007c34a85bbc3b934031b57eafc903.tar.gz
gcc-67821e3a9e007c34a85bbc3b934031b57eafc903.tar.bz2
re PR preprocessor/3081 (Preprocessor merges 2 first lines when -imacros is being used)
PR preprocessor/3081 * c-lex.c (map): New. (cb_file_change): Update map and use it. (cb_def_pragma, cb_define, cb_undef): Use map and line. (c_lex): Update to use map. * cpperror.c (print_location): Move to using logical line numbers. * cppfiles.c (stack_include_file): Update for new _cpp_do_file_change. (cpp_make_system_header): Similarly. (_cpp_execute_include): Stop line numbering hacks. Store the line we will return to. * cpphash.h (CPP_BUF_LINE): Remove. (struct cpp_buffer): Remove lineno and pseudo_newlines. Add map and return_to_line. (_cpp_do_file_change): Update. * cppinit.c (cpp_start_read): Update line kludge. * cpplex.c (handle_newline): Don't update lineno and pseudo_newlines. (trigraph_ok): Use logical line numbers for diagnostics. (skip_block_comment): Likewise. (skip_whitespace): Likewise. (skip_line_comment): Use pfile->line instead. (_cpp_lex_token): Update to use logical line numbering exclusively. Handle BOL locally. Accept new lines in directives, but keep pfile->line decremented. Diagnostics use logical lines. Update directive handling. * cpplib.c (SEEN_EOL): New. (skip_rest_of_line, check_eol): Use it. (end_directive): Increase line number when accepting the newline at the end of a directive. (run_directive): Simplify. (do_line): Bad LC_LEAVEs become LC_RENAMEs. Update. (_cpp_do_file_change): Update to take buffer line number as an argument, and store the current map in the cpp_reader. Remove line number kludges. (_cpp_do__Pragma): Restore output position after a _Pragma. (cpp_push_buffer): Don't set output line or lineno. (_cpp_pop_buffer): Transfer more info from a faked buffer. Remove line kludge. Set output_line. * cppmacro.c (builtin_macro): Update handling of __LINE__. (parse_arg): Use logical lines. (save_lookahead_token): Save EOFs too now. * cppmain.c (struct printer): Fix comments. (printer_init): Simplify, let caller do errors. (scan_translation_unit, check_multiline_token, dump_macro): Update. (maybe_print_line): Simplify. (print_line): Don't print a linemarker if -P. (cb_define, cb_undef, cb_def_pragma, cb_ident, cb_include): Update. (cb_file_change): Simplify. * line-map.h (LAST_SOURCE_LINE): Fix. (CURRENT_LINE_MAP): New. * gcc.dg/cpp/19951025-1.c: Revert. * gcc.dg/cpp/directiv.c: We no longer process directives that interrupt macro arguments. From-SVN: r44650
-rw-r--r--gcc/ChangeLog52
-rw-r--r--gcc/c-lex.c24
-rw-r--r--gcc/cpperror.c20
-rw-r--r--gcc/cppfiles.c9
-rw-r--r--gcc/cpphash.h16
-rw-r--r--gcc/cppinit.c8
-rw-r--r--gcc/cpplex.c128
-rw-r--r--gcc/cpplib.c85
-rw-r--r--gcc/cppmacro.c32
-rw-r--r--gcc/cppmain.c152
-rw-r--r--gcc/line-map.h5
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/cpp/19951025-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/cpp/directiv.c7
14 files changed, 296 insertions, 252 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5679160..70f07e3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,55 @@
+2001-08-05 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ PR preprocessor/3081
+ * c-lex.c (map): New.
+ (cb_file_change): Update map and use it.
+ (cb_def_pragma, cb_define, cb_undef): Use map and line.
+ (c_lex): Update to use map.
+ * cpperror.c (print_location): Move to using logical line numbers.
+ * cppfiles.c (stack_include_file): Update for new _cpp_do_file_change.
+ (cpp_make_system_header): Similarly.
+ (_cpp_execute_include): Stop line numbering hacks. Store the
+ line we will return to.
+ * cpphash.h (CPP_BUF_LINE): Remove.
+ (struct cpp_buffer): Remove lineno and pseudo_newlines.
+ Add map and return_to_line.
+ (_cpp_do_file_change): Update.
+ * cppinit.c (cpp_start_read): Update line kludge.
+ * cpplex.c (handle_newline): Don't update lineno and pseudo_newlines.
+ (trigraph_ok): Use logical line numbers for diagnostics.
+ (skip_block_comment): Likewise.
+ (skip_whitespace): Likewise.
+ (skip_line_comment): Use pfile->line instead.
+ (_cpp_lex_token): Update to use logical line numbering exclusively.
+ Handle BOL locally. Accept new lines in directives, but keep
+ pfile->line decremented. Diagnostics use logical lines. Update
+ directive handling.
+ * cpplib.c (SEEN_EOL): New.
+ (skip_rest_of_line, check_eol): Use it.
+ (end_directive): Increase line number when accepting the newline
+ at the end of a directive.
+ (run_directive): Simplify.
+ (do_line): Bad LC_LEAVEs become LC_RENAMEs. Update.
+ (_cpp_do_file_change): Update to take buffer line number as an
+ argument, and store the current map in the cpp_reader. Remove
+ line number kludges.
+ (_cpp_do__Pragma): Restore output position after a _Pragma.
+ (cpp_push_buffer): Don't set output line or lineno.
+ (_cpp_pop_buffer): Transfer more info from a faked buffer.
+ Remove line kludge. Set output_line.
+ * cppmacro.c (builtin_macro): Update handling of __LINE__.
+ (parse_arg): Use logical lines.
+ (save_lookahead_token): Save EOFs too now.
+ * cppmain.c (struct printer): Fix comments.
+ (printer_init): Simplify, let caller do errors.
+ (scan_translation_unit, check_multiline_token, dump_macro): Update.
+ (maybe_print_line): Simplify.
+ (print_line): Don't print a linemarker if -P.
+ (cb_define, cb_undef, cb_def_pragma, cb_ident, cb_include): Update.
+ (cb_file_change): Simplify.
+ * line-map.h (LAST_SOURCE_LINE): Fix.
+ (CURRENT_LINE_MAP): New.
+
2001-08-05 Bernd Schmidt <bernds@redhat.com>
* doloop.c (doloop_modify_runtime): Properly compute number of
diff --git a/gcc/c-lex.c b/gcc/c-lex.c
index 89e1702..971d9cd 100644
--- a/gcc/c-lex.c
+++ b/gcc/c-lex.c
@@ -57,6 +57,9 @@ Boston, MA 02111-1307, USA. */
/* The input filename as understood by CPP, where "" represents stdin. */
static const char *cpp_filename;
+/* The current line map. */
+static 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;
@@ -301,9 +304,10 @@ cb_file_change (pfile, fc)
}
update_header_times (fc->map->to_file);
+ map = fc->map;
in_system_header = fc->sysp != 0;
- input_filename = fc->map->to_file;
- lineno = SOURCE_LINE (fc->map, fc->line); /* Do we need this? */
+ input_filename = map->to_file;
+ lineno = SOURCE_LINE (map, fc->line);
/* Hook for C++. */
extract_interface_info ();
@@ -312,7 +316,7 @@ cb_file_change (pfile, fc)
static void
cb_def_pragma (pfile, line)
cpp_reader *pfile;
- unsigned int line ATTRIBUTE_UNUSED;
+ unsigned int line;
{
/* Issue a warning message if we have been asked to do so. Ignore
unknown pragmas in system headers unless an explicit
@@ -328,7 +332,7 @@ cb_def_pragma (pfile, line)
if (s.type == CPP_NAME)
name = cpp_token_as_text (pfile, &s);
- lineno = cpp_get_line (parse_in)->line;
+ lineno = SOURCE_LINE (map, line);
if (name)
warning ("ignoring #pragma %s %s", space, name);
else
@@ -340,21 +344,21 @@ cb_def_pragma (pfile, line)
static void
cb_define (pfile, line, node)
cpp_reader *pfile;
- unsigned int line ATTRIBUTE_UNUSED;
+ unsigned int line;
cpp_hashnode *node;
{
- (*debug_hooks->define) (cpp_get_line (pfile)->line,
+ (*debug_hooks->define) (SOURCE_LINE (map, line),
(const char *) cpp_macro_definition (pfile, node));
}
/* #undef callback for DWARF and DWARF2 debug info. */
static void
cb_undef (pfile, line, node)
- cpp_reader *pfile;
- unsigned int line ATTRIBUTE_UNUSED;
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
+ unsigned int line;
cpp_hashnode *node;
{
- (*debug_hooks->undef) (cpp_get_line (pfile)->line,
+ (*debug_hooks->undef) (SOURCE_LINE (map, line),
(const char *) NODE_NAME (node));
}
@@ -763,7 +767,7 @@ c_lex (value)
/* The C++ front end does horrible things with the current line
number. To ensure an accurate line number, we must reset it
every time we return a token. */
- lineno = cpp_get_line (parse_in)->line;
+ lineno = SOURCE_LINE (map, cpp_get_line (parse_in)->line);
*value = NULL_TREE;
type = tok.type;
diff --git a/gcc/cpperror.c b/gcc/cpperror.c
index f101982..4ed4de6 100644
--- a/gcc/cpperror.c
+++ b/gcc/cpperror.c
@@ -108,23 +108,17 @@ print_location (pfile, filename, pos)
{
struct line_map *map;
- line = pfile->line;
if (type == BUF_PRAGMA)
- {
- buffer = buffer->prev;
- col = CPP_BUF_COL (buffer);
- }
+ buffer = buffer->prev;
- map = lookup_line (&pfile->line_maps, line);
if (pos == 0)
- {
- pos = cpp_get_line (pfile);
- line = SOURCE_LINE (map, line);
- }
- else
- line = pos->line;
- col = pos->col;
+ pos = cpp_get_line (pfile);
+ map = lookup_line (&pfile->line_maps, pos->line);
+ line = SOURCE_LINE (map, pos->line);
+ if (filename == 0)
+ filename = map->to_file;
+ col = pos->col;
if (col == 0)
col = 1;
diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c
index fb01145..8af65c8 100644
--- a/gcc/cppfiles.c
+++ b/gcc/cppfiles.c
@@ -337,9 +337,7 @@ stack_include_file (pfile, inc)
pfile->include_depth++;
/* Generate the call back. */
- fp->lineno = 0;
- _cpp_do_file_change (pfile, LC_ENTER);
- fp->lineno = 1;
+ _cpp_do_file_change (pfile, LC_ENTER, 1);
}
/* Read the file referenced by INC into the file cache.
@@ -579,7 +577,8 @@ cpp_make_system_header (pfile, syshdr, externc)
if (syshdr)
flags = 1 + (externc != 0);
pfile->buffer->sysp = flags;
- _cpp_do_file_change (pfile, LC_RENAME);
+ _cpp_do_file_change (pfile, LC_RENAME,
+ SOURCE_LINE (pfile->map, pfile->line));
}
/* Report on all files that might benefit from a multiple include guard.
@@ -679,8 +678,8 @@ _cpp_execute_include (pfile, header, type)
if (header->type == CPP_HEADER_NAME)
pfile->system_include_depth++;
+ pfile->buffer->return_to_line = SOURCE_LINE (pfile->map, pfile->line);
stack_include_file (pfile, inc);
- pfile->line++; /* Fake the '\n' at the end of #include. */
if (type == IT_IMPORT)
_cpp_never_reread (inc);
diff --git a/gcc/cpphash.h b/gcc/cpphash.h
index 1abeb57..1ba4282 100644
--- a/gcc/cpphash.h
+++ b/gcc/cpphash.h
@@ -35,7 +35,6 @@ struct directive; /* Deliberately incomplete. */
#define CPP_OPTION(PFILE, OPTION) ((PFILE)->opts.OPTION)
#define CPP_BUFFER(PFILE) ((PFILE)->buffer)
-#define CPP_BUF_LINE(BUF) ((BUF)->lineno)
#define CPP_BUF_COLUMN(BUF, CUR) ((CUR) - (BUF)->line_base + (BUF)->col_adjust)
#define CPP_BUF_COL(BUF) CPP_BUF_COLUMN(BUF, (BUF)->cur)
@@ -194,8 +193,10 @@ struct cpp_buffer
/* Token column position adjustment owing to tabs in whitespace. */
unsigned int col_adjust;
- /* Line number at line_base (above). */
- unsigned int lineno;
+ /* The line of the buffer that we return to after a #include.
+ Strictly this is redundant, since it can be calculated from the
+ line maps, but it is clearest to save it here. */
+ unsigned int return_to_line;
/* Contains PREV_WHITE and/or AVOID_LPASTE. */
unsigned char saved_flags;
@@ -251,12 +252,10 @@ struct cpp_reader
/* Lexer state. */
struct lexer_state state;
- /* Source line tracking. Subtract pseudo_newlines from the actual
- line number to get the line number of preprocessed output. Used
- for escaped newlines and macro args that cross multiple lines. */
+ /* Source line tracking. */
struct line_maps line_maps;
+ struct line_map *map;
unsigned int line;
- unsigned int pseudo_newlines;
/* The position of the last lexed token and last lexed directive. */
cpp_lexer_pos lexer_pos;
@@ -446,7 +445,8 @@ extern void _cpp_define_builtin PARAMS ((cpp_reader *, const char *));
extern void _cpp_do__Pragma PARAMS ((cpp_reader *));
extern void _cpp_init_directives PARAMS ((cpp_reader *));
extern void _cpp_init_internal_pragmas PARAMS ((cpp_reader *));
-extern void _cpp_do_file_change PARAMS ((cpp_reader *, enum lc_reason));
+extern void _cpp_do_file_change PARAMS ((cpp_reader *, enum lc_reason,
+ unsigned int));
extern void _cpp_pop_buffer PARAMS ((cpp_reader *));
/* Utility routines and macros. */
diff --git a/gcc/cppinit.c b/gcc/cppinit.c
index 6d4c7a0..f1b6b24 100644
--- a/gcc/cppinit.c
+++ b/gcc/cppinit.c
@@ -949,10 +949,10 @@ cpp_start_read (pfile, fname)
p = q;
}
- /* This was zero when the initial buffer was stacked; so we must
- make up for a non-existent new line, as well as the intervening
- macro definitions, by setting it to 1. */
- pfile->line = 1;
+ /* Hopefully a short-term kludge. We stacked the main file at line
+ zero. The intervening macro definitions have messed up line
+ numbering, so we need to restore it. */
+ pfile->lexer_pos.output_line = pfile->line = 0;
/* The -imacros files can be scanned now, but the -include files
have to be pushed onto the buffer stack and processed later,
diff --git a/gcc/cpplex.c b/gcc/cpplex.c
index e0002be..f9c4bb9 100644
--- a/gcc/cpplex.c
+++ b/gcc/cpplex.c
@@ -132,11 +132,8 @@ handle_newline (pfile, newline_char)
cppchar_t next = EOF;
pfile->line++;
- pfile->pseudo_newlines++;
-
buffer = pfile->buffer;
buffer->col_adjust = 0;
- buffer->lineno++;
buffer->line_base = buffer->cur;
/* Handle CR-LF and LF-CR combinations, get the next character. */
@@ -173,15 +170,16 @@ trigraph_ok (pfile, from_char)
if (CPP_OPTION (pfile, warn_trigraphs) && !pfile->state.lexing_comment)
{
cpp_buffer *buffer = pfile->buffer;
+
if (accept)
- cpp_warning_with_line (pfile, buffer->lineno, CPP_BUF_COL (buffer) - 2,
+ cpp_warning_with_line (pfile, pfile->line, CPP_BUF_COL (buffer) - 2,
"trigraph ??%c converted to %c",
(int) from_char,
(int) _cpp_trigraph_map[from_char]);
else if (buffer->cur != buffer->last_Wtrigraphs)
{
buffer->last_Wtrigraphs = buffer->cur;
- cpp_warning_with_line (pfile, buffer->lineno,
+ cpp_warning_with_line (pfile, pfile->line,
CPP_BUF_COL (buffer) - 2,
"trigraph ??%c ignored", (int) from_char);
}
@@ -344,8 +342,8 @@ skip_block_comment (pfile)
{
prevc = c, c = *buffer->cur++;
if (c != '/')
- cpp_warning_with_line (pfile, CPP_BUF_LINE (buffer),
- CPP_BUF_COL (buffer),
+ cpp_warning_with_line (pfile, pfile->line,
+ CPP_BUF_COL (buffer) - 2,
"\"/*\" within comment");
}
goto next_char;
@@ -373,7 +371,7 @@ skip_line_comment (pfile)
cpp_reader *pfile;
{
cpp_buffer *buffer = pfile->buffer;
- unsigned int orig_lineno = buffer->lineno;
+ unsigned int orig_line = pfile->line;
cppchar_t c;
pfile->state.lexing_comment = 1;
@@ -391,7 +389,7 @@ skip_line_comment (pfile)
pfile->state.lexing_comment = 0;
buffer->read_ahead = c; /* Leave any newline for caller. */
- return orig_lineno != buffer->lineno;
+ return orig_line != pfile->line;
}
/* pfile->buffer->cur is one beyond the \t character. Update
@@ -437,7 +435,7 @@ skip_whitespace (pfile, c)
}
}
else if (pfile->state.in_directive && CPP_PEDANTIC (pfile))
- cpp_pedwarn_with_line (pfile, CPP_BUF_LINE (buffer),
+ cpp_pedwarn_with_line (pfile, pfile->line,
CPP_BUF_COL (buffer),
"%s in preprocessing directive",
c == '\f' ? "form feed" : "vertical tab");
@@ -865,17 +863,16 @@ _cpp_lex_token (pfile, result)
cppchar_t c;
cpp_buffer *buffer;
const unsigned char *comment_start;
- unsigned char bol;
+ int bol;
- skip:
- bol = pfile->state.next_bol;
- done_directive:
+ next_token:
buffer = pfile->buffer;
- pfile->state.next_bol = 0;
result->flags = buffer->saved_flags;
buffer->saved_flags = 0;
+ bol = (buffer->cur <= buffer->line_base + 1
+ && pfile->lexer_pos.output_line == pfile->line);
next_char:
- pfile->lexer_pos.line = buffer->lineno;
+ pfile->lexer_pos.line = pfile->line;
result->line = pfile->line;
next_char2:
pfile->lexer_pos.col = CPP_BUF_COLUMN (buffer, buffer->cur);
@@ -893,22 +890,29 @@ _cpp_lex_token (pfile, result)
switch (c)
{
case EOF:
- if (!pfile->state.in_directive)
+ /* To prevent bogus diagnostics, only pop the buffer when
+ in-progress directives and arguments have been taken care of.
+ Decrement the line to terminate an in-progress directive. */
+ if (pfile->state.in_directive)
+ pfile->line--;
+ else if (! pfile->state.parsing_args)
{
unsigned char ret = pfile->buffer->return_at_eof;
/* Non-empty files should end in a newline. Don't warn for
command line and _Pragma buffers. */
- if (pfile->lexer_pos.col != 0 && !buffer->from_stage3)
- cpp_pedwarn (pfile, "no newline at end of file");
- _cpp_pop_buffer (pfile);
- if (pfile->buffer && !ret)
+ if (pfile->lexer_pos.col != 0)
{
- bol = 1;
- goto done_directive;
+ /* Account for the missing \n. */
+ pfile->line++;
+ if (!buffer->from_stage3)
+ cpp_pedwarn (pfile, "no newline at end of file");
}
+
+ _cpp_pop_buffer (pfile);
+ if (pfile->buffer && !ret)
+ goto next_token;
}
- pfile->state.next_bol = 1;
result->type = CPP_EOF;
return;
@@ -918,36 +922,41 @@ _cpp_lex_token (pfile, result)
goto next_char2;
case '\n': case '\r':
- if (!pfile->state.in_directive)
+ if (pfile->state.in_directive)
{
- handle_newline (pfile, c);
- if (!pfile->state.parsing_args)
- pfile->pseudo_newlines = 0;
- bol = 1;
- pfile->lexer_pos.output_line = buffer->lineno;
- /* This is a new line, so clear any white space flag.
- Newlines in arguments are white space (6.10.3.10);
- parse_arg takes care of that. */
- result->flags &= ~(PREV_WHITE | AVOID_LPASTE);
- goto next_char;
+ result->type = CPP_EOF;
+ if (pfile->state.parsing_args)
+ buffer->read_ahead = c;
+ else
+ {
+ handle_newline (pfile, c);
+ /* Decrementing pfile->line allows directives to
+ recognise that the newline has been seen, and also
+ means that diagnostics don't point to the next line. */
+ pfile->lexer_pos.output_line = pfile->line--;
+ }
+ return;
}
- /* Don't let directives spill over to the next line. */
- buffer->read_ahead = c;
- pfile->state.next_bol = 1;
- result->type = CPP_EOF;
- /* Don't break; pfile->state.skipping might be true. */
- return;
+ handle_newline (pfile, c);
+ /* This is a new line, so clear any white space flag. Newlines
+ in arguments are white space (6.10.3.10); parse_arg takes
+ care of that. */
+ result->flags &= ~(PREV_WHITE | AVOID_LPASTE);
+ bol = 1;
+ if (pfile->state.parsing_args != 2)
+ pfile->lexer_pos.output_line = pfile->line;
+ goto next_char;
case '?':
case '\\':
/* These could start an escaped newline, or '?' a trigraph. Let
skip_escaped_newlines do all the work. */
{
- unsigned int lineno = buffer->lineno;
+ unsigned int line = pfile->line;
c = skip_escaped_newlines (buffer, c);
- if (lineno != buffer->lineno)
+ if (line != pfile->line)
/* We had at least one escaped newline of some sort, and the
next character is in buffer->read_ahead. Update the
token's line and column. */
@@ -1026,9 +1035,7 @@ _cpp_lex_token (pfile, result)
if (c == '*')
{
if (skip_block_comment (pfile))
- cpp_error_with_line (pfile, pfile->lexer_pos.line,
- pfile->lexer_pos.col,
- "unterminated comment");
+ cpp_error (pfile, "unterminated comment");
}
else
{
@@ -1212,26 +1219,21 @@ _cpp_lex_token (pfile, result)
macro invocation, and proceed to process the directive. */
if (pfile->state.parsing_args)
{
+ pfile->lexer_pos.output_line = pfile->line;
if (pfile->state.parsing_args == 2)
- cpp_error (pfile,
- "directives may not be used inside a macro argument");
-
- /* Put a '#' in lookahead, return CPP_EOF for parse_arg. */
- buffer->extra_char = buffer->read_ahead;
- buffer->read_ahead = '#';
- pfile->state.next_bol = 1;
- result->type = CPP_EOF;
-
- /* Get whitespace right - newline_in_args sets it. */
- if (pfile->lexer_pos.col == 1)
- result->flags &= ~(PREV_WHITE | AVOID_LPASTE);
+ {
+ cpp_error (pfile,
+ "directives may not be used inside a macro argument");
+ result->type = CPP_EOF;
+ }
}
- else
+ /* in_directive can be true inside a _Pragma. */
+ else if (!pfile->state.in_directive)
{
- /* This is the hash introducing a directive. */
+ /* This is the hash introducing a directive. If the return
+ value is false, it is an assembler #. */
if (_cpp_handle_directive (pfile, result->flags & PREV_WHITE))
- goto done_directive; /* bol still 1. */
- /* This is in fact an assembler #. */
+ goto next_token;
}
break;
@@ -1283,7 +1285,7 @@ _cpp_lex_token (pfile, result)
}
if (!pfile->state.in_directive && pfile->state.skipping)
- goto skip;
+ goto next_char;
/* If not in a directive, this token invalidates controlling macros. */
if (!pfile->state.in_directive)
diff --git a/gcc/cpplib.c b/gcc/cpplib.c
index d46fb93..5932a44 100644
--- a/gcc/cpplib.c
+++ b/gcc/cpplib.c
@@ -178,6 +178,8 @@ DIRECTIVE_TABLE
#undef D
#undef DIRECTIVE_TABLE
+#define SEEN_EOL() (pfile->lexer_pos.output_line > pfile->line)
+
/* Skip any remaining tokens in a directive. */
static void
skip_rest_of_line (pfile)
@@ -194,7 +196,7 @@ skip_rest_of_line (pfile)
_cpp_pop_context (pfile);
/* Sweep up all tokens remaining on the line. */
- while (!pfile->state.next_bol)
+ while (! SEEN_EOL ())
_cpp_lex_token (pfile, &token);
}
@@ -203,7 +205,7 @@ static void
check_eol (pfile)
cpp_reader *pfile;
{
- if (!pfile->state.next_bol)
+ if (! SEEN_EOL ())
{
cpp_token token;
@@ -240,7 +242,11 @@ end_directive (pfile, skip_line)
{
/* We don't skip for an assembler #. */
if (skip_line)
- skip_rest_of_line (pfile);
+ {
+ skip_rest_of_line (pfile);
+ /* "Accept" the newline now. */
+ pfile->line++;
+ }
/* Restore state. */
pfile->la_write = pfile->la_saved;
@@ -395,19 +401,9 @@ run_directive (pfile, dir_no, type, buf, count)
const char *buf;
size_t count;
{
- unsigned int output_line = pfile->lexer_pos.output_line;
cpp_buffer *buffer;
buffer = cpp_push_buffer (pfile, (const U_CHAR *) buf, count, type, 0, 1);
-
- if (dir_no == T_PRAGMA)
- {
- /* A kludge to avoid line markers for _Pragma. */
- pfile->lexer_pos.output_line = output_line;
- /* Avoid interpretation of directives in a _Pragma string. */
- pfile->state.next_bol = 0;
- }
-
start_directive (pfile);
pfile->state.prevent_expansion++;
pfile->directive = &dtable[dir_no];
@@ -779,8 +775,11 @@ do_line (pfile)
else if (reason == LC_LEAVE)
{
if (buffer->type != BUF_FAKE)
- cpp_warning (pfile, "file \"%s\" left but not entered",
- buffer->nominal_fname);
+ {
+ cpp_warning (pfile, "file \"%s\" left but not entered",
+ buffer->nominal_fname);
+ reason = LC_RENAME;
+ }
else
{
_cpp_pop_buffer (pfile);
@@ -789,9 +788,6 @@ do_line (pfile)
if (strcmp (buffer->nominal_fname, fname))
cpp_warning (pfile, "expected to return to file \"%s\"",
buffer->nominal_fname);
- if (buffer->lineno + 1 != new_lineno)
- cpp_warning (pfile, "expected to return to line number %u",
- buffer->lineno + 1);
if (buffer->sysp != sysp)
cpp_warning (pfile, "header flags for \"%s\" have changed",
buffer->nominal_fname);
@@ -810,30 +806,29 @@ do_line (pfile)
}
end_directive (pfile, 1);
- buffer->lineno = new_lineno - 1;
- _cpp_do_file_change (pfile, reason);
+ _cpp_do_file_change (pfile, reason, new_lineno);
}
-/* Arrange the file_change callback. It is assumed that the next line
- is given by incrementing buffer->lineno and pfile->line. */
+/* Arrange the file_change callback. pfile->line has changed to
+ FILE_LINE of the current buffer, for reason REASON. */
void
-_cpp_do_file_change (pfile, reason)
+_cpp_do_file_change (pfile, reason, file_line)
cpp_reader *pfile;
enum lc_reason reason;
+ unsigned int file_line;
{
cpp_buffer *buffer;
- struct line_map *map;
buffer = pfile->buffer;
- map = add_line_map (&pfile->line_maps, reason,
- pfile->line + 1, buffer->nominal_fname, buffer->lineno + 1);
+ pfile->map = add_line_map (&pfile->line_maps, reason,
+ pfile->line, buffer->nominal_fname, file_line);
if (pfile->cb.file_change)
{
cpp_file_change fc;
- fc.map = map;
- fc.line = pfile->line + 1;
+ fc.map = pfile->map;
+ fc.line = pfile->line;
fc.reason = reason;
fc.sysp = buffer->sysp;
fc.externc = CPP_OPTION (pfile, cplusplus) && buffer->sysp == 2;
@@ -1195,16 +1190,19 @@ _cpp_do__Pragma (pfile)
cpp_token string;
unsigned char *buffer;
unsigned int len;
+ cpp_lexer_pos orig_pos;
+ orig_pos = pfile->lexer_pos;
if (get__Pragma_string (pfile, &string))
+ cpp_error (pfile, "_Pragma takes a parenthesized string literal");
+ else
{
- cpp_error (pfile, "_Pragma takes a parenthesized string literal");
- return;
+ buffer = destringize (&string.val.str, &len);
+ run_directive (pfile, T_PRAGMA, BUF_PRAGMA, (char *) buffer, len);
+ free ((PTR) buffer);
+ pfile->lexer_pos = orig_pos;
+ pfile->line = pfile->lexer_pos.line;
}
-
- buffer = destringize (&string.val.str, &len);
- run_directive (pfile, T_PRAGMA, BUF_PRAGMA, (char *) buffer, len);
- free ((PTR) buffer);
}
/* Just ignore #sccs, on systems where we define it at all. */
@@ -1815,8 +1813,6 @@ cpp_push_buffer (pfile, buffer, len, type, filename, return_at_eof)
/* Preprocessed files, builtins, _Pragma and command line
options don't do trigraph and escaped newline processing. */
new->from_stage3 = type != BUF_FILE || CPP_OPTION (pfile, preprocessed);
-
- pfile->lexer_pos.output_line = 1;
}
if (*filename == '\0')
@@ -1827,7 +1823,6 @@ cpp_push_buffer (pfile, buffer, len, type, filename, return_at_eof)
new->prev = pfile->buffer;
new->pfile = pfile;
new->include_stack_listed = 0;
- new->lineno = 1;
new->return_at_eof = return_at_eof;
pfile->state.next_bol = 1;
@@ -1857,7 +1852,11 @@ _cpp_pop_buffer (pfile)
"unterminated #%s", dtable[ifs->type].name);
if (buffer->type == BUF_FAKE)
- buffer->prev->cur = buffer->cur;
+ {
+ buffer->prev->cur = buffer->cur;
+ buffer->prev->line_base = buffer->line_base;
+ buffer->prev->read_ahead = buffer->read_ahead;
+ }
else if (buffer->type == BUF_FILE)
_cpp_pop_file_buffer (pfile, buffer);
@@ -1877,8 +1876,7 @@ _cpp_pop_buffer (pfile)
if (pfile->directive == &dtable[T_LINE])
break;
- pfile->line--; /* We have a '\n' at the end of #include. */
- _cpp_do_file_change (pfile, LC_LEAVE);
+ _cpp_do_file_change (pfile, LC_LEAVE, pfile->buffer->return_to_line);
if (pfile->buffer->type == BUF_FILE)
break;
@@ -1888,7 +1886,12 @@ _cpp_pop_buffer (pfile)
obstack_free (&pfile->buffer_ob, buffer);
- pfile->state.skipping = 0; /* In case missing #endif. */
+ /* The output line can fall out of sync if we missed the final
+ newline from the previous buffer, for example because of an
+ unterminated comment. Similarly, skipping needs to be cleared in
+ case of a missing #endif. */
+ pfile->lexer_pos.output_line = pfile->line;
+ pfile->state.skipping = 0;
}
void
diff --git a/gcc/cppmacro.c b/gcc/cppmacro.c
index d45a949..1618e7e 100644
--- a/gcc/cppmacro.c
+++ b/gcc/cppmacro.c
@@ -175,7 +175,8 @@ builtin_macro (pfile, token)
/* 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. */
- make_number_token (pfile, token, cpp_get_line (pfile)->line);
+ make_number_token (pfile, token,
+ SOURCE_LINE (pfile->map, cpp_get_line (pfile)->line));
break;
case BT_STDC:
@@ -484,9 +485,9 @@ parse_arg (pfile, arg, variadic)
}
/* Newlines in arguments are white space (6.10.3.10). */
- line = pfile->lexer_pos.output_line;
+ line = pfile->line;
cpp_get_token (pfile, token);
- if (line != pfile->lexer_pos.output_line)
+ if (line != pfile->line)
token->flags |= PREV_WHITE;
result = token->type;
@@ -1027,22 +1028,19 @@ save_lookahead_token (pfile, token)
cpp_reader *pfile;
const cpp_token *token;
{
- if (token->type != CPP_EOF)
- {
- cpp_lookahead *la = pfile->la_write;
- cpp_token_with_pos *twp;
-
- if (la->count == la->cap)
- {
- la->cap += la->cap + 8;
- la->tokens = (cpp_token_with_pos *)
- xrealloc (la->tokens, la->cap * sizeof (cpp_token_with_pos));
- }
+ cpp_lookahead *la = pfile->la_write;
+ cpp_token_with_pos *twp;
- twp = &la->tokens[la->count++];
- twp->token = *token;
- twp->pos = *cpp_get_line (pfile);
+ if (la->count == la->cap)
+ {
+ la->cap += la->cap + 8;
+ la->tokens = (cpp_token_with_pos *)
+ xrealloc (la->tokens, la->cap * sizeof (cpp_token_with_pos));
}
+
+ twp = &la->tokens[la->count++];
+ twp->token = *token;
+ twp->pos = *cpp_get_line (pfile);
}
static void
diff --git a/gcc/cppmain.c b/gcc/cppmain.c
index 6302610..86d245a 100644
--- a/gcc/cppmain.c
+++ b/gcc/cppmain.c
@@ -30,12 +30,12 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
cpp_get_token back into a text file. */
struct printer
{
- FILE *outf; /* stream to write to. */
- const char *last_fname; /* previous file name. */
- const char *syshdr_flags; /* system header flags, if any. */
- unsigned int lineno; /* line currently being written. */
- unsigned char printed; /* nonzero if something output at lineno. */
- struct line_map *map; /* logical to physical line mappings. */
+ FILE *outf; /* Stream to write to. */
+ const char *filename; /* Name of current file. */
+ const char *syshdr_flags; /* System header flags, if any. */
+ unsigned int line; /* Line currently being written. */
+ unsigned char printed; /* Nonzero if something output at line. */
+ struct line_map *map; /* Logical to physical line mappings. */
};
int main PARAMS ((int, char **));
@@ -46,10 +46,10 @@ static void setup_callbacks PARAMS ((void));
/* General output routines. */
static void scan_translation_unit PARAMS ((cpp_reader *));
static void check_multiline_token PARAMS ((cpp_string *));
-static int printer_init PARAMS ((cpp_reader *));
+static void printer_init PARAMS ((void));
static int dump_macro PARAMS ((cpp_reader *, cpp_hashnode *, void *));
-static void print_line PARAMS ((const char *));
+static void print_line PARAMS ((unsigned int, const char *));
static void maybe_print_line PARAMS ((unsigned int));
/* Callback routines for the parser. Most of these are active only
@@ -144,8 +144,12 @@ do_preprocessing (argc, argv)
/* Open the output now. We must do so even if no_output is on,
because there may be other output than from the actual
preprocessing (e.g. from -dM). */
- if (printer_init (pfile))
- return;
+ printer_init ();
+ if (print.outf == NULL)
+ {
+ cpp_notice_from_errno (pfile, options->out_fname);
+ return;
+ }
setup_callbacks ();
@@ -216,7 +220,7 @@ scan_translation_unit (pfile)
break;
line = cpp_get_line (pfile)->output_line;
- if (print.lineno != line)
+ if (print.line != line)
{
unsigned int col = cpp_get_line (pfile)->col;
@@ -253,7 +257,7 @@ scan_translation_unit (pfile)
}
}
-/* Adjust print.lineno for newlines embedded in tokens. */
+/* Adjust print.line for newlines embedded in tokens. */
static void
check_multiline_token (str)
cpp_string *str;
@@ -262,85 +266,69 @@ check_multiline_token (str)
for (i = 0; i < str->len; i++)
if (str->text[i] == '\n')
- print.lineno++;
+ print.line++;
}
/* Initialize a cpp_printer structure. As a side effect, open the
- output file. */
-static int
-printer_init (pfile)
- cpp_reader *pfile;
+ output file. If print.outf is NULL an error occurred. */
+static void
+printer_init ()
{
- print.last_fname = 0;
- print.lineno = 0;
+ /* Setting print.line to -1 here guarantees that the first token of
+ the file will cause a linemarker to be output by maybe_print_line. */
+ print.line = (unsigned int) -1;
print.printed = 0;
+ print.map = 0;
if (options->out_fname[0] == '\0')
print.outf = stdout;
else
- {
- print.outf = fopen (options->out_fname, "w");
- if (! print.outf)
- {
- cpp_notice_from_errno (pfile, options->out_fname);
- return 1;
- }
- }
-
- return 0;
+ print.outf = fopen (options->out_fname, "w");
}
-/* Newline-terminate any output line currently in progress. If
- appropriate, write the current line number to the output, or pad
- with newlines so the output line matches the current line. */
+/* If the token read on logical line LINE needs to be output on a
+ 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 (line)
unsigned int line;
{
- /* End the previous line of text (probably only needed until we get
- multi-line tokens fixed). */
+ /* End the previous line of text. */
if (print.printed)
{
putc ('\n', print.outf);
- print.lineno++;
+ print.line++;
print.printed = 0;
}
- if (options->no_line_commands)
+ if (line >= print.line && line < print.line + 8)
{
- print.lineno = line;
- return;
- }
-
- /* print.lineno is zero if this is the first token of the file. We
- handle this specially, so that a first line of "# 1 "foo.c" in
- file foo.i outputs just the foo.c line, and not a foo.i line. */
- if (line >= print.lineno && line < print.lineno + 8 && print.lineno)
- {
- while (line > print.lineno)
+ while (line > print.line)
{
putc ('\n', print.outf);
- print.lineno++;
+ print.line++;
}
}
else
- {
- print.lineno = line;
- print_line ("");
- }
+ print_line (line, "");
}
static void
-print_line (special_flags)
- const char *special_flags;
+print_line (line, special_flags)
+ unsigned int line;
+ const char *special_flags;
{
/* End any previous line of text. */
if (print.printed)
putc ('\n', print.outf);
print.printed = 0;
- fprintf (print.outf, "# %u \"%s\"%s%s\n",
- print.lineno, print.last_fname, special_flags, print.syshdr_flags);
+ print.line = line;
+ if (! options->no_line_commands)
+ fprintf (print.outf, "# %u \"%s\"%s%s\n",
+ SOURCE_LINE (print.map, print.line),
+ print.filename, special_flags, print.syshdr_flags);
}
/* Callbacks. */
@@ -348,21 +336,21 @@ print_line (special_flags)
static void
cb_ident (pfile, line, str)
cpp_reader *pfile ATTRIBUTE_UNUSED;
- unsigned int line ATTRIBUTE_UNUSED;
+ unsigned int line;
const cpp_string * str;
{
- maybe_print_line (cpp_get_line (pfile)->output_line);
+ maybe_print_line (line);
fprintf (print.outf, "#ident \"%s\"\n", str->text);
- print.lineno++;
+ print.line++;
}
static void
cb_define (pfile, line, node)
cpp_reader *pfile;
- unsigned int line ATTRIBUTE_UNUSED;
+ unsigned int line;
cpp_hashnode *node;
{
- maybe_print_line (cpp_get_line (pfile)->output_line);
+ maybe_print_line (line);
fputs ("#define ", print.outf);
/* -dD command line option. */
@@ -372,30 +360,30 @@ cb_define (pfile, line, node)
fputs ((const char *) NODE_NAME (node), print.outf);
putc ('\n', print.outf);
- print.lineno++;
+ print.line++;
}
static void
cb_undef (pfile, line, node)
- cpp_reader *pfile;
- unsigned int line ATTRIBUTE_UNUSED;
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
+ unsigned int line;
cpp_hashnode *node;
{
- maybe_print_line (cpp_get_line (pfile)->output_line);
+ maybe_print_line (line);
fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
- print.lineno++;
+ print.line++;
}
static void
cb_include (pfile, line, dir, header)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
- unsigned int line ATTRIBUTE_UNUSED;
+ cpp_reader *pfile;
+ unsigned int line;
const unsigned char *dir;
const cpp_token *header;
{
- maybe_print_line (cpp_get_line (pfile)->output_line);
+ maybe_print_line (line);
fprintf (print.outf, "#%s %s\n", dir, cpp_token_as_text (pfile, header));
- print.lineno++;
+ print.line++;
}
static void
@@ -403,12 +391,16 @@ cb_file_change (pfile, fc)
cpp_reader *pfile ATTRIBUTE_UNUSED;
const cpp_file_change *fc;
{
- /* Bring current file to correct line (except first file). */
- if (fc->reason == LC_ENTER && !MAIN_FILE_P (fc->map))
- maybe_print_line (SOURCE_LINE (fc->map - 1, fc->line - 1));
+ bool first_time = print.map == NULL;
+
+ /* Bring current file to correct line. We handle the first file
+ change callback specially, so that a first line of "# 1 "foo.c"
+ in file foo.i outputs just the foo.c line, and not a foo.i line. */
+ if (fc->reason == LC_ENTER && !first_time)
+ maybe_print_line (fc->line - 1);
print.map = fc->map;
- print.last_fname = fc->map->to_file;
+ print.filename = fc->map->to_file;
if (fc->externc)
print.syshdr_flags = " 3 4";
else if (fc->sysp)
@@ -416,18 +408,16 @@ cb_file_change (pfile, fc)
else
print.syshdr_flags = "";
- if (print.lineno)
+ if (!first_time)
{
const char *flags = "";
- print.lineno = SOURCE_LINE (fc->map, fc->line);
if (fc->reason == LC_ENTER)
flags = " 1";
else if (fc->reason == LC_LEAVE)
flags = " 2";
- if (! options->no_line_commands)
- print_line (flags);
+ print_line (fc->line, flags);
}
}
@@ -436,12 +426,12 @@ cb_file_change (pfile, fc)
static void
cb_def_pragma (pfile, line)
cpp_reader *pfile;
- unsigned int line ATTRIBUTE_UNUSED;
+ unsigned int line;
{
- maybe_print_line (cpp_get_line (pfile)->output_line);
+ maybe_print_line (line);
fputs ("#pragma ", print.outf);
cpp_output_line (pfile, print.outf);
- print.lineno++;
+ print.line++;
}
/* Dump out the hash table. */
@@ -456,7 +446,7 @@ dump_macro (pfile, node, v)
fputs ("#define ", print.outf);
fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
putc ('\n', print.outf);
- print.lineno++;
+ print.line++;
}
return 1;
diff --git a/gcc/line-map.h b/gcc/line-map.h
index 1f9a47d..b6c9344 100644
--- a/gcc/line-map.h
+++ b/gcc/line-map.h
@@ -75,9 +75,12 @@ extern struct line_map *lookup_line
/* Returns the last source line within a map. This is the (last) line
of the #include, or other directive, that caused a map change. */
-#define LAST_SOURCE_LINE(MAP) SOURCE_LINE (MAP, (MAP)[1].from_line - 1)
+#define LAST_SOURCE_LINE(MAP) SOURCE_LINE ((MAP), (MAP)[1].from_line - 1)
/* Non-zero if the map is at the bottom of the include stack. */
#define MAIN_FILE_P(MAP) ((MAP)->included_from < 0)
+/* The current line map. */
+#define CURRENT_LINE_MAP(MAPS) ((MAPS)->maps + (MAPS)->used - 1)
+
#endif /* !GCC_LINE_MAP_H */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d0813ca..512f539 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2001-08-05 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * gcc.dg/cpp/19951025-1.c: Revert.
+ * gcc.dg/cpp/directiv.c: We no longer process directives that
+ interrupt macro arguments.
+
2001-08-03 Zack Weinberg <zackw@stanford.edu>
* gcc.dg/bconstp-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/cpp/19951025-1.c b/gcc/testsuite/gcc.dg/cpp/19951025-1.c
index ca21a22..283b5f5 100644
--- a/gcc/testsuite/gcc.dg/cpp/19951025-1.c
+++ b/gcc/testsuite/gcc.dg/cpp/19951025-1.c
@@ -1,4 +1,4 @@
/* { dg-do preprocess } */
-/* { dg-error "include expects" "" { target *-*-* } 5 } */
-/* { dg-error "newline at end" "" { target *-*-* } 5 } */
+/* { dg-error "include expects" "" { target *-*-* } 4 } */
+/* { dg-error "newline at end" "" { target *-*-* } 4 } */
#include /\
diff --git a/gcc/testsuite/gcc.dg/cpp/directiv.c b/gcc/testsuite/gcc.dg/cpp/directiv.c
index 2cb772d..622f7a3 100644
--- a/gcc/testsuite/gcc.dg/cpp/directiv.c
+++ b/gcc/testsuite/gcc.dg/cpp/directiv.c
@@ -31,13 +31,6 @@ EMPTY #define bar
func (2 /* { dg-error "unterminated" "" { target *-*-* } 32 } */
#define foobar /* { dg-error "directives may not" } */
-/* For tidiness, I think the directive should still be processed
- above. Certainly, continuing to try to find the closing ')' can
- lead to some really confusing error messages. Hence this test. */
-#ifndef foobar
-#error It is nice if the directive is processed!
-#endif
-
/* Check newlines end directives, even in function-like macro
invocations. 6.10 paragraph 1.