cpphash.h (_cpp_lex_direct): New.

* cpphash.h (_cpp_lex_direct): New.
	* cpplex.c (_cpp_lex_token): Update.
	(lex_token): Rename _cpp_lex_direct; lex into pfile->cur_token,
	and increment that pointer.
	* cppmacro.c (alloc_expansion_token): New.
	(lex_expansion_token): Lex macro expansion directly into
	macro storage.

From-SVN: r45656
This commit is contained in:
Neil Booth 2001-09-17 18:26:12 +00:00 committed by Neil Booth
parent 7a91449ca1
commit 14baae01f6
4 changed files with 82 additions and 34 deletions

View File

@ -1,3 +1,13 @@
2001-09-17 Neil Booth <neil@daikokuya.demon.co.uk>
* cpphash.h (_cpp_lex_direct): New.
* cpplex.c (_cpp_lex_token): Update.
(lex_token): Rename _cpp_lex_direct; lex into pfile->cur_token,
and increment that pointer.
* cppmacro.c (alloc_expansion_token): New.
(lex_expansion_token): Lex macro expansion directly into
macro storage.
2001-09-16 Brad Lucier <lucier@math.purdue.edu> 2001-09-16 Brad Lucier <lucier@math.purdue.edu>
* Makefile.in: Make rtl-error.o depend on $(CONFIG_H). * Makefile.in: Make rtl-error.o depend on $(CONFIG_H).

View File

@ -399,6 +399,7 @@ extern int _cpp_parse_expr PARAMS ((cpp_reader *));
/* In cpplex.c */ /* In cpplex.c */
extern const cpp_token *_cpp_lex_token PARAMS ((cpp_reader *)); extern const cpp_token *_cpp_lex_token PARAMS ((cpp_reader *));
extern cpp_token *_cpp_lex_direct PARAMS ((cpp_reader *));
extern int _cpp_equiv_tokens PARAMS ((const cpp_token *, extern int _cpp_equiv_tokens PARAMS ((const cpp_token *,
const cpp_token *)); const cpp_token *));
extern void _cpp_init_tokenrun PARAMS ((tokenrun *, unsigned int)); extern void _cpp_init_tokenrun PARAMS ((tokenrun *, unsigned int));

View File

@ -102,7 +102,6 @@ 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 cpp_token *lex_token PARAMS ((cpp_reader *, cpp_token *));
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));
@ -811,7 +810,7 @@ save_comment (pfile, token, from)
memcpy (buffer + 1, from, len - 1); memcpy (buffer + 1, from, len - 1);
} }
/* Subroutine of lex_token to handle '%'. A little tricky, since we /* Subroutine of _cpp_lex_direct to handle '%'. A little tricky, since we
want to avoid stepping back when lexing %:%X. */ want to avoid stepping back when lexing %:%X. */
static void static void
lex_percent (pfile, result) lex_percent (pfile, result)
@ -860,7 +859,7 @@ lex_percent (pfile, result)
} }
} }
/* Subroutine of lex_token to handle '.'. This is tricky, since we /* Subroutine of _cpp_lex_direct to handle '.'. This is tricky, since we
want to avoid stepping back when lexing '...' or '.123'. In the want to avoid stepping back when lexing '...' or '.123'. In the
latter case we should also set a flag for parse_number. */ latter case we should also set a flag for parse_number. */
static void static void
@ -932,7 +931,9 @@ next_tokenrun (run)
return run->next; return run->next;
} }
/* Lex a token into RESULT (external interface). */ /* Lex a token into RESULT (external interface). Takes care of issues
like directive handling, token lookahead, multiple include
opimisation and skipping. */
const cpp_token * const cpp_token *
_cpp_lex_token (pfile) _cpp_lex_token (pfile)
cpp_reader *pfile; cpp_reader *pfile;
@ -946,12 +947,14 @@ _cpp_lex_token (pfile)
pfile->cur_run = next_tokenrun (pfile->cur_run); pfile->cur_run = next_tokenrun (pfile->cur_run);
pfile->cur_token = pfile->cur_run->base; pfile->cur_token = pfile->cur_run->base;
} }
result = pfile->cur_token++;
if (pfile->lookaheads) if (pfile->lookaheads)
pfile->lookaheads--; {
pfile->lookaheads--;
result = pfile->cur_token++;
}
else else
result = lex_token (pfile, result); result = _cpp_lex_direct (pfile);
if (result->flags & BOL) if (result->flags & BOL)
{ {
@ -970,7 +973,7 @@ _cpp_lex_token (pfile)
break; break;
/* Outside a directive, invalidate controlling macros. At file /* Outside a directive, invalidate controlling macros. At file
EOF, lex_token takes care of popping the buffer, so we never EOF, _cpp_lex_direct takes care of popping the buffer, so we never
get here and MI optimisation works. */ get here and MI optimisation works. */
pfile->mi_valid = false; pfile->mi_valid = false;
@ -981,17 +984,25 @@ _cpp_lex_token (pfile)
return result; return result;
} }
/* Lex a token into RESULT. When meeting a newline, returns CPP_EOF /* Lex a token into pfile->cur_token, which is also incremented, to
if parsing a directive, otherwise returns to the start of the token get diagnostics pointing to the correct location.
buffer if permissible. Returns the location of the lexed token. */
static cpp_token * Does not handle issues such as token lookahead, multiple-include
lex_token (pfile, result) optimisation, directives, skipping etc. This function is only
suitable for use by _cpp_lex_token, and in special cases like
lex_expansion_token which doesn't care for any of these issues.
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. */
cpp_token *
_cpp_lex_direct (pfile)
cpp_reader *pfile; cpp_reader *pfile;
cpp_token *result;
{ {
cppchar_t c; cppchar_t c;
cpp_buffer *buffer; cpp_buffer *buffer;
const unsigned char *comment_start; const unsigned char *comment_start;
cpp_token *result = pfile->cur_token++;
fresh_line: fresh_line:
buffer = pfile->buffer; buffer = pfile->buffer;

View File

@ -79,6 +79,7 @@ static void replace_args PARAMS ((cpp_reader *, cpp_macro *, macro_arg *,
/* #define directive parsing and handling. */ /* #define directive parsing and handling. */
static cpp_token *alloc_expansion_token PARAMS ((cpp_reader *, cpp_macro *));
static cpp_token *lex_expansion_token PARAMS ((cpp_reader *, cpp_macro *)); static cpp_token *lex_expansion_token PARAMS ((cpp_reader *, cpp_macro *));
static int warn_of_redefinition PARAMS ((cpp_reader *, const cpp_hashnode *, static int warn_of_redefinition PARAMS ((cpp_reader *, const cpp_hashnode *,
const cpp_macro *)); const cpp_macro *));
@ -1089,6 +1090,8 @@ _cpp_free_definition (h)
h->flags &= ~NODE_BUILTIN; h->flags &= ~NODE_BUILTIN;
} }
/* Save parameter NODE to the parameter list of macro MACRO. Returns
zero on success, non-zero if the paramter is a duplicate. */
static int static int
save_parameter (pfile, macro, node) save_parameter (pfile, macro, node)
cpp_reader *pfile; cpp_reader *pfile;
@ -1119,6 +1122,7 @@ save_parameter (pfile, macro, node)
return 0; return 0;
} }
/* Check the syntax of the paramters in a MACRO definition. */
static int static int
parse_params (pfile, macro) parse_params (pfile, macro)
cpp_reader *pfile; cpp_reader *pfile;
@ -1195,10 +1199,9 @@ parse_params (pfile, macro)
} }
} }
/* Lex a token from a macro's replacement list. Translate it to a /* Allocate room for a token from a macro's replacement list. */
CPP_MACRO_ARG if appropriate. */
static cpp_token * static cpp_token *
lex_expansion_token (pfile, macro) alloc_expansion_token (pfile, macro)
cpp_reader *pfile; cpp_reader *pfile;
cpp_macro *macro; cpp_macro *macro;
{ {
@ -1213,7 +1216,18 @@ lex_expansion_token (pfile, macro)
} }
macro->count++; macro->count++;
*token = *_cpp_lex_token (pfile); return token;
}
static cpp_token *
lex_expansion_token (pfile, macro)
cpp_reader *pfile;
cpp_macro *macro;
{
cpp_token *token;
pfile->cur_token = alloc_expansion_token (pfile, macro);
token = _cpp_lex_direct (pfile);
/* Is this an argument? */ /* Is this an argument? */
if (token->type == CPP_NAME && token->val.node->arg_index) if (token->type == CPP_NAME && token->val.node->arg_index)
@ -1235,7 +1249,8 @@ _cpp_create_definition (pfile, node)
cpp_hashnode *node; cpp_hashnode *node;
{ {
cpp_macro *macro; cpp_macro *macro;
cpp_token *token; cpp_token *token, *saved_cur_token;
const cpp_token *ctoken;
unsigned int i, ok = 1; unsigned int i, ok = 1;
macro = (cpp_macro *) _cpp_pool_alloc (&pfile->macro_pool, macro = (cpp_macro *) _cpp_pool_alloc (&pfile->macro_pool,
@ -1243,29 +1258,34 @@ _cpp_create_definition (pfile, node)
macro->line = pfile->directive_line; macro->line = pfile->directive_line;
macro->params = 0; macro->params = 0;
macro->paramc = 0; macro->paramc = 0;
macro->fun_like = 0;
macro->variadic = 0; macro->variadic = 0;
macro->count = 0; macro->count = 0;
macro->expansion = (cpp_token *) POOL_FRONT (&pfile->macro_pool); macro->fun_like = 0;
/* Get the first token of the expansion (or the '(' of a /* Get the first token of the expansion (or the '(' of a
function-like macro). */ function-like macro). */
token = lex_expansion_token (pfile, macro); ctoken = _cpp_lex_token (pfile);
if (token->type == CPP_OPEN_PAREN && !(token->flags & PREV_WHITE))
if (ctoken->type == CPP_OPEN_PAREN && !(ctoken->flags & PREV_WHITE))
{ {
if (!(ok = parse_params (pfile, macro))) if (!(ok = parse_params (pfile, macro)))
goto cleanup; goto cleanup2;
macro->count = 0;
macro->fun_like = 1; macro->fun_like = 1;
/* Some of the pool may have been used for the parameter store. */
macro->expansion = (cpp_token *) POOL_FRONT (&pfile->macro_pool);
token = lex_expansion_token (pfile, macro);
} }
else if (token->type != CPP_EOF && !(token->flags & PREV_WHITE)) else if (ctoken->type != CPP_EOF && !(ctoken->flags & PREV_WHITE))
cpp_pedwarn (pfile, "ISO C requires whitespace after the macro name"); cpp_pedwarn (pfile, "ISO C requires whitespace after the macro name");
/* Setting it here means we don't catch leading comments. */
pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments); pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
saved_cur_token = pfile->cur_token;
macro->expansion = (cpp_token *) POOL_FRONT (&pfile->macro_pool);
if (macro->fun_like)
token = lex_expansion_token (pfile, macro);
else
{
token = alloc_expansion_token (pfile, macro);
*token = *ctoken;
}
for (;;) for (;;)
{ {
@ -1286,7 +1306,7 @@ _cpp_create_definition (pfile, node)
{ {
ok = 0; ok = 0;
cpp_error (pfile, "'#' is not followed by a macro parameter"); cpp_error (pfile, "'#' is not followed by a macro parameter");
goto cleanup; goto cleanup1;
} }
} }
@ -1306,7 +1326,7 @@ _cpp_create_definition (pfile, node)
ok = 0; ok = 0;
cpp_error (pfile, cpp_error (pfile,
"'##' cannot appear at either end of a macro expansion"); "'##' cannot appear at either end of a macro expansion");
goto cleanup; goto cleanup1;
} }
token[-1].flags |= PASTE_LEFT; token[-1].flags |= PASTE_LEFT;
@ -1346,7 +1366,7 @@ _cpp_create_definition (pfile, node)
"\"%s\" redefined", NODE_NAME (node)); "\"%s\" redefined", NODE_NAME (node));
if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)) if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
cpp_pedwarn_with_line (pfile, node->value.macro->line, 1, cpp_pedwarn_with_line (pfile, node->value.macro->line, 0,
"this is the location of the previous definition"); "this is the location of the previous definition");
} }
_cpp_free_definition (node); _cpp_free_definition (node);
@ -1358,7 +1378,13 @@ _cpp_create_definition (pfile, node)
if (! ustrncmp (NODE_NAME (node), DSC ("__STDC_"))) if (! ustrncmp (NODE_NAME (node), DSC ("__STDC_")))
node->flags |= NODE_WARN; node->flags |= NODE_WARN;
cleanup: cleanup1:
/* Set type for SEEN_EOL() in cpplib.c, restore the lexer position. */
saved_cur_token[-1].type = pfile->cur_token[-1].type;
pfile->cur_token = saved_cur_token;
cleanup2:
/* Stop the lexer accepting __VA_ARGS__. */ /* Stop the lexer accepting __VA_ARGS__. */
pfile->state.va_args_ok = 0; pfile->state.va_args_ok = 0;