Commit bdcbe496 by Neil Booth Committed by Neil Booth

c-parse.in (_yylex): Use _cpp_backup_tokens.

	* c-parse.in (_yylex): Use _cpp_backup_tokens.
	* cpphash.h (struct tokenrun): Add prev.
	(struct lexer_state): Remove bol.
	(struct cpp_reader): Remove old lookahead stuff, add lookaheads.
	(_cpp_free_lookaheads, _cpp_release_lookahead, _cpp_push_token)
	: Remove.
	* cppinit.c (cpp_create_reader): Don't set bol.
	(cpp_destroy): Don't free lookaheads.
	* cpplex.c (lex_directive): Remove.
	(next_tokenrun): Update.
	(_cpp_lex_token): Clean up logic.
	(lex_token): Update to return a pointer to lexed token, since it
	can move to the start of the buffer.  Simpify newline handling.
	* cpplib.c (SEEN_EOL): Update.
	(skip_rest_of_line): Remove lookahead stuff.
	(end_directive): Line numbers are already incremented.  Revert
	to start of lexed token buffer if we can.
	(_cpp_handle_directive, do_pragma, do_pragma_dependency,
	parse_answer): Use _cpp_backup_tokens.
	(run_directive, cpp_pop_buffer): Don't set bol, set saved_flags
	instead.  Don't check for EOL.
	(do_include_common, do_line, do_pragma_system_header): Use
	skip_rest_of_line.
	* cpplib.h (BOL, _cpp_backup_tokens): New.
	* cppmacro.c (save_lookahead_token, take_lookahead_token,
	alloc_lookahead, free_lookahead, _cpp_free_lookaheads,
	cpp_start_lookahead, cpp_stop_lookahead, _cpp_push_token): Remove.
	(builtin_macro): Don't use cpp_get_line.
	(cpp_get_line): Short term kludge.
	(parse_arg): Handle directives in arguments here.  Back up when
	appropriate.  Store EOF at end of argument list.
	(funlike_invocation_p): Use _cpp_backup_tokens.
	(push_arg_context): Account for EOF at end of list.
	(cpp_get_token): Remove lookahead stuff.  Update.

	* gcc.dg/cpp/directiv.c: Update.
	* gcc.dg/cpp/undef1.c: Update.

