OSDN Git Service

PR c/5420:
[pf3gnuchains/gcc-fork.git] / gcc / cppmacro.c
index ad4cfed..538c689 100644 (file)
@@ -1,6 +1,6 @@
 /* Part of CPP library.  (Macro and #define handling.)
    Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1998,
-   1999, 2000, 2001 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
    Written by Per Bothner, 1994.
    Based on CCCP program by Paul Rubin, June 1986
    Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -25,20 +25,18 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
 #include "config.h"
 #include "system.h"
-#include "intl.h"              /* for _("<command line>") below.  */
 #include "cpplib.h"
 #include "cpphash.h"
 
 struct cpp_macro
 {
   cpp_hashnode **params;       /* Parameters, if any.  */
-  cpp_token *expansion;                /* First token of replacement list.   */
+  cpp_token *expansion;                /* First token of replacement list.  */
   unsigned int line;           /* Starting line number.  */
   unsigned int count;          /* Number of tokens in expansion.  */
   unsigned short paramc;       /* Number of parameters.  */
   unsigned int fun_like : 1;   /* If a function-like macro.  */
   unsigned int variadic : 1;   /* If a variadic macro.  */
-  unsigned int disabled : 1;   /* If macro is disabled.  */
   unsigned int syshdr   : 1;   /* If macro defined in system header.  */
 };
 
