Commit 67821e3a by Neil Booth Committed by Neil Booth

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
parent 8125d7e9
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> 2001-08-05 Bernd Schmidt <bernds@redhat.com>
* doloop.c (doloop_modify_runtime): Properly compute number of * doloop.c (doloop_modify_runtime): Properly compute number of
......
...@@ -57,6 +57,9 @@ Boston, MA 02111-1307, USA. */ ...@@ -57,6 +57,9 @@ Boston, MA 02111-1307, USA. */
/* The input filename as understood by CPP, where "" represents stdin. */ /* The input filename as understood by CPP, where "" represents stdin. */
static const char *cpp_filename; 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. */ /* We may keep statistics about how long which files took to compile. */
static int header_time, body_time; static int header_time, body_time;
static splay_tree file_info_tree; static splay_tree file_info_tree;
...@@ -301,9 +304,10 @@ cb_file_change (pfile, fc) ...@@ -301,9 +304,10 @@ cb_file_change (pfile, fc)
} }
update_header_times (fc->map->to_file); update_header_times (fc->map->to_file);
map = fc->map;
in_system_header = fc->sysp != 0; in_system_header = fc->sysp != 0;
input_filename = fc->map->to_file; input_filename = map->to_file;
lineno = SOURCE_LINE (fc->map, fc->line); /* Do we need this? */ lineno = SOURCE_LINE (map, fc->line);
/* Hook for C++. */ /* Hook for C++. */
extract_interface_info (); extract_interface_info ();
...@@ -312,7 +316,7 @@ cb_file_change (pfile, fc) ...@@ -312,7 +316,7 @@ cb_file_change (pfile, fc)
static void static void
cb_def_pragma (pfile, line) cb_def_pragma (pfile, line)
cpp_reader *pfile; cpp_reader *pfile;
unsigned int line ATTRIBUTE_UNUSED; unsigned int line;
{ {
/* Issue a warning message if we have been asked to do so. Ignore /* Issue a warning message if we have been asked to do so. Ignore
unknown pragmas in system headers unless an explicit unknown pragmas in system headers unless an explicit
...@@ -328,7 +332,7 @@ cb_def_pragma (pfile, line) ...@@ -328,7 +332,7 @@ cb_def_pragma (pfile, line)
if (s.type == CPP_NAME) if (s.type == CPP_NAME)
name = cpp_token_as_text (pfile, &s); name = cpp_token_as_text (pfile, &s);
lineno = cpp_get_line (parse_in)->line; lineno = SOURCE_LINE (map, line);
if (name) if (name)
warning ("ignoring #pragma %s %s", space, name); warning ("ignoring #pragma %s %s", space, name);
else else
...@@ -340,21 +344,21 @@ cb_def_pragma (pfile, line) ...@@ -340,21 +344,21 @@ cb_def_pragma (pfile, line)
static void static void
cb_define (pfile, line, node) cb_define (pfile, line, node)
cpp_reader *pfile; cpp_reader *pfile;
unsigned int line ATTRIBUTE_UNUSED; unsigned int line;
cpp_hashnode *node; 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)); (const char *) cpp_macro_definition (pfile, node));
} }
/* #undef callback for DWARF and DWARF2 debug info. */ /* #undef callback for DWARF and DWARF2 debug info. */
static void static void
cb_undef (pfile, line, node) cb_undef (pfile, line, node)
cpp_reader *pfile; cpp_reader *pfile ATTRIBUTE_UNUSED;
unsigned int line ATTRIBUTE_UNUSED; unsigned int line;
cpp_hashnode *node; cpp_hashnode *node;
{ {
(*debug_hooks->undef) (cpp_get_line (pfile)->line, (*debug_hooks->undef) (SOURCE_LINE (map, line),
(const char *) NODE_NAME (node)); (const char *) NODE_NAME (node));
} }
...@@ -763,7 +767,7 @@ c_lex (value) ...@@ -763,7 +767,7 @@ c_lex (value)
/* The C++ front end does horrible things with the current line /* The C++ front end does horrible things with the current line
number. To ensure an accurate line number, we must reset it number. To ensure an accurate line number, we must reset it
every time we return a token. */ 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; *value = NULL_TREE;
type = tok.type; type = tok.type;
......
...@@ -108,23 +108,17 @@ print_location (pfile, filename, pos) ...@@ -108,23 +108,17 @@ print_location (pfile, filename, pos)
{ {
struct line_map *map; struct line_map *map;
line = pfile->line;
if (type == BUF_PRAGMA) if (type == BUF_PRAGMA)
{ buffer = buffer->prev;
buffer = buffer->prev;
col = CPP_BUF_COL (buffer);
}
map = lookup_line (&pfile->line_maps, line);
if (pos == 0) if (pos == 0)
{ pos = cpp_get_line (pfile);
pos = cpp_get_line (pfile); map = lookup_line (&pfile->line_maps, pos->line);
line = SOURCE_LINE (map, line); line = SOURCE_LINE (map, pos->line);
} if (filename == 0)
else filename = map->to_file;
line = pos->line;
col = pos->col;
col = pos->col;
if (col == 0) if (col == 0)
col = 1; col = 1;
......
...@@ -337,9 +337,7 @@ stack_include_file (pfile, inc) ...@@ -337,9 +337,7 @@ stack_include_file (pfile, inc)
pfile->include_depth++; pfile->include_depth++;
/* Generate the call back. */ /* Generate the call back. */
fp->lineno = 0; _cpp_do_file_change (pfile, LC_ENTER, 1);
_cpp_do_file_change (pfile, LC_ENTER);
fp->lineno = 1;
} }
/* Read the file referenced by INC into the file cache. /* Read the file referenced by INC into the file cache.
...@@ -579,7 +577,8 @@ cpp_make_system_header (pfile, syshdr, externc) ...@@ -579,7 +577,8 @@ cpp_make_system_header (pfile, syshdr, externc)
if (syshdr) if (syshdr)
flags = 1 + (externc != 0); flags = 1 + (externc != 0);
pfile->buffer->sysp = flags; 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. /* Report on all files that might benefit from a multiple include guard.
...@@ -679,8 +678,8 @@ _cpp_execute_include (pfile, header, type) ...@@ -679,8 +678,8 @@ _cpp_execute_include (pfile, header, type)
if (header->type == CPP_HEADER_NAME) if (header->type == CPP_HEADER_NAME)
pfile->system_include_depth++; pfile->system_include_depth++;
pfile->buffer->return_to_line = SOURCE_LINE (pfile->map, pfile->line);
stack_include_file (pfile, inc); stack_include_file (pfile, inc);
pfile->line++; /* Fake the '\n' at the end of #include. */
if (type == IT_IMPORT) if (type == IT_IMPORT)
_cpp_never_reread (inc); _cpp_never_reread (inc);
......
...@@ -35,7 +35,6 @@ struct directive; /* Deliberately incomplete. */ ...@@ -35,7 +35,6 @@ struct directive; /* Deliberately incomplete. */
#define CPP_OPTION(PFILE, OPTION) ((PFILE)->opts.OPTION) #define CPP_OPTION(PFILE, OPTION) ((PFILE)->opts.OPTION)
#define CPP_BUFFER(PFILE) ((PFILE)->buffer) #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_COLUMN(BUF, CUR) ((CUR) - (BUF)->line_base + (BUF)->col_adjust)
#define CPP_BUF_COL(BUF) CPP_BUF_COLUMN(BUF, (BUF)->cur) #define CPP_BUF_COL(BUF) CPP_BUF_COLUMN(BUF, (BUF)->cur)
...@@ -194,8 +193,10 @@ struct cpp_buffer ...@@ -194,8 +193,10 @@ struct cpp_buffer
/* Token column position adjustment owing to tabs in whitespace. */ /* Token column position adjustment owing to tabs in whitespace. */
unsigned int col_adjust; unsigned int col_adjust;
/* Line number at line_base (above). */ /* The line of the buffer that we return to after a #include.
unsigned int lineno; 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. */ /* Contains PREV_WHITE and/or AVOID_LPASTE. */
unsigned char saved_flags; unsigned char saved_flags;
...@@ -251,12 +252,10 @@ struct cpp_reader ...@@ -251,12 +252,10 @@ struct cpp_reader
/* Lexer state. */ /* Lexer state. */
struct lexer_state state; struct lexer_state state;
/* Source line tracking. Subtract pseudo_newlines from the actual /* Source line tracking. */
line number to get the line number of preprocessed output. Used
for escaped newlines and macro args that cross multiple lines. */
struct line_maps line_maps; struct line_maps line_maps;
struct line_map *map;
unsigned int line; unsigned int line;
unsigned int pseudo_newlines;
/* The position of the last lexed token and last lexed directive. */ /* The position of the last lexed token and last lexed directive. */
cpp_lexer_pos lexer_pos; cpp_lexer_pos lexer_pos;
...@@ -446,7 +445,8 @@ extern void _cpp_define_builtin PARAMS ((cpp_reader *, const char *)); ...@@ -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_do__Pragma PARAMS ((cpp_reader *));
extern void _cpp_init_directives PARAMS ((cpp_reader *)); extern void _cpp_init_directives PARAMS ((cpp_reader *));
extern void _cpp_init_internal_pragmas 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 *)); extern void _cpp_pop_buffer PARAMS ((cpp_reader *));
/* Utility routines and macros. */ /* Utility routines and macros. */
......
...@@ -949,10 +949,10 @@ cpp_start_read (pfile, fname) ...@@ -949,10 +949,10 @@ cpp_start_read (pfile, fname)
p = q; p = q;
} }
/* This was zero when the initial buffer was stacked; so we must /* Hopefully a short-term kludge. We stacked the main file at line
make up for a non-existent new line, as well as the intervening zero. The intervening macro definitions have messed up line
macro definitions, by setting it to 1. */ numbering, so we need to restore it. */
pfile->line = 1; pfile->lexer_pos.output_line = pfile->line = 0;
/* The -imacros files can be scanned now, but the -include files /* The -imacros files can be scanned now, but the -include files
have to be pushed onto the buffer stack and processed later, have to be pushed onto the buffer stack and processed later,
......
...@@ -132,11 +132,8 @@ handle_newline (pfile, newline_char) ...@@ -132,11 +132,8 @@ handle_newline (pfile, newline_char)
cppchar_t next = EOF; cppchar_t next = EOF;
pfile->line++; pfile->line++;
pfile->pseudo_newlines++;
buffer = pfile->buffer; buffer = pfile->buffer;
buffer->col_adjust = 0; buffer->col_adjust = 0;
buffer->lineno++;
buffer->line_base = buffer->cur; buffer->line_base = buffer->cur;
/* Handle CR-LF and LF-CR combinations, get the next character. */ /* Handle CR-LF and LF-CR combinations, get the next character. */
...@@ -173,15 +170,16 @@ trigraph_ok (pfile, from_char) ...@@ -173,15 +170,16 @@ trigraph_ok (pfile, from_char)
if (CPP_OPTION (pfile, warn_trigraphs) && !pfile->state.lexing_comment) if (CPP_OPTION (pfile, warn_trigraphs) && !pfile->state.lexing_comment)
{ {
cpp_buffer *buffer = pfile->buffer; cpp_buffer *buffer = pfile->buffer;
if (accept) 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", "trigraph ??%c converted to %c",
(int) from_char, (int) from_char,
(int) _cpp_trigraph_map[from_char]); (int) _cpp_trigraph_map[from_char]);
else if (buffer->cur != buffer->last_Wtrigraphs) else if (buffer->cur != buffer->last_Wtrigraphs)
{ {
buffer->last_Wtrigraphs = buffer->cur; buffer->last_Wtrigraphs = buffer->cur;
cpp_warning_with_line (pfile, buffer->lineno, cpp_warning_with_line (pfile, pfile->line,
CPP_BUF_COL (buffer) - 2, CPP_BUF_COL (buffer) - 2,
"trigraph ??%c ignored", (int) from_char); "trigraph ??%c ignored", (int) from_char);
} }
...@@ -344,8 +342,8 @@ skip_block_comment (pfile) ...@@ -344,8 +342,8 @@ skip_block_comment (pfile)
{ {
prevc = c, c = *buffer->cur++; prevc = c, c = *buffer->cur++;
if (c != '/') if (c != '/')
cpp_warning_with_line (pfile, CPP_BUF_LINE (buffer), cpp_warning_with_line (pfile, pfile->line,
CPP_BUF_COL (buffer), CPP_BUF_COL (buffer) - 2,
"\"/*\" within comment"); "\"/*\" within comment");
} }
goto next_char; goto next_char;
...@@ -373,7 +371,7 @@ skip_line_comment (pfile) ...@@ -373,7 +371,7 @@ skip_line_comment (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
cpp_buffer *buffer = pfile->buffer; cpp_buffer *buffer = pfile->buffer;
unsigned int orig_lineno = buffer->lineno; unsigned int orig_line = pfile->line;
cppchar_t c; cppchar_t c;
pfile->state.lexing_comment = 1; pfile->state.lexing_comment = 1;
...@@ -391,7 +389,7 @@ skip_line_comment (pfile) ...@@ -391,7 +389,7 @@ skip_line_comment (pfile)
pfile->state.lexing_comment = 0; pfile->state.lexing_comment = 0;
buffer->read_ahead = c; /* Leave any newline for caller. */ 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 /* pfile->buffer->cur is one beyond the \t character. Update
...@@ -437,7 +435,7 @@ skip_whitespace (pfile, c) ...@@ -437,7 +435,7 @@ skip_whitespace (pfile, c)
} }
} }
else if (pfile->state.in_directive && CPP_PEDANTIC (pfile)) 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), CPP_BUF_COL (buffer),
"%s in preprocessing directive", "%s in preprocessing directive",
c == '\f' ? "form feed" : "vertical tab"); c == '\f' ? "form feed" : "vertical tab");
...@@ -865,17 +863,16 @@ _cpp_lex_token (pfile, result) ...@@ -865,17 +863,16 @@ _cpp_lex_token (pfile, result)
cppchar_t c; cppchar_t c;
cpp_buffer *buffer; cpp_buffer *buffer;
const unsigned char *comment_start; const unsigned char *comment_start;
unsigned char bol; int bol;
skip: next_token:
bol = pfile->state.next_bol;
done_directive:
buffer = pfile->buffer; buffer = pfile->buffer;
pfile->state.next_bol = 0;
result->flags = buffer->saved_flags; result->flags = buffer->saved_flags;
buffer->saved_flags = 0; buffer->saved_flags = 0;
bol = (buffer->cur <= buffer->line_base + 1
&& pfile->lexer_pos.output_line == pfile->line);
next_char: next_char:
pfile->lexer_pos.line = buffer->lineno; pfile->lexer_pos.line = pfile->line;
result->line = pfile->line; result->line = pfile->line;
next_char2: next_char2:
pfile->lexer_pos.col = CPP_BUF_COLUMN (buffer, buffer->cur); pfile->lexer_pos.col = CPP_BUF_COLUMN (buffer, buffer->cur);
...@@ -893,22 +890,29 @@ _cpp_lex_token (pfile, result) ...@@ -893,22 +890,29 @@ _cpp_lex_token (pfile, result)
switch (c) switch (c)
{ {
case EOF: 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; unsigned char ret = pfile->buffer->return_at_eof;
/* Non-empty files should end in a newline. Don't warn for /* Non-empty files should end in a newline. Don't warn for
command line and _Pragma buffers. */ command line and _Pragma buffers. */
if (pfile->lexer_pos.col != 0 && !buffer->from_stage3) if (pfile->lexer_pos.col != 0)
cpp_pedwarn (pfile, "no newline at end of file");
_cpp_pop_buffer (pfile);
if (pfile->buffer && !ret)
{ {
bol = 1; /* Account for the missing \n. */
goto done_directive; 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; result->type = CPP_EOF;
return; return;
...@@ -918,36 +922,41 @@ _cpp_lex_token (pfile, result) ...@@ -918,36 +922,41 @@ _cpp_lex_token (pfile, result)
goto next_char2; goto next_char2;
case '\n': case '\r': case '\n': case '\r':
if (!pfile->state.in_directive) if (pfile->state.in_directive)
{ {
handle_newline (pfile, c); result->type = CPP_EOF;
if (!pfile->state.parsing_args) if (pfile->state.parsing_args)
pfile->pseudo_newlines = 0; buffer->read_ahead = c;
bol = 1; else
pfile->lexer_pos.output_line = buffer->lineno; {
/* This is a new line, so clear any white space flag. handle_newline (pfile, c);
Newlines in arguments are white space (6.10.3.10); /* Decrementing pfile->line allows directives to
parse_arg takes care of that. */ recognise that the newline has been seen, and also
result->flags &= ~(PREV_WHITE | AVOID_LPASTE); means that diagnostics don't point to the next line. */
goto next_char; pfile->lexer_pos.output_line = pfile->line--;
}
return;
} }
/* Don't let directives spill over to the next line. */ handle_newline (pfile, c);
buffer->read_ahead = c; /* This is a new line, so clear any white space flag. Newlines
pfile->state.next_bol = 1; in arguments are white space (6.10.3.10); parse_arg takes
result->type = CPP_EOF; care of that. */
/* Don't break; pfile->state.skipping might be true. */ result->flags &= ~(PREV_WHITE | AVOID_LPASTE);
return; bol = 1;
if (pfile->state.parsing_args != 2)
pfile->lexer_pos.output_line = pfile->line;
goto next_char;
case '?': case '?':
case '\\': case '\\':
/* These could start an escaped newline, or '?' a trigraph. Let /* These could start an escaped newline, or '?' a trigraph. Let
skip_escaped_newlines do all the work. */ skip_escaped_newlines do all the work. */
{ {
unsigned int lineno = buffer->lineno; unsigned int line = pfile->line;
c = skip_escaped_newlines (buffer, c); 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 /* We had at least one escaped newline of some sort, and the
next character is in buffer->read_ahead. Update the next character is in buffer->read_ahead. Update the
token's line and column. */ token's line and column. */
...@@ -1026,9 +1035,7 @@ _cpp_lex_token (pfile, result) ...@@ -1026,9 +1035,7 @@ _cpp_lex_token (pfile, result)
if (c == '*') if (c == '*')
{ {
if (skip_block_comment (pfile)) if (skip_block_comment (pfile))
cpp_error_with_line (pfile, pfile->lexer_pos.line, cpp_error (pfile, "unterminated comment");
pfile->lexer_pos.col,
"unterminated comment");
} }
else else
{ {
...@@ -1212,26 +1219,21 @@ _cpp_lex_token (pfile, result) ...@@ -1212,26 +1219,21 @@ _cpp_lex_token (pfile, result)
macro invocation, and proceed to process the directive. */ macro invocation, and proceed to process the directive. */
if (pfile->state.parsing_args) if (pfile->state.parsing_args)
{ {
pfile->lexer_pos.output_line = pfile->line;
if (pfile->state.parsing_args == 2) if (pfile->state.parsing_args == 2)
cpp_error (pfile, {
"directives may not be used inside a macro argument"); cpp_error (pfile,
"directives may not be used inside a macro argument");
/* Put a '#' in lookahead, return CPP_EOF for parse_arg. */ result->type = CPP_EOF;
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);
} }
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)) if (_cpp_handle_directive (pfile, result->flags & PREV_WHITE))
goto done_directive; /* bol still 1. */ goto next_token;
/* This is in fact an assembler #. */
} }
break; break;
...@@ -1283,7 +1285,7 @@ _cpp_lex_token (pfile, result) ...@@ -1283,7 +1285,7 @@ _cpp_lex_token (pfile, result)
} }
if (!pfile->state.in_directive && pfile->state.skipping) if (!pfile->state.in_directive && pfile->state.skipping)
goto skip; goto next_char;
/* If not in a directive, this token invalidates controlling macros. */ /* If not in a directive, this token invalidates controlling macros. */
if (!pfile->state.in_directive) if (!pfile->state.in_directive)
......
...@@ -178,6 +178,8 @@ DIRECTIVE_TABLE ...@@ -178,6 +178,8 @@ DIRECTIVE_TABLE
#undef D #undef D
#undef DIRECTIVE_TABLE #undef DIRECTIVE_TABLE
#define SEEN_EOL() (pfile->lexer_pos.output_line > pfile->line)
/* Skip any remaining tokens in a directive. */ /* Skip any remaining tokens in a directive. */
static void static void
skip_rest_of_line (pfile) skip_rest_of_line (pfile)
...@@ -194,7 +196,7 @@ skip_rest_of_line (pfile) ...@@ -194,7 +196,7 @@ skip_rest_of_line (pfile)
_cpp_pop_context (pfile); _cpp_pop_context (pfile);
/* Sweep up all tokens remaining on the line. */ /* Sweep up all tokens remaining on the line. */
while (!pfile->state.next_bol) while (! SEEN_EOL ())
_cpp_lex_token (pfile, &token); _cpp_lex_token (pfile, &token);
} }
...@@ -203,7 +205,7 @@ static void ...@@ -203,7 +205,7 @@ static void
check_eol (pfile) check_eol (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
if (!pfile->state.next_bol) if (! SEEN_EOL ())
{ {
cpp_token token; cpp_token token;
...@@ -240,7 +242,11 @@ end_directive (pfile, skip_line) ...@@ -240,7 +242,11 @@ end_directive (pfile, skip_line)
{ {
/* We don't skip for an assembler #. */ /* We don't skip for an assembler #. */
if (skip_line) if (skip_line)
skip_rest_of_line (pfile); {
skip_rest_of_line (pfile);
/* "Accept" the newline now. */
pfile->line++;
}
/* Restore state. */ /* Restore state. */
pfile->la_write = pfile->la_saved; pfile->la_write = pfile->la_saved;
...@@ -395,19 +401,9 @@ run_directive (pfile, dir_no, type, buf, count) ...@@ -395,19 +401,9 @@ run_directive (pfile, dir_no, type, buf, count)
const char *buf; const char *buf;
size_t count; size_t count;
{ {
unsigned int output_line = pfile->lexer_pos.output_line;
cpp_buffer *buffer; cpp_buffer *buffer;
buffer = cpp_push_buffer (pfile, (const U_CHAR *) buf, count, type, 0, 1); 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); start_directive (pfile);
pfile->state.prevent_expansion++; pfile->state.prevent_expansion++;
pfile->directive = &dtable[dir_no]; pfile->directive = &dtable[dir_no];
...@@ -779,8 +775,11 @@ do_line (pfile) ...@@ -779,8 +775,11 @@ do_line (pfile)
else if (reason == LC_LEAVE) else if (reason == LC_LEAVE)
{ {
if (buffer->type != BUF_FAKE) 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 else
{ {
_cpp_pop_buffer (pfile); _cpp_pop_buffer (pfile);
...@@ -789,9 +788,6 @@ do_line (pfile) ...@@ -789,9 +788,6 @@ do_line (pfile)
if (strcmp (buffer->nominal_fname, fname)) if (strcmp (buffer->nominal_fname, fname))
cpp_warning (pfile, "expected to return to file \"%s\"", cpp_warning (pfile, "expected to return to file \"%s\"",
buffer->nominal_fname); 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) if (buffer->sysp != sysp)
cpp_warning (pfile, "header flags for \"%s\" have changed", cpp_warning (pfile, "header flags for \"%s\" have changed",
buffer->nominal_fname); buffer->nominal_fname);
...@@ -810,30 +806,29 @@ do_line (pfile) ...@@ -810,30 +806,29 @@ do_line (pfile)
} }
end_directive (pfile, 1); end_directive (pfile, 1);
buffer->lineno = new_lineno - 1; _cpp_do_file_change (pfile, reason, new_lineno);
_cpp_do_file_change (pfile, reason);
} }
/* Arrange the file_change callback. It is assumed that the next line /* Arrange the file_change callback. pfile->line has changed to
is given by incrementing buffer->lineno and pfile->line. */ FILE_LINE of the current buffer, for reason REASON. */
void void
_cpp_do_file_change (pfile, reason) _cpp_do_file_change (pfile, reason, file_line)
cpp_reader *pfile; cpp_reader *pfile;
enum lc_reason reason; enum lc_reason reason;
unsigned int file_line;
{ {
cpp_buffer *buffer; cpp_buffer *buffer;
struct line_map *map;
buffer = pfile->buffer; buffer = pfile->buffer;
map = add_line_map (&pfile->line_maps, reason, pfile->map = add_line_map (&pfile->line_maps, reason,
pfile->line + 1, buffer->nominal_fname, buffer->lineno + 1); pfile->line, buffer->nominal_fname, file_line);
if (pfile->cb.file_change) if (pfile->cb.file_change)
{ {
cpp_file_change fc; cpp_file_change fc;
fc.map = map; fc.map = pfile->map;
fc.line = pfile->line + 1; fc.line = pfile->line;
fc.reason = reason; fc.reason = reason;
fc.sysp = buffer->sysp; fc.sysp = buffer->sysp;
fc.externc = CPP_OPTION (pfile, cplusplus) && buffer->sysp == 2; fc.externc = CPP_OPTION (pfile, cplusplus) && buffer->sysp == 2;
...@@ -1195,16 +1190,19 @@ _cpp_do__Pragma (pfile) ...@@ -1195,16 +1190,19 @@ _cpp_do__Pragma (pfile)
cpp_token string; cpp_token string;
unsigned char *buffer; unsigned char *buffer;
unsigned int len; unsigned int len;
cpp_lexer_pos orig_pos;
orig_pos = pfile->lexer_pos;
if (get__Pragma_string (pfile, &string)) 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"); buffer = destringize (&string.val.str, &len);
return; 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. */ /* 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) ...@@ -1815,8 +1813,6 @@ cpp_push_buffer (pfile, buffer, len, type, filename, return_at_eof)
/* Preprocessed files, builtins, _Pragma and command line /* Preprocessed files, builtins, _Pragma and command line
options don't do trigraph and escaped newline processing. */ options don't do trigraph and escaped newline processing. */
new->from_stage3 = type != BUF_FILE || CPP_OPTION (pfile, preprocessed); new->from_stage3 = type != BUF_FILE || CPP_OPTION (pfile, preprocessed);
pfile->lexer_pos.output_line = 1;
} }
if (*filename == '\0') if (*filename == '\0')
...@@ -1827,7 +1823,6 @@ cpp_push_buffer (pfile, buffer, len, type, filename, return_at_eof) ...@@ -1827,7 +1823,6 @@ cpp_push_buffer (pfile, buffer, len, type, filename, return_at_eof)
new->prev = pfile->buffer; new->prev = pfile->buffer;
new->pfile = pfile; new->pfile = pfile;
new->include_stack_listed = 0; new->include_stack_listed = 0;
new->lineno = 1;
new->return_at_eof = return_at_eof; new->return_at_eof = return_at_eof;
pfile->state.next_bol = 1; pfile->state.next_bol = 1;
...@@ -1857,7 +1852,11 @@ _cpp_pop_buffer (pfile) ...@@ -1857,7 +1852,11 @@ _cpp_pop_buffer (pfile)
"unterminated #%s", dtable[ifs->type].name); "unterminated #%s", dtable[ifs->type].name);
if (buffer->type == BUF_FAKE) 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) else if (buffer->type == BUF_FILE)
_cpp_pop_file_buffer (pfile, buffer); _cpp_pop_file_buffer (pfile, buffer);
...@@ -1877,8 +1876,7 @@ _cpp_pop_buffer (pfile) ...@@ -1877,8 +1876,7 @@ _cpp_pop_buffer (pfile)
if (pfile->directive == &dtable[T_LINE]) if (pfile->directive == &dtable[T_LINE])
break; break;
pfile->line--; /* We have a '\n' at the end of #include. */ _cpp_do_file_change (pfile, LC_LEAVE, pfile->buffer->return_to_line);
_cpp_do_file_change (pfile, LC_LEAVE);
if (pfile->buffer->type == BUF_FILE) if (pfile->buffer->type == BUF_FILE)
break; break;
...@@ -1888,7 +1886,12 @@ _cpp_pop_buffer (pfile) ...@@ -1888,7 +1886,12 @@ _cpp_pop_buffer (pfile)
obstack_free (&pfile->buffer_ob, buffer); 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 void
......
...@@ -175,7 +175,8 @@ builtin_macro (pfile, token) ...@@ -175,7 +175,8 @@ builtin_macro (pfile, token)
/* If __LINE__ is embedded in a macro, it must expand to the /* If __LINE__ is embedded in a macro, it must expand to the
line of the macro's invocation, not its definition. line of the macro's invocation, not its definition.
Otherwise things like assert() will not work properly. */ Otherwise things like assert() will not work properly. */
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; break;
case BT_STDC: case BT_STDC:
...@@ -484,9 +485,9 @@ parse_arg (pfile, arg, variadic) ...@@ -484,9 +485,9 @@ parse_arg (pfile, arg, variadic)
} }
/* Newlines in arguments are white space (6.10.3.10). */ /* Newlines in arguments are white space (6.10.3.10). */
line = pfile->lexer_pos.output_line; line = pfile->line;
cpp_get_token (pfile, token); cpp_get_token (pfile, token);
if (line != pfile->lexer_pos.output_line) if (line != pfile->line)
token->flags |= PREV_WHITE; token->flags |= PREV_WHITE;
result = token->type; result = token->type;
...@@ -1027,22 +1028,19 @@ save_lookahead_token (pfile, token) ...@@ -1027,22 +1028,19 @@ save_lookahead_token (pfile, token)
cpp_reader *pfile; cpp_reader *pfile;
const cpp_token *token; const cpp_token *token;
{ {
if (token->type != CPP_EOF) cpp_lookahead *la = pfile->la_write;
{ cpp_token_with_pos *twp;
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));
}
twp = &la->tokens[la->count++]; if (la->count == la->cap)
twp->token = *token; {
twp->pos = *cpp_get_line (pfile); 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 static void
......
...@@ -30,12 +30,12 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -30,12 +30,12 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
cpp_get_token back into a text file. */ cpp_get_token back into a text file. */
struct printer struct printer
{ {
FILE *outf; /* stream to write to. */ FILE *outf; /* Stream to write to. */
const char *last_fname; /* previous file name. */ const char *filename; /* Name of current file. */
const char *syshdr_flags; /* system header flags, if any. */ const char *syshdr_flags; /* System header flags, if any. */
unsigned int lineno; /* line currently being written. */ unsigned int line; /* Line currently being written. */
unsigned char printed; /* nonzero if something output at lineno. */ unsigned char printed; /* Nonzero if something output at line. */
struct line_map *map; /* logical to physical line mappings. */ struct line_map *map; /* Logical to physical line mappings. */
}; };
int main PARAMS ((int, char **)); int main PARAMS ((int, char **));
...@@ -46,10 +46,10 @@ static void setup_callbacks PARAMS ((void)); ...@@ -46,10 +46,10 @@ static void setup_callbacks PARAMS ((void));
/* General output routines. */ /* General output routines. */
static void scan_translation_unit PARAMS ((cpp_reader *)); static void scan_translation_unit PARAMS ((cpp_reader *));
static void check_multiline_token PARAMS ((cpp_string *)); 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 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)); static void maybe_print_line PARAMS ((unsigned int));
/* Callback routines for the parser. Most of these are active only /* Callback routines for the parser. Most of these are active only
...@@ -144,8 +144,12 @@ do_preprocessing (argc, argv) ...@@ -144,8 +144,12 @@ do_preprocessing (argc, argv)
/* Open the output now. We must do so even if no_output is on, /* Open the output now. We must do so even if no_output is on,
because there may be other output than from the actual because there may be other output than from the actual
preprocessing (e.g. from -dM). */ preprocessing (e.g. from -dM). */
if (printer_init (pfile)) printer_init ();
return; if (print.outf == NULL)
{
cpp_notice_from_errno (pfile, options->out_fname);
return;
}
setup_callbacks (); setup_callbacks ();
...@@ -216,7 +220,7 @@ scan_translation_unit (pfile) ...@@ -216,7 +220,7 @@ scan_translation_unit (pfile)
break; break;
line = cpp_get_line (pfile)->output_line; line = cpp_get_line (pfile)->output_line;
if (print.lineno != line) if (print.line != line)
{ {
unsigned int col = cpp_get_line (pfile)->col; unsigned int col = cpp_get_line (pfile)->col;
...@@ -253,7 +257,7 @@ scan_translation_unit (pfile) ...@@ -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 static void
check_multiline_token (str) check_multiline_token (str)
cpp_string *str; cpp_string *str;
...@@ -262,85 +266,69 @@ check_multiline_token (str) ...@@ -262,85 +266,69 @@ check_multiline_token (str)
for (i = 0; i < str->len; i++) for (i = 0; i < str->len; i++)
if (str->text[i] == '\n') if (str->text[i] == '\n')
print.lineno++; print.line++;
} }
/* Initialize a cpp_printer structure. As a side effect, open the /* Initialize a cpp_printer structure. As a side effect, open the
output file. */ output file. If print.outf is NULL an error occurred. */
static int static void
printer_init (pfile) printer_init ()
cpp_reader *pfile;
{ {
print.last_fname = 0; /* Setting print.line to -1 here guarantees that the first token of
print.lineno = 0; the file will cause a linemarker to be output by maybe_print_line. */
print.line = (unsigned int) -1;
print.printed = 0; print.printed = 0;
print.map = 0;
if (options->out_fname[0] == '\0') if (options->out_fname[0] == '\0')
print.outf = stdout; print.outf = stdout;
else else
{ print.outf = fopen (options->out_fname, "w");
print.outf = fopen (options->out_fname, "w");
if (! print.outf)
{
cpp_notice_from_errno (pfile, options->out_fname);
return 1;
}
}
return 0;
} }
/* Newline-terminate any output line currently in progress. If /* If the token read on logical line LINE needs to be output on a
appropriate, write the current line number to the output, or pad different line to the current one, output the required newlines or
with newlines so the output line matches the current line. */ a line marker, and return 1. Otherwise return 0. */
static void static void
maybe_print_line (line) maybe_print_line (line)
unsigned int line; unsigned int line;
{ {
/* End the previous line of text (probably only needed until we get /* End the previous line of text. */
multi-line tokens fixed). */
if (print.printed) if (print.printed)
{ {
putc ('\n', print.outf); putc ('\n', print.outf);
print.lineno++; print.line++;
print.printed = 0; print.printed = 0;
} }
if (options->no_line_commands) if (line >= print.line && line < print.line + 8)
{ {
print.lineno = line; while (line > print.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)
{ {
putc ('\n', print.outf); putc ('\n', print.outf);
print.lineno++; print.line++;
} }
} }
else else
{ print_line (line, "");
print.lineno = line;
print_line ("");
}
} }
static void static void
print_line (special_flags) print_line (line, special_flags)
const char *special_flags; unsigned int line;
const char *special_flags;
{ {
/* End any previous line of text. */ /* End any previous line of text. */
if (print.printed) if (print.printed)
putc ('\n', print.outf); putc ('\n', print.outf);
print.printed = 0; print.printed = 0;
fprintf (print.outf, "# %u \"%s\"%s%s\n", print.line = line;
print.lineno, print.last_fname, special_flags, print.syshdr_flags); 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. */ /* Callbacks. */
...@@ -348,21 +336,21 @@ print_line (special_flags) ...@@ -348,21 +336,21 @@ print_line (special_flags)
static void static void
cb_ident (pfile, line, str) cb_ident (pfile, line, str)
cpp_reader *pfile ATTRIBUTE_UNUSED; cpp_reader *pfile ATTRIBUTE_UNUSED;
unsigned int line ATTRIBUTE_UNUSED; unsigned int line;
const cpp_string * str; 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); fprintf (print.outf, "#ident \"%s\"\n", str->text);
print.lineno++; print.line++;
} }
static void static void
cb_define (pfile, line, node) cb_define (pfile, line, node)
cpp_reader *pfile; cpp_reader *pfile;
unsigned int line ATTRIBUTE_UNUSED; unsigned int line;
cpp_hashnode *node; cpp_hashnode *node;
{ {
maybe_print_line (cpp_get_line (pfile)->output_line); maybe_print_line (line);
fputs ("#define ", print.outf); fputs ("#define ", print.outf);
/* -dD command line option. */ /* -dD command line option. */
...@@ -372,30 +360,30 @@ cb_define (pfile, line, node) ...@@ -372,30 +360,30 @@ cb_define (pfile, line, node)
fputs ((const char *) NODE_NAME (node), print.outf); fputs ((const char *) NODE_NAME (node), print.outf);
putc ('\n', print.outf); putc ('\n', print.outf);
print.lineno++; print.line++;
} }
static void static void
cb_undef (pfile, line, node) cb_undef (pfile, line, node)
cpp_reader *pfile; cpp_reader *pfile ATTRIBUTE_UNUSED;
unsigned int line ATTRIBUTE_UNUSED; unsigned int line;
cpp_hashnode *node; 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)); fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
print.lineno++; print.line++;
} }
static void static void
cb_include (pfile, line, dir, header) cb_include (pfile, line, dir, header)
cpp_reader *pfile ATTRIBUTE_UNUSED; cpp_reader *pfile;
unsigned int line ATTRIBUTE_UNUSED; unsigned int line;
const unsigned char *dir; const unsigned char *dir;
const cpp_token *header; 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)); fprintf (print.outf, "#%s %s\n", dir, cpp_token_as_text (pfile, header));
print.lineno++; print.line++;
} }
static void static void
...@@ -403,12 +391,16 @@ cb_file_change (pfile, fc) ...@@ -403,12 +391,16 @@ cb_file_change (pfile, fc)
cpp_reader *pfile ATTRIBUTE_UNUSED; cpp_reader *pfile ATTRIBUTE_UNUSED;
const cpp_file_change *fc; const cpp_file_change *fc;
{ {
/* Bring current file to correct line (except first file). */ bool first_time = print.map == NULL;
if (fc->reason == LC_ENTER && !MAIN_FILE_P (fc->map))
maybe_print_line (SOURCE_LINE (fc->map - 1, fc->line - 1)); /* 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.map = fc->map;
print.last_fname = fc->map->to_file; print.filename = fc->map->to_file;
if (fc->externc) if (fc->externc)
print.syshdr_flags = " 3 4"; print.syshdr_flags = " 3 4";
else if (fc->sysp) else if (fc->sysp)
...@@ -416,18 +408,16 @@ cb_file_change (pfile, fc) ...@@ -416,18 +408,16 @@ cb_file_change (pfile, fc)
else else
print.syshdr_flags = ""; print.syshdr_flags = "";
if (print.lineno) if (!first_time)
{ {
const char *flags = ""; const char *flags = "";
print.lineno = SOURCE_LINE (fc->map, fc->line);
if (fc->reason == LC_ENTER) if (fc->reason == LC_ENTER)
flags = " 1"; flags = " 1";
else if (fc->reason == LC_LEAVE) else if (fc->reason == LC_LEAVE)
flags = " 2"; flags = " 2";
if (! options->no_line_commands) print_line (fc->line, flags);
print_line (flags);
} }
} }
...@@ -436,12 +426,12 @@ cb_file_change (pfile, fc) ...@@ -436,12 +426,12 @@ cb_file_change (pfile, fc)
static void static void
cb_def_pragma (pfile, line) cb_def_pragma (pfile, line)
cpp_reader *pfile; 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); fputs ("#pragma ", print.outf);
cpp_output_line (pfile, print.outf); cpp_output_line (pfile, print.outf);
print.lineno++; print.line++;
} }
/* Dump out the hash table. */ /* Dump out the hash table. */
...@@ -456,7 +446,7 @@ dump_macro (pfile, node, v) ...@@ -456,7 +446,7 @@ dump_macro (pfile, node, v)
fputs ("#define ", print.outf); fputs ("#define ", print.outf);
fputs ((const char *) cpp_macro_definition (pfile, node), print.outf); fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
putc ('\n', print.outf); putc ('\n', print.outf);
print.lineno++; print.line++;
} }
return 1; return 1;
......
...@@ -75,9 +75,12 @@ extern struct line_map *lookup_line ...@@ -75,9 +75,12 @@ extern struct line_map *lookup_line
/* Returns the last source line within a map. This is the (last) line /* Returns the last source line within a map. This is the (last) line
of the #include, or other directive, that caused a map change. */ of the #include, or other directive, that caused a map change. */
#define LAST_SOURCE_LINE(MAP) SOURCE_LINE (MAP, (MAP)[1].from_line - 1) #define LAST_SOURCE_LINE(MAP) SOURCE_LINE ((MAP), (MAP)[1].from_line - 1)
/* Non-zero if the map is at the bottom of the include stack. */ /* Non-zero if the map is at the bottom of the include stack. */
#define MAIN_FILE_P(MAP) ((MAP)->included_from < 0) #define MAIN_FILE_P(MAP) ((MAP)->included_from < 0)
/* The current line map. */
#define CURRENT_LINE_MAP(MAPS) ((MAPS)->maps + (MAPS)->used - 1)
#endif /* !GCC_LINE_MAP_H */ #endif /* !GCC_LINE_MAP_H */
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> 2001-08-03 Zack Weinberg <zackw@stanford.edu>
* gcc.dg/bconstp-1.c: New test. * gcc.dg/bconstp-1.c: New test.
......
/* { dg-do preprocess } */ /* { dg-do preprocess } */
/* { dg-error "include expects" "" { target *-*-* } 5 } */ /* { dg-error "include expects" "" { target *-*-* } 4 } */
/* { dg-error "newline at end" "" { target *-*-* } 5 } */ /* { dg-error "newline at end" "" { target *-*-* } 4 } */
#include /\ #include /\
...@@ -31,13 +31,6 @@ EMPTY #define bar ...@@ -31,13 +31,6 @@ EMPTY #define bar
func (2 /* { dg-error "unterminated" "" { target *-*-* } 32 } */ func (2 /* { dg-error "unterminated" "" { target *-*-* } 32 } */
#define foobar /* { dg-error "directives may not" } */ #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 /* Check newlines end directives, even in function-like macro
invocations. 6.10 paragraph 1. invocations. 6.10 paragraph 1.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment