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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46503 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Lex/MacroExpander.cpp b/Lex/MacroExpander.cpp
index 8dbec64..9d4b072 100644
--- a/Lex/MacroExpander.cpp
+++ b/Lex/MacroExpander.cpp
@@ -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());
diff --git a/test/Preprocessor/macro_paste_commaext.c b/test/Preprocessor/macro_paste_commaext.c
new file mode 100644
index 0000000..0fcd90d
--- /dev/null
+++ b/test/Preprocessor/macro_paste_commaext.c
@@ -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,);
+