@@ -46,7 +44,7 @@ typedef struct macro_arg macro_arg;
 struct macro_arg
 {
   const cpp_token **first;     /* First token in unexpanded argument.  */
-  const cpp_token **expanded;  /* Macro-expanded argument.   */
+  const cpp_token **expanded;  /* Macro-expanded argument.  */
   const cpp_token *stringified;        /* Stringified argument.  */
   unsigned int count;          /* # of tokens in argument.  */
   unsigned int expanded_count; /* # of tokens in expanded argument.  */
@@ -55,11 +53,11 @@ struct macro_arg
 /* Macro expansion.  */
 
 static int enter_macro_context PARAMS ((cpp_reader *, cpp_hashnode *));
-static const cpp_token *builtin_macro PARAMS ((cpp_reader *, cpp_hashnode *));
+static int builtin_macro PARAMS ((cpp_reader *, cpp_hashnode *));
 static void push_token_context
-  PARAMS ((cpp_reader *, cpp_macro *, const cpp_token *, unsigned int));
+  PARAMS ((cpp_reader *, cpp_hashnode *, const cpp_token *, unsigned int));
 static void push_ptoken_context
-  PARAMS ((cpp_reader *, cpp_macro *, _cpp_buff *,
+  PARAMS ((cpp_reader *, cpp_hashnode *, _cpp_buff *,
           const cpp_token **, unsigned int));
 static _cpp_buff *collect_args PARAMS ((cpp_reader *, const cpp_hashnode *));
 static cpp_context *next_context PARAMS ((cpp_reader *));
@@ -71,19 +69,19 @@ static unsigned char *quote_string PARAMS ((unsigned char *,
                                            unsigned int));
 static const cpp_token *new_string_token PARAMS ((cpp_reader *, U_CHAR *,
                                                  unsigned int));
-static const cpp_token *new_number_token PARAMS ((cpp_reader *, int));
+static const cpp_token *new_number_token PARAMS ((cpp_reader *, unsigned int));
 static const cpp_token *stringify_arg PARAMS ((cpp_reader *, macro_arg *));
 static void paste_all_tokens PARAMS ((cpp_reader *, const cpp_token *));
-static int paste_tokens PARAMS ((cpp_reader *, cpp_token *,
-                                const cpp_token *));
-static int funlike_invocation_p PARAMS ((cpp_reader *, const cpp_hashnode *));
-static void replace_args PARAMS ((cpp_reader *, cpp_macro *, macro_arg *));
+static bool paste_tokens PARAMS ((cpp_reader *, const cpp_token **,
+                                 const cpp_token *));
+static void replace_args PARAMS ((cpp_reader *, cpp_hashnode *, macro_arg *));
+static _cpp_buff *funlike_invocation_p PARAMS ((cpp_reader *, cpp_hashnode *));
 
 /* #define directive parsing and handling.  */
 
 static cpp_token *alloc_expansion_token PARAMS ((cpp_reader *, cpp_macro *));
 static cpp_token *lex_expansion_token PARAMS ((cpp_reader *, cpp_macro *));
-static int warn_of_redefinition PARAMS ((cpp_reader *, const cpp_hashnode *,
+static int warn_of_redefinition PARAMS ((const cpp_hashnode *,
                                         const cpp_macro *));
 static int save_parameter PARAMS ((cpp_reader *, cpp_macro *, cpp_hashnode *));
 static int parse_params PARAMS ((cpp_reader *, cpp_macro *));
@@ -113,12 +111,13 @@ new_string_token (pfile, text, len)
 static const cpp_token *
 new_number_token (pfile, number)
      cpp_reader *pfile;
-     int number;
+     unsigned int number;
 {
   cpp_token *token = _cpp_temp_token (pfile);
-  unsigned char *buf = _cpp_pool_alloc (&pfile->ident_pool, 20);
+  /* 21 bytes holds all NUL-terminated unsigned 64-bit numbers.  */
+  unsigned char *buf = _cpp_unaligned_alloc (pfile, 21);
 
-  sprintf ((char *) buf, "%d", number);
+  sprintf ((char *) buf, "%u", number);
   token->type = CPP_NUMBER;
   token->val.str.text = buf;
   token->val.str.len = ustrlen (buf);
@@ -132,17 +131,22 @@ static const char * const monthnames[] =
   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
 };
 
-/* Handle builtin macros like __FILE__.  */
-static const cpp_token *
+/* Handle builtin macros like __FILE__, and push the resulting token
+   on the context stack.  Also handles _Pragma, for which no new token
+   is created.  Returns 1 if it generates a new token context, 0 to
+   return the token to the caller.  */
+static int
 builtin_macro (pfile, node)
      cpp_reader *pfile;
      cpp_hashnode *node;
 {
+  const cpp_token *result;
+
   switch (node->value.builtin)
     {
     default:
-      cpp_ice (pfile, "invalid builtin macro \"%s\"", NODE_NAME (node));
-      return new_number_token (pfile, 1);
+      cpp_ice (pfile, "invalid built-in macro \"%s\"", NODE_NAME (node));
+      return 0;
 
     case BT_FILE:
     case BT_BASE_FILE:
@@ -158,31 +162,36 @@ builtin_macro (pfile, node)
 
        name = map->to_file;
        len = strlen (name);
-       buf = _cpp_pool_alloc (&pfile->ident_pool, len * 4 + 1);
+       buf = _cpp_unaligned_alloc (pfile, len * 4 + 1);
        len = quote_string (buf, (const unsigned char *) name, len) - buf;
 
-       return new_string_token (pfile, buf, len);
+       result = new_string_token (pfile, buf, len);
       }
-       
+      break;
+
     case BT_INCLUDE_LEVEL:
       /* The line map depth counts the primary source as level 1, but
         historically __INCLUDE_DEPTH__ has called the primary source
         level 0.  */
-      return new_number_token (pfile, pfile->line_maps.depth - 1);
+      result = new_number_token (pfile, pfile->line_maps.depth - 1);
+      break;
 
     case BT_SPECLINE:
       /* If __LINE__ is embedded in a macro, it must expand to the
         line of the macro's invocation, not its definition.
         Otherwise things like assert() will not work properly.  */
-      return new_number_token (pfile, SOURCE_LINE (pfile->map,
-                                                  pfile->cur_token[-1].line));
+      result = new_number_token (pfile,
+                                SOURCE_LINE (pfile->map,
+                                             pfile->cur_token[-1].line));
+      break;
 
     case BT_STDC:
       {
        int stdc = (!CPP_IN_SYSTEM_HEADER (pfile)
                    || pfile->spec_nodes.n__STRICT_ANSI__->type != NT_VOID);
-       return new_number_token (pfile, stdc);
+       result = new_number_token (pfile, stdc);
       }
+      break;
 
     case BT_DATE:
     case BT_TIME:
@@ -196,7 +205,7 @@ builtin_macro (pfile, node)
          struct tm *tb = localtime (&tt);
 
          pfile->date.val.str.text =
-           _cpp_pool_alloc (&pfile->ident_pool, sizeof ("Oct 11 1347"));
+           _cpp_unaligned_alloc (pfile, sizeof ("Oct 11 1347"));
          pfile->date.val.str.len = sizeof ("Oct 11 1347") - 1;
          pfile->date.type = CPP_STRING;
          pfile->date.flags = 0;
@@ -204,7 +213,7 @@ builtin_macro (pfile, node)
                   monthnames[tb->tm_mon], tb->tm_mday, tb->tm_year + 1900);
 
          pfile->time.val.str.text =
-           _cpp_pool_alloc (&pfile->ident_pool, sizeof ("12:34:56"));
+           _cpp_unaligned_alloc (pfile, sizeof ("12:34:56"));
          pfile->time.val.str.len = sizeof ("12:34:56") - 1;
          pfile->time.type = CPP_STRING;
          pfile->time.flags = 0;
@@ -212,12 +221,29 @@ builtin_macro (pfile, node)
                   tb->tm_hour, tb->tm_min, tb->tm_sec);
        }
 
-      return node->value.builtin == BT_DATE ? &pfile->date: &pfile->time;
+      if (node->value.builtin == BT_DATE)
+       result = &pfile->date;
+      else
+       result = &pfile->time;
+      break;
+
+    case BT_PRAGMA:
+      /* Don't interpret _Pragma within directives.  The standard is
+         not clear on this, but to me this makes most sense.  */
+      if (pfile->state.in_directive)
+       return 0;
+
+      _cpp_do__Pragma (pfile);
+      return 1;
     }
+
+  push_token_context (pfile, NULL, result, 1);
+  return 1;
 }
 
-/* Adds backslashes before all backslashes and double quotes appearing
-   in strings.  Non-printable characters are converted to octal.  */
+/* Copies SRC, of length LEN, to DEST, adding backslashes before all
+   backslashes and double quotes.  Non-printable characters are
+   converted to octal.  DEST must be of sufficient size.  */
 static U_CHAR *
 quote_string (dest, src, len)
      U_CHAR *dest;
@@ -248,24 +274,22 @@ quote_string (dest, src, len)
   return dest;
 }
 
