Commit 417f3e3a by Zack Weinberg

[multiple changes]

2000-07-11  Zack Weinberg  <zack@wolery.cumb.org>

	* cpplex.c (parse_name): No longer inline (premature optimization).
	(do_pop_context): Fold into pop_context.
	(pop_context): Returns int.
	(lex_next): Hoist test for end of directive into pop_context.
	(push_macro_context): Returns int; takes just reader and token.
	Hoist test for excessive nesting to caller.
	(push_arg_context): Returns void; takes just reader and token.
	Do not call stringify_arg or get_raw_token.
	(get_raw_token): Convert tail recursion through	push_arg_context
	to a loop at this level.  Call stringify_arg here if appropriate.
	(maybe_paste_with_next): Convert tail recursion to a while loop.
	Hoist test of paste_level to caller.

	(stringify_arg): Push arg context at beginning.
	(cpp_get_token): Split out core into _cpp_get_token.  Call
	process_directive here.  Throw away CPP_PLACEMARKER tokens.
	(_cpp_get_token): Convert tail recursion through
	push_macro_context to a loop at this level.
	(_cpp_glue_header_name, is_macro_disabled, stringify_arg,
	_cpp_get_raw_token): Use _cpp_get_token.
	(_cpp_skip_rest_of_line): Drop the context stack directly; do
	not call pop_context.
	(_cpp_run_directive): Call lex_next directly.

	* cpphash.h: Prototype _cpp_get_token.
	* cppexp.c (lex): Use it.
	* cpphash.c (parse_define): Use it.
	* cpplib.c (get_define_node, do_undef, parse_include,
	read_line_number, do_line, do_ident, do_pragma, do_pragma_gcc,
	do_pragma_implementation, do_pragma_poison, do_pragma_dependency,
	parse_ifdef, validate_else): Use it.
	(cpp_push_buffer): Tweak error message; abort if anyone tries
	to push a buffer while macro expansions are stacked.

2000-07-11  Donn Terry  <donnte@microsoft.com>

	* cpplex.c (free_macro_args, save_token): Cast arg of free
	and/or xrealloc to PTR.
	(_cpp_init_input_buffer): Clear all fields of the base context.

