OSDN Git Service

Fix bad regexp
[pf3gnuchains/gcc-fork.git] / gcc / cppmacro.c
index 403920c..876506b 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,7 +25,6 @@ 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"
 
@@ -65,24 +64,22 @@ 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 unsigned char *quote_string PARAMS ((unsigned char *,
-                                           const unsigned char *,
-                                           unsigned int));
-static const cpp_token *new_string_token PARAMS ((cpp_reader *, U_CHAR *,
+static const cpp_token *new_string_token PARAMS ((cpp_reader *, uchar *,
                                                  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 bool paste_tokens PARAMS ((cpp_reader *, const cpp_token **,
                                  const cpp_token *));
-static void replace_args PARAMS ((cpp_reader *, cpp_hashnode *, macro_arg *));
+static void replace_args PARAMS ((cpp_reader *, cpp_hashnode *, cpp_macro *,
+                                 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 *));
@@ -112,12 +109,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_unaligned_alloc (pfile, 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);
@@ -133,8 +131,8 @@ static const char * const monthnames[] =
 
 /* 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 on success, 0 to return the token to the
-   caller.  */
+   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;
@@ -145,7 +143,8 @@ builtin_macro (pfile, node)
   switch (node->value.builtin)
     {
     default:
-      cpp_ice (pfile, "invalid builtin macro \"%s\"", NODE_NAME (node));
+      cpp_error (pfile, DL_ICE, "invalid built-in macro \"%s\"",
+                NODE_NAME (node));
       return 0;
 
     case BT_FILE:
@@ -153,7 +152,7 @@ builtin_macro (pfile, node)
       {
        unsigned int len;
        const char *name;
-       U_CHAR *buf;
+       uchar *buf;
        const struct line_map *map = pfile->map;
 
        if (node->value.builtin == BT_BASE_FILE)
@@ -163,7 +162,7 @@ builtin_macro (pfile, node)
        name = map->to_file;
        len = strlen (name);
        buf = _cpp_unaligned_alloc (pfile, len * 4 + 1);
-       len = quote_string (buf, (const unsigned char *) name, len) - buf;
+       len = cpp_quote_string (buf, (const unsigned char *) name, len) - buf;
 
        result = new_string_token (pfile, buf, len);
       }
@@ -241,17 +240,19 @@ builtin_macro (pfile, node)
   return 1;
 }
 
-/* Adds backslashes before all backslashes and double quotes appearing
-   in strings.  Non-printable characters are converted to octal.  */
-static U_CHAR *
-quote_string (dest, src, len)
-     U_CHAR *dest;
-     const U_CHAR *src;
+/* 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.  Returns
+   a pointer to the end of the string.  */
+uchar *
+cpp_quote_string (dest, src, len)
+     uchar *dest;
+     const uchar *src;
      unsigned int len;
 {
   while (len--)
     {
-      U_CHAR c = *src++;
+      uchar c = *src++;
 
       if (c == '\\' || c == '"')
        {
@@ -273,8 +274,8 @@ 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;
@@ -329,7 +330,7 @@ stringify_arg (pfile, arg)
          _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);
+         dest = cpp_quote_string (dest, buf, len);
          _cpp_release_buff (pfile, buff);
        }
       else
@@ -344,7 +345,8 @@ stringify_arg (pfile, arg)
   /* Ignore the final \ of invalid string literals.  */
   if (backslash_count & 1)
     {
-      cpp_warning (pfile, "invalid string literal, ignoring final '\\'");
+      cpp_error (pfile, DL_WARNING,
+                "invalid string literal, ignoring final '\\'");
       dest--;
     }
 
@@ -380,6 +382,7 @@ paste_tokens (pfile, plhs, rhs)
       && (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);
 
@@ -398,11 +401,13 @@ paste_tokens (pfile, plhs, rhs)
   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;
@@ -432,10 +437,10 @@ paste_all_tokens (pfile, lhs)
 
          /* Mandatory warning for all apart from assembler.  */
          if (CPP_OPTION (pfile, lang) != CLK_ASM)
-           cpp_warning (pfile,
+           cpp_error (pfile, DL_WARNING,
         "pasting \"%s\" and \"%s\" does not give a valid preprocessing token",
-                        cpp_token_as_text (pfile, lhs),
-                        cpp_token_as_text (pfile, rhs));
+                      cpp_token_as_text (pfile, lhs),
+                      cpp_token_as_text (pfile, rhs));
          break;
        }
     }
@@ -445,9 +450,11 @@ paste_all_tokens (pfile, lhs)
   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;
@@ -540,36 +547,18 @@ collect_args (pfile, node)
            arg++;
        }
     }
-  while (token->type != CPP_CLOSE_PAREN
-        && token->type != CPP_EOF
-        && token->type != CPP_HASH);
+  while (token->type != CPP_CLOSE_PAREN && token->type != CPP_EOF);
 
-  if (token->type == CPP_EOF || token->type == CPP_HASH)
+  if (token->type == CPP_EOF)
     {
-      bool step_back = false;
-
-      /* 6.10.3 paragraph 11: If there are sequences of preprocessing
-        tokens within the list of arguments that would otherwise act
-        as preprocessing directives, the behavior is undefined.
-
-        This implementation will report a hard error, terminate the
-        macro invocation, and proceed to process the directive.  */
-      if (token->type == CPP_HASH)
-       {
-         cpp_error (pfile,
-                    "directives may not be used inside a macro argument");
-         step_back = true;
-       }
-      else
-       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)
+      if (pfile->context->prev || pfile->state.in_directive)
        _cpp_backup_tokens (pfile, 1);
-      cpp_error (pfile, "unterminated argument list invoking macro \"%s\"",
+      cpp_error (pfile, DL_ERROR,
+                "unterminated argument list invoking macro \"%s\"",
                 NODE_NAME (node));
       error = true;
     }
@@ -586,11 +575,12 @@ collect_args (pfile, node)
       if (argc + 1 == macro->paramc && macro->variadic)
        {
          if (CPP_PEDANTIC (pfile) && ! macro->syshdr)
-           cpp_pedwarn (pfile, "ISO C99 requires rest arguments to be used");
+           cpp_error (pfile, DL_PEDWARN,
+                      "ISO C99 requires rest arguments to be used");
        }
       else
        {
-         cpp_error (pfile,
+         cpp_error (pfile, DL_ERROR,
                     "macro \"%s\" requires %u arguments, but only %u given",
                     NODE_NAME (node), macro->paramc, argc);
          error = true;
@@ -601,7 +591,7 @@ collect_args (pfile, node)
       /* Empty argument to a macro taking no arguments is OK.  */
       if (argc != 1 || arg->count)
        {
-         cpp_error (pfile,
+         cpp_error (pfile, DL_ERROR,
                     "macro \"%s\" passed %u arguments, but takes just %u",
                     NODE_NAME (node), argc, macro->paramc);
          error = true;
@@ -642,29 +632,34 @@ funlike_invocation_p (pfile, node)
       return collect_args (pfile, node);
     }
 
-  /* 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);
+  /* CPP_EOF can be the end of macro arguments, or the end of the
+     file.  We mustn't back up over the latter.  Ugh.  */
+  if (token->type != CPP_EOF || token == &pfile->eof)
+    {
+      /* 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;
 {
-  /* Macros invalidate controlling macros.  */
+  /* The presence of a macro invalidates a file's controlling macro.  */
   pfile->mi_valid = false;
 
-  /* Handle macros and the _Pragma operator.  */
+  /* Handle standard macros.  */
   if (! (node->flags & NODE_BUILTIN))
     {
       cpp_macro *macro = node->value.macro;
@@ -684,15 +679,15 @@ enter_macro_context (pfile, node)
          if (buff == NULL)
            {
              if (CPP_WTRADITIONAL (pfile) && ! node->value.macro->syshdr)
-               cpp_warning (pfile,
+               cpp_error (pfile, DL_WARNING,
  "function-like macro \"%s\" must be used with arguments in traditional C",
-                            NODE_NAME (node));
+                          NODE_NAME (node));
 
              return 0;
            }
 
-         if (node->value.macro->paramc > 0)
-           replace_args (pfile, node, (macro_arg *) buff->base);
+         if (macro->paramc > 0)
+           replace_args (pfile, node, macro, (macro_arg *) buff->base);
          _cpp_release_buff (pfile, buff);
        }
 
@@ -705,16 +700,19 @@ enter_macro_context (pfile, node)
       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, node, args)
+replace_args (pfile, node, macro, args)
      cpp_reader *pfile;
      cpp_hashnode *node;
+     cpp_macro *macro;
      macro_arg *args;
 {
   unsigned int i, total;
@@ -722,13 +720,11 @@ replace_args (pfile, node, 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;
 
@@ -863,7 +859,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;
@@ -917,6 +914,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;
@@ -955,13 +958,15 @@ 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->flags &= ~NODE_DISABLED;
 
@@ -1019,6 +1024,9 @@ cpp_get_token (pfile)
          return &pfile->avoid_paste;
        }
 
+      if (pfile->state.in_directive && result->type == CPP_COMMENT)
+       continue;
+
       if (result->type != CPP_NAME)
        break;
 
@@ -1039,7 +1047,8 @@ cpp_get_token (pfile)
        }
       else
        {
-         /* Flag this token as always unexpandable.  */
+         /* 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;
@@ -1065,12 +1074,16 @@ cpp_sys_macro_p (pfile)
   return node && node->value.macro && node->value.macro->syshdr;
 }
 
-/* Read each token in, until EOF.  Directives are transparently
-   processed.  */
+/* Read each token in, until end of the current file.  Directives are
+   transparently processed.  */
 void
 cpp_scan_nooutput (pfile)
      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)
     ;
 }
@@ -1112,8 +1125,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;
 {
@@ -1149,7 +1161,6 @@ warn_of_redefinition (pfile, node, macro2)
 }
 
 /* Free the definition of hashnode H.  */
-
 void
 _cpp_free_definition (h)
      cpp_hashnode *h;
@@ -1171,7 +1182,8 @@ save_parameter (pfile, macro, node)
   /* Constraint 6.10.3.6 - duplicate parameter names.  */
   if (node->arg_index)
     {
-      cpp_error (pfile, "duplicate macro parameter \"%s\"", NODE_NAME (node));
+      cpp_error (pfile, DL_ERROR, "duplicate macro parameter \"%s\"",
+                NODE_NAME (node));
       return 1;
     }
 
@@ -1199,14 +1211,22 @@ parse_params (pfile, macro)
       switch (token->type)
        {
        default:
-         cpp_error (pfile, "\"%s\" may not appear in macro parameter list",
+         /* Allow/ignore comments in parameter lists if we are
+            preserving comments in macro expansions.  */
+         if (token->type == CPP_COMMENT
+             && ! CPP_OPTION (pfile, discard_comments_in_macro_exp))
+           continue;
+
+         cpp_error (pfile, DL_ERROR,
+                    "\"%s\" may not appear in macro parameter list",
                     cpp_token_as_text (pfile, token));
          return 0;
 
        case CPP_NAME:
          if (prev_ident)
            {
-             cpp_error (pfile, "macro parameters must be comma-separated");
+             cpp_error (pfile, DL_ERROR,
+                        "macro parameters must be comma-separated");
              return 0;
            }
          prev_ident = 1;
@@ -1223,7 +1243,7 @@ parse_params (pfile, macro)
        case CPP_COMMA:
          if (!prev_ident)
            {
-             cpp_error (pfile, "parameter name missing");
+             cpp_error (pfile, DL_ERROR, "parameter name missing");
              return 0;
            }
          prev_ident = 0;
@@ -1236,11 +1256,12 @@ parse_params (pfile, macro)
              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))
-               cpp_pedwarn (pfile,
-                    "anonymous variadic macros were introduced in C99");
+               cpp_error (pfile, DL_PEDWARN,
+                          "anonymous variadic macros were introduced in C99");
            }
          else if (CPP_OPTION (pfile, pedantic))
-           cpp_pedwarn (pfile, "ISO C does not permit named variadic macros");
+           cpp_error (pfile, 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);
@@ -1249,7 +1270,7 @@ parse_params (pfile, macro)
          /* Fall through.  */
 
        case CPP_EOF:
-         cpp_error (pfile, "missing ')' in macro parameter list");
+         cpp_error (pfile, DL_ERROR, "missing ')' in macro parameter list");
          return 0;
        }
     }