-/* Convert a token sequence to a single string token according to the
-   rules of the ISO C #-operator.  */
+/* Convert a token sequence ARG to a single string token according to
+   the rules of the ISO C #-operator.  */
 static const cpp_token *
 stringify_arg (pfile, arg)
      cpp_reader *pfile;
      macro_arg *arg;
 {
-  cpp_pool *pool = &pfile->ident_pool;
-  unsigned char *start = POOL_FRONT (pool);
-  unsigned int i, escape_it, total_len = 0, backslash_count = 0;
+  unsigned char *dest = BUFF_FRONT (pfile->u_buff);
+  unsigned int i, escape_it, backslash_count = 0;
   const cpp_token *source = NULL;
+  size_t len;
 
   /* Loop, reading in the argument's tokens.  */
   for (i = 0; i < arg->count; i++)
     {
-      unsigned char *dest;
       const cpp_token *token = arg->first[i];
-      unsigned int len;
 
       if (token->type == CPP_PADDING)
        {
@@ -277,21 +301,22 @@ stringify_arg (pfile, arg)
       escape_it = (token->type == CPP_STRING || token->type == CPP_WSTRING
                   || token->type == CPP_CHAR || token->type == CPP_WCHAR);
 
+      /* Room for each char being written in octal, initial space and
+        final NUL.  */
       len = cpp_token_len (token);
       if (escape_it)
-       /* Worst case is each char is octal.  */
        len *= 4;
-      len += 2;                        /* Room for initial space and final NUL.  */
+      len += 2;
 
-      dest = &start[total_len];
-      if (dest + len > POOL_LIMIT (pool))
+      if ((size_t) (BUFF_LIMIT (pfile->u_buff) - dest) < len)
        {
-         _cpp_next_chunk (pool, len, (unsigned char **) &start);
-         dest = &start[total_len];
+         size_t len_so_far = dest - BUFF_FRONT (pfile->u_buff);
+         _cpp_extend_buff (pfile, &pfile->u_buff, len);
+         dest = BUFF_FRONT (pfile->u_buff) + len_so_far;
        }
 
       /* Leading white space?  */
-      if (total_len)
+      if (dest != BUFF_FRONT (pfile->u_buff))
        {
          if (source == NULL)
            source = token;
@@ -302,15 +327,14 @@ stringify_arg (pfile, arg)
 
       if (escape_it)
        {
-         unsigned char *buf = (unsigned char *) xmalloc (len);
-
+         _cpp_buff *buff = _cpp_get_buff (pfile, len);
+         unsigned char *buf = BUFF_FRONT (buff);
          len = cpp_spell_token (pfile, token, buf) - buf;
          dest = quote_string (dest, buf, len);
-         free (buf);
+         _cpp_release_buff (pfile, buff);
        }
       else
        dest = cpp_spell_token (pfile, token, dest);
-      total_len = dest - start;
 
       if (token->type == CPP_OTHER && token->val.c == '\\')
        backslash_count++;
@@ -322,101 +346,75 @@ stringify_arg (pfile, arg)
   if (backslash_count & 1)
     {
       cpp_warning (pfile, "invalid string literal, ignoring final '\\'");
-      total_len--;
+      dest--;
     }
 
   /* Commit the memory, including NUL, and return the token.  */
-  POOL_COMMIT (pool, total_len + 1);
-  return new_string_token (pfile, start, total_len);
+  len = dest - BUFF_FRONT (pfile->u_buff);
+  BUFF_FRONT (pfile->u_buff) = dest + 1;
+  return new_string_token (pfile, dest - len, len);
 }
 
-/* Try to paste two tokens.  On success, the LHS becomes the pasted
-   token, and 0 is returned.  For failure, we update the flags of the
-   RHS appropriately and return non-zero.  */
-static int
-paste_tokens (pfile, lhs, rhs)
+/* Try to paste two tokens.  On success, return non-zero.  In any
+   case, PLHS is updated to point to the pasted token, which is
+   guaranteed to not have the PASTE_LEFT flag set.  */
+static bool
+paste_tokens (pfile, plhs, rhs)
      cpp_reader *pfile;
-     cpp_token *lhs;
-     const cpp_token *rhs;
+     const cpp_token **plhs, *rhs;
 {
-  unsigned char flags = 0;
-  int digraph = 0;
-  enum cpp_ttype type;
-
-  type = cpp_can_paste (pfile, lhs, rhs, &digraph);
-  
-  if (type == CPP_EOF)
-    {
-      /* Mandatory warning for all apart from assembler.  */
-      if (CPP_OPTION (pfile, lang) != CLK_ASM)
-       cpp_warning (pfile,
-        "pasting \"%s\" and \"%s\" does not give a valid preprocessing token",
-                    cpp_token_as_text (pfile, lhs),
-                    cpp_token_as_text (pfile, rhs));
-      return 1;
-    }
-
-  if (digraph)
-    flags |= DIGRAPH;
-
-  /* Identifiers and numbers need spellings to be pasted.  */
-  if (type == CPP_NAME || type == CPP_NUMBER)
-    {
-      unsigned int total_len = cpp_token_len (lhs) + cpp_token_len (rhs);
-      unsigned char *result, *end;
-
-      result = _cpp_pool_alloc (&pfile->ident_pool, total_len + 1);
-
-      /* Paste the spellings and null terminate.  */
-      end = cpp_spell_token (pfile, rhs, cpp_spell_token (pfile, lhs, result));
-      *end = '\0';
-      total_len = end - result;
-
-      if (type == CPP_NAME)
-       {
-         lhs->val.node = cpp_lookup (pfile, result, total_len);
-         if (lhs->val.node->flags & NODE_OPERATOR)
-           {
-             flags |= NAMED_OP;
-             lhs->type = lhs->val.node->value.operator;
-           }
-       }
-      else
-       {
-         lhs->val.str.text = result;
-         lhs->val.str.len = total_len;
-       }
-    }
-  else if (type == CPP_WCHAR || type == CPP_WSTRING)
-    lhs->val.str = rhs->val.str;
-
-  /* Set type and flags after pasting spellings.  */
-  lhs->type = type;
-  lhs->flags = flags;
-
-  return 0;
+  unsigned char *buf, *end;
+  const cpp_token *lhs;
+  unsigned int len;
+  bool valid;
+
+  lhs = *plhs;
+  len = cpp_token_len (lhs) + cpp_token_len (rhs) + 1;
+  buf = (unsigned char *) alloca (len);
+  end = cpp_spell_token (pfile, lhs, buf);
+
+  /* Avoid comment headers, since they are still processed in stage 3.
+     It is simpler to insert a space here, rather than modifying the
+     lexer to ignore comments in some circumstances.  Simply returning
+     false doesn't work, since we want to clear the PASTE_LEFT flag.  */
+  if (lhs->type == CPP_DIV
+      && (rhs->type == CPP_MULT || rhs->type == CPP_DIV))
+    *end++ = ' ';
+  end = cpp_spell_token (pfile, rhs, end);
+  *end = '\0';
+
+  cpp_push_buffer (pfile, buf, end - buf, /* from_stage3 */ true, 1);
+
+  /* Tweak the column number the lexer will report.  */
+  pfile->buffer->col_adjust = pfile->cur_token[-1].col - 1;
+
+  /* We don't want a leading # to be interpreted as a directive.  */
+  pfile->buffer->saved_flags = 0;
+
+  /* Set pfile->cur_token as required by _cpp_lex_direct.  */
+  pfile->cur_token = _cpp_temp_token (pfile);
+  *plhs = _cpp_lex_direct (pfile);
+  valid = pfile->buffer->cur == pfile->buffer->rlimit;
+  _cpp_pop_buffer (pfile);
+
+  return valid;
 }
 
-/* Handles an arbitrarily long sequence of ## operators.  This
-   implementation is left-associative, non-recursive, and finishes a
-   paste before handling succeeding ones.  If the paste fails, we back
-   up a token to just after the ## operator, with the effect that it
-   appears in the output stream normally.  */
+/* Handles an arbitrarily long sequence of ## operators, with initial
+   operand LHS.  This implementation is left-associative,
+   non-recursive, and finishes a paste before handling succeeding
+   ones.  If a paste fails, we back up to the RHS of the failing ##
+   operator before pushing the context containing the result of prior
+   successful pastes, with the effect that the RHS appears in the
+   output stream after the pasted LHS normally.  */
 static void
 paste_all_tokens (pfile, lhs)
      cpp_reader *pfile;
      const cpp_token *lhs;
 {
-  cpp_token *pasted;
   const cpp_token *rhs;
   cpp_context *context = pfile->context;
 
-  /* Copy lhs to pasted, but preserve original line and column.  */
-  pasted = _cpp_temp_token (pfile);
-  pasted->type = lhs->type;
-  pasted->flags = lhs->flags;
-  pasted->val.str = lhs->val.str;
-
   do
     {
       /* Take the token directly from the current context.  We can do
@@ -432,22 +430,30 @@ paste_all_tokens (pfile, lhs)
       if (rhs->type == CPP_PADDING)
        abort ();
 
-      if (paste_tokens (pfile, pasted, rhs))
+      if (!paste_tokens (pfile, &lhs, rhs))
        {
          _cpp_backup_tokens (pfile, 1);
+
+         /* Mandatory warning for all apart from assembler.  */
+         if (CPP_OPTION (pfile, lang) != CLK_ASM)
+           cpp_warning (pfile,
+        "pasting \"%s\" and \"%s\" does not give a valid preprocessing token",
+                        cpp_token_as_text (pfile, lhs),
+                        cpp_token_as_text (pfile, rhs));
          break;
        }
     }
   while (rhs->flags & PASTE_LEFT);
 
-  /* Clear PASTE_LEFT flag, put the token in its own context.  */
-  pasted->flags &= ~PASTE_LEFT;
-  push_token_context (pfile, NULL, pasted, 1);
+  /* Put the resulting token in its own context.  */
+  push_token_context (pfile, NULL, lhs, 1);
 }
 
-/* Reads and returns the arguments to a function-like macro invocation.
-   Assumes the opening parenthesis has been processed.  If there is an
-   error, emits an appropriate diagnostic and returns NULL.  */
+/* Reads and returns the arguments to a function-like macro
+   invocation.  Assumes the opening parenthesis has been processed.
+   If there is an error, emits an appropriate diagnostic and returns
+   NULL.  Each argument is terminated by a CPP_EOF token, for the
+   future benefit of expand_arg().  */
 static _cpp_buff *
 collect_args (pfile, node)
      cpp_reader *pfile;
@@ -470,7 +476,7 @@ collect_args (pfile, node)
   base_buff = buff;
   args = (macro_arg *) buff->base;
   memset (args, 0, argc * sizeof (macro_arg));
-  buff->cur = (char *) &args[argc];
+  buff->cur = (unsigned char *) &args[argc];
   arg = args, argc = 0;
 
   /* Collect the tokens making up each argument.  We don't yet know
@@ -487,10 +493,10 @@ collect_args (pfile, node)
       for (;;)
        {
          /* Require space for 2 new tokens (including a CPP_EOF).  */
-         if ((char *) &arg->first[ntokens + 2] > buff->limit)
+         if ((unsigned char *) &arg->first[ntokens + 2] > buff->limit)
            {
-             buff = _cpp_extend_buff (pfile, buff,
-                                      1000 * sizeof (cpp_token *));
+             buff = _cpp_append_extend_buff (pfile, buff,
+                                             1000 * sizeof (cpp_token *));
              arg->first = (const cpp_token **) buff->cur;
            }
 
@@ -535,7 +541,7 @@ collect_args (pfile, node)
         overwrite the final legitimate argument, before failing.  */
       if (argc <= macro->paramc)
        {
-         buff->cur = (char *) &arg->first[ntokens + 1];
+         buff->cur = (unsigned char *) &arg->first[ntokens + 1];
          if (argc != macro->paramc)
            arg++;
        }
@@ -561,10 +567,12 @@ collect_args (pfile, node)
          step_back = true;
        }
       else
-       /* We still need the CPP_EOF to end directives, and to end
-           pre-expansion of a macro argument.  */
        step_back = (pfile->context->prev || pfile->state.in_directive);
 
+      /* We still need the CPP_EOF to end directives, and to end
+        pre-expansion of a macro argument.  Step back is not
+        unconditional, since we don't want to return a CPP_EOF to our
+        callers at the end of an -include-d file.  */
       if (step_back)
        _cpp_backup_tokens (pfile, 1);
       cpp_error (pfile, "unterminated argument list invoking macro \"%s\"",
@@ -613,83 +621,108 @@ collect_args (pfile, node)
   return NULL;
 }
 
-static int
+/* Search for an opening parenthesis to the macro of NODE, in such a
+   way that, if none is found, we don't lose the information in any
+   intervening padding tokens.  If we find the parenthesis, collect
+   the arguments and return the buffer containing them.  */
+static _cpp_buff *
 funlike_invocation_p (pfile, node)
      cpp_reader *pfile;
-     const cpp_hashnode *node;
+     cpp_hashnode *node;
 {
-  const cpp_token *maybe_paren;
-  _cpp_buff *buff = NULL;
-
-  pfile->state.prevent_expansion++;
-  pfile->keep_tokens++;
+  const cpp_token *token, *padding = NULL;
 
-  pfile->state.parsing_args = 1;
-  do
-    maybe_paren = cpp_get_token (pfile);
-  while (maybe_paren->type == CPP_PADDING);
-  pfile->state.parsing_args = 2;
-
-  if (maybe_paren->type == CPP_OPEN_PAREN)
-    buff = collect_args (pfile, node);
-  else
+  for (;;)
     {
-      _cpp_backup_tokens (pfile, 1);
-      if (CPP_WTRADITIONAL (pfile) && ! node->value.macro->syshdr)
-       cpp_warning (pfile,
- "function-like macro \"%s\" must be used with arguments in traditional C",
-                    NODE_NAME (node));
+      token = cpp_get_token (pfile);
+      if (token->type != CPP_PADDING)
+       break;
+      if (padding == NULL
+         || (!(padding->flags & PREV_WHITE) && token->val.source == NULL))
+       padding = token;
     }
 
-  pfile->state.parsing_args = 0;
-  pfile->keep_tokens--;
-  pfile->state.prevent_expansion--;
-
-  if (buff)
+  if (token->type == CPP_OPEN_PAREN)
     {
-      if (node->value.macro->paramc > 0)
-       replace_args (pfile, node->value.macro, (macro_arg *) buff->base);
-      _cpp_release_buff (pfile, buff);
+      pfile->state.parsing_args = 2;
+      return collect_args (pfile, node);
     }
 
-  return buff != 0;
+  /* Back up.  We may have skipped padding, in which case backing up
+     more than one token when expanding macros is in general too
+     difficult.  We re-insert it in its own context.  */
+  _cpp_backup_tokens (pfile, 1);
+  if (padding)
+    push_token_context (pfile, NULL, padding, 1);
+
+  return NULL;
 }
 
-/* Push the context of a macro onto the context stack.  TOKEN is the
-   macro name.  If we can successfully start expanding the macro,
-   TOKEN is replaced with the first token of the expansion, and we
-   return non-zero.  */
+/* Push the context of a macro with hash entry NODE onto the context
+   stack.  If we can successfully expand the macro, we push a context
+   containing its yet-to-be-rescanned replacement list and return one.
+   Otherwise, we don't push a context and return zero.  */
 static int
 enter_macro_context (pfile, node)
      cpp_reader *pfile;
      cpp_hashnode *node;
 {
-  if (node->flags & NODE_BUILTIN)
-    push_token_context (pfile, NULL, builtin_macro (pfile, node), 1);
-  else
+  /* The presence of a macro invalidates a file's controlling macro.  */
+  pfile->mi_valid = false;
+
+  /* Handle standard macros.  */
+  if (! (node->flags & NODE_BUILTIN))
     {
       cpp_macro *macro = node->value.macro;
 
-      if (macro->fun_like && !funlike_invocation_p (pfile, node))
-       return 0;
+      if (macro->fun_like)
+       {
+         _cpp_buff *buff;
+
+         pfile->state.prevent_expansion++;
+         pfile->keep_tokens++;
+         pfile->state.parsing_args = 1;
+         buff = funlike_invocation_p (pfile, node);
+         pfile->state.parsing_args = 0;
+         pfile->keep_tokens--;
+         pfile->state.prevent_expansion--;
+
+         if (buff == NULL)
+           {
+             if (CPP_WTRADITIONAL (pfile) && ! node->value.macro->syshdr)
+               cpp_warning (pfile,
+ "function-like macro \"%s\" must be used with arguments in traditional C",
+                            NODE_NAME (node));
+
+             return 0;
+           }
+
+         if (node->value.macro->paramc > 0)
+           replace_args (pfile, node, (macro_arg *) buff->base);
+         _cpp_release_buff (pfile, buff);
+       }
 
       /* Disable the macro within its expansion.  */
-      macro->disabled = 1;
+      node->flags |= NODE_DISABLED;
 
       if (macro->paramc == 0)
-       push_token_context (pfile, macro, macro->expansion, macro->count);
+       push_token_context (pfile, node, macro->expansion, macro->count);
+
+      return 1;
     }
-  return 1;
+
+  /* Handle built-in macros and the _Pragma operator.  */
+  return builtin_macro (pfile, node);
 }
 
-/* Take the expansion of a function-like MACRO, replacing parameters
-   with the actual arguments.  Each argument is macro-expanded before
-   replacement, unless operated upon by the # or ## operators.  */
+/* Replace the parameters in a function-like macro of NODE with the
+   actual ARGS, and place the result in a newly pushed token context.
+   Expand each argument before replacing, unless it is operated upon
+   by the # or ## operators.  */
 static void
-replace_args (pfile, macro, args)
+replace_args (pfile, node, args)
      cpp_reader *pfile;
-     cpp_macro *macro;
+     cpp_hashnode *node;
      macro_arg *args;
 {
   unsigned int i, total;
@@ -697,11 +730,13 @@ replace_args (pfile, macro, args)
   const cpp_token **dest, **first;
   macro_arg *arg;
   _cpp_buff *buff;
+  cpp_macro *macro;
 
   /* First, fully macro-expand arguments, calculating the number of
      tokens in the final expansion as we go.  The ordering of the if
      statements below is subtle; we must handle stringification before
      pasting.  */
+  macro = node->value.macro;
   total = macro->count;
   limit = macro->expansion + macro->count;
 
@@ -819,7 +854,7 @@ replace_args (pfile, macro, args)
     if (args[i].expanded)
       free (args[i].expanded);
 
-  push_ptoken_context (pfile, macro, buff, first, dest - first);
+  push_ptoken_context (pfile, node, buff, first, dest - first);
 }
 
 /* Return a special padding token, with padding inherited from SOURCE.  */
@@ -836,7 +871,8 @@ padding_token (pfile, source)
   return result;
 }
 
