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
This commit is contained in:
Neil Booth 2001-08-05 17:31:25 +00:00 committed by Neil Booth
parent 8125d7e9ad
commit 67821e3a9e
14 changed files with 296 additions and 252 deletions

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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. */

View file

@ -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,

View file

@ -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");
if (pfile->lexer_pos.col != 0)
{
/* 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)
{
bol = 1;
goto done_directive;
}
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)

View file

@ -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

View file

@ -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)
{
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++];
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

View file

@ -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;

View file

@ -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 */

View file

@ -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.

View file

@ -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 /\

View file

@ -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.