@@ -1267,6 +1288,8 @@ alloc_expansion_token (pfile, macro)
   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;
@@ -1277,7 +1300,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;
@@ -1321,11 +1344,12 @@ _cpp_create_definition (pfile, node)
        goto cleanup2;
 
       /* Success.  Commit the parameter array.  */
-      BUFF_FRONT (pfile->a_buff) = (U_CHAR *) &macro->params[macro->paramc];
+      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_pedwarn (pfile, "ISO C requires whitespace after the macro name");
+    cpp_error (pfile, DL_PEDWARN,
+              "ISO C requires whitespace after the macro name");
 
   saved_cur_token = pfile->cur_token;
 
@@ -1355,7 +1379,8 @@ _cpp_create_definition (pfile, node)
          else if (CPP_OPTION (pfile, lang) != CLK_ASM)
            {
              ok = 0;
-             cpp_error (pfile, "'#' is not followed by a macro parameter");
+             cpp_error (pfile, DL_ERROR,
+                        "'#' is not followed by a macro parameter");
              goto cleanup1;
            }
        }
@@ -1374,7 +1399,7 @@ _cpp_create_definition (pfile, node)
          if (macro->count == 0 || token->type == CPP_EOF)
            {
              ok = 0;
-             cpp_error (pfile,
+             cpp_error (pfile, DL_ERROR,
                         "'##' cannot appear at either end of a macro expansion");
              goto cleanup1;
            }
@@ -1390,12 +1415,12 @@ _cpp_create_definition (pfile, node)
   /* Don't count the CPP_EOF.  */
   macro->count--;
 
-  /* Clear whitespace on first token for macro equivalence purposes.  */
+  /* 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];
+  BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->expansion[macro->count];
 
   /* Implement the macro-defined-to-itself optimisation.  */
   if (macro->count == 1 && !macro->fun_like
@@ -1408,13 +1433,13 @@ _cpp_create_definition (pfile, node)
 
   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));