-/* Move to the next context.  Create one if there is none.  */
+/* Get a new uninitialized context.  Create a new one if we cannot
+   re-use an old one.  */
 static cpp_context *
 next_context (pfile)
      cpp_reader *pfile;
@@ -859,7 +895,7 @@ next_context (pfile)
 static void
 push_ptoken_context (pfile, macro, buff, first, count)
      cpp_reader *pfile;
-     cpp_macro *macro;
+     cpp_hashnode *macro;
      _cpp_buff *buff;
      const cpp_token **first;
      unsigned int count;
@@ -877,7 +913,7 @@ push_ptoken_context (pfile, macro, buff, first, count)
 static void
 push_token_context (pfile, macro, first, count)
      cpp_reader *pfile;
-     cpp_macro *macro;
+     cpp_hashnode *macro;
      const cpp_token *first;
      unsigned int count;
 {
@@ -890,6 +926,12 @@ push_token_context (pfile, macro, first, count)
   context->last.token = first + count;
 }
 
+/* Expand an argument ARG before replacing parameters in a
+   function-like macro.  This works by pushing a context with the
+   argument's tokens, and then expanding that into a temporary buffer
+   as if it were a normal part of the token stream.  collect_args()
+   has terminated the argument's tokens with a CPP_EOF so that we know
+   when we have fully expanded the argument.  */
 static void
 expand_arg (pfile, arg)
      cpp_reader *pfile;