From-SVN: r45582
parent 83182544
2001-09-13 Neil Booth <neil@daikokuya.demon.co.uk>
* c-parse.in (_yylex): Use _cpp_backup_tokens.
* cpphash.h (struct tokenrun): Add prev.
(struct lexer_state): Remove bol.
(struct cpp_reader): Remove old lookahead stuff, add lookaheads.
(_cpp_free_lookaheads, _cpp_release_lookahead, _cpp_push_token)
: Remove.
* cppinit.c (cpp_create_reader): Don't set bol.
(cpp_destroy): Don't free lookaheads.
* cpplex.c (lex_directive): Remove.
(next_tokenrun): Update.
(_cpp_lex_token): Clean up logic.
(lex_token): Update to return a pointer to lexed token, since it
can move to the start of the buffer. Simpify newline handling.
* cpplib.c (SEEN_EOL): Update.
(skip_rest_of_line): Remove lookahead stuff.
(end_directive): Line numbers are already incremented. Revert
to start of lexed token buffer if we can.
(_cpp_handle_directive, do_pragma, do_pragma_dependency,
parse_answer): Use _cpp_backup_tokens.
(run_directive, cpp_pop_buffer): Don't set bol, set saved_flags
instead. Don't check for EOL.
(do_include_common, do_line, do_pragma_system_header): Use
skip_rest_of_line.
* cpplib.h (BOL, _cpp_backup_tokens): New.
* cppmacro.c (save_lookahead_token, take_lookahead_token,
alloc_lookahead, free_lookahead, _cpp_free_lookaheads,
cpp_start_lookahead, cpp_stop_lookahead, _cpp_push_token): Remove.
(builtin_macro): Don't use cpp_get_line.
(cpp_get_line): Short term kludge.
(parse_arg): Handle directives in arguments here. Back up when
appropriate. Store EOF at end of argument list.
(funlike_invocation_p): Use _cpp_backup_tokens.
(push_arg_context): Account for EOF at end of list.
(cpp_get_token): Remove lookahead stuff. Update.
2001-09-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 2001-09-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* c-parse.in (yyerror): Const-ification and/or static-ization. * c-parse.in (yyerror): Const-ification and/or static-ization.
......
...@@ -3788,19 +3788,17 @@ ifobjc ...@@ -3788,19 +3788,17 @@ ifobjc
tree after_at; tree after_at;
enum cpp_ttype after_at_type; enum cpp_ttype after_at_type;
cpp_start_lookahead (parse_in);
after_at_type = c_lex (&after_at); after_at_type = c_lex (&after_at);
if (after_at_type == CPP_NAME if (after_at_type == CPP_NAME
&& C_IS_RESERVED_WORD (after_at) && C_IS_RESERVED_WORD (after_at)
&& OBJC_IS_AT_KEYWORD (C_RID_CODE (after_at))) && OBJC_IS_AT_KEYWORD (C_RID_CODE (after_at)))
{ {
cpp_stop_lookahead (parse_in, 1); /* accept this token */
yylval.ttype = after_at; yylval.ttype = after_at;
last_token = after_at_type; last_token = after_at_type;
return rid_to_yy [(int) C_RID_CODE (after_at)]; return rid_to_yy [(int) C_RID_CODE (after_at)];
} }
cpp_stop_lookahead (parse_in, 0); /* put back this token */ _cpp_backup_tokens (parse_in, 1);
return '@'; return '@';
} }
end ifobjc end ifobjc
......
...@@ -105,7 +105,7 @@ struct toklist ...@@ -105,7 +105,7 @@ struct toklist
typedef struct tokenrun tokenrun; typedef struct tokenrun tokenrun;
struct tokenrun struct tokenrun
{ {
tokenrun *next; tokenrun *next, *prev;
cpp_token *base, *limit; cpp_token *base, *limit;
}; };
...@@ -131,9 +131,6 @@ struct lexer_state ...@@ -131,9 +131,6 @@ struct lexer_state
/* True if we are skipping a failed conditional group. */ /* True if we are skipping a failed conditional group. */
unsigned char skipping; unsigned char skipping;
/* Nonzero if next token is the start of a line. */
unsigned char bol;
/* Nonzero if in a directive that takes angle-bracketed headers. */ /* Nonzero if in a directive that takes angle-bracketed headers. */
unsigned char angled_headers; unsigned char angled_headers;
...@@ -271,16 +268,11 @@ struct cpp_reader ...@@ -271,16 +268,11 @@ struct cpp_reader
/* Lexing. */ /* Lexing. */
cpp_token *cur_token; cpp_token *cur_token;
tokenrun base_run, *cur_run; tokenrun base_run, *cur_run;
unsigned int lookaheads;
/* Non-zero prevents the lexer from re-using the token runs. */ /* Non-zero prevents the lexer from re-using the token runs. */
unsigned int keep_tokens; unsigned int keep_tokens;
/* Token lookahead. */
struct cpp_lookahead *la_read; /* Read from this lookahead. */
struct cpp_lookahead *la_write; /* Write to this lookahead. */
struct cpp_lookahead *la_unused; /* Free store. */
struct cpp_lookahead *la_saved; /* Backup when entering directive. */
/* Error counter for exit code. */ /* Error counter for exit code. */
unsigned int errors; unsigned int errors;
...@@ -382,10 +374,6 @@ extern int _cpp_begin_message PARAMS ((cpp_reader *, enum error_type, ...@@ -382,10 +374,6 @@ extern int _cpp_begin_message PARAMS ((cpp_reader *, enum error_type,
extern void _cpp_free_definition PARAMS ((cpp_hashnode *)); extern void _cpp_free_definition PARAMS ((cpp_hashnode *));
extern int _cpp_create_definition PARAMS ((cpp_reader *, cpp_hashnode *)); extern int _cpp_create_definition PARAMS ((cpp_reader *, cpp_hashnode *));
extern void _cpp_pop_context PARAMS ((cpp_reader *)); extern void _cpp_pop_context PARAMS ((cpp_reader *));
extern void _cpp_free_lookaheads PARAMS ((cpp_reader *));
extern void _cpp_release_lookahead PARAMS ((cpp_reader *));
extern void _cpp_push_token PARAMS ((cpp_reader *, const cpp_token *,
const cpp_lexer_pos *));
/* In cpphash.c */ /* In cpphash.c */
extern void _cpp_init_hashtable PARAMS ((cpp_reader *, hash_table *)); extern void _cpp_init_hashtable PARAMS ((cpp_reader *, hash_table *));
......
...@@ -515,7 +515,6 @@ cpp_create_reader (table, lang) ...@@ -515,7 +515,6 @@ cpp_create_reader (table, lang)
_cpp_init_tokenrun (&pfile->base_run, 250); _cpp_init_tokenrun (&pfile->base_run, 250);
pfile->cur_run = &pfile->base_run; pfile->cur_run = &pfile->base_run;
pfile->cur_token = pfile->base_run.base; pfile->cur_token = pfile->base_run.base;
pfile->state.bol = 1;
/* Initialise the base context. */ /* Initialise the base context. */
pfile->context = &pfile->base_context; pfile->context = &pfile->base_context;
...@@ -581,7 +580,6 @@ cpp_destroy (pfile) ...@@ -581,7 +580,6 @@ cpp_destroy (pfile)
_cpp_destroy_hashtable (pfile); _cpp_destroy_hashtable (pfile);
_cpp_cleanup_includes (pfile); _cpp_cleanup_includes (pfile);
_cpp_free_lookaheads (pfile);
_cpp_free_pool (&pfile->ident_pool); _cpp_free_pool (&pfile->ident_pool);
_cpp_free_pool (&pfile->macro_pool); _cpp_free_pool (&pfile->macro_pool);
......
...@@ -102,8 +102,7 @@ static void lex_dot PARAMS ((cpp_reader *, cpp_token *)); ...@@ -102,8 +102,7 @@ static void lex_dot PARAMS ((cpp_reader *, cpp_token *));
static int name_p PARAMS ((cpp_reader *, const cpp_string *)); static int name_p PARAMS ((cpp_reader *, const cpp_string *));
static int maybe_read_ucs PARAMS ((cpp_reader *, const unsigned char **, static int maybe_read_ucs PARAMS ((cpp_reader *, const unsigned char **,
const unsigned char *, unsigned int *)); const unsigned char *, unsigned int *));
static int lex_directive PARAMS ((cpp_reader *)); static cpp_token *lex_token PARAMS ((cpp_reader *, cpp_token *));
static void lex_token PARAMS ((cpp_reader *, cpp_token *, int));
static tokenrun *next_tokenrun PARAMS ((tokenrun *)); static tokenrun *next_tokenrun PARAMS ((tokenrun *));
static cpp_chunk *new_chunk PARAMS ((unsigned int)); static cpp_chunk *new_chunk PARAMS ((unsigned int));
...@@ -925,114 +924,69 @@ next_tokenrun (run) ...@@ -925,114 +924,69 @@ next_tokenrun (run)
if (run->next == NULL) if (run->next == NULL)
{ {
run->next = xnew (tokenrun); run->next = xnew (tokenrun);
run->next->prev = run;
_cpp_init_tokenrun (run->next, 250); _cpp_init_tokenrun (run->next, 250);
} }
return run->next; return run->next;
} }
static int
lex_directive (pfile)
cpp_reader *pfile;
{
/* 6.10.3 paragraph 11: If there are sequences of preprocessing
tokens within the list of arguments that would otherwise act as
preprocessing directives, the behavior is undefined.
This implementation will report a hard error, terminate the 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");
pfile->state.bol = 1;
pfile->buffer->cur = pfile->buffer->line_base;
pfile->buffer->read_ahead = EOF;
pfile->cur_token->type = CPP_EOF;
}
return 0;
}
/* This is a directive. If the return value is false, it is an
assembler #. */
{
/* FIXME: short-term kludge only - it doesn't handle the case that
the # is at the end of a run and we moved to the start of the
next one. Easily fixed once we kill lookaheads. */
cpp_token *token = pfile->cur_token++;
if (_cpp_handle_directive (pfile, token->flags & PREV_WHITE))
return 1;
pfile->cur_token = token;
return 0;
}
}
/* Lex a token into RESULT (external interface). */ /* Lex a token into RESULT (external interface). */
void void
_cpp_lex_token (pfile, result) _cpp_lex_token (pfile, dest)
cpp_reader *pfile; cpp_reader *pfile;
cpp_token *result; cpp_token *dest;
{ {
if (pfile->cur_token == pfile->cur_run->limit) cpp_token *result;
{
pfile->cur_run = next_tokenrun (pfile->cur_run);
pfile->cur_token = pfile->cur_run->base;
}
next_token: for (;;)
if (pfile->state.bol)
{ {
start_new_line: if (pfile->cur_token == pfile->cur_run->limit)
pfile->state.bol = 0;
/* Return lexer back to base. */
if (!pfile->keep_tokens)
{ {
pfile->cur_run = &pfile->base_run; pfile->cur_run = next_tokenrun (pfile->cur_run);
pfile->cur_token = pfile->base_run.base; pfile->cur_token = pfile->cur_run->base;
} }
result = pfile->cur_token++;
lex_token (pfile, pfile->cur_token, 1); if (pfile->lookaheads)
pfile->lexer_pos.output_line = pfile->cur_token->line; pfile->lookaheads--;
if (pfile->cur_token->type == CPP_HASH && lex_directive (pfile)) else
goto start_new_line; result = lex_token (pfile, result);
}
else if (result->flags & BOL)
{
lex_token (pfile, pfile->cur_token, 0);
if (pfile->cur_token->type == CPP_EOF)
{ {
if (!pfile->state.in_directive) pfile->lexer_pos.output_line = result->line;
goto start_new_line; /* Is this a directive. If _cpp_handle_directive returns
/* Decrementing pfile->line allows directives to recognise false, it is an assembler #. */
that the newline has been seen, and also means that if (result->type == CPP_HASH
diagnostics don't point to the next line. */ && !pfile->state.parsing_args
pfile->lexer_pos.output_line = pfile->line--; && _cpp_handle_directive (pfile, result->flags & PREV_WHITE))
continue;
} }
}
if (!pfile->state.in_directive) /* We don't skip tokens in directives. */
{ if (pfile->state.in_directive)
if (pfile->state.skipping && pfile->cur_token->type != CPP_EOF) break;
goto next_token;
/* Outside a directive, invalidate controlling macros. */ /* Outside a directive, invalidate controlling macros. At file
EOF, lex_token takes care of popping the buffer, so we never
get here and MI optimisation works. */
pfile->mi_valid = false; pfile->mi_valid = false;
if (!pfile->state.skipping || result->type == CPP_EOF)
break;
} }
*result = *pfile->cur_token++; *dest = *result;
} }
/* Lex a token into RESULT (internal interface). */ /* Lex a token into RESULT. When meeting a newline, returns CPP_EOF
static void if parsing a directive, otherwise returns to the start of the token
lex_token (pfile, result, skip_newlines) buffer if permissible. Returns the location of the lexed token. */
static cpp_token *
lex_token (pfile, result)
cpp_reader *pfile; cpp_reader *pfile;
cpp_token *result; cpp_token *result;
int skip_newlines;
{ {
cppchar_t c; cppchar_t c;
cpp_buffer *buffer; cpp_buffer *buffer;
...@@ -1058,21 +1012,10 @@ lex_token (pfile, result, skip_newlines) ...@@ -1058,21 +1012,10 @@ lex_token (pfile, result, skip_newlines)
switch (c) switch (c)
{ {
case EOF: case EOF:
buffer->saved_flags = BOL;
if (!pfile->state.parsing_args && !pfile->state.in_directive) if (!pfile->state.parsing_args && !pfile->state.in_directive)
{ {
if (buffer->cur == buffer->line_base) if (buffer->cur != buffer->line_base)
{
/* Don't pop the last buffer. */
if (buffer->prev)
{
unsigned char stop = buffer->return_at_eof;
_cpp_pop_buffer (pfile);
if (!stop)
goto fresh_line;
}
}
else
{ {
/* Non-empty files should end in a newline. Don't warn /* Non-empty files should end in a newline. Don't warn
for command line and _Pragma buffers. */ for command line and _Pragma buffers. */
...@@ -1080,6 +1023,16 @@ lex_token (pfile, result, skip_newlines) ...@@ -1080,6 +1023,16 @@ lex_token (pfile, result, skip_newlines)
cpp_pedwarn (pfile, "no newline at end of file"); cpp_pedwarn (pfile, "no newline at end of file");
handle_newline (pfile, '\n'); handle_newline (pfile, '\n');
} }
/* Don't pop the last buffer. */
if (buffer->prev)
{
unsigned char stop = buffer->return_at_eof;
_cpp_pop_buffer (pfile);
if (!stop)
goto fresh_line;
}
} }
result->type = CPP_EOF; result->type = CPP_EOF;
break; break;
...@@ -1090,13 +1043,17 @@ lex_token (pfile, result, skip_newlines) ...@@ -1090,13 +1043,17 @@ lex_token (pfile, result, skip_newlines)
goto skipped_white; goto skipped_white;
case '\n': case '\r': case '\n': case '\r':
if (pfile->state.in_directive && pfile->state.parsing_args) handle_newline (pfile, c);
buffer->read_ahead = c; buffer->saved_flags = BOL;
else if (! pfile->state.in_directive)
{ {
handle_newline (pfile, c); if (!pfile->keep_tokens)
if (skip_newlines) {
goto fresh_line; pfile->cur_run = &pfile->base_run;
result = pfile->base_run.base;
pfile->cur_token = result + 1;
}
goto fresh_line;
} }
result->type = CPP_EOF; result->type = CPP_EOF;
break; break;
...@@ -1228,7 +1185,7 @@ lex_token (pfile, result, skip_newlines) ...@@ -1228,7 +1185,7 @@ lex_token (pfile, result, skip_newlines)
/* Save the comment as a token in its own right. */ /* Save the comment as a token in its own right. */
save_comment (pfile, result, comment_start); save_comment (pfile, result, comment_start);
/* Don't do MI optimisation. */ /* Don't do MI optimisation. */
return; break;
case '<': case '<':
if (pfile->state.angled_headers) if (pfile->state.angled_headers)
...@@ -1397,6 +1354,8 @@ lex_token (pfile, result, skip_newlines) ...@@ -1397,6 +1354,8 @@ lex_token (pfile, result, skip_newlines)
result->val.c = c; result->val.c = c;
break; break;
} }
return result;
} }
/* An upper bound on the number of bytes needed to spell a token, /* An upper bound on the number of bytes needed to spell a token,
......
...@@ -176,7 +176,7 @@ DIRECTIVE_TABLE ...@@ -176,7 +176,7 @@ DIRECTIVE_TABLE
#undef D #undef D
#undef DIRECTIVE_TABLE #undef DIRECTIVE_TABLE
#define SEEN_EOL() (pfile->lexer_pos.output_line > pfile->line) #define SEEN_EOL() (pfile->cur_token[-1].type == CPP_EOF)
/* Skip any remaining tokens in a directive. */ /* Skip any remaining tokens in a directive. */
static void static void
...@@ -185,10 +185,6 @@ skip_rest_of_line (pfile) ...@@ -185,10 +185,6 @@ skip_rest_of_line (pfile)
{ {
cpp_token token; cpp_token token;
/* Discard all input lookaheads. */
while (pfile->la_read)
_cpp_release_lookahead (pfile);
/* Discard all stacked contexts. */ /* Discard all stacked contexts. */
while (pfile->context != &pfile->base_context) while (pfile->context != &pfile->base_context)
_cpp_pop_context (pfile); _cpp_pop_context (pfile);
...@@ -227,10 +223,6 @@ start_directive (pfile) ...@@ -227,10 +223,6 @@ start_directive (pfile)
pfile->directive_pos = pfile->lexer_pos; pfile->directive_pos = pfile->lexer_pos;
pfile->directive_pos.line = pfile->line; pfile->directive_pos.line = pfile->line;
pfile->directive_line = pfile->line; pfile->directive_line = pfile->line;
/* Don't save directive tokens for external clients. */
pfile->la_saved = pfile->la_write;
pfile->la_write = 0;
} }
/* Called when leaving a directive, _Pragma or command-line directive. */ /* Called when leaving a directive, _Pragma or command-line directive. */
...@@ -243,12 +235,14 @@ end_directive (pfile, skip_line) ...@@ -243,12 +235,14 @@ end_directive (pfile, skip_line)
if (skip_line) if (skip_line)
{ {
skip_rest_of_line (pfile); skip_rest_of_line (pfile);
/* "Accept" the newline now. */ if (!pfile->keep_tokens)
pfile->line++; {
pfile->cur_run = &pfile->base_run;
pfile->cur_token = pfile->base_run.base;
}
} }
/* Restore state. */ /* Restore state. */
pfile->la_write = pfile->la_saved;
pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments); pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
pfile->state.in_directive = 0; pfile->state.in_directive = 0;
pfile->state.angled_headers = 0; pfile->state.angled_headers = 0;
...@@ -289,7 +283,7 @@ _cpp_handle_directive (pfile, indented) ...@@ -289,7 +283,7 @@ _cpp_handle_directive (pfile, indented)
{ {
dir = &dtable[T_LINE]; dir = &dtable[T_LINE];
pfile->state.line_extension = 1; pfile->state.line_extension = 1;
_cpp_push_token (pfile, &dname, &pfile->directive_pos); _cpp_backup_tokens (pfile, 1);
if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, preprocessed)) if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, preprocessed))
cpp_pedwarn (pfile, "# followed by integer"); cpp_pedwarn (pfile, "# followed by integer");
} }
...@@ -324,7 +318,7 @@ _cpp_handle_directive (pfile, indented) ...@@ -324,7 +318,7 @@ _cpp_handle_directive (pfile, indented)
/* We don't want to process this directive. Put back the /* We don't want to process this directive. Put back the
tokens so caller will see them (and issue an error, tokens so caller will see them (and issue an error,
probably). */ probably). */
_cpp_push_token (pfile, &dname, &pfile->directive_pos); _cpp_backup_tokens (pfile, 1);
skip = 0; skip = 0;
} }
} }
...@@ -376,8 +370,8 @@ _cpp_handle_directive (pfile, indented) ...@@ -376,8 +370,8 @@ _cpp_handle_directive (pfile, indented)
directives in skipped conditional groups (6.10 p4). */ directives in skipped conditional groups (6.10 p4). */
if (CPP_OPTION (pfile, lang) == CLK_ASM) if (CPP_OPTION (pfile, lang) == CLK_ASM)
{ {
/* Output the # and lookahead token for the assembler. */ /* Output the # and this token for the assembler. */
_cpp_push_token (pfile, &dname, &pfile->directive_pos); _cpp_backup_tokens (pfile, 1);
skip = 0; skip = 0;
} }
else else
...@@ -402,12 +396,11 @@ run_directive (pfile, dir_no, buf, count) ...@@ -402,12 +396,11 @@ run_directive (pfile, dir_no, buf, count)
cpp_push_buffer (pfile, (const U_CHAR *) buf, count, cpp_push_buffer (pfile, (const U_CHAR *) buf, count,
/* from_stage3 */ true, 1); /* from_stage3 */ true, 1);
start_directive (pfile); start_directive (pfile);
pfile->state.bol = 0; pfile->buffer->saved_flags = 0; /* We don't want to recognise directives. */
pfile->state.prevent_expansion++; pfile->state.prevent_expansion++;
pfile->directive = &dtable[dir_no]; pfile->directive = &dtable[dir_no];
(void) (*pfile->directive->handler) (pfile); (void) (*pfile->directive->handler) (pfile);
pfile->state.prevent_expansion--; pfile->state.prevent_expansion--;
check_eol (pfile);
end_directive (pfile, 1); end_directive (pfile, 1);
_cpp_pop_buffer (pfile); _cpp_pop_buffer (pfile);
} }
...@@ -618,7 +611,7 @@ do_include_common (pfile, type) ...@@ -618,7 +611,7 @@ do_include_common (pfile, type)
{ {
check_eol (pfile); check_eol (pfile);
/* Get out of macro context, if we are. */ /* Get out of macro context, if we are. */
end_directive (pfile, 1); skip_rest_of_line (pfile);
if (pfile->cb.include) if (pfile->cb.include)
(*pfile->cb.include) (pfile, pfile->directive_line, (*pfile->cb.include) (pfile, pfile->directive_line,
pfile->directive->name, &header); pfile->directive->name, &header);
...@@ -772,7 +765,7 @@ do_line (pfile) ...@@ -772,7 +765,7 @@ do_line (pfile)
return; return;
} }
end_directive (pfile, 1); skip_rest_of_line (pfile);
_cpp_do_file_change (pfile, reason, new_file, new_lineno, new_sysp); _cpp_do_file_change (pfile, reason, new_file, new_lineno, new_sysp);
} }
...@@ -961,12 +954,13 @@ do_pragma (pfile) ...@@ -961,12 +954,13 @@ do_pragma (pfile)
pragma_cb handler = NULL; pragma_cb handler = NULL;
const struct pragma_entry *p; const struct pragma_entry *p;
cpp_token tok; cpp_token tok;
unsigned int count = 0;
p = pfile->pragmas; p = pfile->pragmas;
pfile->state.prevent_expansion++; pfile->state.prevent_expansion++;
cpp_start_lookahead (pfile);
new_space: new_space:
count++;
cpp_get_token (pfile, &tok); cpp_get_token (pfile, &tok);
if (tok.type == CPP_NAME) if (tok.type == CPP_NAME)
{ {
...@@ -993,13 +987,14 @@ do_pragma (pfile) ...@@ -993,13 +987,14 @@ do_pragma (pfile)
} }
} }
cpp_stop_lookahead (pfile, handler != NULL);
pfile->state.prevent_expansion--; pfile->state.prevent_expansion--;
if (handler) if (handler)
(*handler) (pfile); (*handler) (pfile);
else if (pfile->cb.def_pragma) else if (pfile->cb.def_pragma)
(*pfile->cb.def_pragma) (pfile, pfile->directive_line); {
_cpp_backup_tokens (pfile, count);
(*pfile->cb.def_pragma) (pfile, pfile->directive_line);
}
} }
static void static void
...@@ -1066,7 +1061,7 @@ do_pragma_system_header (pfile) ...@@ -1066,7 +1061,7 @@ do_pragma_system_header (pfile)
else else
{ {
check_eol (pfile); check_eol (pfile);
end_directive (pfile, 1); skip_rest_of_line (pfile);
cpp_make_system_header (pfile, 1, 0); cpp_make_system_header (pfile, 1, 0);
} }
} }
...@@ -1092,11 +1087,12 @@ do_pragma_dependency (pfile) ...@@ -1092,11 +1087,12 @@ do_pragma_dependency (pfile)
{ {
cpp_warning (pfile, "current file is older than %s", cpp_warning (pfile, "current file is older than %s",
cpp_token_as_text (pfile, &header)); cpp_token_as_text (pfile, &header));
cpp_start_lookahead (pfile);
cpp_get_token (pfile, &msg); cpp_get_token (pfile, &msg);
cpp_stop_lookahead (pfile, msg.type == CPP_EOF);
if (msg.type != CPP_EOF) if (msg.type != CPP_EOF)
do_diagnostic (pfile, WARNING, 0); {
_cpp_backup_tokens (pfile, 1);
do_diagnostic (pfile, WARNING, 0);
}
} }
} }
...@@ -1387,11 +1383,7 @@ parse_answer (pfile, answerp, type) ...@@ -1387,11 +1383,7 @@ parse_answer (pfile, answerp, type)
/* In a conditional, it is legal to not have an open paren. We /* In a conditional, it is legal to not have an open paren. We
should save the following token in this case. */ should save the following token in this case. */
if (type == T_IF)
cpp_start_lookahead (pfile);
cpp_get_token (pfile, &paren); cpp_get_token (pfile, &paren);
if (type == T_IF)
cpp_stop_lookahead (pfile, paren.type == CPP_OPEN_PAREN);
/* If not a paren, see if we're OK. */ /* If not a paren, see if we're OK. */
if (paren.type != CPP_OPEN_PAREN) if (paren.type != CPP_OPEN_PAREN)
...@@ -1399,7 +1391,10 @@ parse_answer (pfile, answerp, type) ...@@ -1399,7 +1391,10 @@ parse_answer (pfile, answerp, type)
/* In a conditional no answer is a test for any answer. It /* In a conditional no answer is a test for any answer. It
could be followed by any token. */ could be followed by any token. */
if (type == T_IF) if (type == T_IF)
return 0; {
_cpp_backup_tokens (pfile, 1);
return 0;
}
/* #unassert with no answer is valid - it removes all answers. */ /* #unassert with no answer is valid - it removes all answers. */
if (type == T_UNASSERT && paren.type == CPP_EOF) if (type == T_UNASSERT && paren.type == CPP_EOF)
...@@ -1755,6 +1750,7 @@ cpp_push_buffer (pfile, buffer, len, from_stage3, return_at_eof) ...@@ -1755,6 +1750,7 @@ cpp_push_buffer (pfile, buffer, len, from_stage3, return_at_eof)
new->from_stage3 = from_stage3; new->from_stage3 = from_stage3;
new->prev = pfile->buffer; new->prev = pfile->buffer;
new->return_at_eof = return_at_eof; new->return_at_eof = return_at_eof;
new->saved_flags = BOL;
pfile->buffer = new; pfile->buffer = new;
...@@ -1783,7 +1779,6 @@ _cpp_pop_buffer (pfile) ...@@ -1783,7 +1779,6 @@ _cpp_pop_buffer (pfile)
case of a missing #endif. */ case of a missing #endif. */
pfile->lexer_pos.output_line = pfile->line; pfile->lexer_pos.output_line = pfile->line;
pfile->state.skipping = 0; pfile->state.skipping = 0;
pfile->state.bol = 1;
/* Update the reader's buffer before _cpp_do_file_change. */ /* Update the reader's buffer before _cpp_do_file_change. */
pfile->buffer = buffer->prev; pfile->buffer = buffer->prev;
......
...@@ -167,6 +167,7 @@ struct cpp_string ...@@ -167,6 +167,7 @@ struct cpp_string
#define NAMED_OP (1 << 4) /* C++ named operators. */ #define NAMED_OP (1 << 4) /* C++ named operators. */
#define NO_EXPAND (1 << 5) /* Do not macro-expand this token. */ #define NO_EXPAND (1 << 5) /* Do not macro-expand this token. */
#define AVOID_LPASTE (1 << 6) /* Check left for accidental pastes. */ #define AVOID_LPASTE (1 << 6) /* Check left for accidental pastes. */
#define BOL (1 << 7) /* Token at beginning of line. */
/* A preprocessing token. This has been carefully packed and should /* A preprocessing token. This has been carefully packed and should
occupy 12 bytes on 32-bit hosts and 16 bytes on 64-bit hosts. */ occupy 12 bytes on 32-bit hosts and 16 bytes on 64-bit hosts. */
...@@ -524,6 +525,7 @@ extern void cpp_get_token PARAMS ((cpp_reader *, cpp_token *)); ...@@ -524,6 +525,7 @@ extern void cpp_get_token PARAMS ((cpp_reader *, cpp_token *));
extern const cpp_lexer_pos *cpp_get_line PARAMS ((cpp_reader *)); extern const cpp_lexer_pos *cpp_get_line PARAMS ((cpp_reader *));
extern const unsigned char *cpp_macro_definition PARAMS ((cpp_reader *, extern const unsigned char *cpp_macro_definition PARAMS ((cpp_reader *,
const cpp_hashnode *)); const cpp_hashnode *));
extern void _cpp_backup_tokens PARAMS ((cpp_reader *, unsigned int));
/* Evaluate a CPP_CHAR or CPP_WCHAR token. */ /* Evaluate a CPP_CHAR or CPP_WCHAR token. */
extern HOST_WIDE_INT extern HOST_WIDE_INT
......
...@@ -77,13 +77,6 @@ static int funlike_invocation_p PARAMS ((cpp_reader *, const cpp_hashnode *, ...@@ -77,13 +77,6 @@ static int funlike_invocation_p PARAMS ((cpp_reader *, const cpp_hashnode *,
static void replace_args PARAMS ((cpp_reader *, cpp_macro *, macro_arg *, static void replace_args PARAMS ((cpp_reader *, cpp_macro *, macro_arg *,
struct toklist *)); struct toklist *));
/* Lookaheads. */
static void save_lookahead_token PARAMS ((cpp_reader *, const cpp_token *));
static void take_lookahead_token PARAMS ((cpp_reader *, cpp_token *));
static cpp_lookahead *alloc_lookahead PARAMS ((cpp_reader *));
static void free_lookahead PARAMS ((cpp_lookahead *));
/* #define directive parsing and handling. */ /* #define directive parsing and handling. */
static cpp_token *lex_expansion_token PARAMS ((cpp_reader *, cpp_macro *)); static cpp_token *lex_expansion_token PARAMS ((cpp_reader *, cpp_macro *));
...@@ -175,7 +168,7 @@ builtin_macro (pfile, token) ...@@ -175,7 +168,7 @@ builtin_macro (pfile, token)
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, make_number_token (pfile, token,
SOURCE_LINE (pfile->map, cpp_get_line (pfile)->line)); SOURCE_LINE (pfile->map, pfile->cur_token[-1].line));
break; break;
case BT_STDC: case BT_STDC:
...@@ -224,6 +217,12 @@ const cpp_lexer_pos * ...@@ -224,6 +217,12 @@ const cpp_lexer_pos *
cpp_get_line (pfile) cpp_get_line (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
if (pfile->context->prev == NULL)
{
pfile->lexer_pos.line = pfile->cur_token[-1].line;
pfile->lexer_pos.col = pfile->cur_token[-1].col;
}
return &pfile->lexer_pos; return &pfile->lexer_pos;
} }
...@@ -486,10 +485,12 @@ parse_arg (pfile, arg, variadic) ...@@ -486,10 +485,12 @@ 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->line; line = pfile->line;
cpp_get_token (pfile, token); cpp_get_token (pfile, token);
if (line != pfile->line) if (line != pfile->line)
token->flags |= PREV_WHITE; token->flags |= PREV_WHITE;
result = token->type; result = token->type;
if (result == CPP_OPEN_PAREN) if (result == CPP_OPEN_PAREN)
paren++; paren++;
else if (result == CPP_CLOSE_PAREN && paren-- == 0) else if (result == CPP_CLOSE_PAREN && paren-- == 0)
...@@ -498,11 +499,37 @@ parse_arg (pfile, arg, variadic) ...@@ -498,11 +499,37 @@ parse_arg (pfile, arg, variadic)
else if (result == CPP_COMMA && paren == 0 && !variadic) else if (result == CPP_COMMA && paren == 0 && !variadic)
break; break;
else if (result == CPP_EOF) else if (result == CPP_EOF)
break; /* Error reported by caller. */ {
/* We still need the EOF (added below) to end pre-expansion
and directives. */
if (pfile->context->prev || pfile->state.in_directive)
_cpp_backup_tokens (pfile, 1);
/* Error reported by caller. */
break;
}
else if (result == CPP_HASH && token->flags & BOL)
{
/* 6.10.3 paragraph 11: If there are sequences of
preprocessing tokens within the list of arguments that
would otherwise act as preprocessing directives, the
behavior is undefined.
This implementation will report a hard error, terminate
the macro invocation, and proceed to process the
directive. */
cpp_error (pfile,
"directives may not be used inside a macro argument");
_cpp_backup_tokens (pfile, 1);
result = CPP_EOF;
break;
}
} }
/* Commit the memory used to store the arguments. */ /* Commit the memory used to store the arguments. We make the last
POOL_COMMIT (&pfile->argument_pool, arg->count * sizeof (cpp_token)); argument a CPP_EOF, so that it terminates macro pre-expansion,
but it is not included in arg->count. */
arg->first[arg->count].type = CPP_EOF;
POOL_COMMIT (&pfile->argument_pool, (arg->count + 1) * sizeof (cpp_token));
return result; return result;
} }
...@@ -600,17 +627,19 @@ funlike_invocation_p (pfile, node, list) ...@@ -600,17 +627,19 @@ funlike_invocation_p (pfile, node, list)
pfile->state.prevent_expansion++; pfile->state.prevent_expansion++;
pfile->keep_tokens++; pfile->keep_tokens++;
cpp_start_lookahead (pfile);
cpp_get_token (pfile, &maybe_paren); cpp_get_token (pfile, &maybe_paren);
cpp_stop_lookahead (pfile, maybe_paren.type == CPP_OPEN_PAREN);
pfile->state.parsing_args = 2; pfile->state.parsing_args = 2;
if (maybe_paren.type == CPP_OPEN_PAREN) if (maybe_paren.type == CPP_OPEN_PAREN)
args = parse_args (pfile, node); args = parse_args (pfile, node);
else if (CPP_WTRADITIONAL (pfile) && ! node->value.macro->syshdr) else
cpp_warning (pfile, {
"function-like macro \"%s\" must be used with arguments in traditional C", _cpp_backup_tokens (pfile, 1);
NODE_NAME (node)); if (CPP_WTRADITIONAL (pfile) && ! node->value.macro->syshdr)
cpp_warning (pfile,
"function-like macro \"%s\" must be used with arguments in traditional C",
NODE_NAME (node));
}
pfile->state.prevent_expansion--; pfile->state.prevent_expansion--;
pfile->state.parsing_args = 0; pfile->state.parsing_args = 0;
...@@ -623,13 +652,7 @@ funlike_invocation_p (pfile, node, list) ...@@ -623,13 +652,7 @@ funlike_invocation_p (pfile, node, list)
if (args) if (args)
{ {
if (node->value.macro->paramc > 0) if (node->value.macro->paramc > 0)
{ replace_args (pfile, node->value.macro, args, list);
/* Don't save tokens during pre-expansion. */
struct cpp_lookahead *la_saved = pfile->la_write;
pfile->la_write = 0;
replace_args (pfile, node->value.macro, args, list);
pfile->la_write = la_saved;
}
free (args); free (args);
} }
...@@ -838,7 +861,7 @@ push_arg_context (pfile, arg) ...@@ -838,7 +861,7 @@ push_arg_context (pfile, arg)
cpp_context *context = next_context (pfile); cpp_context *context = next_context (pfile);
context->macro = 0; context->macro = 0;
context->list.first = arg->first; context->list.first = arg->first;
context->list.limit = arg->first + arg->count; context->list.limit = arg->first + arg->count + 1;
return context; return context;
} }
...@@ -908,10 +931,8 @@ cpp_get_token (pfile, token) ...@@ -908,10 +931,8 @@ cpp_get_token (pfile, token)
{ {
cpp_context *context = pfile->context; cpp_context *context = pfile->context;
if (pfile->la_read)
take_lookahead_token (pfile, token);
/* Context->prev == 0 <=> base context. */ /* Context->prev == 0 <=> base context. */
else if (!context->prev) if (!context->prev)
_cpp_lex_token (pfile, token); _cpp_lex_token (pfile, token);
else if (context->list.first != context->list.limit) else if (context->list.first != context->list.limit)
{ {
...@@ -928,17 +949,13 @@ cpp_get_token (pfile, token) ...@@ -928,17 +949,13 @@ cpp_get_token (pfile, token)
} }
else else
{ {
if (context->macro) if (!context->macro)
{ cpp_ice (pfile, "context->macro == 0");
/* Avoid accidental paste at the end of a macro. */
pfile->buffer->saved_flags |= AVOID_LPASTE; /* Avoid accidental paste at the end of a macro. */
_cpp_pop_context (pfile); pfile->buffer->saved_flags |= AVOID_LPASTE;
continue; _cpp_pop_context (pfile);
} continue;
/* End of argument pre-expansion. */
token->type = CPP_EOF;
token->flags = 0;
return;
} }
if (token->type != CPP_NAME) if (token->type != CPP_NAME)
...@@ -983,9 +1000,6 @@ cpp_get_token (pfile, token) ...@@ -983,9 +1000,6 @@ cpp_get_token (pfile, token)
since this token came from either the lexer or a macro. */ since this token came from either the lexer or a macro. */
_cpp_do__Pragma (pfile); _cpp_do__Pragma (pfile);
} }
if (pfile->la_write)
save_lookahead_token (pfile, token);
} }
/* Returns true if we're expanding an object-like macro that was /* Returns true if we're expanding an object-like macro that was
...@@ -1013,154 +1027,36 @@ cpp_scan_nooutput (pfile) ...@@ -1013,154 +1027,36 @@ cpp_scan_nooutput (pfile)
while (token.type != CPP_EOF); while (token.type != CPP_EOF);
} }
/* Lookahead handling. */ /* Step back one (or more) tokens. Can only step mack more than 1 if
they are from the lexer, and not from macro expansion. */
static void
save_lookahead_token (pfile, token)
cpp_reader *pfile;
const cpp_token *token;
{
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);
}
static void
take_lookahead_token (pfile, token)
cpp_reader *pfile;
cpp_token *token;
{
cpp_lookahead *la = pfile->la_read;
cpp_token_with_pos *twp = &la->tokens[la->cur];
*token = twp->token;
pfile->lexer_pos = twp->pos;
if (++la->cur == la->count)
_cpp_release_lookahead (pfile);
}
/* Moves the lookahead at the front of the read list to the free store. */
void void
_cpp_release_lookahead (pfile) _cpp_backup_tokens (pfile, count)
cpp_reader *pfile; cpp_reader *pfile;
unsigned int count;
{ {
cpp_lookahead *la = pfile->la_read; if (pfile->context->prev == NULL)
pfile->la_read = la->next;
la->next = pfile->la_unused;
pfile->la_unused = la;
unlock_pools (pfile);
}
/* Take a new lookahead from the free store, or allocate one if none. */
static cpp_lookahead *
alloc_lookahead (pfile)
cpp_reader *pfile;
{
cpp_lookahead *la = pfile->la_unused;
if (la)
pfile->la_unused = la->next;
else
{ {
la = xnew (cpp_lookahead); pfile->lookaheads += count;
la->tokens = 0; while (count--)
la->cap = 0; {
pfile->cur_token--;
if (pfile->cur_token == pfile->cur_run->base)
{
if (pfile->cur_run == NULL)
abort ();
pfile->cur_run = pfile->cur_run->prev;
pfile->cur_token = pfile->cur_run->limit;
}
}
} }
else
la->cur = la->count = 0;
return la;
}
/* Free memory associated with a lookahead list. */
static void
free_lookahead (la)
cpp_lookahead *la;
{
if (la->tokens)
free ((PTR) la->tokens);
free ((PTR) la);
}
/* Free all the lookaheads of a cpp_reader. */
void
_cpp_free_lookaheads (pfile)
cpp_reader *pfile;
{
cpp_lookahead *la, *lan;
if (pfile->la_read)
free_lookahead (pfile->la_read);
if (pfile->la_write)
free_lookahead (pfile->la_write);
for (la = pfile->la_unused; la; la = lan)
{ {
lan = la->next; if (count != 1)
free_lookahead (la); abort ();
pfile->context->list.first--;
} }
} }
/* Allocate a lookahead and move it to the front of the write list. */
void
cpp_start_lookahead (pfile)
cpp_reader *pfile;
{
cpp_lookahead *la = alloc_lookahead (pfile);
la->next = pfile->la_write;
pfile->la_write = la;
la->pos = *cpp_get_line (pfile);
/* Don't allow memory pools to be re-used whilst we're reading ahead. */
lock_pools (pfile);
}
/* Stop reading ahead - either step back, or drop the read ahead. */
void
cpp_stop_lookahead (pfile, drop)
cpp_reader *pfile;
int drop;
{
cpp_lookahead *la = pfile->la_write;
pfile->la_write = la->next;
la->next = pfile->la_read;
pfile->la_read = la;
if (drop || la->count == 0)
_cpp_release_lookahead (pfile);
else
pfile->lexer_pos = la->pos;
}
/* Push a single token back to the front of the queue. Only to be
used by cpplib, and only then when necessary. POS is the position
to report for the preceding token. */
void
_cpp_push_token (pfile, token, pos)
cpp_reader *pfile;
const cpp_token *token;
const cpp_lexer_pos *pos;
{
cpp_start_lookahead (pfile);
save_lookahead_token (pfile, token);
cpp_stop_lookahead (pfile, 0);
pfile->lexer_pos = *pos;
}
/* #define directive parsing and handling. */ /* #define directive parsing and handling. */
/* Returns non-zero if a macro redefinition warning is required. */ /* Returns non-zero if a macro redefinition warning is required. */
......
2001-09-13 Neil Booth <neil@daikokuya.demon.co.uk>
* gcc.dg/cpp/directiv.c: Update.
* gcc.dg/cpp/undef1.c: Update.
2001-09-12 Jakub Jelinek <jakub@redhat.com> 2001-09-12 Jakub Jelinek <jakub@redhat.com>
* gcc.dg/20010912-1.c: New test. * gcc.dg/20010912-1.c: New test.
......
...@@ -28,7 +28,7 @@ EMPTY #define bar ...@@ -28,7 +28,7 @@ EMPTY #define bar
/* Check that directives always start a line, even if in middle of /* Check that directives always start a line, even if in middle of
macro expansion. */ macro expansion. */
#define func(x) x #define func(x) x
func (2 /* { dg-error "unterminated" "" { target *-*-* } 32 } */ func (2 /* { dg-error "unterminated" "" } */
#define foobar /* { dg-error "directives may not" } */ #define foobar /* { dg-error "directives may not" } */
/* Check newlines end directives, even in function-like macro /* Check newlines end directives, even in function-like macro
......
...@@ -9,6 +9,6 @@ ...@@ -9,6 +9,6 @@
#define foo(bar) bar #define foo(bar) bar
foo( blah /* { dg-error "unterminated" "" { target *-*-* } 13 } */ foo( blah /* { dg-error "unterminated" "" } */
#undef foo /* { dg-error "may not be used inside" "foo(#undef foo)" } */ #undef foo /* { dg-error "may not be used inside" "foo(#undef foo)" } */
blah ) blah )
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