* 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
+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>
* c-parse.in (yyerror): Const-ification and/or static-ization.
tree after_at;
enum cpp_ttype after_at_type;
- cpp_start_lookahead (parse_in);
after_at_type = c_lex (&after_at);
if (after_at_type == CPP_NAME
&& C_IS_RESERVED_WORD (after_at)
&& OBJC_IS_AT_KEYWORD (C_RID_CODE (after_at)))
{
- cpp_stop_lookahead (parse_in, 1); /* accept this token */
yylval.ttype = after_at;
last_token = after_at_type;
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 '@';
}
end ifobjc
typedef struct tokenrun tokenrun;
struct tokenrun
{
- tokenrun *next;
+ tokenrun *next, *prev;
cpp_token *base, *limit;
};
/* True if we are skipping a failed conditional group. */
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. */
unsigned char angled_headers;
/* Lexing. */
cpp_token *cur_token;
tokenrun base_run, *cur_run;
+ unsigned int lookaheads;
/* Non-zero prevents the lexer from re-using the token runs. */
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. */
unsigned int errors;
extern void _cpp_free_definition PARAMS ((cpp_hashnode *));
extern int _cpp_create_definition PARAMS ((cpp_reader *, cpp_hashnode *));
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 */
extern void _cpp_init_hashtable PARAMS ((cpp_reader *, hash_table *));
_cpp_init_tokenrun (&pfile->base_run, 250);
pfile->cur_run = &pfile->base_run;
pfile->cur_token = pfile->base_run.base;
- pfile->state.bol = 1;
/* Initialise the base context. */
pfile->context = &pfile->base_context;
_cpp_destroy_hashtable (pfile);
_cpp_cleanup_includes (pfile);
- _cpp_free_lookaheads (pfile);
_cpp_free_pool (&pfile->ident_pool);
_cpp_free_pool (&pfile->macro_pool);
static int name_p PARAMS ((cpp_reader *, const cpp_string *));
static int maybe_read_ucs PARAMS ((cpp_reader *, const unsigned char **,
const unsigned char *, unsigned int *));
-static int lex_directive PARAMS ((cpp_reader *));
-static void lex_token PARAMS ((cpp_reader *, cpp_token *, int));
+static cpp_token *lex_token PARAMS ((cpp_reader *, cpp_token *));
static tokenrun *next_tokenrun PARAMS ((tokenrun *));
static cpp_chunk *new_chunk PARAMS ((unsigned int));
if (run->next == NULL)
{
run->next = xnew (tokenrun);
+ run->next->prev = run;
_cpp_init_tokenrun (run->next, 250);
}
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). */
void
-_cpp_lex_token (pfile, result)
+_cpp_lex_token (pfile, dest)
cpp_reader *pfile;
- cpp_token *result;
+ cpp_token *dest;
{
- if (pfile->cur_token == pfile->cur_run->limit)
- {
- pfile->cur_run = next_tokenrun (pfile->cur_run);
- pfile->cur_token = pfile->cur_run->base;
- }
+ cpp_token *result;
- next_token:
- if (pfile->state.bol)
+ for (;;)
{
- start_new_line:
- pfile->state.bol = 0;
-
- /* Return lexer back to base. */
- if (!pfile->keep_tokens)
+ if (pfile->cur_token == pfile->cur_run->limit)
{
- pfile->cur_run = &pfile->base_run;
- pfile->cur_token = pfile->base_run.base;
+ pfile->cur_run = next_tokenrun (pfile->cur_run);
+ pfile->cur_token = pfile->cur_run->base;
}
+ result = pfile->cur_token++;
- lex_token (pfile, pfile->cur_token, 1);
- pfile->lexer_pos.output_line = pfile->cur_token->line;
- if (pfile->cur_token->type == CPP_HASH && lex_directive (pfile))
- goto start_new_line;
- }
- else
- {
- lex_token (pfile, pfile->cur_token, 0);
- if (pfile->cur_token->type == CPP_EOF)
+ if (pfile->lookaheads)
+ pfile->lookaheads--;
+ else
+ result = lex_token (pfile, result);
+
+ if (result->flags & BOL)
{
- if (!pfile->state.in_directive)
- goto start_new_line;
- /* 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--;
+ pfile->lexer_pos.output_line = result->line;
+ /* Is this a directive. If _cpp_handle_directive returns
+ false, it is an assembler #. */
+ if (result->type == CPP_HASH
+ && !pfile->state.parsing_args
+ && _cpp_handle_directive (pfile, result->flags & PREV_WHITE))
+ continue;
}
- }
- if (!pfile->state.in_directive)
- {
- if (pfile->state.skipping && pfile->cur_token->type != CPP_EOF)
- goto next_token;
+ /* We don't skip tokens in directives. */
+ if (pfile->state.in_directive)
+ break;
- /* 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;
+
+ if (!pfile->state.skipping || result->type == CPP_EOF)
+ break;
}
- *result = *pfile->cur_token++;
+ *dest = *result;
}
-/* Lex a token into RESULT (internal interface). */
-static void
-lex_token (pfile, result, skip_newlines)
+/* Lex a token into RESULT. When meeting a newline, returns CPP_EOF
+ if parsing a directive, otherwise returns to the start of the token
+ buffer if permissible. Returns the location of the lexed token. */
+static cpp_token *
+lex_token (pfile, result)
cpp_reader *pfile;
cpp_token *result;
- int skip_newlines;
{
cppchar_t c;
cpp_buffer *buffer;
switch (c)
{
case EOF:
+ buffer->saved_flags = BOL;
if (!pfile->state.parsing_args && !pfile->state.in_directive)
{
- 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
+ if (buffer->cur != buffer->line_base)
{
/* Non-empty files should end in a newline. Don't warn
for command line and _Pragma buffers. */
cpp_pedwarn (pfile, "no newline at end of file");
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;
break;
goto skipped_white;
case '\n': case '\r':
- if (pfile->state.in_directive && pfile->state.parsing_args)
- buffer->read_ahead = c;
- else
+ handle_newline (pfile, c);
+ buffer->saved_flags = BOL;
+ if (! pfile->state.in_directive)
{
- handle_newline (pfile, c);
- if (skip_newlines)
- goto fresh_line;
+ if (!pfile->keep_tokens)
+ {
+ pfile->cur_run = &pfile->base_run;
+ result = pfile->base_run.base;
+ pfile->cur_token = result + 1;
+ }
+ goto fresh_line;
}
result->type = CPP_EOF;
break;
/* Save the comment as a token in its own right. */
save_comment (pfile, result, comment_start);
/* Don't do MI optimisation. */
- return;
+ break;
case '<':
if (pfile->state.angled_headers)
result->val.c = c;
break;
}
+
+ return result;
}
/* An upper bound on the number of bytes needed to spell a token,
#undef D
#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. */
static void
{
cpp_token token;
- /* Discard all input lookaheads. */
- while (pfile->la_read)
- _cpp_release_lookahead (pfile);
-
/* Discard all stacked contexts. */
while (pfile->context != &pfile->base_context)
_cpp_pop_context (pfile);
pfile->directive_pos = pfile->lexer_pos;
pfile->directive_pos.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. */
if (skip_line)
{
skip_rest_of_line (pfile);
- /* "Accept" the newline now. */
- pfile->line++;
+ if (!pfile->keep_tokens)
+ {
+ pfile->cur_run = &pfile->base_run;
+ pfile->cur_token = pfile->base_run.base;
+ }
}
/* Restore state. */
- pfile->la_write = pfile->la_saved;
pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
pfile->state.in_directive = 0;
pfile->state.angled_headers = 0;
{
dir = &dtable[T_LINE];
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))
cpp_pedwarn (pfile, "# followed by integer");
}
/* We don't want to process this directive. Put back the
tokens so caller will see them (and issue an error,
probably). */
- _cpp_push_token (pfile, &dname, &pfile->directive_pos);
+ _cpp_backup_tokens (pfile, 1);
skip = 0;
}
}
directives in skipped conditional groups (6.10 p4). */
if (CPP_OPTION (pfile, lang) == CLK_ASM)
{
- /* Output the # and lookahead token for the assembler. */
- _cpp_push_token (pfile, &dname, &pfile->directive_pos);
+ /* Output the # and this token for the assembler. */
+ _cpp_backup_tokens (pfile, 1);
skip = 0;
}
else
cpp_push_buffer (pfile, (const U_CHAR *) buf, count,
/* from_stage3 */ true, 1);
start_directive (pfile);
- pfile->state.bol = 0;
+ pfile->buffer->saved_flags = 0; /* We don't want to recognise directives. */
pfile->state.prevent_expansion++;
pfile->directive = &dtable[dir_no];
(void) (*pfile->directive->handler) (pfile);
pfile->state.prevent_expansion--;
- check_eol (pfile);
end_directive (pfile, 1);
_cpp_pop_buffer (pfile);
}
{
check_eol (pfile);
/* Get out of macro context, if we are. */
- end_directive (pfile, 1);
+ skip_rest_of_line (pfile);
if (pfile->cb.include)
(*pfile->cb.include) (pfile, pfile->directive_line,
pfile->directive->name, &header);
return;
}
- end_directive (pfile, 1);
+ skip_rest_of_line (pfile);
_cpp_do_file_change (pfile, reason, new_file, new_lineno, new_sysp);
}
pragma_cb handler = NULL;
const struct pragma_entry *p;
cpp_token tok;
+ unsigned int count = 0;
p = pfile->pragmas;
pfile->state.prevent_expansion++;
- cpp_start_lookahead (pfile);
new_space:
+ count++;
cpp_get_token (pfile, &tok);
if (tok.type == CPP_NAME)
{
}
}
- cpp_stop_lookahead (pfile, handler != NULL);
pfile->state.prevent_expansion--;
-
if (handler)
(*handler) (pfile);
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
else
{
check_eol (pfile);
- end_directive (pfile, 1);
+ skip_rest_of_line (pfile);
cpp_make_system_header (pfile, 1, 0);
}
}
{
cpp_warning (pfile, "current file is older than %s",
cpp_token_as_text (pfile, &header));
- cpp_start_lookahead (pfile);
cpp_get_token (pfile, &msg);
- cpp_stop_lookahead (pfile, msg.type == CPP_EOF);
if (msg.type != CPP_EOF)
- do_diagnostic (pfile, WARNING, 0);
+ {
+ _cpp_backup_tokens (pfile, 1);
+ do_diagnostic (pfile, WARNING, 0);
+ }
}
}
/* In a conditional, it is legal to not have an open paren. We
should save the following token in this case. */
- if (type == T_IF)
- cpp_start_lookahead (pfile);
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 (paren.type != CPP_OPEN_PAREN)
/* In a conditional no answer is a test for any answer. It
could be followed by any token. */
if (type == T_IF)
- return 0;
+ {
+ _cpp_backup_tokens (pfile, 1);
+ return 0;
+ }
/* #unassert with no answer is valid - it removes all answers. */
if (type == T_UNASSERT && paren.type == CPP_EOF)
new->from_stage3 = from_stage3;
new->prev = pfile->buffer;
new->return_at_eof = return_at_eof;
+ new->saved_flags = BOL;
pfile->buffer = new;
case of a missing #endif. */
pfile->lexer_pos.output_line = pfile->line;
pfile->state.skipping = 0;
- pfile->state.bol = 1;
/* Update the reader's buffer before _cpp_do_file_change. */
pfile->buffer = buffer->prev;
#define NAMED_OP (1 << 4) /* C++ named operators. */
#define NO_EXPAND (1 << 5) /* Do not macro-expand this token. */
#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
occupy 12 bytes on 32-bit hosts and 16 bytes on 64-bit hosts. */
extern const cpp_lexer_pos *cpp_get_line PARAMS ((cpp_reader *));
extern const unsigned char *cpp_macro_definition PARAMS ((cpp_reader *,
const cpp_hashnode *));
+extern void _cpp_backup_tokens PARAMS ((cpp_reader *, unsigned int));
/* Evaluate a CPP_CHAR or CPP_WCHAR token. */
extern HOST_WIDE_INT
static void replace_args PARAMS ((cpp_reader *, cpp_macro *, macro_arg *,
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. */
static cpp_token *lex_expansion_token PARAMS ((cpp_reader *, cpp_macro *));
line of the macro's invocation, not its definition.
Otherwise things like assert() will not work properly. */
make_number_token (pfile, token,
- SOURCE_LINE (pfile->map, cpp_get_line (pfile)->line));
+ SOURCE_LINE (pfile->map, pfile->cur_token[-1].line));
break;
case BT_STDC:
cpp_get_line (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;
}
/* Newlines in arguments are white space (6.10.3.10). */
line = pfile->line;
cpp_get_token (pfile, token);
+
if (line != pfile->line)
token->flags |= PREV_WHITE;
result = token->type;
+
if (result == CPP_OPEN_PAREN)
paren++;
else if (result == CPP_CLOSE_PAREN && paren-- == 0)
else if (result == CPP_COMMA && paren == 0 && !variadic)
break;
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. */
- POOL_COMMIT (&pfile->argument_pool, arg->count * sizeof (cpp_token));
+ /* Commit the memory used to store the arguments. We make the last
+ 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;
}
pfile->state.prevent_expansion++;
pfile->keep_tokens++;
- cpp_start_lookahead (pfile);
cpp_get_token (pfile, &maybe_paren);
- cpp_stop_lookahead (pfile, maybe_paren.type == CPP_OPEN_PAREN);
pfile->state.parsing_args = 2;
if (maybe_paren.type == CPP_OPEN_PAREN)
args = parse_args (pfile, node);
- else 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));
+ else
+ {
+ _cpp_backup_tokens (pfile, 1);
+ 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.parsing_args = 0;
if (args)
{
if (node->value.macro->paramc > 0)
- {
- /* 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;
- }
+ replace_args (pfile, node->value.macro, args, list);
free (args);
}
cpp_context *context = next_context (pfile);
context->macro = 0;
context->list.first = arg->first;
- context->list.limit = arg->first + arg->count;
+ context->list.limit = arg->first + arg->count + 1;
return context;
}
{
cpp_context *context = pfile->context;
- if (pfile->la_read)
- take_lookahead_token (pfile, token);
/* Context->prev == 0 <=> base context. */
- else if (!context->prev)
+ if (!context->prev)
_cpp_lex_token (pfile, token);
else if (context->list.first != context->list.limit)
{
}
else
{
- if (context->macro)
- {
- /* Avoid accidental paste at the end of a macro. */
- pfile->buffer->saved_flags |= AVOID_LPASTE;
- _cpp_pop_context (pfile);
- continue;
- }
- /* End of argument pre-expansion. */
- token->type = CPP_EOF;
- token->flags = 0;
- return;
+ if (!context->macro)
+ cpp_ice (pfile, "context->macro == 0");
+
+ /* Avoid accidental paste at the end of a macro. */
+ pfile->buffer->saved_flags |= AVOID_LPASTE;
+ _cpp_pop_context (pfile);
+ continue;
}
if (token->type != CPP_NAME)
since this token came from either the lexer or a macro. */
_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
while (token.type != CPP_EOF);
}
-/* Lookahead handling. */
-
-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. */
+/* Step back one (or more) tokens. Can only step mack more than 1 if
+ they are from the lexer, and not from macro expansion. */
void
-_cpp_release_lookahead (pfile)
+_cpp_backup_tokens (pfile, count)
cpp_reader *pfile;
+ unsigned int count;
{
- cpp_lookahead *la = pfile->la_read;
-
- 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
+ if (pfile->context->prev == NULL)
{
- la = xnew (cpp_lookahead);
- la->tokens = 0;
- la->cap = 0;
+ pfile->lookaheads += count;
+ while (count--)
+ {
+ 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;
+ }
+ }
}
-
- 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)
+ else
{
- lan = la->next;
- free_lookahead (la);
+ if (count != 1)
+ 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. */
/* 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>
* gcc.dg/20010912-1.c: New test.
/* Check that directives always start a line, even if in middle of
macro expansion. */
#define func(x) x
-func (2 /* { dg-error "unterminated" "" { target *-*-* } 32 } */
+func (2 /* { dg-error "unterminated" "" } */
#define foobar /* { dg-error "directives may not" } */
/* Check newlines end directives, even in function-like macro
#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)" } */
blah )