@@ -928,15 +970,17 @@ expand_arg (pfile, arg)
   _cpp_pop_context (pfile);
 }
 
+/* Pop the current context off the stack, re-enabling the macro if the
+   context represented a macro's replacement list.  The context
+   structure is not freed so that we can re-use it later.  */
 void
 _cpp_pop_context (pfile)
      cpp_reader *pfile;
 {
   cpp_context *context = pfile->context;
 
-  /* Re-enable a macro when leaving its expansion.  */
   if (context->macro)
-    context->macro->disabled = 0;
+    context->macro->flags &= ~NODE_DISABLED;
 
   if (context->buff)
     _cpp_release_buff (pfile, context->buff);
@@ -997,39 +1041,31 @@ cpp_get_token (pfile)
 
       node = result->val.node;
 
-      /* Handle macros and the _Pragma operator.  */
-      if (node->type == NT_MACRO && !(result->flags & NO_EXPAND))
+      if (node->type != NT_MACRO || (result->flags & NO_EXPAND))
+       break;
+      
+      if (!(node->flags & NODE_DISABLED))
        {
-         /* Macros invalidate controlling macros.  */
-         pfile->mi_valid = false;
-
-         if (!(node->flags & NODE_BUILTIN) && node->value.macro->disabled)
-           {
-             /* Flag this token as always unexpandable.  */
-             cpp_token *t = _cpp_temp_token (pfile);
-             t->type = result->type;
-             t->flags = result->flags | NO_EXPAND;
-             t->val.str = result->val.str;
-             result = t;
-           }
-         else if (!pfile->state.prevent_expansion
-                  && enter_macro_context (pfile, node))
+         if (!pfile->state.prevent_expansion
+             && enter_macro_context (pfile, node))
            {
              if (pfile->state.in_directive)
                continue;
              return padding_token (pfile, result);
            }
        }
+      else
+       {
+         /* Flag this token as always unexpandable.  FIXME: move this
+            to collect_args()?.  */
+         cpp_token *t = _cpp_temp_token (pfile);
+         t->type = result->type;
+         t->flags = result->flags | NO_EXPAND;
+         t->val.str = result->val.str;
+         result = t;
+       }
 
-      /* Don't interpret _Pragma within directives.  The standard is
-         not clear on this, but to me this makes most sense.  */
-      if (node != pfile->spec_nodes.n__Pragma
-         || pfile->state.in_directive)
-       break;
-
-      /* Handle it, and loop back for another token.  MI is cleared
-         since this token came from either the lexer or a macro.  */
-      _cpp_do__Pragma (pfile);
+      break;
     }
 
   return result;