+         cpp_error_with_line (pfile, DL_PEDWARN, pfile->directive_line, 0,
+                              "\"%s\" redefined", NODE_NAME (node));
 
          if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
-           cpp_pedwarn_with_line (pfile, node->value.macro->line, 0,
+           cpp_error_with_line (pfile, DL_PEDWARN, node->value.macro->line, 0,
                            "this is the location of the previous definition");
        }
       _cpp_free_definition (node);
@@ -1444,9 +1469,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;
@@ -1454,7 +1478,7 @@ check_trad_stringification (pfile, macro, string)
      const cpp_string *string;
 {
   unsigned int i, len;
-  const U_CHAR *p, *q, *limit = string->text + string->len;
+  const uchar *p, *q, *limit = string->text + string->len;
   
   /* Loop over the string.  */
   for (p = string->text; p < limit; p = q)
@@ -1479,9 +1503,9 @@ check_trad_stringification (pfile, macro, string)
          if (NODE_LEN (node) == len
              && !memcmp (p, NODE_NAME (node), len))
            {
-             cpp_warning (pfile,
-          "macro argument \"%s\" would be stringified with -traditional.",
-                          NODE_NAME (node));
+             cpp_error (pfile, DL_WARNING,
+          "macro argument \"%s\" would be stringified in traditional C",
+                        NODE_NAME (node));
              break;
            }
        }
