forked from OSchip/llvm-project
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. llvm-svn: 46503
This commit is contained in:
parent
361de6164d
commit
0c8a1edb8b
|
@ -409,6 +409,19 @@ void MacroExpander::ExpandFunctionArguments() {
|
||||||
const Token *ArgToks = ActualArgs->getUnexpArgument(ArgNo);
|
const Token *ArgToks = ActualArgs->getUnexpArgument(ArgNo);
|
||||||
unsigned NumToks = MacroArgs::getArgLength(ArgToks);
|
unsigned NumToks = MacroArgs::getArgLength(ArgToks);
|
||||||
if (NumToks) { // Not an empty argument?
|
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);
|
ResultToks.append(ArgToks, ArgToks+NumToks);
|
||||||
|
|
||||||
// If the next token was supposed to get leading whitespace, ensure it has
|
// If the next token was supposed to get leading whitespace, ensure it has
|
||||||
|
@ -447,6 +460,8 @@ void MacroExpander::ExpandFunctionArguments() {
|
||||||
!ResultToks.empty() && ResultToks.back().is(tok::comma)) {
|
!ResultToks.empty() && ResultToks.back().is(tok::comma)) {
|
||||||
// Never add a space, even if the comma, ##, or arg had a space.
|
// Never add a space, even if the comma, ##, or arg had a space.
|
||||||
NextTokGetsSpace = false;
|
NextTokGetsSpace = false;
|
||||||
|
// Remove the paste operator, report use of the extension.
|
||||||
|
PP.Diag(ResultToks.back().getLocation(), diag::ext_paste_comma);
|
||||||
ResultToks.pop_back();
|
ResultToks.pop_back();
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
@ -615,7 +630,7 @@ void MacroExpander::PasteTokens(Token &Tok) {
|
||||||
// Turn ## into 'other' to avoid # ## # from looking like a paste operator.
|
// Turn ## into 'other' to avoid # ## # from looking like a paste operator.
|
||||||
if (Result.is(tok::hashhash))
|
if (Result.is(tok::hashhash))
|
||||||
Result.setKind(tok::unknown);
|
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.
|
// Transfer properties of the LHS over the the Result.
|
||||||
Result.setFlagValue(Token::StartOfLine , Tok.isAtStartOfLine());
|
Result.setFlagValue(Token::StartOfLine , Tok.isAtStartOfLine());
|
||||||
|
|
|
@ -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,);
|
||||||
|
|
Loading…
Reference in New Issue