From-SVN: r34972
parent 268afb99
2000-07-11 Zack Weinberg <zack@wolery.cumb.org>
* cpplex.c (parse_name): No longer inline (premature optimization).
(do_pop_context): Fold into pop_context.
(pop_context): Returns int.
(lex_next): Hoist test for end of directive into pop_context.
(push_macro_context): Returns int; takes just reader and token.
Hoist test for excessive nesting to caller.
(push_arg_context): Returns void; takes just reader and token.
Do not call stringify_arg or get_raw_token.
(get_raw_token): Convert tail recursion through push_arg_context
to a loop at this level. Call stringify_arg here if appropriate.
(maybe_paste_with_next): Convert tail recursion to a while loop.
Hoist test of paste_level to caller.
(stringify_arg): Push arg context at beginning.
(cpp_get_token): Split out core into _cpp_get_token. Call
process_directive here. Throw away CPP_PLACEMARKER tokens.
(_cpp_get_token): Convert tail recursion through
push_macro_context to a loop at this level.
(_cpp_glue_header_name, is_macro_disabled, stringify_arg,
_cpp_get_raw_token): Use _cpp_get_token.
(_cpp_skip_rest_of_line): Drop the context stack directly; do
not call pop_context.
(_cpp_run_directive): Call lex_next directly.
* cpphash.h: Prototype _cpp_get_token.
* cppexp.c (lex): Use it.
* cpphash.c (parse_define): Use it.
* cpplib.c (get_define_node, do_undef, parse_include,
read_line_number, do_line, do_ident, do_pragma, do_pragma_gcc,
do_pragma_implementation, do_pragma_poison, do_pragma_dependency,
parse_ifdef, validate_else): Use it.
(cpp_push_buffer): Tweak error message; abort if anyone tries
to push a buffer while macro expansions are stacked.
2000-07-11 Donn Terry <donnte@microsoft.com>
* cpplex.c (free_macro_args, save_token): Cast arg of free
and/or xrealloc to PTR.
(_cpp_init_input_buffer): Clear all fields of the base context.
Tue Jul 11 15:28:21 CDT 2000 Clinton Popetz <cpopetz@cygnus.com> Tue Jul 11 15:28:21 CDT 2000 Clinton Popetz <cpopetz@cygnus.com>
* gensupport.c (process_rtx): Make rtl checking stop * gensupport.c (process_rtx): Make rtl checking stop
......
...@@ -392,7 +392,7 @@ lex (pfile, skip_evaluation) ...@@ -392,7 +392,7 @@ lex (pfile, skip_evaluation)
const cpp_token *tok; const cpp_token *tok;
retry: retry:
tok = cpp_get_token (pfile); tok = _cpp_get_token (pfile);
switch (tok->type) switch (tok->type)
{ {
......
...@@ -354,7 +354,7 @@ parse_define (pfile) ...@@ -354,7 +354,7 @@ parse_define (pfile)
int prev_white = 0; int prev_white = 0;
/* The first token after the macro's name. */ /* The first token after the macro's name. */
token = cpp_get_token (pfile); token = _cpp_get_token (pfile);
/* Constraint 6.10.3.5 */ /* Constraint 6.10.3.5 */
if (is__va_args__ (pfile, token - 1)) if (is__va_args__ (pfile, token - 1))
......
...@@ -256,6 +256,7 @@ extern void _cpp_run_directive PARAMS ((cpp_reader *, ...@@ -256,6 +256,7 @@ extern void _cpp_run_directive PARAMS ((cpp_reader *,
const char *, size_t)); const char *, size_t));
extern unsigned int _cpp_get_line PARAMS ((cpp_reader *, extern unsigned int _cpp_get_line PARAMS ((cpp_reader *,
unsigned int *)); unsigned int *));
extern const cpp_token *_cpp_get_token PARAMS ((cpp_reader *));
extern const cpp_token *_cpp_get_raw_token PARAMS ((cpp_reader *)); extern const cpp_token *_cpp_get_raw_token PARAMS ((cpp_reader *));
extern void _cpp_push_token PARAMS ((cpp_reader *, const cpp_token*)); extern void _cpp_push_token PARAMS ((cpp_reader *, const cpp_token*));
extern const cpp_token *_cpp_glue_header_name PARAMS ((cpp_reader *)); extern const cpp_token *_cpp_glue_header_name PARAMS ((cpp_reader *));
......
...@@ -417,7 +417,7 @@ _cpp_glue_header_name (pfile) ...@@ -417,7 +417,7 @@ _cpp_glue_header_name (pfile)
for (;;) for (;;)
{ {
t = cpp_get_token (pfile); t = _cpp_get_token (pfile);
if (t->type == CPP_GREATER || t->type == CPP_EOF) if (t->type == CPP_GREATER || t->type == CPP_EOF)
break; break;
...@@ -947,7 +947,7 @@ skip_whitespace (pfile, in_directive) ...@@ -947,7 +947,7 @@ skip_whitespace (pfile, in_directive)
} }
/* Parse (append) an identifier. */ /* Parse (append) an identifier. */
static inline const U_CHAR * static const U_CHAR *
parse_name (pfile, tok, cur, rlimit) parse_name (pfile, tok, cur, rlimit)
cpp_reader *pfile; cpp_reader *pfile;
cpp_token *tok; cpp_token *tok;
...@@ -1960,7 +1960,7 @@ struct cpp_context ...@@ -1960,7 +1960,7 @@ struct cpp_context
const cpp_token **arg; /* Used for arg contexts only. */ const cpp_token **arg; /* Used for arg contexts only. */
} u; } u;
/* Pushed token to be returned by next call to cpp_get_token. */ /* Pushed token to be returned by next call to get_raw_token. */
const cpp_token *pushed_token; const cpp_token *pushed_token;
struct macro_args *args; /* 0 for arguments and object-like macros. */ struct macro_args *args; /* 0 for arguments and object-like macros. */
...@@ -1985,13 +1985,9 @@ static const cpp_token *parse_arg PARAMS ((cpp_reader *, int, unsigned int, ...@@ -1985,13 +1985,9 @@ static const cpp_token *parse_arg PARAMS ((cpp_reader *, int, unsigned int,
macro_args *, unsigned int *)); macro_args *, unsigned int *));
static int parse_args PARAMS ((cpp_reader *, cpp_hashnode *, macro_args *)); static int parse_args PARAMS ((cpp_reader *, cpp_hashnode *, macro_args *));
static void save_token PARAMS ((macro_args *, const cpp_token *)); static void save_token PARAMS ((macro_args *, const cpp_token *));
static const cpp_token *push_arg_context PARAMS ((cpp_reader *, static int pop_context PARAMS ((cpp_reader *));
const cpp_token *)); static int push_macro_context PARAMS ((cpp_reader *, const cpp_token *));
static int do_pop_context PARAMS ((cpp_reader *)); static void push_arg_context PARAMS ((cpp_reader *, const cpp_token *));
static const cpp_token *pop_context PARAMS ((cpp_reader *));
static const cpp_token *push_macro_context PARAMS ((cpp_reader *,
cpp_hashnode *,
const cpp_token *));
static void free_macro_args PARAMS ((macro_args *)); static void free_macro_args PARAMS ((macro_args *));
/* Free the storage allocated for macro arguments. */ /* Free the storage allocated for macro arguments. */
...@@ -2000,7 +1996,7 @@ free_macro_args (args) ...@@ -2000,7 +1996,7 @@ free_macro_args (args)
macro_args *args; macro_args *args;
{ {
if (args->tokens) if (args->tokens)
free (args->tokens); free ((PTR) args->tokens);
free (args->ends); free (args->ends);
free (args); free (args);
} }
...@@ -2069,7 +2065,7 @@ is_macro_disabled (pfile, expansion, token) ...@@ -2069,7 +2065,7 @@ is_macro_disabled (pfile, expansion, token)
prev_nme = pfile->no_expand_level; prev_nme = pfile->no_expand_level;
pfile->no_expand_level = context - pfile->contexts; pfile->no_expand_level = context - pfile->contexts;
next = cpp_get_token (pfile); next = _cpp_get_token (pfile);
restore_macro_expansion (pfile, prev_nme); restore_macro_expansion (pfile, prev_nme);
if (next->type != CPP_OPEN_PAREN) if (next->type != CPP_OPEN_PAREN)
{ {
...@@ -2096,7 +2092,8 @@ save_token (args, token) ...@@ -2096,7 +2092,8 @@ save_token (args, token)
{ {
args->capacity += args->capacity + 100; args->capacity += args->capacity + 100;
args->tokens = (const cpp_token **) args->tokens = (const cpp_token **)
xrealloc (args->tokens, args->capacity * sizeof (const cpp_token *)); xrealloc ((PTR) args->tokens,
args->capacity * sizeof (const cpp_token *));
} }
args->tokens[args->used++] = token; args->tokens[args->used++] = token;
} }
...@@ -2117,7 +2114,7 @@ parse_arg (pfile, var_args, paren_context, args, pcount) ...@@ -2117,7 +2114,7 @@ parse_arg (pfile, var_args, paren_context, args, pcount)
for (count = 0;; count++) for (count = 0;; count++)
{ {
token = cpp_get_token (pfile); token = _cpp_get_token (pfile);
switch (token->type) switch (token->type)
{ {
...@@ -2511,33 +2508,30 @@ maybe_paste_with_next (pfile, token) ...@@ -2511,33 +2508,30 @@ maybe_paste_with_next (pfile, token)
cpp_context *context = CURRENT_CONTEXT (pfile); cpp_context *context = CURRENT_CONTEXT (pfile);
/* Is this token on the LHS of ## ? */ /* Is this token on the LHS of ## ? */
if (!((context->flags & CONTEXT_PASTEL) && context->posn == context->count)
&& !(token->flags & PASTE_LEFT))
return token;
/* Prevent recursion, and possibly pushing back more than one token. */ while ((token->flags & PASTE_LEFT)
if (pfile->paste_level) || ((context->flags & CONTEXT_PASTEL)
return token; && context->posn == context->count))
{
/* Suppress macro expansion for next token, but don't conflict with /* Suppress macro expansion for next token, but don't conflict
the other method of suppression. If it is an argument, macro with the other method of suppression. If it is an argument,
expansion within the argument will still occur. */ macro expansion within the argument will still occur. */
pfile->paste_level = pfile->cur_context; pfile->paste_level = pfile->cur_context;
second = cpp_get_token (pfile); second = _cpp_get_token (pfile);
pfile->paste_level = 0; pfile->paste_level = 0;
/* Ignore placemarker argument tokens (cannot be from an empty macro /* Ignore placemarker argument tokens (cannot be from an empty
since macros are not expanded). */ macro since macros are not expanded). */
if (token->type == CPP_PLACEMARKER) if (token->type == CPP_PLACEMARKER)
pasted = duplicate_token (pfile, second); pasted = duplicate_token (pfile, second);
else if (second->type == CPP_PLACEMARKER) else if (second->type == CPP_PLACEMARKER)
{ {
cpp_context *mac_context = CURRENT_CONTEXT (pfile) - 1; cpp_context *mac_context = CURRENT_CONTEXT (pfile) - 1;
/* GCC has special extended semantics for a ## b where b is a /* GCC has special extended semantics for a ## b where b is
varargs parameter: a disappears if b consists of no tokens. a varargs parameter: a disappears if b consists of no
This extension is deprecated. */ tokens. This extension is deprecated. */
if ((mac_context->u.list->flags & GNU_REST_ARGS) if ((mac_context->u.list->flags & GNU_REST_ARGS)
&& (mac_context->u.list->tokens[mac_context->posn - 1].val.aux + 1 && (mac_context->u.list->tokens[mac_context->posn-1].val.aux + 1
== (unsigned) mac_context->u.list->paramc)) == (unsigned) mac_context->u.list->paramc))
{ {
cpp_warning (pfile, "deprecated GNU ## extension used"); cpp_warning (pfile, "deprecated GNU ## extension used");
...@@ -2601,7 +2595,13 @@ maybe_paste_with_next (pfile, token) ...@@ -2601,7 +2595,13 @@ maybe_paste_with_next (pfile, token)
pasted->col = token->col; pasted->col = token->col;
pasted->line = token->line; pasted->line = token->line;
return maybe_paste_with_next (pfile, pasted); /* See if there is another token to be pasted onto the one we just
constructed. */
token = pasted;
context = CURRENT_CONTEXT (pfile);
/* and loop */
}
return token;
} }
/* Convert a token sequence to a single string token according to the /* Convert a token sequence to a single string token according to the
...@@ -2617,13 +2617,14 @@ stringify_arg (pfile, token) ...@@ -2617,13 +2617,14 @@ stringify_arg (pfile, token)
unsigned int prev_value, backslash_count = 0; unsigned int prev_value, backslash_count = 0;
unsigned int buf_used = 0, whitespace = 0, buf_cap = INIT_SIZE; unsigned int buf_used = 0, whitespace = 0, buf_cap = INIT_SIZE;
push_arg_context (pfile, token);
prev_value = prevent_macro_expansion (pfile); prev_value = prevent_macro_expansion (pfile);
main_buf = (unsigned char *) xmalloc (buf_cap); main_buf = (unsigned char *) xmalloc (buf_cap);
result = get_temp_token (pfile); result = get_temp_token (pfile);
ASSIGN_FLAGS_AND_POS (result, token); ASSIGN_FLAGS_AND_POS (result, token);
for (; (token = cpp_get_token (pfile))->type != CPP_EOF; ) for (; (token = _cpp_get_token (pfile))->type != CPP_EOF; )
{ {
int escape; int escape;
unsigned char *buf; unsigned char *buf;
...@@ -2690,21 +2691,15 @@ expand_context_stack (pfile) ...@@ -2690,21 +2691,15 @@ expand_context_stack (pfile)
/* Push the context of macro NODE onto the context stack. TOKEN is /* Push the context of macro NODE onto the context stack. TOKEN is
the CPP_NAME token invoking the macro. */ the CPP_NAME token invoking the macro. */
static const cpp_token * static int
push_macro_context (pfile, node, token) push_macro_context (pfile, token)
cpp_reader *pfile; cpp_reader *pfile;
cpp_hashnode *node;
const cpp_token *token; const cpp_token *token;
{ {
unsigned char orig_flags; unsigned char orig_flags;
macro_args *args; macro_args *args;
cpp_context *context; cpp_context *context;
cpp_hashnode *node = token->val.node;
if (pfile->cur_context > CPP_STACK_MAX)
{
cpp_error (pfile, "infinite macro recursion invoking '%s'", node->name);
return token;
}
/* Token's flags may change when parsing args containing a nested /* Token's flags may change when parsing args containing a nested
invocation of this macro. */ invocation of this macro. */
...@@ -2731,7 +2726,7 @@ push_macro_context (pfile, node, token) ...@@ -2731,7 +2726,7 @@ push_macro_context (pfile, node, token)
if (error) if (error)
{ {
free_macro_args (args); free_macro_args (args);
return token; return 1;
} }
} }
...@@ -2753,12 +2748,12 @@ push_macro_context (pfile, node, token) ...@@ -2753,12 +2748,12 @@ push_macro_context (pfile, node, token)
be one, empty macros are a single placemarker token. */ be one, empty macros are a single placemarker token. */
MODIFY_FLAGS_AND_POS (&context->u.list->tokens[0], token, orig_flags); MODIFY_FLAGS_AND_POS (&context->u.list->tokens[0], token, orig_flags);
return cpp_get_token (pfile); return 0;
} }
/* Push an argument to the current macro onto the context stack. /* Push an argument to the current macro onto the context stack.
TOKEN is the MACRO_ARG token representing the argument expansion. */ TOKEN is the MACRO_ARG token representing the argument expansion. */
static const cpp_token * static void
push_arg_context (pfile, token) push_arg_context (pfile, token)
cpp_reader *pfile; cpp_reader *pfile;
const cpp_token *token; const cpp_token *token;
...@@ -2792,15 +2787,10 @@ push_arg_context (pfile, token) ...@@ -2792,15 +2787,10 @@ push_arg_context (pfile, token)
token->flags & (PREV_WHITE | BOL)); token->flags & (PREV_WHITE | BOL));
} }
if (token->flags & STRINGIFY_ARG)
return stringify_arg (pfile, token);
if (token->flags & PASTE_LEFT) if (token->flags & PASTE_LEFT)
context->flags |= CONTEXT_PASTEL; context->flags |= CONTEXT_PASTEL;
if (pfile->paste_level) if (pfile->paste_level)
context->flags |= CONTEXT_PASTER; context->flags |= CONTEXT_PASTER;
return get_raw_token (pfile);
} }
/* "Unget" a token. It is effectively inserted in the token queue and /* "Unget" a token. It is effectively inserted in the token queue and
...@@ -2859,39 +2849,69 @@ cpp_get_token (pfile) ...@@ -2859,39 +2849,69 @@ cpp_get_token (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
const cpp_token *token; const cpp_token *token;
cpp_hashnode *node; /* Loop till we hit a non-directive, non-placemarker token. */
/* Loop till we hit a non-directive, non-skipped, non-placemarker token. */
for (;;) for (;;)
{ {
token = get_raw_token (pfile); token = _cpp_get_token (pfile);
if (token->flags & BOL && token->type == CPP_HASH
if (token->type == CPP_PLACEMARKER)
continue;
if (token->type == CPP_HASH && token->flags & BOL
&& pfile->token_list.directive) && pfile->token_list.directive)
{ {
process_directive (pfile, token); process_directive (pfile, token);
continue; continue;
} }
return token;
}
}
/* The internal interface to return the next token. There are two
differences between the internal and external interfaces: the
internal interface may return a PLACEMARKER token, and it does not
process directives. */
const cpp_token *
_cpp_get_token (pfile)
cpp_reader *pfile;
{
const cpp_token *token;
cpp_hashnode *node;
/* Loop until we hit a non-macro token. */
for (;;)
{
token = get_raw_token (pfile);
/* Short circuit EOF. */ /* Short circuit EOF. */
if (token->type == CPP_EOF) if (token->type == CPP_EOF)
return token; return token;
if (pfile->skipping && ! pfile->token_list.directive) /* If we are skipping... */
if (pfile->skipping)
{ {
/* we still have to process directives, */
if (pfile->token_list.directive)
return token;
/* but everything else is ignored. */
_cpp_skip_rest_of_line (pfile); _cpp_skip_rest_of_line (pfile);
continue; continue;
} }
break;
}
/* If there's a potential control macro and we get here, then that /* If there's a potential control macro and we get here, then that
#ifndef didn't cover the entire file and its argument shouldn't #ifndef didn't cover the entire file and its argument shouldn't
be taken as a control macro. */ be taken as a control macro. */
pfile->potential_control_macro = 0; pfile->potential_control_macro = 0;
/* See if there's a token to paste with this one. */
if (!pfile->paste_level)
token = maybe_paste_with_next (pfile, token); token = maybe_paste_with_next (pfile, token);
if (token->type != CPP_NAME) /* If it isn't a macro, return it now. */
if (token->type != CPP_NAME
|| token->val.node->type == T_VOID)
return token; return token;
/* Is macro expansion disabled in general? */ /* Is macro expansion disabled in general? */
...@@ -2899,18 +2919,22 @@ cpp_get_token (pfile) ...@@ -2899,18 +2919,22 @@ cpp_get_token (pfile)
return token; return token;
node = token->val.node; node = token->val.node;
if (node->type == T_VOID) if (node->type != T_MACRO)
return special_symbol (pfile, node, token);
if (is_macro_disabled (pfile, node->value.expansion, token))
return token; return token;
if (node->type == T_MACRO) if (pfile->cur_context > CPP_STACK_MAX)
{ {
if (is_macro_disabled (pfile, node->value.expansion, token)) cpp_error (pfile, "macros nested too deep invoking '%s'", node->name);
return token; return token;
}
return push_macro_context (pfile, node, token); if (push_macro_context (pfile, token))
return token;
/* else loop */
} }
else
return special_symbol (pfile, node, token);
} }
/* Returns the next raw token, i.e. without performing macro /* Returns the next raw token, i.e. without performing macro
...@@ -2920,15 +2944,22 @@ get_raw_token (pfile) ...@@ -2920,15 +2944,22 @@ get_raw_token (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
const cpp_token *result; const cpp_token *result;
cpp_context *context = CURRENT_CONTEXT (pfile); cpp_context *context;
for (;;)
{
context = CURRENT_CONTEXT (pfile);
if (context->pushed_token) if (context->pushed_token)
{ {
result = context->pushed_token; result = context->pushed_token;
context->pushed_token = 0; context->pushed_token = 0;
} }
else if (context->posn == context->count) else if (context->posn == context->count)
result = pop_context (pfile); {
if (pop_context (pfile))
return &eof_token;
continue;
}
else else
{ {
if (IS_ARG_CONTEXT (context)) if (IS_ARG_CONTEXT (context))
...@@ -2944,9 +2975,14 @@ get_raw_token (pfile) ...@@ -2944,9 +2975,14 @@ get_raw_token (pfile)
result = &context->u.list->tokens[context->posn++]; result = &context->u.list->tokens[context->posn++];
} }
if (result->type == CPP_MACRO_ARG) if (result->type != CPP_MACRO_ARG)
result = push_arg_context (pfile, result);
return result; return result;
if (result->flags & STRINGIFY_ARG)
return stringify_arg (pfile, result);
push_arg_context (pfile, result);
}
} }
/* Internal interface to get the token without macro expanding. */ /* Internal interface to get the token without macro expanding. */
...@@ -2955,7 +2991,7 @@ _cpp_get_raw_token (pfile) ...@@ -2955,7 +2991,7 @@ _cpp_get_raw_token (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
int prev_nme = prevent_macro_expansion (pfile); int prev_nme = prevent_macro_expansion (pfile);
const cpp_token *result = cpp_get_token (pfile); const cpp_token *result = _cpp_get_token (pfile);
restore_macro_expansion (pfile, prev_nme); restore_macro_expansion (pfile, prev_nme);
return result; return result;
} }
...@@ -2973,16 +3009,6 @@ lex_next (pfile, clear) ...@@ -2973,16 +3009,6 @@ lex_next (pfile, clear)
const cpp_token *old_list = list->tokens; const cpp_token *old_list = list->tokens;
unsigned int old_used = list->tokens_used; unsigned int old_used = list->tokens_used;
/* If we are currently processing a directive, do not advance. 6.10
paragraph 2: A new-line character ends the directive even if it
occurs within what would otherwise be an invocation of a
function-like macro.
It is possible that clear == 1 too; e.g. "#if funlike_macro ("
since parse_args swallowed the directive's EOF. */
if (list->directive)
return 1;
if (clear) if (clear)
{ {
/* Release all temporary tokens. */ /* Release all temporary tokens. */
...@@ -3034,18 +3060,27 @@ lex_next (pfile, clear) ...@@ -3034,18 +3060,27 @@ lex_next (pfile, clear)
return 0; return 0;
} }
/* Pops a context of the context stack. If we're at the bottom, lexes /* Pops a context off the context stack. If we're at the bottom, lexes
the next logical line. Returns 1 if we're at the end of the the next logical line. Returns EOF if we're at the end of the
argument list to the # operator, or if it is illegal to "overflow" argument list to the # operator, or if it is illegal to "overflow"
into the rest of the file (e.g. 6.10.3.1.1). */ into the rest of the file (e.g. 6.10.3.1.1). */
static int static int
do_pop_context (pfile) pop_context (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
cpp_context *context; cpp_context *context;
if (pfile->cur_context == 0) if (pfile->cur_context == 0)
{
/* If we are currently processing a directive, do not advance. 6.10
paragraph 2: A new-line character ends the directive even if it
occurs within what would otherwise be an invocation of a
function-like macro. */
if (pfile->token_list.directive)
return 1;
return lex_next (pfile, pfile->no_expand_level == UINT_MAX); return lex_next (pfile, pfile->no_expand_level == UINT_MAX);
}
/* Argument contexts, when parsing args or handling # operator /* Argument contexts, when parsing args or handling # operator
return CPP_EOF at the end. */ return CPP_EOF at the end. */
...@@ -3064,16 +3099,6 @@ do_pop_context (pfile) ...@@ -3064,16 +3099,6 @@ do_pop_context (pfile)
return 0; return 0;
} }
/* Move down the context stack, and return the next raw token. */
static const cpp_token *
pop_context (pfile)
cpp_reader *pfile;
{
if (do_pop_context (pfile))
return &eof_token;
return get_raw_token (pfile);
}
/* Turn off macro expansion at the current context level. */ /* Turn off macro expansion at the current context level. */
static unsigned int static unsigned int
prevent_macro_expansion (pfile) prevent_macro_expansion (pfile)
...@@ -3286,18 +3311,26 @@ void ...@@ -3286,18 +3311,26 @@ void
_cpp_init_input_buffer (pfile) _cpp_init_input_buffer (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
cpp_context *base;
init_trigraph_map (); init_trigraph_map ();
_cpp_init_toklist (&pfile->token_list, DUMMY_TOKEN);
pfile->no_expand_level = UINT_MAX;
pfile->context_cap = 20; pfile->context_cap = 20;
pfile->contexts = (cpp_context *)
xmalloc (pfile->context_cap * sizeof (cpp_context));
pfile->cur_context = 0; pfile->cur_context = 0;
pfile->contexts[0].u.list = &pfile->token_list;
pfile->contexts[0].posn = 0; pfile->contexts = (cpp_context *)
pfile->contexts[0].count = 0; xmalloc (pfile->context_cap * sizeof (cpp_context));
pfile->no_expand_level = UINT_MAX;
_cpp_init_toklist (&pfile->token_list, DUMMY_TOKEN); /* Clear the base context. */
base = &pfile->contexts[0];
base->u.list = &pfile->token_list;
base->posn = 0;
base->count = 0;
base->args = 0;
base->level = 0;
base->flags = 0;
base->pushed_token = 0;
} }
/* Moves to the end of the directive line, popping contexts as /* Moves to the end of the directive line, popping contexts as
...@@ -3306,17 +3339,20 @@ void ...@@ -3306,17 +3339,20 @@ void
_cpp_skip_rest_of_line (pfile) _cpp_skip_rest_of_line (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
/* Get to base context. Clear parsing args and each contexts flags, /* Discard all stacked contexts. */
since these can cause pop_context to return without popping. */ int i;
pfile->no_expand_level = UINT_MAX; for (i = pfile->cur_context; i > 0; i--)
while (pfile->cur_context != 0) if (pfile->contexts[i].args)
{ free_macro_args (pfile->contexts[i].args);
pfile->contexts[pfile->cur_context].flags = 0;
do_pop_context (pfile); if (pfile->no_expand_level <= pfile->cur_context)
} pfile->no_expand_level = 0;
pfile->cur_context = 0;
pfile->contexts[pfile->cur_context].count = 0; /* Clear the base context, and clear the directive pointer so that
pfile->contexts[pfile->cur_context].posn = 0; get_raw_token will advance to the next line. */
pfile->contexts[0].count = 0;
pfile->contexts[0].posn = 0;
pfile->token_list.directive = 0; pfile->token_list.directive = 0;
} }
...@@ -3332,8 +3368,9 @@ _cpp_run_directive (pfile, dir, buf, count) ...@@ -3332,8 +3368,9 @@ _cpp_run_directive (pfile, dir, buf, count)
if (cpp_push_buffer (pfile, (const U_CHAR *)buf, count) != NULL) if (cpp_push_buffer (pfile, (const U_CHAR *)buf, count) != NULL)
{ {
unsigned int prev_lvl = 0; unsigned int prev_lvl = 0;
/* scan the line now, else prevent_macro_expansion won't work */
do_pop_context (pfile); /* Scan the line now, else prevent_macro_expansion won't work. */
lex_next (pfile, 1);
if (! (dir->flags & EXPAND)) if (! (dir->flags & EXPAND))
prev_lvl = prevent_macro_expansion (pfile); prev_lvl = prevent_macro_expansion (pfile);
......
...@@ -250,7 +250,7 @@ get_define_node (pfile) ...@@ -250,7 +250,7 @@ get_define_node (pfile)
const cpp_token *token; const cpp_token *token;
/* Skip any -C comments. */ /* Skip any -C comments. */
while ((token = cpp_get_token (pfile))->type == CPP_COMMENT) while ((token = _cpp_get_token (pfile))->type == CPP_COMMENT)
; ;
if (token->type != CPP_NAME) if (token->type != CPP_NAME)
...@@ -307,7 +307,7 @@ do_undef (pfile) ...@@ -307,7 +307,7 @@ do_undef (pfile)
{ {
cpp_hashnode *node = get_define_node (pfile); cpp_hashnode *node = get_define_node (pfile);
if (cpp_get_token (pfile)->type != CPP_EOF) if (_cpp_get_token (pfile)->type != CPP_EOF)
cpp_pedwarn (pfile, "junk on line after #undef"); cpp_pedwarn (pfile, "junk on line after #undef");
/* 6.10.3.5 paragraph 2: [#undef] is ignored if the specified identifier /* 6.10.3.5 paragraph 2: [#undef] is ignored if the specified identifier
...@@ -343,7 +343,7 @@ parse_include (pfile, dir, trail, strp, lenp, abp) ...@@ -343,7 +343,7 @@ parse_include (pfile, dir, trail, strp, lenp, abp)
unsigned int *lenp; unsigned int *lenp;
int *abp; int *abp;
{ {
const cpp_token *name = cpp_get_token (pfile); const cpp_token *name = _cpp_get_token (pfile);
if (name->type != CPP_STRING && name->type != CPP_HEADER_NAME) if (name->type != CPP_STRING && name->type != CPP_HEADER_NAME)
{ {
...@@ -361,7 +361,7 @@ parse_include (pfile, dir, trail, strp, lenp, abp) ...@@ -361,7 +361,7 @@ parse_include (pfile, dir, trail, strp, lenp, abp)
return 1; return 1;
} }
if (!trail && cpp_get_token (pfile)->type != CPP_EOF) if (!trail && _cpp_get_token (pfile)->type != CPP_EOF)
cpp_error (pfile, "junk at end of #%s", dir); cpp_error (pfile, "junk at end of #%s", dir);
*lenp = name->val.str.len; *lenp = name->val.str.len;
...@@ -459,7 +459,7 @@ read_line_number (pfile, num) ...@@ -459,7 +459,7 @@ read_line_number (pfile, num)
cpp_reader *pfile; cpp_reader *pfile;
int *num; int *num;
{ {
const cpp_token *tok = cpp_get_token (pfile); const cpp_token *tok = _cpp_get_token (pfile);
enum cpp_ttype type = tok->type; enum cpp_ttype type = tok->type;
const U_CHAR *p = tok->val.str.text; const U_CHAR *p = tok->val.str.text;
unsigned int len = tok->val.str.len; unsigned int len = tok->val.str.len;
...@@ -519,7 +519,7 @@ do_line (pfile) ...@@ -519,7 +519,7 @@ do_line (pfile)
unsigned int len; unsigned int len;
const cpp_token *tok; const cpp_token *tok;
tok = cpp_get_token (pfile); tok = _cpp_get_token (pfile);
type = tok->type; type = tok->type;
str = tok->val.str.text; str = tok->val.str.text;
len = tok->val.str.len; len = tok->val.str.len;
...@@ -535,7 +535,7 @@ do_line (pfile) ...@@ -535,7 +535,7 @@ do_line (pfile)
old_lineno = ip->lineno; old_lineno = ip->lineno;
ip->lineno = new_lineno; ip->lineno = new_lineno;
tok = cpp_get_token (pfile); tok = _cpp_get_token (pfile);
type = tok->type; type = tok->type;
str = tok->val.str.text; str = tok->val.str.text;
len = tok->val.str.len; len = tok->val.str.len;
...@@ -645,9 +645,9 @@ do_ident (pfile) ...@@ -645,9 +645,9 @@ do_ident (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
/* Next token should be a string constant. */ /* Next token should be a string constant. */
if (cpp_get_token (pfile)->type == CPP_STRING) if (_cpp_get_token (pfile)->type == CPP_STRING)
/* And then a newline. */ /* And then a newline. */
if (cpp_get_token (pfile)->type == CPP_EOF) if (_cpp_get_token (pfile)->type == CPP_EOF)
{ {
/* Good - ship it. */ /* Good - ship it. */
pass_thru_directive (pfile); pass_thru_directive (pfile);
...@@ -725,7 +725,7 @@ do_pragma (pfile) ...@@ -725,7 +725,7 @@ do_pragma (pfile)
const cpp_token *tok; const cpp_token *tok;
int pop; int pop;
tok = cpp_get_token (pfile); tok = _cpp_get_token (pfile);
if (tok->type == CPP_EOF) if (tok->type == CPP_EOF)
return 0; return 0;
else if (tok->type != CPP_NAME) else if (tok->type != CPP_NAME)
...@@ -746,7 +746,7 @@ do_pragma_gcc (pfile) ...@@ -746,7 +746,7 @@ do_pragma_gcc (pfile)
{ {
const cpp_token *tok; const cpp_token *tok;
tok = cpp_get_token (pfile); tok = _cpp_get_token (pfile);
if (tok->type == CPP_EOF) if (tok->type == CPP_EOF)
return 1; return 1;
else if (tok->type != CPP_NAME) else if (tok->type != CPP_NAME)
...@@ -780,13 +780,13 @@ do_pragma_implementation (pfile) ...@@ -780,13 +780,13 @@ do_pragma_implementation (pfile)
{ {
/* Be quiet about `#pragma implementation' for a file only if it hasn't /* Be quiet about `#pragma implementation' for a file only if it hasn't
been included yet. */ been included yet. */
const cpp_token *tok = cpp_get_token (pfile); const cpp_token *tok = _cpp_get_token (pfile);
char *copy; char *copy;
if (tok->type == CPP_EOF) if (tok->type == CPP_EOF)
return 0; return 0;
else if (tok->type != CPP_STRING else if (tok->type != CPP_STRING
|| cpp_get_token (pfile)->type != CPP_EOF) || _cpp_get_token (pfile)->type != CPP_EOF)
{ {
cpp_error (pfile, "malformed #pragma implementation"); cpp_error (pfile, "malformed #pragma implementation");
return 1; return 1;
...@@ -822,7 +822,7 @@ do_pragma_poison (pfile) ...@@ -822,7 +822,7 @@ do_pragma_poison (pfile)
for (;;) for (;;)
{ {
tok = cpp_get_token (pfile); tok = _cpp_get_token (pfile);
if (tok->type == CPP_EOF) if (tok->type == CPP_EOF)
break; break;
if (tok->type != CPP_NAME) if (tok->type != CPP_NAME)
...@@ -887,7 +887,7 @@ do_pragma_dependency (pfile) ...@@ -887,7 +887,7 @@ do_pragma_dependency (pfile)
cpp_warning (pfile, "cannot find source %c%s%c", left, name, right); cpp_warning (pfile, "cannot find source %c%s%c", left, name, right);
else if (ordering > 0) else if (ordering > 0)
{ {
const cpp_token *msg = cpp_get_token (pfile); const cpp_token *msg = _cpp_get_token (pfile);
cpp_warning (pfile, "current file is older than %c%s%c", cpp_warning (pfile, "current file is older than %c%s%c",
left, name, right); left, name, right);
...@@ -974,7 +974,7 @@ parse_ifdef (pfile, name) ...@@ -974,7 +974,7 @@ parse_ifdef (pfile, name)
enum cpp_ttype type; enum cpp_ttype type;
const cpp_hashnode *node = 0; const cpp_hashnode *node = 0;
const cpp_token *token = cpp_get_token (pfile); const cpp_token *token = _cpp_get_token (pfile);
type = token->type; type = token->type;
if (!CPP_TRADITIONAL (pfile)) if (!CPP_TRADITIONAL (pfile))
...@@ -983,7 +983,7 @@ parse_ifdef (pfile, name) ...@@ -983,7 +983,7 @@ parse_ifdef (pfile, name)
cpp_pedwarn (pfile, "#%s with no argument", name); cpp_pedwarn (pfile, "#%s with no argument", name);
else if (type != CPP_NAME) else if (type != CPP_NAME)
cpp_pedwarn (pfile, "#%s with invalid argument", name); cpp_pedwarn (pfile, "#%s with invalid argument", name);
else if (cpp_get_token (pfile)->type != CPP_EOF) else if (_cpp_get_token (pfile)->type != CPP_EOF)
cpp_pedwarn (pfile, "garbage at end of #%s", name); cpp_pedwarn (pfile, "garbage at end of #%s", name);
} }
...@@ -1186,7 +1186,7 @@ validate_else (pfile, directive) ...@@ -1186,7 +1186,7 @@ validate_else (pfile, directive)
cpp_reader *pfile; cpp_reader *pfile;
const U_CHAR *directive; const U_CHAR *directive;
{ {
if (CPP_PEDANTIC (pfile) && cpp_get_token (pfile)->type != CPP_EOF) if (CPP_PEDANTIC (pfile) && _cpp_get_token (pfile)->type != CPP_EOF)
cpp_pedwarn (pfile, "ISO C forbids text after #%s", directive); cpp_pedwarn (pfile, "ISO C forbids text after #%s", directive);
} }
...@@ -1515,9 +1515,14 @@ cpp_push_buffer (pfile, buffer, length) ...@@ -1515,9 +1515,14 @@ cpp_push_buffer (pfile, buffer, length)
cpp_buffer *new; cpp_buffer *new;
if (++pfile->buffer_stack_depth == CPP_STACK_MAX) if (++pfile->buffer_stack_depth == CPP_STACK_MAX)
{ {
cpp_fatal (pfile, "#include recursion too deep"); cpp_fatal (pfile, "#include nested too deep");
return NULL; return NULL;
} }
if (pfile->cur_context > 0)
{
cpp_ice (pfile, "buffer pushed with contexts stacked");
_cpp_skip_rest_of_line (pfile);
}
new = xobnew (pfile->buffer_ob, cpp_buffer); new = xobnew (pfile->buffer_ob, cpp_buffer);
memset (new, 0, sizeof (cpp_buffer)); memset (new, 0, sizeof (cpp_buffer));
......
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