aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorZack Weinberg <zack@gcc.gnu.org>2000-07-11 23:20:53 +0000
committerZack Weinberg <zack@gcc.gnu.org>2000-07-11 23:20:53 +0000
commit417f3e3a5efba3ed497f7971ab1254eaafadcadb (patch)
tree976249a00737110d95a5b5c760a60c97bb68595a /gcc
parent268afb999d5d67e4083d42c64d32d49df28dee0e (diff)
downloadgcc-417f3e3a5efba3ed497f7971ab1254eaafadcadb.zip
gcc-417f3e3a5efba3ed497f7971ab1254eaafadcadb.tar.gz
gcc-417f3e3a5efba3ed497f7971ab1254eaafadcadb.tar.bz2
[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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog42
-rw-r--r--gcc/cppexp.c2
-rw-r--r--gcc/cpphash.c2
-rw-r--r--gcc/cpphash.h1
-rw-r--r--gcc/cpplex.c433
-rw-r--r--gcc/cpplib.c43
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 <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>
* 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));