[cfe-commits] r46503 - in /cfe/trunk: Lex/MacroExpander.cpp test/Preprocessor/macro_paste_commaext.c

Chris Lattner sabre at nondot.org
Mon Jan 28 23:54:23 PST 2008


Author: lattner
Date: Tue Jan 29 01:54:23 2008
New Revision: 46503

URL: http://llvm.org/viewvc/llvm-project?rev=46503&view=rev
Log:
Fix a bug where we would incorrectly emit a "cannot paste" error 
message when handling the GNU ", ## __VA_ARGS__" extension.  While
I'm at it, flag uses of this as extensions.

Added:
    cfe/trunk/test/Preprocessor/macro_paste_commaext.c
Modified:
    cfe/trunk/Lex/MacroExpander.cpp

Modified: cfe/trunk/Lex/MacroExpander.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Lex/MacroExpander.cpp?rev=46503&r1=46502&r2=46503&view=diff

==============================================================================
--- cfe/trunk/Lex/MacroExpander.cpp (original)
+++ cfe/trunk/Lex/MacroExpander.cpp Tue Jan 29 01:54:23 2008
@@ -409,6 +409,19 @@
     const Token *ArgToks = ActualArgs->getUnexpArgument(ArgNo);
     unsigned NumToks = MacroArgs::getArgLength(ArgToks);
     if (NumToks) {  // Not an empty argument?
+      // If this is the GNU ", ## __VA_ARG__" extension, and we just learned
+      // that __VA_ARG__ expands to multiple tokens, avoid a pasting error when
+      // the expander trys to paste ',' with the first token of the __VA_ARG__
+      // expansion.
+      if (PasteBefore && ResultToks.size() >= 2 &&
+          ResultToks[ResultToks.size()-2].is(tok::comma) &&
+          (unsigned)ArgNo == Macro->getNumArgs()-1 &&
+          Macro->isVariadic()) {
+        // Remove the paste operator, report use of the extension.
+        PP.Diag(ResultToks.back().getLocation(), diag::ext_paste_comma);
+        ResultToks.pop_back();
+      }
+      
       ResultToks.append(ArgToks, ArgToks+NumToks);
       
       // If the next token was supposed to get leading whitespace, ensure it has
@@ -447,6 +460,8 @@
         !ResultToks.empty() && ResultToks.back().is(tok::comma)) {
       // Never add a space, even if the comma, ##, or arg had a space.
       NextTokGetsSpace = false;
+      // Remove the paste operator, report use of the extension.
+      PP.Diag(ResultToks.back().getLocation(), diag::ext_paste_comma);
       ResultToks.pop_back();
     }
     continue;
@@ -615,7 +630,7 @@
     // Turn ## into 'other' to avoid # ## # from looking like a paste operator.
     if (Result.is(tok::hashhash))
       Result.setKind(tok::unknown);
-    // FIXME: Turn __VARRGS__ into "not a token"?
+    // FIXME: Turn __VA_ARGS__ into "not a token"?
     
     // Transfer properties of the LHS over the the Result.
     Result.setFlagValue(Token::StartOfLine , Tok.isAtStartOfLine());

Added: cfe/trunk/test/Preprocessor/macro_paste_commaext.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/macro_paste_commaext.c?rev=46503&view=auto

==============================================================================
--- cfe/trunk/test/Preprocessor/macro_paste_commaext.c (added)
+++ cfe/trunk/test/Preprocessor/macro_paste_commaext.c Tue Jan 29 01:54:23 2008
@@ -0,0 +1,13 @@
+// RUN: clang %s -E | grep 'V);' &&
+// RUN: clang %s -E | grep 'W, 1, 2);'
+// RUN: clang %s -E | grep 'X, 1, 2);'
+// RUN: clang %s -E | grep 'Y, );'
+// RUN: clang %s -E | grep 'Z, );'
+
+#define debug(format, ...) format, ## __VA_ARGS__)
+debug(V);
+debug(W, 1, 2);
+debug(X, 1, 2 );
+debug(Y, );
+debug(Z,);
+





More information about the cfe-commits mailing list