OSDN Git Service

2000-07-11 Zack Weinberg <zack@wolery.cumb.org>
authorzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 Jul 2000 23:20:53 +0000 (23:20 +0000)
committerzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 Jul 2000 23:20:53 +0000 (23:20 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@34972 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cppexp.c
gcc/cpphash.c
gcc/cpphash.h
gcc/cpplex.c
gcc/cpplib.c

index aa41bee..4550181 100644 (file)
@@ -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
index 31b740f..e8ee20e 100644 (file)
@@ -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)
     {
index c25a56b..1f37898 100644 (file)
@@ -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))
index 5cfd5a3..e90f0e4 100644 (file)
@@ -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 *));
index 5b60096..a1e1ad2 100644 (file)
@@ -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);
 
index f6108f4..71859d7 100644 (file)
@@ -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));