@@ -1493,7 +1517,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;
@@ -1505,7 +1528,8 @@ cpp_macro_definition (pfile, node)
 
   if (node->type != NT_MACRO || (node->flags & NODE_BUILTIN))
     {
-      cpp_ice (pfile, "invalid hash type %d in cpp_macro_definition", node->type);
+      cpp_error (pfile, DL_ICE,
+                "invalid hash type %d in cpp_macro_definition", node->type);
       return 0;
     }
 
@@ -1513,10 +1537,10 @@ cpp_macro_definition (pfile, node)
   len = NODE_LEN (node) + 1;                   /* ' ' */
   if (macro->fun_like)
     {
-      len += 3;                /* "()" plus possible final "." of named
-                          varargs (we have + 2 below).  */
+      len += 4;                /* "()" plus possible final ".." of named
+                          varargs (we have + 1 below).  */
       for (i = 0; i < macro->paramc; i++)
-       len += NODE_LEN (macro->params[i]) + 2; /* ", " */
+       len += NODE_LEN (macro->params[i]) + 1; /* "," */
     }
 
   for (i = 0; i < macro->count; i++)
@@ -1535,7 +1559,7 @@ cpp_macro_definition (pfile, node)
 
   if (len > pfile->macro_buffer_len)
     {
-      pfile->macro_buffer = (U_CHAR *) xrealloc (pfile->macro_buffer, len);
+      pfile->macro_buffer = (uchar *) xrealloc (pfile->macro_buffer, len);
       pfile->macro_buffer_len = len;
     }
 
@@ -1559,17 +1583,23 @@ cpp_macro_definition (pfile, node)
            }
 
          if (i + 1 < macro->paramc)
-           *buffer++ = ',', *buffer++ = ' ';
+            /* Don't emit a space after the comma here; we're trying
+               to emit a Dwarf-friendly definition, and the Dwarf spec
+               forbids spaces in the argument list.  */
+           *buffer++ = ',';
          else if (macro->variadic)
            *buffer++ = '.', *buffer++ = '.', *buffer++ = '.';
        }
       *buffer++ = ')';
     }
 
+  /* The Dwarf spec requires a space after the macro name, even if the
+     definition is the empty string.  */
+  *buffer++ = ' ';
+
   /* Expansion tokens.  */
   if (macro->count)
     {
-      *buffer++ = ' ';
       for (i = 0; i < macro->count; i++)
        {
          cpp_token *token = &macro->expansion[i];