OSDN Git Service

* include/ext/pool_allocator.h: Include c++config.h.
[pf3gnuchains/gcc-fork.git] / gcc / cppmacro.c
index 40a9a07..c797100 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,
 /* Part of CPP library.  (Macro and #define handling.)
    Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1998,
-   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004 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
    Written by Per Bothner, 1994.
    Based on CCCP program by Paul Rubin, June 1986
    Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -40,48 +40,58 @@ struct macro_arg
 
 /* Macro expansion.  */
 
 
 /* Macro expansion.  */
 
-static int enter_macro_context PARAMS ((cpp_reader *, cpp_hashnode *));
-static int builtin_macro PARAMS ((cpp_reader *, cpp_hashnode *));
-static void push_token_context
-  PARAMS ((cpp_reader *, cpp_hashnode *, const cpp_token *, unsigned int));
-static void push_ptoken_context
-  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 *));
-static const cpp_token *padding_token
-  PARAMS ((cpp_reader *, const cpp_token *));
-static void expand_arg PARAMS ((cpp_reader *, macro_arg *));
-static const cpp_token *new_string_token PARAMS ((cpp_reader *, uchar *,
-                                                 unsigned 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 bool paste_tokens PARAMS ((cpp_reader *, const cpp_token **,
-                                 const cpp_token *));
-static void replace_args PARAMS ((cpp_reader *, cpp_hashnode *, cpp_macro *,
-                                 macro_arg *));
-static _cpp_buff *funlike_invocation_p PARAMS ((cpp_reader *, cpp_hashnode *));
+static int enter_macro_context (cpp_reader *, cpp_hashnode *);
+static int builtin_macro (cpp_reader *, cpp_hashnode *);
+static void push_token_context (cpp_reader *, cpp_hashnode *,
+                               const cpp_token *, unsigned int);
+static void push_ptoken_context (cpp_reader *, cpp_hashnode *, _cpp_buff *,
+                                const cpp_token **, unsigned int);
+static _cpp_buff *collect_args (cpp_reader *, const cpp_hashnode *);
+static cpp_context *next_context (cpp_reader *);
+static const cpp_token *padding_token (cpp_reader *, const cpp_token *);
+static void expand_arg (cpp_reader *, macro_arg *);
+static const cpp_token *new_string_token (cpp_reader *, uchar *, unsigned int);
+static const cpp_token *stringify_arg (cpp_reader *, macro_arg *);
+static void paste_all_tokens (cpp_reader *, const cpp_token *);
+static bool paste_tokens (cpp_reader *, const cpp_token **, const cpp_token *);
+static void replace_args (cpp_reader *, cpp_hashnode *, cpp_macro *,
+                         macro_arg *);
+static _cpp_buff *funlike_invocation_p (cpp_reader *, cpp_hashnode *);
+static bool create_iso_definition (cpp_reader *, cpp_macro *);
 
 /* #define directive parsing and handling.  */
 
 
 /* #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 ((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 *));
-static void check_trad_stringification PARAMS ((cpp_reader *,
-                                               const cpp_macro *,
-                                               const cpp_string *));
+static cpp_token *alloc_expansion_token (cpp_reader *, cpp_macro *);
+static cpp_token *lex_expansion_token (cpp_reader *, cpp_macro *);
+static bool warn_of_redefinition (cpp_reader *, const cpp_hashnode *,
+                                 const cpp_macro *);
+static bool parse_params (cpp_reader *, cpp_macro *);
+static void check_trad_stringification (cpp_reader *, const cpp_macro *,
+                                       const cpp_string *);
+
+/* Emits a warning if NODE is a macro defined in the main file that
+   has not been used.  */
+int
+_cpp_warn_if_unused_macro (cpp_reader *pfile, cpp_hashnode *node,
+                          void *v ATTRIBUTE_UNUSED)
+{
+  if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
+    {
+      cpp_macro *macro = node->value.macro;
+
+      if (!macro->used
+         && MAIN_FILE_P (linemap_lookup (pfile->line_table, macro->line)))
+       cpp_error_with_line (pfile, CPP_DL_WARNING, macro->line, 0,
+                            "macro \"%s\" is not used", NODE_NAME (node));
+    }
+
+  return 1;
+}
 
 /* Allocates and returns a CPP_STRING token, containing TEXT of length
    LEN, after null-terminating it.  TEXT must be in permanent storage.  */
 static const cpp_token *
 
 /* Allocates and returns a CPP_STRING token, containing TEXT of length
    LEN, after null-terminating it.  TEXT must be in permanent storage.  */
 static const cpp_token *
-new_string_token (pfile, text, len)
-     cpp_reader *pfile;
-     unsigned char *text;
-     unsigned int len;
+new_string_token (cpp_reader *pfile, unsigned char *text, unsigned int len)
 {
   cpp_token *token = _cpp_temp_token (pfile);
 
 {
   cpp_token *token = _cpp_temp_token (pfile);
 
@@ -93,24 +103,6 @@ new_string_token (pfile, text, len)
   return token;
 }
 
   return token;
 }
 
-/* Allocates and returns a CPP_NUMBER token evaluating to NUMBER.  */
-static const cpp_token *
-new_number_token (pfile, number)
-     cpp_reader *pfile;
-     unsigned int number;
-{
-  cpp_token *token = _cpp_temp_token (pfile);
-  /* 21 bytes holds all NUL-terminated unsigned 64-bit numbers.  */
-  unsigned char *buf = _cpp_unaligned_alloc (pfile, 21);
-
-  sprintf ((char *) buf, "%u", number);
-  token->type = CPP_NUMBER;
-  token->val.str.text = buf;
-  token->val.str.len = ustrlen (buf);
-  token->flags = 0;
-  return token;
-}
-
 static const char * const monthnames[] =
 {
   "Jan", "Feb", "Mar", "Apr", "May", "Jun",
 static const char * const monthnames[] =
 {
   "Jan", "Feb", "Mar", "Apr", "May", "Jun",
@@ -121,19 +113,18 @@ static const char * const monthnames[] =
    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.  */
    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 uchar *
+_cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
 {
 {
-  const cpp_token *result;
+  const uchar *result = NULL;
+  unsigned int number = 1;
 
   switch (node->value.builtin)
     {
     default:
 
   switch (node->value.builtin)
     {
     default:
-      cpp_error (pfile, DL_ICE, "invalid built-in macro \"%s\"",
+      cpp_error (pfile, CPP_DL_ICE, "invalid built-in macro \"%s\"",
                 NODE_NAME (node));
                 NODE_NAME (node));
-      return 0;
+      break;
 
     case BT_FILE:
     case BT_BASE_FILE:
 
     case BT_FILE:
     case BT_BASE_FILE:
@@ -145,14 +136,16 @@ builtin_macro (pfile, node)
 
        if (node->value.builtin == BT_BASE_FILE)
          while (! MAIN_FILE_P (map))
 
        if (node->value.builtin == BT_BASE_FILE)
          while (! MAIN_FILE_P (map))
-           map = INCLUDED_FROM (&pfile->line_maps, map);
+           map = INCLUDED_FROM (pfile->line_table, map);
 
        name = map->to_file;
        len = strlen (name);
 
        name = map->to_file;
        len = strlen (name);
-       buf = _cpp_unaligned_alloc (pfile, len * 4 + 1);
-       len = cpp_quote_string (buf, (const unsigned char *) name, len) - buf;
-
-       result = new_string_token (pfile, buf, len);
+       buf = _cpp_unaligned_alloc (pfile, len * 4 + 3);
+       result = buf;
+       *buf = '"';
+       buf = cpp_quote_string (buf + 1, (const unsigned char *) name, len);
+       *buf++ = '"';
+       *buf = '\0';
       }
       break;
 
       }
       break;
 
@@ -160,16 +153,18 @@ builtin_macro (pfile, node)
       /* The line map depth counts the primary source as level 1, but
         historically __INCLUDE_DEPTH__ has called the primary source
         level 0.  */
       /* The line map depth counts the primary source as level 1, but
         historically __INCLUDE_DEPTH__ has called the primary source
         level 0.  */
-      result = new_number_token (pfile, pfile->line_maps.depth - 1);
+      number = pfile->line_table->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.  */
       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.  */
-      result = new_number_token (pfile,
-                                SOURCE_LINE (pfile->map,
-                                             pfile->cur_token[-1].line));
+      if (CPP_OPTION (pfile, traditional))
+       number = pfile->line;
+      else
+       number = pfile->cur_token[-1].line;
+      number = SOURCE_LINE (pfile->map, number);
       break;
 
       /* __STDC__ has the value 1 under normal circumstances.
       break;
 
       /* __STDC__ has the value 1 under normal circumstances.
@@ -179,55 +174,87 @@ builtin_macro (pfile, node)
         value 0.  */
     case BT_STDC:
       {
         value 0.  */
     case BT_STDC:
       {
-       int stdc;
-       enum c_lang lang = CPP_OPTION (pfile, lang);
        if (CPP_IN_SYSTEM_HEADER (pfile)
            && CPP_OPTION (pfile, stdc_0_in_system_headers)
        if (CPP_IN_SYSTEM_HEADER (pfile)
            && CPP_OPTION (pfile, stdc_0_in_system_headers)
-           && !(lang == CLK_STDC89 || lang == CLK_STDC94
-                || lang == CLK_STDC99))  /* || lang == CLK_CXX98 ? */
-         stdc = 0;
+           && !CPP_OPTION (pfile,std))
+         number = 0;
        else
        else
-         stdc = 1;
-
-       result = new_number_token (pfile, stdc);
+         number = 1;
       }
       break;
 
     case BT_DATE:
     case BT_TIME:
       }
       break;
 
     case BT_DATE:
     case BT_TIME:
-      if (pfile->date.type == CPP_EOF)
+      if (pfile->date == NULL)
        {
          /* Allocate __DATE__ and __TIME__ strings from permanent
             storage.  We only do this once, and don't generate them
             at init time, because time() and localtime() are very
             slow on some systems.  */
        {
          /* Allocate __DATE__ and __TIME__ strings from permanent
             storage.  We only do this once, and don't generate them
             at init time, because time() and localtime() are very
             slow on some systems.  */
-         time_t tt = time (NULL);
-         struct tm *tb = localtime (&tt);
-
-         pfile->date.val.str.text =
-           _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;
-         sprintf ((char *) pfile->date.val.str.text, "%s %2d %4d",
-                  monthnames[tb->tm_mon], tb->tm_mday, tb->tm_year + 1900);
-
-         pfile->time.val.str.text =
-           _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;
-         sprintf ((char *) pfile->time.val.str.text, "%02d:%02d:%02d",
-                  tb->tm_hour, tb->tm_min, tb->tm_sec);
+         time_t tt;
+         struct tm *tb = NULL;
+
+         /* (time_t) -1 is a legitimate value for "number of seconds
+            since the Epoch", so we have to do a little dance to
+            distinguish that from a genuine error.  */
+         errno = 0;
+         tt = time(NULL);
+         if (tt != (time_t)-1 || errno == 0)
+           tb = localtime (&tt);
+
+         if (tb)
+           {
+             pfile->date = _cpp_unaligned_alloc (pfile,
+                                                 sizeof ("\"Oct 11 1347\""));
+             sprintf ((char *) pfile->date, "\"%s %2d %4d\"",
+                      monthnames[tb->tm_mon], tb->tm_mday,
+                      tb->tm_year + 1900);
+
+             pfile->time = _cpp_unaligned_alloc (pfile,
+                                                 sizeof ("\"12:34:56\""));
+             sprintf ((char *) pfile->time, "\"%02d:%02d:%02d\"",
+                      tb->tm_hour, tb->tm_min, tb->tm_sec);
+           }
+         else
+           {
+             cpp_errno (pfile, CPP_DL_WARNING,
+                        "could not determine date and time");
+               
+             pfile->date = U"\"??? ?? ????\"";
+             pfile->time = U"\"??:??:??\"";
+           }
        }
 
       if (node->value.builtin == BT_DATE)
        }
 
       if (node->value.builtin == BT_DATE)
-       result = &pfile->date;
+       result = pfile->date;
       else
       else
-       result = &pfile->time;
+       result = pfile->time;
       break;
       break;
+    }
+
+  if (result == NULL)
+    {
+      /* 21 bytes holds all NUL-terminated unsigned 64-bit numbers.  */
+      result = _cpp_unaligned_alloc (pfile, 21);
+      sprintf ((char *) result, "%u", number);
+    }
+
+  return result;      
+}
 
 
-    case BT_PRAGMA:
+/* Convert builtin macros like __FILE__ to a token and push it 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 (cpp_reader *pfile, cpp_hashnode *node)
+{
+  const uchar *buf;
+  size_t len;
+  char *nbuf;
+
+  if (node->value.builtin == 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)
       /* 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)
@@ -237,7 +264,23 @@ builtin_macro (pfile, node)
       return 1;
     }
 
       return 1;
     }
 
-  push_token_context (pfile, NULL, result, 1);
+  buf = _cpp_builtin_macro_text (pfile, node);
+  len = ustrlen (buf);
+  nbuf = alloca (len + 1);
+  memcpy (nbuf, buf, len);
+  nbuf[len]='\n';
+
+  cpp_push_buffer (pfile, (uchar *) nbuf, len, /* from_stage3 */ true);
+  _cpp_clean_line (pfile);
+
+  /* Set pfile->cur_token as required by _cpp_lex_direct.  */
+  pfile->cur_token = _cpp_temp_token (pfile);
+  push_token_context (pfile, NULL, _cpp_lex_direct (pfile), 1);
+  if (pfile->buffer->cur != pfile->buffer->rlimit)
+    cpp_error (pfile, CPP_DL_ICE, "invalid built-in macro \"%s\"",
+              NODE_NAME (node));
+  _cpp_pop_buffer (pfile);
+
   return 1;
 }
 
   return 1;
 }
 
@@ -246,10 +289,7 @@ builtin_macro (pfile, node)
    converted to octal.  DEST must be of sufficient size.  Returns
    a pointer to the end of the string.  */
 uchar *
    converted to octal.  DEST must be of sufficient size.  Returns
    a pointer to the end of the string.  */
 uchar *
-cpp_quote_string (dest, src, len)
-     uchar *dest;
-     const uchar *src;
-     unsigned int len;
+cpp_quote_string (uchar *dest, const uchar *src, unsigned int len)
 {
   while (len--)
     {
 {
   while (len--)
     {
@@ -278,15 +318,18 @@ cpp_quote_string (dest, src, len)
 /* Convert a token sequence ARG to a single string token according to
    the rules of the ISO C #-operator.  */
 static const cpp_token *
 /* 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;
+stringify_arg (cpp_reader *pfile, macro_arg *arg)
 {
 {
-  unsigned char *dest = BUFF_FRONT (pfile->u_buff);
+  unsigned char *dest;
   unsigned int i, escape_it, backslash_count = 0;
   const cpp_token *source = NULL;
   size_t len;
 
   unsigned int i, escape_it, backslash_count = 0;
   const cpp_token *source = NULL;
   size_t len;
 
+  if (BUFF_ROOM (pfile->u_buff) < 3)
+    _cpp_extend_buff (pfile, &pfile->u_buff, 3);
+  dest = BUFF_FRONT (pfile->u_buff);
+  *dest++ = '"';
+
   /* Loop, reading in the argument's tokens.  */
   for (i = 0; i < arg->count; i++)
     {
   /* Loop, reading in the argument's tokens.  */
   for (i = 0; i < arg->count; i++)
     {
@@ -303,11 +346,11 @@ stringify_arg (pfile, arg)
                   || token->type == CPP_CHAR || token->type == CPP_WCHAR);
 
       /* Room for each char being written in octal, initial space and
                   || token->type == CPP_CHAR || token->type == CPP_WCHAR);
 
       /* Room for each char being written in octal, initial space and
-        final NUL.  */
+        final quote and NUL.  */
       len = cpp_token_len (token);
       if (escape_it)
        len *= 4;
       len = cpp_token_len (token);
       if (escape_it)
        len *= 4;
-      len += 2;
+      len += 3;
 
       if ((size_t) (BUFF_LIMIT (pfile->u_buff) - dest) < len)
        {
 
       if ((size_t) (BUFF_LIMIT (pfile->u_buff) - dest) < len)
        {
@@ -317,7 +360,7 @@ stringify_arg (pfile, arg)
        }
 
       /* Leading white space?  */
        }
 
       /* Leading white space?  */
-      if (dest != BUFF_FRONT (pfile->u_buff))
+      if (dest - 1 != BUFF_FRONT (pfile->u_buff))
        {
          if (source == NULL)
            source = token;
        {
          if (source == NULL)
            source = token;
@@ -337,7 +380,7 @@ stringify_arg (pfile, arg)
       else
        dest = cpp_spell_token (pfile, token, dest);
 
       else
        dest = cpp_spell_token (pfile, token, dest);
 
-      if (token->type == CPP_OTHER && token->val.c == '\\')
+      if (token->type == CPP_OTHER && token->val.str.text[0] == '\\')
        backslash_count++;
       else
        backslash_count = 0;
        backslash_count++;
       else
        backslash_count = 0;
@@ -346,24 +389,23 @@ stringify_arg (pfile, arg)
   /* Ignore the final \ of invalid string literals.  */
   if (backslash_count & 1)
     {
   /* Ignore the final \ of invalid string literals.  */
   if (backslash_count & 1)
     {
-      cpp_error (pfile, DL_WARNING,
+      cpp_error (pfile, CPP_DL_WARNING,
                 "invalid string literal, ignoring final '\\'");
       dest--;
     }
 
   /* Commit the memory, including NUL, and return the token.  */
                 "invalid string literal, ignoring final '\\'");
       dest--;
     }
 
   /* Commit the memory, including NUL, and return the token.  */
+  *dest++ = '"';
   len = dest - BUFF_FRONT (pfile->u_buff);
   BUFF_FRONT (pfile->u_buff) = dest + 1;
   return new_string_token (pfile, dest - len, 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, return non-zero.  In any
+/* Try to paste two tokens.  On success, return nonzero.  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
    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;
-     const cpp_token **plhs, *rhs;
+paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs)
 {
   unsigned char *buf, *end;
   const cpp_token *lhs;
 {
   unsigned char *buf, *end;
   const cpp_token *lhs;
@@ -372,26 +414,20 @@ paste_tokens (pfile, plhs, rhs)
 
   lhs = *plhs;
   len = cpp_token_len (lhs) + cpp_token_len (rhs) + 1;
 
   lhs = *plhs;
   len = cpp_token_len (lhs) + cpp_token_len (rhs) + 1;
-  buf = (unsigned char *) alloca (len);
+  buf = 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.  */
   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))
+  if (lhs->type == CPP_DIV && rhs->type != CPP_EQ)
     *end++ = ' ';
   end = cpp_spell_token (pfile, rhs, end);
     *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;
+  *end = '\n';
 
 
-  /* We don't want a leading # to be interpreted as a directive.  */
-  pfile->buffer->saved_flags = 0;
+  cpp_push_buffer (pfile, buf, end - buf, /* from_stage3 */ true);
+  _cpp_clean_line (pfile);
 
   /* Set pfile->cur_token as required by _cpp_lex_direct.  */
   pfile->cur_token = _cpp_temp_token (pfile);
 
   /* Set pfile->cur_token as required by _cpp_lex_direct.  */
   pfile->cur_token = _cpp_temp_token (pfile);
@@ -410,9 +446,7 @@ paste_tokens (pfile, plhs, rhs)
    successful pastes, with the effect that the RHS appears in the
    output stream after the pasted LHS normally.  */
 static void
    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;
+paste_all_tokens (cpp_reader *pfile, const cpp_token *lhs)
 {
   const cpp_token *rhs;
   cpp_context *context = pfile->context;
 {
   const cpp_token *rhs;
   cpp_context *context = pfile->context;
@@ -425,9 +459,9 @@ paste_all_tokens (pfile, lhs)
         inserted.  In either case, the constraints to #define
         guarantee we have at least one more token.  */
       if (context->direct_p)
         inserted.  In either case, the constraints to #define
         guarantee we have at least one more token.  */
       if (context->direct_p)
-       rhs = context->first.token++;
+       rhs = FIRST (context).token++;
       else
       else
-       rhs = *context->first.ptoken++;
+       rhs = *FIRST (context).ptoken++;
 
       if (rhs->type == CPP_PADDING)
        abort ();
 
       if (rhs->type == CPP_PADDING)
        abort ();
@@ -438,7 +472,7 @@ paste_all_tokens (pfile, lhs)
 
          /* Mandatory error for all apart from assembler.  */
          if (CPP_OPTION (pfile, lang) != CLK_ASM)
 
          /* Mandatory error for all apart from assembler.  */
          if (CPP_OPTION (pfile, lang) != CLK_ASM)
-           cpp_error (pfile, DL_ERROR,
+           cpp_error (pfile, CPP_DL_ERROR,
         "pasting \"%s\" and \"%s\" does not give a valid preprocessing token",
                       cpp_token_as_text (pfile, lhs),
                       cpp_token_as_text (pfile, rhs));
         "pasting \"%s\" and \"%s\" does not give a valid preprocessing token",
                       cpp_token_as_text (pfile, lhs),
                       cpp_token_as_text (pfile, rhs));
@@ -451,22 +485,61 @@ paste_all_tokens (pfile, lhs)
   push_token_context (pfile, NULL, lhs, 1);
 }
 
   push_token_context (pfile, NULL, lhs, 1);
 }
 
+/* Returns TRUE if the number of arguments ARGC supplied in an
+   invocation of the MACRO referenced by NODE is valid.  An empty
+   invocation to a macro with no parameters should pass ARGC as zero.
+
+   Note that MACRO cannot necessarily be deduced from NODE, in case
+   NODE was redefined whilst collecting arguments.  */
+bool
+_cpp_arguments_ok (cpp_reader *pfile, cpp_macro *macro, const cpp_hashnode *node, unsigned int argc)
+{
+  if (argc == macro->paramc)
+    return true;
+
+  if (argc < macro->paramc)
+    {
+      /* As an extension, a rest argument is allowed to not appear in
+        the invocation at all.
+        e.g. #define debug(format, args...) something
+        debug("string");
+
+        This is exactly the same as if there had been an empty rest
+        argument - debug("string", ).  */
+
+      if (argc + 1 == macro->paramc && macro->variadic)
+       {
+         if (CPP_PEDANTIC (pfile) && ! macro->syshdr)
+           cpp_error (pfile, CPP_DL_PEDWARN,
+                      "ISO C99 requires rest arguments to be used");
+         return true;
+       }
+
+      cpp_error (pfile, CPP_DL_ERROR,
+                "macro \"%s\" requires %u arguments, but only %u given",
+                NODE_NAME (node), macro->paramc, argc);
+    }
+  else
+    cpp_error (pfile, CPP_DL_ERROR,
+              "macro \"%s\" passed %u arguments, but takes just %u",
+              NODE_NAME (node), argc, macro->paramc);
+
+  return false;
+}
+
 /* 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 *
 /* 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;
-     const cpp_hashnode *node;
+collect_args (cpp_reader *pfile, const cpp_hashnode *node)
 {
   _cpp_buff *buff, *base_buff;
   cpp_macro *macro;
   macro_arg *args, *arg;
   const cpp_token *token;
   unsigned int argc;
 {
   _cpp_buff *buff, *base_buff;
   cpp_macro *macro;
   macro_arg *args, *arg;
   const cpp_token *token;
   unsigned int argc;
-  bool error = false;
 
   macro = node->value.macro;
   if (macro->paramc)
 
   macro = node->value.macro;
   if (macro->paramc)
@@ -558,50 +631,33 @@ collect_args (pfile, node)
         callers at the end of an -include-d file.  */
       if (pfile->context->prev || pfile->state.in_directive)
        _cpp_backup_tokens (pfile, 1);
         callers at the end of an -include-d file.  */
       if (pfile->context->prev || pfile->state.in_directive)
        _cpp_backup_tokens (pfile, 1);
-      cpp_error (pfile, DL_ERROR,
+      cpp_error (pfile, CPP_DL_ERROR,
                 "unterminated argument list invoking macro \"%s\"",
                 NODE_NAME (node));
                 "unterminated argument list invoking macro \"%s\"",
                 NODE_NAME (node));
-      error = true;
-    }
-  else if (argc < macro->paramc)
-    {
-      /* As an extension, a rest argument is allowed to not appear in
-        the invocation at all.
-        e.g. #define debug(format, args...) something
-        debug("string");
-
-        This is exactly the same as if there had been an empty rest
-        argument - debug("string", ).  */
-
-      if (argc + 1 == macro->paramc && macro->variadic)
-       {
-         if (CPP_PEDANTIC (pfile) && ! macro->syshdr)
-           cpp_error (pfile, DL_PEDWARN,
-                      "ISO C99 requires rest arguments to be used");
-       }
-      else
-       {
-         cpp_error (pfile, DL_ERROR,
-                    "macro \"%s\" requires %u arguments, but only %u given",
-                    NODE_NAME (node), macro->paramc, argc);
-         error = true;
-       }
     }
     }
-  else if (argc > macro->paramc)
+  else
     {
     {
-      /* Empty argument to a macro taking no arguments is OK.  */
-      if (argc != 1 || arg->count)
+      /* A single empty argument is counted as no argument.  */
+      if (argc == 1 && macro->paramc == 0 && args[0].count == 0)
+       argc = 0;
+      if (_cpp_arguments_ok (pfile, macro, node, argc))
        {
        {
-         cpp_error (pfile, DL_ERROR,
-                    "macro \"%s\" passed %u arguments, but takes just %u",
-                    NODE_NAME (node), argc, macro->paramc);
-         error = true;
+         /* GCC has special semantics for , ## b where b is a varargs
+            parameter: we remove the comma if b was omitted entirely.
+            If b was merely an empty argument, the comma is retained.
+            If the macro takes just one (varargs) parameter, then we
+            retain the comma only if we are standards conforming.
+
+            If FIRST is NULL replace_args () swallows the comma.  */
+         if (macro->variadic && (argc < macro->paramc
+                                 || (argc == 1 && args[0].count == 0
+                                     && !CPP_OPTION (pfile, std))))
+           args[macro->paramc - 1].first = NULL;
+         return base_buff;
        }
     }
 
        }
     }
 
-  if (!error)
-    return base_buff;
-
+  /* An error occurred.  */
   _cpp_release_buff (pfile, base_buff);
   return NULL;
 }
   _cpp_release_buff (pfile, base_buff);
   return NULL;
 }
@@ -611,9 +667,7 @@ collect_args (pfile, node)
    intervening padding tokens.  If we find the parenthesis, collect
    the arguments and return the buffer containing them.  */
 static _cpp_buff *
    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;
-     cpp_hashnode *node;
+funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node)
 {
   const cpp_token *token, *padding = NULL;
 
 {
   const cpp_token *token, *padding = NULL;
 
@@ -653,13 +707,13 @@ funlike_invocation_p (pfile, node)
    containing its yet-to-be-rescanned replacement list and return one.
    Otherwise, we don't push a context and return zero.  */
 static int
    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;
+enter_macro_context (cpp_reader *pfile, cpp_hashnode *node)
 {
   /* The presence of a macro invalidates a file's controlling macro.  */
   pfile->mi_valid = false;
 
 {
   /* The presence of a macro invalidates a file's controlling macro.  */
   pfile->mi_valid = false;
 
+  pfile->state.angled_headers = false;
+
   /* Handle standard macros.  */
   if (! (node->flags & NODE_BUILTIN))
     {
   /* Handle standard macros.  */
   if (! (node->flags & NODE_BUILTIN))
     {
@@ -680,7 +734,7 @@ enter_macro_context (pfile, node)
          if (buff == NULL)
            {
              if (CPP_WTRADITIONAL (pfile) && ! node->value.macro->syshdr)
          if (buff == NULL)
            {
              if (CPP_WTRADITIONAL (pfile) && ! node->value.macro->syshdr)
-               cpp_error (pfile, DL_WARNING,
+               cpp_error (pfile, CPP_DL_WARNING,
  "function-like macro \"%s\" must be used with arguments in traditional C",
                           NODE_NAME (node));
 
  "function-like macro \"%s\" must be used with arguments in traditional C",
                           NODE_NAME (node));
 
@@ -695,6 +749,8 @@ enter_macro_context (pfile, node)
       /* Disable the macro within its expansion.  */
       node->flags |= NODE_DISABLED;
 
       /* Disable the macro within its expansion.  */
       node->flags |= NODE_DISABLED;
 
+      macro->used = 1;
+
       if (macro->paramc == 0)
        push_token_context (pfile, node, macro->exp.tokens, macro->count);
 
       if (macro->paramc == 0)
        push_token_context (pfile, node, macro->exp.tokens, macro->count);
 
@@ -710,11 +766,7 @@ enter_macro_context (pfile, node)
    Expand each argument before replacing, unless it is operated upon
    by the # or ## operators.  */
 static void
    Expand each argument before replacing, unless it is operated upon
    by the # or ## operators.  */
 static void
-replace_args (pfile, node, macro, args)
-     cpp_reader *pfile;
-     cpp_hashnode *node;
-     cpp_macro *macro;
-     macro_arg *args;
+replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, macro_arg *args)
 {
   unsigned int i, total;
   const cpp_token *src, *limit;
 {
   unsigned int i, total;
   const cpp_token *src, *limit;
@@ -783,15 +835,13 @@ replace_args (pfile, node, macro, args)
          count = arg->count, from = arg->first;
          if (dest != first)
            {
          count = arg->count, from = arg->first;
          if (dest != first)
            {
-             /* GCC has special semantics for , ## b where b is a
-                varargs parameter: the comma disappears if b was
-                given no actual arguments (not merely if b is an
-                empty argument); otherwise the paste flag is removed.  */
              if (dest[-1]->type == CPP_COMMA
                  && macro->variadic
                  && src->val.arg_no == macro->paramc)
                {
              if (dest[-1]->type == CPP_COMMA
                  && macro->variadic
                  && src->val.arg_no == macro->paramc)
                {
-                 if (count == 0)
+                 /* Swallow a pasted comma if from == NULL, otherwise
+                    drop the paste flag.  */
+                 if (from == NULL)
                    dest--;
                  else
                    paste_flag = dest - 1;
                    dest--;
                  else
                    paste_flag = dest - 1;
@@ -805,7 +855,7 @@ replace_args (pfile, node, macro, args)
        count = arg->expanded_count, from = arg->expanded;
 
       /* Padding on the left of an argument (unless RHS of ##).  */
        count = arg->expanded_count, from = arg->expanded;
 
       /* Padding on the left of an argument (unless RHS of ##).  */
-      if (!pfile->state.in_directive
+      if ((!pfile->state.in_directive || pfile->state.directive_wants_padding)
          && src != macro->exp.tokens && !(src[-1].flags & PASTE_LEFT))
        *dest++ = padding_token (pfile, src);
 
          && src != macro->exp.tokens && !(src[-1].flags & PASTE_LEFT))
        *dest++ = padding_token (pfile, src);
 
@@ -848,9 +898,7 @@ replace_args (pfile, node, macro, args)
 
 /* Return a special padding token, with padding inherited from SOURCE.  */
 static const cpp_token *
 
 /* Return a special padding token, with padding inherited from SOURCE.  */
 static const cpp_token *
-padding_token (pfile, source)
-     cpp_reader *pfile;
-     const cpp_token *source;
+padding_token (cpp_reader *pfile, const cpp_token *source)
 {
   cpp_token *result = _cpp_temp_token (pfile);
 
 {
   cpp_token *result = _cpp_temp_token (pfile);
 
@@ -863,8 +911,7 @@ padding_token (pfile, source)
 /* Get a new uninitialized context.  Create a new one if we cannot
    re-use an old one.  */
 static cpp_context *
 /* 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;
+next_context (cpp_reader *pfile)
 {
   cpp_context *result = pfile->context->next;
 
 {
   cpp_context *result = pfile->context->next;
 
@@ -882,37 +929,45 @@ next_context (pfile)
 
 /* Push a list of pointers to tokens.  */
 static void
 
 /* Push a list of pointers to tokens.  */
 static void
-push_ptoken_context (pfile, macro, buff, first, count)
-     cpp_reader *pfile;
-     cpp_hashnode *macro;
-     _cpp_buff *buff;
-     const cpp_token **first;
-     unsigned int count;
+push_ptoken_context (cpp_reader *pfile, cpp_hashnode *macro, _cpp_buff *buff,
+                    const cpp_token **first, unsigned int count)
 {
   cpp_context *context = next_context (pfile);
 
   context->direct_p = false;
   context->macro = macro;
   context->buff = buff;
 {
   cpp_context *context = next_context (pfile);
 
   context->direct_p = false;
   context->macro = macro;
   context->buff = buff;
-  context->first.ptoken = first;
-  context->last.ptoken = first + count;
+  FIRST (context).ptoken = first;
+  LAST (context).ptoken = first + count;
 }
 
 /* Push a list of tokens.  */
 static void
 }
 
 /* Push a list of tokens.  */
 static void
-push_token_context (pfile, macro, first, count)
-     cpp_reader *pfile;
-     cpp_hashnode *macro;
-     const cpp_token *first;
-     unsigned int count;
+push_token_context (cpp_reader *pfile, cpp_hashnode *macro,
+                   const cpp_token *first, unsigned int count)
 {
   cpp_context *context = next_context (pfile);
 
   context->direct_p = true;
   context->macro = macro;
   context->buff = NULL;
 {
   cpp_context *context = next_context (pfile);
 
   context->direct_p = true;
   context->macro = macro;
   context->buff = NULL;
-  context->first.token = first;
-  context->last.token = first + count;
+  FIRST (context).token = first;
+  LAST (context).token = first + count;
+}
+
+/* Push a traditional macro's replacement text.  */
+void
+_cpp_push_text_context (cpp_reader *pfile, cpp_hashnode *macro,
+                       const uchar *start, size_t len)
+{
+  cpp_context *context = next_context (pfile);
+
+  context->direct_p = true;
+  context->macro = macro;
+  context->buff = NULL;
+  CUR (context) = start;
+  RLIMIT (context) = start + len;
+  macro->flags |= NODE_DISABLED;
 }
 
 /* Expand an argument ARG before replacing parameters in a
 }
 
 /* Expand an argument ARG before replacing parameters in a
@@ -922,19 +977,21 @@ push_token_context (pfile, macro, first, count)
    has terminated the argument's tokens with a CPP_EOF so that we know
    when we have fully expanded the argument.  */
 static void
    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;
-     macro_arg *arg;
+expand_arg (cpp_reader *pfile, macro_arg *arg)
 {
   unsigned int capacity;
 {
   unsigned int capacity;
+  bool saved_warn_trad;
 
   if (arg->count == 0)
     return;
 
 
   if (arg->count == 0)
     return;
 
+  /* Don't warn about funlike macros when pre-expanding.  */
+  saved_warn_trad = CPP_WTRADITIONAL (pfile);
+  CPP_WTRADITIONAL (pfile) = 0;
+
   /* Loop, reading in the arguments.  */
   capacity = 256;
   /* Loop, reading in the arguments.  */
   capacity = 256;
-  arg->expanded = (const cpp_token **)
-    xmalloc (capacity * sizeof (cpp_token *));
+  arg->expanded = xmalloc (capacity * sizeof (cpp_token *));
 
   push_ptoken_context (pfile, NULL, NULL, arg->first, arg->count + 1);
   for (;;)
 
   push_ptoken_context (pfile, NULL, NULL, arg->first, arg->count + 1);
   for (;;)
@@ -944,8 +1001,8 @@ expand_arg (pfile, arg)
       if (arg->expanded_count + 1 >= capacity)
        {
          capacity *= 2;
       if (arg->expanded_count + 1 >= capacity)
        {
          capacity *= 2;
-         arg->expanded = (const cpp_token **)
-           xrealloc (arg->expanded, capacity * sizeof (cpp_token *));
+         arg->expanded = xrealloc (arg->expanded,
+                                   capacity * sizeof (cpp_token *));
        }
 
       token = cpp_get_token (pfile);
        }
 
       token = cpp_get_token (pfile);
@@ -957,14 +1014,15 @@ expand_arg (pfile, arg)
     }
 
   _cpp_pop_context (pfile);
     }
 
   _cpp_pop_context (pfile);
+
+  CPP_WTRADITIONAL (pfile) = saved_warn_trad;
 }
 
 /* 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
 }
 
 /* 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_pop_context (cpp_reader *pfile)
 {
   cpp_context *context = pfile->context;
 
 {
   cpp_context *context = pfile->context;
 
@@ -977,9 +1035,9 @@ _cpp_pop_context (pfile)
   pfile->context = context->prev;
 }
 
   pfile->context = context->prev;
 }
 
-/* Eternal routine to get a token.  Also used nearly everywhere
+/* External routine to get a token.  Also used nearly everywhere
    internally, except for places where we know we can safely call
    internally, except for places where we know we can safely call
-   the lexer directly, such as lexing a directive name.
+   _cpp_lex_token directly, such as lexing a directive name.
 
    Macro expansions and directives are transparently handled,
    including entering included files.  Thus tokens are post-macro
 
    Macro expansions and directives are transparently handled,
    including entering included files.  Thus tokens are post-macro
@@ -989,8 +1047,7 @@ _cpp_pop_context (pfile)
    state.in_directive is still 1, and at the end of argument
    pre-expansion.  */
 const cpp_token *
    state.in_directive is still 1, and at the end of argument
    pre-expansion.  */
 const cpp_token *
-cpp_get_token (pfile)
-     cpp_reader *pfile;
+cpp_get_token (cpp_reader *pfile)
 {
   const cpp_token *result;
 
 {
   const cpp_token *result;
 
@@ -1002,12 +1059,12 @@ cpp_get_token (pfile)
       /* Context->prev == 0 <=> base context.  */
       if (!context->prev)
        result = _cpp_lex_token (pfile);
       /* Context->prev == 0 <=> base context.  */
       if (!context->prev)
        result = _cpp_lex_token (pfile);
-      else if (context->first.token != context->last.token)
+      else if (FIRST (context).token != LAST (context).token)
        {
          if (context->direct_p)
        {
          if (context->direct_p)
-           result = context->first.token++;
+           result = FIRST (context).token++;
          else
          else
-           result = *context->first.ptoken++;
+           result = *FIRST (context).ptoken++;
 
          if (result->flags & PASTE_LEFT)
            {
 
          if (result->flags & PASTE_LEFT)
            {
@@ -1067,8 +1124,7 @@ cpp_get_token (pfile)
    defined in a system header.  Just checks the macro at the top of
    the stack.  Used for diagnostic suppression.  */
 int
    defined in a system header.  Just checks the macro at the top of
    the stack.  Used for diagnostic suppression.  */
 int
-cpp_sys_macro_p (pfile)
-     cpp_reader *pfile;
+cpp_sys_macro_p (cpp_reader *pfile)
 {
   cpp_hashnode *node = pfile->context->macro;
 
 {
   cpp_hashnode *node = pfile->context->macro;
 
@@ -1078,23 +1134,20 @@ cpp_sys_macro_p (pfile)
 /* Read each token in, until end of the current file.  Directives are
    transparently processed.  */
 void
 /* Read each token in, until end of the current file.  Directives are
    transparently processed.  */
 void
-cpp_scan_nooutput (pfile)
-     cpp_reader *pfile;
+cpp_scan_nooutput (cpp_reader *pfile)
 {
 {
-  /* Request a CPP_EOF token at the end of this file, rather than
-     transparently continuing with the including file.  */
-  pfile->buffer->return_at_eof = true;
-
-  while (cpp_get_token (pfile)->type != CPP_EOF)
-    ;
+  if (CPP_OPTION (pfile, traditional))
+    while (_cpp_read_logical_line_trad (pfile))
+      ;
+  else
+    while (cpp_get_token (pfile)->type != CPP_EOF)
+      ;
 }
 
 /* Step back one (or more) tokens.  Can only step mack more than 1 if
    they are from the lexer, and not from macro expansion.  */
 void
 }
 
 /* Step back one (or more) tokens.  Can only step mack more than 1 if
    they are from the lexer, and not from macro expansion.  */
 void
-_cpp_backup_tokens (pfile, count)
-     cpp_reader *pfile;
-     unsigned int count;
+_cpp_backup_tokens (cpp_reader *pfile, unsigned int count)
 {
   if (pfile->context->prev == NULL)
     {
 {
   if (pfile->context->prev == NULL)
     {
@@ -1116,55 +1169,59 @@ _cpp_backup_tokens (pfile, count)
       if (count != 1)
        abort ();
       if (pfile->context->direct_p)
       if (count != 1)
        abort ();
       if (pfile->context->direct_p)
-       pfile->context->first.token--;
+       FIRST (pfile->context).token--;
       else
       else
-       pfile->context->first.ptoken--;
+       FIRST (pfile->context).ptoken--;
     }
 }
 
 /* #define directive parsing and handling.  */
 
     }
 }
 
 /* #define directive parsing and handling.  */
 
-/* Returns non-zero if a macro redefinition warning is required.  */
-static int
-warn_of_redefinition (node, macro2)
-     const cpp_hashnode *node;
-     const cpp_macro *macro2;
+/* Returns nonzero if a macro redefinition warning is required.  */
+static bool
+warn_of_redefinition (cpp_reader *pfile, const cpp_hashnode *node,
+                     const cpp_macro *macro2)
 {
   const cpp_macro *macro1;
   unsigned int i;
 
   /* Some redefinitions need to be warned about regardless.  */
   if (node->flags & NODE_WARN)
 {
   const cpp_macro *macro1;
   unsigned int i;
 
   /* Some redefinitions need to be warned about regardless.  */
   if (node->flags & NODE_WARN)
-    return 1;
+    return true;
 
   /* 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;
 
 
   /* 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;
 
-  /* The quick failures.  */
-  if (macro1->count != macro2->count
-      || macro1->paramc != macro2->paramc
+  /* Don't check count here as it can be different in valid
+     traditional redefinitions with just whitespace differences.  */
+  if (macro1->paramc != macro2->paramc
       || macro1->fun_like != macro2->fun_like
       || macro1->variadic != macro2->variadic)
       || macro1->fun_like != macro2->fun_like
       || macro1->variadic != macro2->variadic)
-    return 1;
-
-  /* Check each token.  */
-  for (i = 0; i < macro1->count; i++)
-    if (! _cpp_equiv_tokens (&macro1->exp.tokens[i], &macro2->exp.tokens[i]))
-      return 1;
+    return true;
 
   /* Check parameter spellings.  */
   for (i = 0; i < macro1->paramc; i++)
     if (macro1->params[i] != macro2->params[i])
 
   /* Check parameter spellings.  */
   for (i = 0; i < macro1->paramc; i++)
     if (macro1->params[i] != macro2->params[i])
-      return 1;
+      return true;
+
+  /* Check the replacement text or tokens.  */
+  if (CPP_OPTION (pfile, traditional))
+    return _cpp_expansions_different_trad (macro1, macro2);
+
+  if (macro1->count != macro2->count)
+    return true;
 
 
-  return 0;
+  for (i = 0; i < macro1->count; i++)
+    if (!_cpp_equiv_tokens (&macro1->exp.tokens[i], &macro2->exp.tokens[i]))
+      return true;
+
+  return false;
 }
 
 /* Free the definition of hashnode H.  */
 void
 }
 
 /* Free the definition of hashnode H.  */
 void
-_cpp_free_definition (h)
-     cpp_hashnode *h;
+_cpp_free_definition (cpp_hashnode *h)
 {
   /* Macros and assertions no longer have anything to free.  */
   h->type = NT_VOID;
 {
   /* Macros and assertions no longer have anything to free.  */
   h->type = NT_VOID;
@@ -1173,19 +1230,17 @@ _cpp_free_definition (h)
 }
 
 /* Save parameter NODE to the parameter list of macro MACRO.  Returns
 }
 
 /* Save parameter NODE to the parameter list of macro MACRO.  Returns
-   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;
+   zero on success, nonzero if the parameter is a duplicate.  */
+bool
+_cpp_save_parameter (cpp_reader *pfile, cpp_macro *macro, cpp_hashnode *node)
 {
 {
+  unsigned int len;
   /* Constraint 6.10.3.6 - duplicate parameter names.  */
   /* Constraint 6.10.3.6 - duplicate parameter names.  */
-  if (node->arg_index)
+  if (node->flags & NODE_MACRO_ARG)
     {
     {
-      cpp_error (pfile, DL_ERROR, "duplicate macro parameter \"%s\"",
+      cpp_error (pfile, CPP_DL_ERROR, "duplicate macro parameter \"%s\"",
                 NODE_NAME (node));
                 NODE_NAME (node));
-      return 1;
+      return true;
     }
 
   if (BUFF_ROOM (pfile->a_buff)
     }
 
   if (BUFF_ROOM (pfile->a_buff)
@@ -1193,15 +1248,24 @@ save_parameter (pfile, macro, node)
     _cpp_extend_buff (pfile, &pfile->a_buff, sizeof (cpp_hashnode *));
 
   ((cpp_hashnode **) BUFF_FRONT (pfile->a_buff))[macro->paramc++] = node;
     _cpp_extend_buff (pfile, &pfile->a_buff, sizeof (cpp_hashnode *));
 
   ((cpp_hashnode **) BUFF_FRONT (pfile->a_buff))[macro->paramc++] = node;
-  node->arg_index = macro->paramc;
-  return 0;
+  node->flags |= NODE_MACRO_ARG;
+  len = macro->paramc * sizeof (union _cpp_hashnode_value);
+  if (len > pfile->macro_buffer_len)
+    {
+      pfile->macro_buffer = xrealloc (pfile->macro_buffer, len);
+      pfile->macro_buffer_len = len;
+    }
+  ((union _cpp_hashnode_value *) pfile->macro_buffer)[macro->paramc - 1]
+    = node->value;
+  
+  node->value.arg_index  = macro->paramc;
+  return false;
 }
 
 }
 
-/* Check the syntax of the parameters in a MACRO definition.  */
-static int
-parse_params (pfile, macro)
-     cpp_reader *pfile;
-     cpp_macro *macro;
+/* Check the syntax of the parameters in a MACRO definition.  Returns
+   false if an error occurs.  */
+static bool
+parse_params (cpp_reader *pfile, cpp_macro *macro)
 {
   unsigned int prev_ident = 0;
 
 {
   unsigned int prev_ident = 0;
 
@@ -1218,34 +1282,34 @@ parse_params (pfile, macro)
              && ! CPP_OPTION (pfile, discard_comments_in_macro_exp))
            continue;
 
              && ! CPP_OPTION (pfile, discard_comments_in_macro_exp))
            continue;
 
-         cpp_error (pfile, DL_ERROR,
+         cpp_error (pfile, CPP_DL_ERROR,
                     "\"%s\" may not appear in macro parameter list",
                     cpp_token_as_text (pfile, token));
                     "\"%s\" may not appear in macro parameter list",
                     cpp_token_as_text (pfile, token));
-         return 0;
+         return false;
 
        case CPP_NAME:
          if (prev_ident)
            {
 
        case CPP_NAME:
          if (prev_ident)
            {
-             cpp_error (pfile, DL_ERROR,
+             cpp_error (pfile, CPP_DL_ERROR,
                         "macro parameters must be comma-separated");
                         "macro parameters must be comma-separated");
-             return 0;
+             return false;
            }
          prev_ident = 1;
 
            }
          prev_ident = 1;
 
-         if (save_parameter (pfile, macro, token->val.node))
-           return 0;
+         if (_cpp_save_parameter (pfile, macro, token->val.node))
+           return false;
          continue;
 
        case CPP_CLOSE_PAREN:
          if (prev_ident || macro->paramc == 0)
          continue;
 
        case CPP_CLOSE_PAREN:
          if (prev_ident || macro->paramc == 0)
-           return 1;
+           return true;
 
          /* Fall through to pick up the error.  */
        case CPP_COMMA:
          if (!prev_ident)
            {
 
          /* Fall through to pick up the error.  */
        case CPP_COMMA:
          if (!prev_ident)
            {
-             cpp_error (pfile, DL_ERROR, "parameter name missing");
-             return 0;
+             cpp_error (pfile, CPP_DL_ERROR, "parameter name missing");
+             return false;
            }
          prev_ident = 0;
          continue;
            }
          prev_ident = 0;
          continue;
@@ -1254,34 +1318,33 @@ parse_params (pfile, macro)
          macro->variadic = 1;
          if (!prev_ident)
            {
          macro->variadic = 1;
          if (!prev_ident)
            {
-             save_parameter (pfile, macro, pfile->spec_nodes.n__VA_ARGS__);
+             _cpp_save_parameter (pfile, macro,
+                                  pfile->spec_nodes.n__VA_ARGS__);
              pfile->state.va_args_ok = 1;
              if (! CPP_OPTION (pfile, c99) && CPP_OPTION (pfile, pedantic))
              pfile->state.va_args_ok = 1;
              if (! CPP_OPTION (pfile, c99) && CPP_OPTION (pfile, pedantic))
-               cpp_error (pfile, DL_PEDWARN,
+               cpp_error (pfile, CPP_DL_PEDWARN,
                           "anonymous variadic macros were introduced in C99");
            }
          else if (CPP_OPTION (pfile, pedantic))
                           "anonymous variadic macros were introduced in C99");
            }
          else if (CPP_OPTION (pfile, pedantic))
-           cpp_error (pfile, DL_PEDWARN,
+           cpp_error (pfile, CPP_DL_PEDWARN,
                       "ISO C does not permit named variadic macros");
 
          /* We're at the end, and just expect a closing parenthesis.  */
          token = _cpp_lex_token (pfile);
          if (token->type == CPP_CLOSE_PAREN)
                       "ISO C does not permit named variadic macros");
 
          /* We're at the end, and just expect a closing parenthesis.  */
          token = _cpp_lex_token (pfile);
          if (token->type == CPP_CLOSE_PAREN)
-           return 1;
+           return true;
          /* Fall through.  */
 
        case CPP_EOF:
          /* Fall through.  */
 
        case CPP_EOF:
-         cpp_error (pfile, DL_ERROR, "missing ')' in macro parameter list");
-         return 0;
+         cpp_error (pfile, CPP_DL_ERROR, "missing ')' in macro parameter list");
+         return false;
        }
     }
 }
 
 /* Allocate room for a token from a macro's replacement list.  */
 static cpp_token *
        }
     }
 }
 
 /* Allocate room for a token from a macro's replacement list.  */
 static cpp_token *
-alloc_expansion_token (pfile, macro)
-     cpp_reader *pfile;
-     cpp_macro *macro;
+alloc_expansion_token (cpp_reader *pfile, cpp_macro *macro)
 {
   if (BUFF_ROOM (pfile->a_buff) < (macro->count + 1) * sizeof (cpp_token))
     _cpp_extend_buff (pfile, &pfile->a_buff, sizeof (cpp_token));
 {
   if (BUFF_ROOM (pfile->a_buff) < (macro->count + 1) * sizeof (cpp_token))
     _cpp_extend_buff (pfile, &pfile->a_buff, sizeof (cpp_token));
@@ -1292,9 +1355,7 @@ alloc_expansion_token (pfile, macro)
 /* Lex a token from the expansion of MACRO, but mark parameters as we
    find them and warn of traditional stringification.  */
 static cpp_token *
 /* 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;
-     cpp_macro *macro;
+lex_expansion_token (cpp_reader *pfile, cpp_macro *macro)
 {
   cpp_token *token;
 
 {
   cpp_token *token;
 
@@ -1302,10 +1363,11 @@ lex_expansion_token (pfile, macro)
   token = _cpp_lex_direct (pfile);
 
   /* Is this a parameter?  */
   token = _cpp_lex_direct (pfile);
 
   /* Is this a parameter?  */
-  if (token->type == CPP_NAME && token->val.node->arg_index)
+  if (token->type == CPP_NAME
+      && (token->val.node->flags & NODE_MACRO_ARG) != 0)
     {
       token->type = CPP_MACRO_ARG;
     {
       token->type = CPP_MACRO_ARG;
-      token->val.arg_no = token->val.node->arg_index;
+      token->val.arg_no = token->val.node->value.arg_index;
     }
   else if (CPP_WTRADITIONAL (pfile) && macro->paramc > 0
           && (token->type == CPP_STRING || token->type == CPP_CHAR))
     }
   else if (CPP_WTRADITIONAL (pfile) && macro->paramc > 0
           && (token->type == CPP_STRING || token->type == CPP_CHAR))
@@ -1314,24 +1376,11 @@ lex_expansion_token (pfile, macro)
   return token;
 }
 
   return token;
 }
 
-/* Parse a macro and save its expansion.  Returns non-zero on success.  */
-int
-_cpp_create_definition (pfile, node)
-     cpp_reader *pfile;
-     cpp_hashnode *node;
+static bool
+create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
 {
 {
-  cpp_macro *macro;
-  cpp_token *token, *saved_cur_token;
+  cpp_token *token;
   const cpp_token *ctoken;
   const cpp_token *ctoken;
-  unsigned int i, ok = 1;
-
-  macro = (cpp_macro *) _cpp_aligned_alloc (pfile, sizeof (cpp_macro));
-  macro->line = pfile->directive_line;
-  macro->params = 0;
-  macro->paramc = 0;
-  macro->variadic = 0;
-  macro->count = 0;
-  macro->fun_like = 0;
 
   /* Get the first token of the expansion (or the '(' of a
      function-like macro).  */
 
   /* Get the first token of the expansion (or the '(' of a
      function-like macro).  */
@@ -1339,21 +1388,19 @@ _cpp_create_definition (pfile, node)
 
   if (ctoken->type == CPP_OPEN_PAREN && !(ctoken->flags & PREV_WHITE))
     {
 
   if (ctoken->type == CPP_OPEN_PAREN && !(ctoken->flags & PREV_WHITE))
     {
-      ok = parse_params (pfile, macro);
+      bool ok = parse_params (pfile, macro);
       macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff);
       if (!ok)
       macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff);
       if (!ok)
-       goto cleanup2;
+       return false;
 
       /* Success.  Commit the parameter array.  */
       BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->params[macro->paramc];
       macro->fun_like = 1;
     }
   else if (ctoken->type != CPP_EOF && !(ctoken->flags & PREV_WHITE))
 
       /* Success.  Commit the parameter array.  */
       BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->params[macro->paramc];
       macro->fun_like = 1;
     }
   else if (ctoken->type != CPP_EOF && !(ctoken->flags & PREV_WHITE))
-    cpp_error (pfile, DL_PEDWARN,
+    cpp_error (pfile, CPP_DL_PEDWARN,
               "ISO C requires whitespace after the macro name");
 
               "ISO C requires whitespace after the macro name");
 
-  saved_cur_token = pfile->cur_token;
-
   if (macro->fun_like)
     token = lex_expansion_token (pfile, macro);
   else
   if (macro->fun_like)
     token = lex_expansion_token (pfile, macro);
   else
@@ -1379,10 +1426,9 @@ _cpp_create_definition (pfile, node)
          /* Let assembler get away with murder.  */
          else if (CPP_OPTION (pfile, lang) != CLK_ASM)
            {
          /* Let assembler get away with murder.  */
          else if (CPP_OPTION (pfile, lang) != CLK_ASM)
            {
-             ok = 0;
-             cpp_error (pfile, DL_ERROR,
+             cpp_error (pfile, CPP_DL_ERROR,
                         "'#' is not followed by a macro parameter");
                         "'#' is not followed by a macro parameter");
-             goto cleanup1;
+             return false;
            }
        }
 
            }
        }
 
@@ -1399,10 +1445,9 @@ _cpp_create_definition (pfile, node)
 
          if (macro->count == 0 || token->type == CPP_EOF)
            {
 
          if (macro->count == 0 || token->type == CPP_EOF)
            {
-             ok = 0;
-             cpp_error (pfile, DL_ERROR,
-                        "'##' cannot appear at either end of a macro expansion");
-             goto cleanup1;
+             cpp_error (pfile, CPP_DL_ERROR,
+                "'##' cannot appear at either end of a macro expansion");
+             return false;
            }
 
          token[-1].flags |= PASTE_LEFT;
            }
 
          token[-1].flags |= PASTE_LEFT;
@@ -1423,66 +1468,101 @@ _cpp_create_definition (pfile, node)
   /* Commit the memory.  */
   BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->exp.tokens[macro->count];
 
   /* Commit the memory.  */
   BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->exp.tokens[macro->count];
 
-  /* Implement the macro-defined-to-itself optimisation.  */
-  if (macro->count == 1 && !macro->fun_like
-      && macro->exp.tokens[0].type == CPP_NAME
-      && macro->exp.tokens[0].val.node == node)
-    node->flags |= NODE_DISABLED;
+  return true;
+}
 
 
+/* Parse a macro and save its expansion.  Returns nonzero on success.  */
+bool
+_cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
+{
+  cpp_macro *macro;
+  unsigned int i;
+  bool ok;
+
+  macro = (cpp_macro *) _cpp_aligned_alloc (pfile, sizeof (cpp_macro));
+  macro->line = pfile->directive_line;
+  macro->params = 0;
+  macro->paramc = 0;
+  macro->variadic = 0;
+  macro->used = !CPP_OPTION (pfile, warn_unused_macros);
+  macro->count = 0;
+  macro->fun_like = 0;
   /* To suppress some diagnostics.  */
   macro->syshdr = pfile->map->sysp != 0;
 
   /* To suppress some diagnostics.  */
   macro->syshdr = pfile->map->sysp != 0;
 
-  if (node->type != NT_VOID)
+  if (CPP_OPTION (pfile, traditional))
+    ok = _cpp_create_trad_definition (pfile, macro);
+  else
+    {
+      cpp_token *saved_cur_token = pfile->cur_token;
+
+      ok = create_iso_definition (pfile, macro);
+
+      /* Restore lexer position because of games lex_expansion_token()
+        plays lexing the macro.  We set the type for SEEN_EOL() in
+        cpplib.c.
+
+        Longer term we should lex the whole line before coming here,
+        and just copy the expansion.  */
+      saved_cur_token[-1].type = pfile->cur_token[-1].type;
+      pfile->cur_token = saved_cur_token;
+
+      /* Stop the lexer accepting __VA_ARGS__.  */
+      pfile->state.va_args_ok = 0;
+    }
+
+  /* Clear the fast argument lookup indices.  */
+  for (i = macro->paramc; i-- > 0; )
     {
     {
-      if (warn_of_redefinition (node, macro))
+      struct cpp_hashnode *node = macro->params[i];
+      node->flags &= ~ NODE_MACRO_ARG;
+      node->value = ((union _cpp_hashnode_value *) pfile->macro_buffer)[i];
+    }
+
+  if (!ok)
+    return ok;
+
+  if (node->type == NT_MACRO)
+    {
+      if (CPP_OPTION (pfile, warn_unused_macros))
+       _cpp_warn_if_unused_macro (pfile, node, NULL);
+
+      if (warn_of_redefinition (pfile, node, macro))
        {
        {
-         cpp_error_with_line (pfile, DL_PEDWARN, pfile->directive_line, 0,
+         cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->directive_line, 0,
                               "\"%s\" redefined", NODE_NAME (node));
 
          if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
                               "\"%s\" redefined", NODE_NAME (node));
 
          if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
-           cpp_error_with_line (pfile, DL_PEDWARN, node->value.macro->line, 0,
-                           "this is the location of the previous definition");
+           cpp_error_with_line (pfile, CPP_DL_PEDWARN,
+                                node->value.macro->line, 0,
+                        "this is the location of the previous definition");
        }
        }
-      _cpp_free_definition (node);
     }
 
     }
 
+  if (node->type != NT_VOID)
+    _cpp_free_definition (node);
+
   /* Enter definition in hash table.  */
   node->type = NT_MACRO;
   node->value.macro = macro;
   if (! ustrncmp (NODE_NAME (node), DSC ("__STDC_")))
     node->flags |= NODE_WARN;
 
   /* Enter definition in hash table.  */
   node->type = NT_MACRO;
   node->value.macro = macro;
   if (! ustrncmp (NODE_NAME (node), DSC ("__STDC_")))
     node->flags |= NODE_WARN;
 
- cleanup1:
-
-  /* Set type for SEEN_EOL() in cpplib.c, restore the lexer position.  */
-  saved_cur_token[-1].type = pfile->cur_token[-1].type;
-  pfile->cur_token = saved_cur_token;
-
- cleanup2:
-
-  /* Stop the lexer accepting __VA_ARGS__.  */
-  pfile->state.va_args_ok = 0;
-
-  /* Clear the fast argument lookup indices.  */
-  for (i = macro->paramc; i-- > 0; )
-    macro->params[i]->arg_index = 0;
-
   return ok;
 }
 
 /* Warn if a token in STRING matches one of a function-like MACRO's
    parameters.  */
 static void
   return ok;
 }
 
 /* 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;
-     const cpp_macro *macro;
-     const cpp_string *string;
+check_trad_stringification (cpp_reader *pfile, const cpp_macro *macro,
+                           const cpp_string *string)
 {
   unsigned int i, len;
 {
   unsigned int i, len;
-  const uchar *p, *q, *limit = string->text + string->len;
+  const uchar *p, *q, *limit;
 
   /* Loop over the string.  */
 
   /* Loop over the string.  */
-  for (p = string->text; p < limit; p = q)
+  limit = string->text + string->len - 1;
+  for (p = string->text + 1; p < limit; p = q)
     {
       /* Find the start of an identifier.  */
       while (p < limit && !is_idstart (*p))
     {
       /* Find the start of an identifier.  */
       while (p < limit && !is_idstart (*p))
@@ -1504,7 +1584,7 @@ check_trad_stringification (pfile, macro, string)
          if (NODE_LEN (node) == len
              && !memcmp (p, NODE_NAME (node), len))
            {
          if (NODE_LEN (node) == len
              && !memcmp (p, NODE_NAME (node), len))
            {
-             cpp_error (pfile, DL_WARNING,
+             cpp_error (pfile, CPP_DL_WARNING,
           "macro argument \"%s\" would be stringified in traditional C",
                         NODE_NAME (node));
              break;
           "macro argument \"%s\" would be stringified in traditional C",
                         NODE_NAME (node));
              break;
@@ -1519,9 +1599,7 @@ check_trad_stringification (pfile, macro, string)
    Caller is expected to generate the "#define" bit if needed.  The
    returned text is temporary, and automatically freed later.  */
 const unsigned char *
    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;
-     const cpp_hashnode *node;
+cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node)
 {
   unsigned int i, len;
   const cpp_macro *macro = node->value.macro;
 {
   unsigned int i, len;
   const cpp_macro *macro = node->value.macro;
@@ -1529,13 +1607,13 @@ cpp_macro_definition (pfile, node)
 
   if (node->type != NT_MACRO || (node->flags & NODE_BUILTIN))
     {
 
   if (node->type != NT_MACRO || (node->flags & NODE_BUILTIN))
     {
-      cpp_error (pfile, DL_ICE,
+      cpp_error (pfile, CPP_DL_ICE,
                 "invalid hash type %d in cpp_macro_definition", node->type);
       return 0;
     }
 
   /* Calculate length.  */
                 "invalid hash type %d in cpp_macro_definition", node->type);
       return 0;
     }
 
   /* Calculate length.  */
-  len = NODE_LEN (node) + 1;                   /* ' ' */
+  len = NODE_LEN (node) + 2;                   /* ' ' and NUL.  */
   if (macro->fun_like)
     {
       len += 4;                /* "()" plus possible final ".." of named
   if (macro->fun_like)
     {
       len += 4;                /* "()" plus possible final ".." of named
@@ -1544,23 +1622,28 @@ cpp_macro_definition (pfile, node)
        len += NODE_LEN (macro->params[i]) + 1; /* "," */
     }
 
        len += NODE_LEN (macro->params[i]) + 1; /* "," */
     }
 
-  for (i = 0; i < macro->count; i++)
+  if (CPP_OPTION (pfile, traditional))
+    len += _cpp_replacement_text_len (macro);
+  else
     {
     {
-      cpp_token *token = &macro->exp.tokens[i];
+      for (i = 0; i < macro->count; i++)
+       {
+         cpp_token *token = &macro->exp.tokens[i];
 
 
-      if (token->type == CPP_MACRO_ARG)
-       len += NODE_LEN (macro->params[token->val.arg_no - 1]);
-      else
-       len += cpp_token_len (token); /* Includes room for ' '.  */
-      if (token->flags & STRINGIFY_ARG)
-       len++;                  /* "#" */
-      if (token->flags & PASTE_LEFT)
-       len += 3;               /* " ##" */
+         if (token->type == CPP_MACRO_ARG)
+           len += NODE_LEN (macro->params[token->val.arg_no - 1]);
+         else
+           len += cpp_token_len (token) + 1; /* Includes room for ' '.  */
+         if (token->flags & STRINGIFY_ARG)
+           len++;                      /* "#" */
+         if (token->flags & PASTE_LEFT)
+           len += 3;           /* " ##" */
+       }
     }
 
   if (len > pfile->macro_buffer_len)
     {
     }
 
   if (len > pfile->macro_buffer_len)
     {
-      pfile->macro_buffer = (uchar *) xrealloc (pfile->macro_buffer, len);
+      pfile->macro_buffer = xrealloc (pfile->macro_buffer, len);
       pfile->macro_buffer_len = len;
     }
 
       pfile->macro_buffer_len = len;
     }
 
@@ -1598,8 +1681,10 @@ cpp_macro_definition (pfile, node)
      definition is the empty string.  */
   *buffer++ = ' ';
 
      definition is the empty string.  */
   *buffer++ = ' ';
 
+  if (CPP_OPTION (pfile, traditional))
+    buffer = _cpp_copy_replacement_text (macro, buffer);
+  else if (macro->count)
   /* Expansion tokens.  */
   /* Expansion tokens.  */
-  if (macro->count)
     {
       for (i = 0; i < macro->count; i++)
        {
     {
       for (i = 0; i < macro->count; i++)
        {