@@ -1042,9 +1078,9 @@ int
 cpp_sys_macro_p (pfile)
      cpp_reader *pfile;
 {
-  cpp_macro *macro = pfile->context->macro;
+  cpp_hashnode *node = pfile->context->macro;
 
-  return macro && macro->syshdr;
+  return node && node->value.macro && node->value.macro->syshdr;
 }
 
 /* Read each token in, until EOF.  Directives are transparently
@@ -1070,7 +1106,9 @@ _cpp_backup_tokens (pfile, count)
       while (count--)
        {
          pfile->cur_token--;
-         if (pfile->cur_token == pfile->cur_run->base)
+         if (pfile->cur_token == pfile->cur_run->base
+             /* Possible with -fpreprocessed and no leading #line.  */
+             && pfile->cur_run->prev != NULL)
            {
              pfile->cur_run = pfile->cur_run->prev;
              pfile->cur_token = pfile->cur_run->limit;
@@ -1092,8 +1130,7 @@ _cpp_backup_tokens (pfile, count)
 
 /* Returns non-zero if a macro redefinition warning is required.  */
 static int
-warn_of_redefinition (pfile, node, macro2)
-     cpp_reader *pfile;
+warn_of_redefinition (node, macro2)
      const cpp_hashnode *node;
      const cpp_macro *macro2;
 {
@@ -1104,9 +1141,6 @@ warn_of_redefinition (pfile, node, macro2)
   if (node->flags & NODE_WARN)
     return 1;
 
-  if (! CPP_PEDANTIC (pfile))
-    return 0;
-
   /* Redefinition of a macro is allowed if and only if the old and new
      definitions are the same.  (6.10.3 paragraph 2).  */
   macro1 = node->value.macro;
@@ -1132,7 +1166,6 @@ warn_of_redefinition (pfile, node, macro2)
 }
 
 /* Free the definition of hashnode H.  */
-
 void
 _cpp_free_definition (h)
      cpp_hashnode *h;
@@ -1140,19 +1173,17 @@ _cpp_free_definition (h)
   /* Macros and assertions no longer have anything to free.  */
   h->type = NT_VOID;
   /* Clear builtin flag in case of redefinition.  */
-  h->flags &= ~NODE_BUILTIN;
+  h->flags &= ~(NODE_BUILTIN | NODE_DISABLED);
 }
 
 /* Save parameter NODE to the parameter list of macro MACRO.  Returns
-   zero on success, non-zero if the paramter is a duplicate.  */
+   zero on success, non-zero if the parameter is a duplicate.  */
 static int
 save_parameter (pfile, macro, node)
      cpp_reader *pfile;
      cpp_macro *macro;
      cpp_hashnode *node;
 {
-  cpp_hashnode **dest;
-
   /* Constraint 6.10.3.6 - duplicate parameter names.  */
   if (node->arg_index)
     {
@@ -1160,22 +1191,16 @@ save_parameter (pfile, macro, node)
       return 1;
     }
 
-  dest = &macro->params[macro->paramc];
+  if (BUFF_ROOM (pfile->a_buff)
+      < (macro->paramc + 1) * sizeof (cpp_hashnode *))
+    _cpp_extend_buff (pfile, &pfile->a_buff, sizeof (cpp_hashnode *));
 
-  /* Check we have room for the parameters.  */
-  if ((unsigned char *) (dest + 1) >= POOL_LIMIT (&pfile->macro_pool))
-    {
-      _cpp_next_chunk (&pfile->macro_pool, sizeof (cpp_hashnode *),
-                      (unsigned char **) &macro->params);
-      dest = &macro->params[macro->paramc];
-    }
-
-  *dest = node;
-  node->arg_index = ++macro->paramc;
+  ((cpp_hashnode **) BUFF_FRONT (pfile->a_buff))[macro->paramc++] = node;
+  node->arg_index = macro->paramc;
   return 0;
 }
 
