OSDN Git Service

PR preprocessor/19475
[pf3gnuchains/gcc-fork.git] / libcpp / macro.c
index 5e59669..daa2bd3 100644 (file)
@@ -380,12 +380,12 @@ stringify_arg (cpp_reader *pfile, macro_arg *arg)
        {
          _cpp_buff *buff = _cpp_get_buff (pfile, len);
          unsigned char *buf = BUFF_FRONT (buff);
-         len = cpp_spell_token (pfile, token, buf) - buf;
+         len = cpp_spell_token (pfile, token, buf, true) - buf;
          dest = cpp_quote_string (dest, buf, len);
          _cpp_release_buff (pfile, buff);
        }
       else
-       dest = cpp_spell_token (pfile, token, dest);
+       dest = cpp_spell_token (pfile, token, dest, true);
 
       if (token->type == CPP_OTHER && token->val.str.text[0] == '\\')
        backslash_count++;
@@ -422,7 +422,7 @@ paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs)
   lhs = *plhs;
   len = cpp_token_len (lhs) + cpp_token_len (rhs) + 1;
   buf = alloca (len);
-  end = cpp_spell_token (pfile, lhs, buf);
+  end = cpp_spell_token (pfile, lhs, buf, false);
 
   /* Avoid comment headers, since they are still processed in stage 3.
      It is simpler to insert a space here, rather than modifying the
@@ -430,7 +430,7 @@ paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs)
      false doesn't work, since we want to clear the PASTE_LEFT flag.  */
   if (lhs->type == CPP_DIV && rhs->type != CPP_EQ)
     *end++ = ' ';
-  end = cpp_spell_token (pfile, rhs, end);
+  end = cpp_spell_token (pfile, rhs, end, false);
   *end = '\n';
 
   cpp_push_buffer (pfile, buf, end - buf, /* from_stage3 */ true);
@@ -886,7 +886,7 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, macro_arg
        {
          cpp_token *token = _cpp_temp_token (pfile);
          token->type = (*paste_flag)->type;
-         token->val.str = (*paste_flag)->val.str;
+         token->val = (*paste_flag)->val;
          if (src->flags & PASTE_LEFT)
            token->flags = (*paste_flag)->flags | PASTE_LEFT;
          else
@@ -1120,7 +1120,7 @@ cpp_get_token (cpp_reader *pfile)
          cpp_token *t = _cpp_temp_token (pfile);
          t->type = result->type;
          t->flags = result->flags | NO_EXPAND;
-         t->val.str = result->val.str;
+         t->val = result->val;
          result = t;
        }
 
@@ -1430,8 +1430,39 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
       macro->fun_like = 1;
     }
   else if (ctoken->type != CPP_EOF && !(ctoken->flags & PREV_WHITE))
-    cpp_error (pfile, CPP_DL_PEDWARN,
-              "ISO C requires whitespace after the macro name");
+    {
+      /* While ISO C99 requires whitespace before replacement text
+        in a macro definition, ISO C90 with TC1 allows there characters
+        from the basic source character set.  */
+      if (CPP_OPTION (pfile, c99))
+       cpp_error (pfile, CPP_DL_PEDWARN,
+                  "ISO C99 requires whitespace after the macro name");
+      else
+       {
+         int warntype = CPP_DL_WARNING;
+         switch (ctoken->type)
+           {
+           case CPP_ATSIGN:
+           case CPP_AT_NAME:
+           case CPP_OBJC_STRING:
+             /* '@' is not in basic character set.  */
+             warntype = CPP_DL_PEDWARN;
+             break;
+           case CPP_OTHER:
+             /* Basic character set sans letters, digits and _.  */
+             if (strchr ("!\"#%&'()*+,-./:;<=>?[\\]^{|}~",
+                         ctoken->val.str.text[0]) == NULL)
+               warntype = CPP_DL_PEDWARN;
+             break;
+           default:
+             /* All other tokens start with a character from basic
+                character set.  */
+             break;
+           }
+         cpp_error (pfile, warntype,
+                    "missing whitespace after the macro name");
+       }
+    }
 
   if (macro->fun_like)
     token = lex_expansion_token (pfile, macro);
@@ -1751,7 +1782,7 @@ cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node)
              buffer += NODE_LEN (macro->params[token->val.arg_no - 1]);
            }
          else
-           buffer = cpp_spell_token (pfile, token, buffer);
+           buffer = cpp_spell_token (pfile, token, buffer, false);
 
          if (token->flags & PASTE_LEFT)
            {