From 417f3e3a5efba3ed497f7971ab1254eaafadcadb Mon Sep 17 00:00:00 2001 From: Zack Weinberg Date: Tue, 11 Jul 2000 23:20:53 +0000 Subject: [multiple changes] 2000-07-11 Zack Weinberg * 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 * 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 --- gcc/ChangeLog | 42 ++++++ gcc/cppexp.c | 2 +- gcc/cpphash.c | 2 +- gcc/cpphash.h | 1 + gcc/cpplex.c | 433 +++++++++++++++++++++++++++++++--------------------------- gcc/cpplib.c | 43 +++--- 6 files changed, 304 insertions(+), 219 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index aa41bee..4550181 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,45 @@ +2000-07-11 Zack Weinberg + + * 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 + + * 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 * gensupport.c (process_rtx): Make rtl checking stop diff --git a/gcc/cppexp.c b/gcc/cppexp.c index 31b740f..e8ee20e 100644 --- a/gcc/cppexp.c +++ b/gcc/cppexp.c @@ -392,7 +392,7 @@ lex (pfile, skip_evaluation) const cpp_token *tok; retry: - tok = cpp_get_token (pfile); + tok = _cpp_get_token (pfile); switch (tok->type) { diff --git a/gcc/cpphash.c b/gcc/cpphash.c index c25a56b..1f37898 100644 --- a/gcc/cpphash.c +++ b/gcc/cpphash.c @@ -354,7 +354,7 @@ parse_define (pfile) int prev_white = 0; /* The first token after the macro's name. */ - token = cpp_get_token (pfile); + token = _cpp_get_token (pfile); /* Constraint 6.10.3.5 */ if (is__va_args__ (pfile, token - 1)) diff --git a/gcc/cpphash.h b/gcc/cpphash.h index 5cfd5a3..e90f0e4 100644 --- a/gcc/cpphash.h +++ b/gcc/cpphash.h @@ -256,6 +256,7 @@ extern void _cpp_run_directive PARAMS ((cpp_reader *, const char *, size_t)); extern unsigned int _cpp_get_line PARAMS ((cpp_reader *, unsigned int *)); +extern const cpp_token *_cpp_get_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 const cpp_token *_cpp_glue_header_name PARAMS ((cpp_reader *)); diff --git a/gcc/cpplex.c b/gcc/cpplex.c index 5b60096..a1e1ad2 100644 --- a/gcc/cpplex.c +++ b/gcc/cpplex.c @@ -417,7 +417,7 @@ _cpp_glue_header_name (pfile) for (;;) { - t = cpp_get_token (pfile); + t = _cpp_get_token (pfile); if (t->type == CPP_GREATER || t->type == CPP_EOF) break; @@ -947,7 +947,7 @@ skip_whitespace (pfile, in_directive) } /* Parse (append) an identifier. */ -static inline const U_CHAR * +static const U_CHAR * parse_name (pfile, tok, cur, rlimit) cpp_reader *pfile; cpp_token *tok; @@ -1960,7 +1960,7 @@ struct cpp_context const cpp_token **arg; /* Used for arg contexts only. */ } 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; 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, macro_args *, unsigned int *)); static int parse_args PARAMS ((cpp_reader *, cpp_hashnode *, macro_args *)); static void save_token PARAMS ((macro_args *, const cpp_token *)); -static const cpp_token *push_arg_context PARAMS ((cpp_reader *, - const cpp_token *)); -static int do_pop_context PARAMS ((cpp_reader *)); -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 int pop_context PARAMS ((cpp_reader *)); +static int push_macro_context PARAMS ((cpp_reader *, const cpp_token *)); +static void push_arg_context PARAMS ((cpp_reader *, const cpp_token *)); static void free_macro_args PARAMS ((macro_args *)); /* Free the storage allocated for macro arguments. */ @@ -2000,7 +1996,7 @@ free_macro_args (args) macro_args *args; { if (args->tokens) - free (args->tokens); + free ((PTR) args->tokens); free (args->ends); free (args); } @@ -2069,7 +2065,7 @@ is_macro_disabled (pfile, expansion, token) prev_nme = pfile->no_expand_level; pfile->no_expand_level = context - pfile->contexts; - next = cpp_get_token (pfile); + next = _cpp_get_token (pfile); restore_macro_expansion (pfile, prev_nme); if (next->type != CPP_OPEN_PAREN) { @@ -2096,7 +2092,8 @@ save_token (args, token) { args->capacity += args->capacity + 100; 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; } @@ -2117,7 +2114,7 @@ parse_arg (pfile, var_args, paren_context, args, pcount) for (count = 0;; count++) { - token = cpp_get_token (pfile); + token = _cpp_get_token (pfile); switch (token->type) { @@ -2511,97 +2508,100 @@ maybe_paste_with_next (pfile, token) cpp_context *context = CURRENT_CONTEXT (pfile); /* 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. */ - if (pfile->paste_level) - return token; - - /* Suppress macro expansion for next token, but don't conflict with - the other method of suppression. If it is an argument, macro - expansion within the argument will still occur. */ - pfile->paste_level = pfile->cur_context; - second = cpp_get_token (pfile); - pfile->paste_level = 0; - - /* Ignore placemarker argument tokens (cannot be from an empty macro - since macros are not expanded). */ - if (token->type == CPP_PLACEMARKER) - pasted = duplicate_token (pfile, second); - else if (second->type == CPP_PLACEMARKER) + while ((token->flags & PASTE_LEFT) + || ((context->flags & CONTEXT_PASTEL) + && context->posn == context->count)) { - cpp_context *mac_context = CURRENT_CONTEXT (pfile) - 1; - /* GCC has special extended semantics for a ## b where b is a - varargs parameter: a disappears if b consists of no tokens. - This extension is deprecated. */ - if ((mac_context->u.list->flags & GNU_REST_ARGS) - && (mac_context->u.list->tokens[mac_context->posn - 1].val.aux + 1 - == (unsigned) mac_context->u.list->paramc)) + /* Suppress macro expansion for next token, but don't conflict + with the other method of suppression. If it is an argument, + macro expansion within the argument will still occur. */ + pfile->paste_level = pfile->cur_context; + second = _cpp_get_token (pfile); + pfile->paste_level = 0; + + /* Ignore placemarker argument tokens (cannot be from an empty + macro since macros are not expanded). */ + if (token->type == CPP_PLACEMARKER) + pasted = duplicate_token (pfile, second); + else if (second->type == CPP_PLACEMARKER) { - cpp_warning (pfile, "deprecated GNU ## extension used"); - pasted = duplicate_token (pfile, second); + cpp_context *mac_context = CURRENT_CONTEXT (pfile) - 1; + /* GCC has special extended semantics for a ## b where b is + a varargs parameter: a disappears if b consists of no + tokens. This extension is deprecated. */ + if ((mac_context->u.list->flags & GNU_REST_ARGS) + && (mac_context->u.list->tokens[mac_context->posn-1].val.aux + 1 + == (unsigned) mac_context->u.list->paramc)) + { + cpp_warning (pfile, "deprecated GNU ## extension used"); + pasted = duplicate_token (pfile, second); + } + else + pasted = duplicate_token (pfile, token); } else - pasted = duplicate_token (pfile, token); - } - else - { - int digraph = 0; - enum cpp_ttype type = can_paste (pfile, token, second, &digraph); - - if (type == CPP_EOF) { - if (CPP_OPTION (pfile, warn_paste)) - cpp_warning (pfile, - "pasting would not give a valid preprocessing token"); - _cpp_push_token (pfile, second); - return token; - } + int digraph = 0; + enum cpp_ttype type = can_paste (pfile, token, second, &digraph); - if (type == CPP_NAME || type == CPP_NUMBER) - { - /* Join spellings. */ - U_CHAR *buf, *end; + if (type == CPP_EOF) + { + if (CPP_OPTION (pfile, warn_paste)) + cpp_warning (pfile, + "pasting would not give a valid preprocessing token"); + _cpp_push_token (pfile, second); + return token; + } - pasted = get_temp_token (pfile); - buf = (U_CHAR *) alloca (TOKEN_LEN (token) + TOKEN_LEN (second)); - end = spell_token (pfile, token, buf); - end = spell_token (pfile, second, end); - *end = '\0'; + if (type == CPP_NAME || type == CPP_NUMBER) + { + /* Join spellings. */ + U_CHAR *buf, *end; + + pasted = get_temp_token (pfile); + buf = (U_CHAR *) alloca (TOKEN_LEN (token) + TOKEN_LEN (second)); + end = spell_token (pfile, token, buf); + end = spell_token (pfile, second, end); + *end = '\0'; - if (type == CPP_NAME) - pasted->val.node = cpp_lookup (pfile, buf, end - buf); + if (type == CPP_NAME) + pasted->val.node = cpp_lookup (pfile, buf, end - buf); + else + { + pasted->val.str.text = uxstrdup (buf); + pasted->val.str.len = end - buf; + } + } + else if (type == CPP_WCHAR || type == CPP_WSTRING) + pasted = duplicate_token (pfile, second); else { - pasted->val.str.text = uxstrdup (buf); - pasted->val.str.len = end - buf; + pasted = get_temp_token (pfile); + pasted->val.integer = 0; } - } - else if (type == CPP_WCHAR || type == CPP_WSTRING) - pasted = duplicate_token (pfile, second); - else - { - pasted = get_temp_token (pfile); - pasted->val.integer = 0; + + pasted->type = type; + pasted->flags = digraph ? DIGRAPH : 0; } - pasted->type = type; - pasted->flags = digraph ? DIGRAPH : 0; + /* The pasted token gets the whitespace flags and position of the + first token, the PASTE_LEFT flag of the second token, plus the + PASTED flag to indicate it is the result of a paste. However, we + want to preserve the DIGRAPH flag. */ + pasted->flags &= ~(PREV_WHITE | BOL | PASTE_LEFT); + pasted->flags |= ((token->flags & (PREV_WHITE | BOL)) + | (second->flags & PASTE_LEFT) | PASTED); + pasted->col = token->col; + pasted->line = token->line; + + /* See if there is another token to be pasted onto the one we just + constructed. */ + token = pasted; + context = CURRENT_CONTEXT (pfile); + /* and loop */ } - - /* The pasted token gets the whitespace flags and position of the - first token, the PASTE_LEFT flag of the second token, plus the - PASTED flag to indicate it is the result of a paste. However, we - want to preserve the DIGRAPH flag. */ - pasted->flags &= ~(PREV_WHITE | BOL | PASTE_LEFT); - pasted->flags |= ((token->flags & (PREV_WHITE | BOL)) - | (second->flags & PASTE_LEFT) | PASTED); - pasted->col = token->col; - pasted->line = token->line; - - return maybe_paste_with_next (pfile, pasted); + return token; } /* Convert a token sequence to a single string token according to the @@ -2617,13 +2617,14 @@ stringify_arg (pfile, token) unsigned int prev_value, backslash_count = 0; unsigned int buf_used = 0, whitespace = 0, buf_cap = INIT_SIZE; + push_arg_context (pfile, token); prev_value = prevent_macro_expansion (pfile); main_buf = (unsigned char *) xmalloc (buf_cap); result = get_temp_token (pfile); 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; unsigned char *buf; @@ -2690,21 +2691,15 @@ expand_context_stack (pfile) /* Push the context of macro NODE onto the context stack. TOKEN is the CPP_NAME token invoking the macro. */ -static const cpp_token * -push_macro_context (pfile, node, token) +static int +push_macro_context (pfile, token) cpp_reader *pfile; - cpp_hashnode *node; const cpp_token *token; { unsigned char orig_flags; macro_args *args; cpp_context *context; - - if (pfile->cur_context > CPP_STACK_MAX) - { - cpp_error (pfile, "infinite macro recursion invoking '%s'", node->name); - return token; - } + cpp_hashnode *node = token->val.node; /* Token's flags may change when parsing args containing a nested invocation of this macro. */ @@ -2731,7 +2726,7 @@ push_macro_context (pfile, node, token) if (error) { free_macro_args (args); - return token; + return 1; } } @@ -2753,12 +2748,12 @@ push_macro_context (pfile, node, token) be one, empty macros are a single placemarker token. */ 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. TOKEN is the MACRO_ARG token representing the argument expansion. */ -static const cpp_token * +static void push_arg_context (pfile, token) cpp_reader *pfile; const cpp_token *token; @@ -2792,15 +2787,10 @@ push_arg_context (pfile, token) token->flags & (PREV_WHITE | BOL)); } - if (token->flags & STRINGIFY_ARG) - return stringify_arg (pfile, token); - if (token->flags & PASTE_LEFT) context->flags |= CONTEXT_PASTEL; if (pfile->paste_level) context->flags |= CONTEXT_PASTER; - - return get_raw_token (pfile); } /* "Unget" a token. It is effectively inserted in the token queue and @@ -2859,58 +2849,92 @@ cpp_get_token (pfile) cpp_reader *pfile; { const cpp_token *token; - cpp_hashnode *node; - - /* Loop till we hit a non-directive, non-skipped, non-placemarker token. */ + /* Loop till we hit a non-directive, non-placemarker token. */ for (;;) { - token = get_raw_token (pfile); - if (token->flags & BOL && token->type == CPP_HASH + token = _cpp_get_token (pfile); + + if (token->type == CPP_PLACEMARKER) + continue; + + if (token->type == CPP_HASH && token->flags & BOL && pfile->token_list.directive) { process_directive (pfile, token); 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. */ if (token->type == CPP_EOF) 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); continue; } - break; - } - /* 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 - be taken as a control macro. */ - pfile->potential_control_macro = 0; + /* 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 + be taken as a control macro. */ + pfile->potential_control_macro = 0; - token = maybe_paste_with_next (pfile, token); + /* See if there's a token to paste with this one. */ + if (!pfile->paste_level) + token = maybe_paste_with_next (pfile, token); - if (token->type != CPP_NAME) - return token; + /* If it isn't a macro, return it now. */ + if (token->type != CPP_NAME + || token->val.node->type == T_VOID) + return token; - /* Is macro expansion disabled in general? */ - if (pfile->no_expand_level == pfile->cur_context || pfile->paste_level) - return token; + /* Is macro expansion disabled in general? */ + if (pfile->no_expand_level == pfile->cur_context || pfile->paste_level) + return token; - node = token->val.node; - if (node->type == T_VOID) - return token; + node = token->val.node; + if (node->type != T_MACRO) + return special_symbol (pfile, node, token); - if (node->type == T_MACRO) - { if (is_macro_disabled (pfile, node->value.expansion, token)) return token; - return push_macro_context (pfile, node, token); + if (pfile->cur_context > CPP_STACK_MAX) + { + cpp_error (pfile, "macros nested too deep invoking '%s'", node->name); + return 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 @@ -2920,33 +2944,45 @@ get_raw_token (pfile) cpp_reader *pfile; { const cpp_token *result; - cpp_context *context = CURRENT_CONTEXT (pfile); + cpp_context *context; - if (context->pushed_token) - { - result = context->pushed_token; - context->pushed_token = 0; - } - else if (context->posn == context->count) - result = pop_context (pfile); - else + for (;;) { - if (IS_ARG_CONTEXT (context)) + context = CURRENT_CONTEXT (pfile); + if (context->pushed_token) { - result = context->u.arg[context->posn++]; - if (result == 0) + result = context->pushed_token; + context->pushed_token = 0; + } + else if (context->posn == context->count) + { + if (pop_context (pfile)) + return &eof_token; + continue; + } + else + { + if (IS_ARG_CONTEXT (context)) { - context->flags ^= CONTEXT_RAW; result = context->u.arg[context->posn++]; + if (result == 0) + { + context->flags ^= CONTEXT_RAW; + result = context->u.arg[context->posn++]; + } + return result; /* Cannot be a CPP_MACRO_ARG */ } - return result; /* Cannot be a CPP_MACRO_ARG */ + result = &context->u.list->tokens[context->posn++]; } - result = &context->u.list->tokens[context->posn++]; - } - if (result->type == CPP_MACRO_ARG) - result = push_arg_context (pfile, result); - return result; + if (result->type != CPP_MACRO_ARG) + 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. */ @@ -2955,7 +2991,7 @@ _cpp_get_raw_token (pfile) cpp_reader *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); return result; } @@ -2973,16 +3009,6 @@ lex_next (pfile, clear) const cpp_token *old_list = list->tokens; 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) { /* Release all temporary tokens. */ @@ -3034,18 +3060,27 @@ lex_next (pfile, clear) return 0; } -/* Pops a context of the context stack. If we're at the bottom, lexes - the next logical line. Returns 1 if we're at the end of the +/* Pops a context off the context stack. If we're at the bottom, lexes + 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" into the rest of the file (e.g. 6.10.3.1.1). */ static int -do_pop_context (pfile) +pop_context (pfile) cpp_reader *pfile; { cpp_context *context; if (pfile->cur_context == 0) - return lex_next (pfile, pfile->no_expand_level == UINT_MAX); + { + /* 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); + } /* Argument contexts, when parsing args or handling # operator return CPP_EOF at the end. */ @@ -3064,16 +3099,6 @@ do_pop_context (pfile) 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. */ static unsigned int prevent_macro_expansion (pfile) @@ -3286,18 +3311,26 @@ void _cpp_init_input_buffer (pfile) cpp_reader *pfile; { + cpp_context *base; + init_trigraph_map (); + _cpp_init_toklist (&pfile->token_list, DUMMY_TOKEN); + pfile->no_expand_level = UINT_MAX; pfile->context_cap = 20; - pfile->contexts = (cpp_context *) - xmalloc (pfile->context_cap * sizeof (cpp_context)); pfile->cur_context = 0; - pfile->contexts[0].u.list = &pfile->token_list; - pfile->contexts[0].posn = 0; - pfile->contexts[0].count = 0; - pfile->no_expand_level = UINT_MAX; + pfile->contexts = (cpp_context *) + xmalloc (pfile->context_cap * sizeof (cpp_context)); - _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 @@ -3306,17 +3339,20 @@ void _cpp_skip_rest_of_line (pfile) cpp_reader *pfile; { - /* Get to base context. Clear parsing args and each contexts flags, - since these can cause pop_context to return without popping. */ - pfile->no_expand_level = UINT_MAX; - while (pfile->cur_context != 0) - { - pfile->contexts[pfile->cur_context].flags = 0; - do_pop_context (pfile); - } + /* Discard all stacked contexts. */ + int i; + for (i = pfile->cur_context; i > 0; i--) + if (pfile->contexts[i].args) + free_macro_args (pfile->contexts[i].args); + + if (pfile->no_expand_level <= pfile->cur_context) + pfile->no_expand_level = 0; + pfile->cur_context = 0; - pfile->contexts[pfile->cur_context].count = 0; - pfile->contexts[pfile->cur_context].posn = 0; + /* Clear the base context, and clear the directive pointer so that + get_raw_token will advance to the next line. */ + pfile->contexts[0].count = 0; + pfile->contexts[0].posn = 0; pfile->token_list.directive = 0; } @@ -3332,8 +3368,9 @@ _cpp_run_directive (pfile, dir, buf, count) if (cpp_push_buffer (pfile, (const U_CHAR *)buf, count) != NULL) { 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)) prev_lvl = prevent_macro_expansion (pfile); diff --git a/gcc/cpplib.c b/gcc/cpplib.c index f6108f4..71859d7 100644 --- a/gcc/cpplib.c +++ b/gcc/cpplib.c @@ -250,7 +250,7 @@ get_define_node (pfile) const cpp_token *token; /* 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) @@ -307,7 +307,7 @@ do_undef (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"); /* 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) unsigned int *lenp; 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) { @@ -361,7 +361,7 @@ parse_include (pfile, dir, trail, strp, lenp, abp) 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); *lenp = name->val.str.len; @@ -459,7 +459,7 @@ read_line_number (pfile, num) cpp_reader *pfile; int *num; { - const cpp_token *tok = cpp_get_token (pfile); + const cpp_token *tok = _cpp_get_token (pfile); enum cpp_ttype type = tok->type; const U_CHAR *p = tok->val.str.text; unsigned int len = tok->val.str.len; @@ -519,7 +519,7 @@ do_line (pfile) unsigned int len; const cpp_token *tok; - tok = cpp_get_token (pfile); + tok = _cpp_get_token (pfile); type = tok->type; str = tok->val.str.text; len = tok->val.str.len; @@ -535,7 +535,7 @@ do_line (pfile) old_lineno = ip->lineno; ip->lineno = new_lineno; - tok = cpp_get_token (pfile); + tok = _cpp_get_token (pfile); type = tok->type; str = tok->val.str.text; len = tok->val.str.len; @@ -645,9 +645,9 @@ do_ident (pfile) cpp_reader *pfile; { /* 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. */ - if (cpp_get_token (pfile)->type == CPP_EOF) + if (_cpp_get_token (pfile)->type == CPP_EOF) { /* Good - ship it. */ pass_thru_directive (pfile); @@ -725,7 +725,7 @@ do_pragma (pfile) const cpp_token *tok; int pop; - tok = cpp_get_token (pfile); + tok = _cpp_get_token (pfile); if (tok->type == CPP_EOF) return 0; else if (tok->type != CPP_NAME) @@ -746,7 +746,7 @@ do_pragma_gcc (pfile) { const cpp_token *tok; - tok = cpp_get_token (pfile); + tok = _cpp_get_token (pfile); if (tok->type == CPP_EOF) return 1; else if (tok->type != CPP_NAME) @@ -780,13 +780,13 @@ do_pragma_implementation (pfile) { /* Be quiet about `#pragma implementation' for a file only if it hasn't been included yet. */ - const cpp_token *tok = cpp_get_token (pfile); + const cpp_token *tok = _cpp_get_token (pfile); char *copy; if (tok->type == CPP_EOF) return 0; 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"); return 1; @@ -822,7 +822,7 @@ do_pragma_poison (pfile) for (;;) { - tok = cpp_get_token (pfile); + tok = _cpp_get_token (pfile); if (tok->type == CPP_EOF) break; if (tok->type != CPP_NAME) @@ -887,7 +887,7 @@ do_pragma_dependency (pfile) cpp_warning (pfile, "cannot find source %c%s%c", left, name, right); 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", left, name, right); @@ -974,7 +974,7 @@ parse_ifdef (pfile, name) enum cpp_ttype type; const cpp_hashnode *node = 0; - const cpp_token *token = cpp_get_token (pfile); + const cpp_token *token = _cpp_get_token (pfile); type = token->type; if (!CPP_TRADITIONAL (pfile)) @@ -983,7 +983,7 @@ parse_ifdef (pfile, name) cpp_pedwarn (pfile, "#%s with no argument", name); else if (type != CPP_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); } @@ -1186,7 +1186,7 @@ validate_else (pfile, directive) cpp_reader *pfile; 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); } @@ -1515,9 +1515,14 @@ cpp_push_buffer (pfile, buffer, length) cpp_buffer *new; if (++pfile->buffer_stack_depth == CPP_STACK_MAX) { - cpp_fatal (pfile, "#include recursion too deep"); + cpp_fatal (pfile, "#include nested too deep"); 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); memset (new, 0, sizeof (cpp_buffer)); -- cgit v1.1