-/* Check the syntax of the paramters in a MACRO definition.  */
+/* Check the syntax of the parameters in a MACRO definition.  */
 static int
 parse_params (pfile, macro)
      cpp_reader *pfile;
@@ -1183,7 +1208,6 @@ parse_params (pfile, macro)
 {
   unsigned int prev_ident = 0;
 
-  macro->params = (cpp_hashnode **) POOL_FRONT (&pfile->macro_pool);
   for (;;)
     {
       const cpp_token *token = _cpp_lex_token (pfile);
@@ -1209,7 +1233,7 @@ parse_params (pfile, macro)
 
        case CPP_CLOSE_PAREN:
          if (prev_ident || macro->paramc == 0)
-           break;
+           return 1;
 
          /* Fall through to pick up the error.  */
        case CPP_COMMA:
@@ -1237,18 +1261,13 @@ parse_params (pfile, macro)
          /* We're at the end, and just expect a closing parenthesis.  */
          token = _cpp_lex_token (pfile);
          if (token->type == CPP_CLOSE_PAREN)
-           break;
+           return 1;
          /* Fall through.  */
 
        case CPP_EOF:
          cpp_error (pfile, "missing ')' in macro parameter list");
          return 0;
        }
-
-      /* Success.  Commit the parameter array.  */
-      POOL_COMMIT (&pfile->macro_pool,
-                  macro->paramc * sizeof (cpp_hashnode *));
-      return 1;
     }
 }
 
@@ -1258,20 +1277,14 @@ alloc_expansion_token (pfile, macro)
      cpp_reader *pfile;
      cpp_macro *macro;
 {
-  cpp_token *token = &macro->expansion[macro->count];
-
-  /* Check we have room for the token.  */
-  if ((unsigned char *) (token + 1) >= POOL_LIMIT (&pfile->macro_pool))
-    {
-      _cpp_next_chunk (&pfile->macro_pool, sizeof (cpp_token),
-                      (unsigned char **) &macro->expansion);
-      token = &macro->expansion[macro->count];
-    }
+  if (BUFF_ROOM (pfile->a_buff) < (macro->count + 1) * sizeof (cpp_token))
+    _cpp_extend_buff (pfile, &pfile->a_buff, sizeof (cpp_token));
 
-  macro->count++;
-  return token;
+  return &((cpp_token *) BUFF_FRONT (pfile->a_buff))[macro->count++];
 }
 
+/* Lex a token from the expansion of MACRO, but mark parameters as we
+   find them and warn of traditional stringification.  */
 static cpp_token *
 lex_expansion_token (pfile, macro)
      cpp_reader *pfile;
@@ -1282,7 +1295,7 @@ lex_expansion_token (pfile, macro)
   pfile->cur_token = alloc_expansion_token (pfile, macro);
   token = _cpp_lex_direct (pfile);
 
-  /* Is this an argument?  */
+  /* Is this a parameter?  */
   if (token->type == CPP_NAME && token->val.node->arg_index)
     {
       token->type = CPP_MACRO_ARG;
@@ -1306,8 +1319,7 @@ _cpp_create_definition (pfile, node)
   const cpp_token *ctoken;
   unsigned int i, ok = 1;
 
-  macro = (cpp_macro *) _cpp_pool_alloc (&pfile->macro_pool,
-                                        sizeof (cpp_macro));
+  macro = (cpp_macro *) _cpp_aligned_alloc (pfile, sizeof (cpp_macro));
   macro->line = pfile->directive_line;
   macro->params = 0;
   macro->paramc = 0;
@@ -1321,16 +1333,19 @@ _cpp_create_definition (pfile, node)
 
   if (ctoken->type == CPP_OPEN_PAREN && !(ctoken->flags & PREV_WHITE))
     {
-      if (!(ok = parse_params (pfile, macro)))
+      ok = parse_params (pfile, macro);
+      macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff);
+      if (!ok)
        goto cleanup2;
+
+      /* Success.  Commit the parameter array.  */
+      BUFF_FRONT (pfile->a_buff) = (U_CHAR *) &macro->params[macro->paramc];
       macro->fun_like = 1;
     }
   else if (ctoken->type != CPP_EOF && !(ctoken->flags & PREV_WHITE))
     cpp_pedwarn (pfile, "ISO C requires whitespace after the macro name");
 
-  pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
   saved_cur_token = pfile->cur_token;
-  macro->expansion = (cpp_token *) POOL_FRONT (&pfile->macro_pool);
 
   if (macro->fun_like)
     token = lex_expansion_token (pfile, macro);
@@ -1388,23 +1403,30 @@ _cpp_create_definition (pfile, node)
       token = lex_expansion_token (pfile, macro);
     }
 
+  macro->expansion = (cpp_token *) BUFF_FRONT (pfile->a_buff);
+
   /* Don't count the CPP_EOF.  */
   macro->count--;
 
+  /* Clear whitespace on first token for warn_of_redefinition().  */
+  if (macro->count)
+    macro->expansion[0].flags &= ~PREV_WHITE;
+
+  /* Commit the memory.  */
+  BUFF_FRONT (pfile->a_buff) = (U_CHAR *) &macro->expansion[macro->count];
+
   /* Implement the macro-defined-to-itself optimisation.  */
-  macro->disabled = (macro->count == 1 && !macro->fun_like
-                    && macro->expansion[0].type == CPP_NAME
-                    && macro->expansion[0].val.node == node);
+  if (macro->count == 1 && !macro->fun_like
+      && macro->expansion[0].type == CPP_NAME
+      && macro->expansion[0].val.node == node)
+    node->flags |= NODE_DISABLED;
 
   /* To suppress some diagnostics.  */
   macro->syshdr = pfile->map->sysp != 0;
 
-  /* Commit the memory.  */
-  POOL_COMMIT (&pfile->macro_pool, macro->count * sizeof (cpp_token));
-
   if (node->type != NT_VOID)
     {
-      if (warn_of_redefinition (pfile, node, macro))
+      if (warn_of_redefinition (node, macro))
        {
          cpp_pedwarn_with_line (pfile, pfile->directive_line, 0,
                                 "\"%s\" redefined", NODE_NAME (node));
@@ -1440,9 +1462,8 @@ _cpp_create_definition (pfile, node)
   return ok;
 }
 
-/* Warn if a token in `string' matches one of the function macro
-   arguments in `info'.  This function assumes that the macro is a
-   function macro and not an object macro.  */
+/* Warn if a token in STRING matches one of a function-like MACRO's
+   parameters.  */
 static void
 check_trad_stringification (pfile, macro, string)
      cpp_reader *pfile;
@@ -1476,7 +1497,7 @@ check_trad_stringification (pfile, macro, string)
              && !memcmp (p, NODE_NAME (node), len))
            {
              cpp_warning (pfile,
-          "macro argument \"%s\" would be stringified with -traditional.",
+          "macro argument \"%s\" would be stringified with -traditional",
                           NODE_NAME (node));
              break;
            }
@@ -1489,7 +1510,6 @@ check_trad_stringification (pfile, macro, string)
    debugging info.  e.g. "PASTE(X, Y) X ## Y", or "MACNAME EXPANSION".
    Caller is expected to generate the "#define" bit if needed.  The
    returned text is temporary, and automatically freed later.  */
-
 const unsigned char *
 cpp_macro_definition (pfile, node)
      cpp_reader *pfile;