diff options
Diffstat (limited to 'clang/lib/Lex')
-rw-r--r-- | clang/lib/Lex/PPMacroExpansion.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Lex/TokenLexer.cpp | 17 |
2 files changed, 17 insertions, 7 deletions
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 18348df0a39..11b4a0b3d8c 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -723,6 +723,7 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName, // heap allocations in the common case. SmallVector<Token, 64> ArgTokens; bool ContainsCodeCompletionTok = false; + bool FoundElidedComma = false; SourceLocation TooManyArgsLoc; @@ -765,6 +766,10 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName, // If we found the ) token, the macro arg list is done. if (NumParens-- == 0) { MacroEnd = Tok.getLocation(); + if (!ArgTokens.empty() && + ArgTokens.back().commaAfterElided()) { + FoundElidedComma = true; + } break; } } else if (Tok.is(tok::l_paren)) { @@ -909,7 +914,7 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName, // then we have an empty "()" argument empty list. This is fine, even if // the macro expects one argument (the argument is just empty). isVarargsElided = MI->isVariadic(); - } else if (MI->isVariadic() && + } else if ((FoundElidedComma || MI->isVariadic()) && (NumActuals+1 == MinArgsExpected || // A(x, ...) -> A(X) (NumActuals == 0 && MinArgsExpected == 2))) {// A(x,...) -> A() // Varargs where the named vararg parameter is missing: OK as extension. diff --git a/clang/lib/Lex/TokenLexer.cpp b/clang/lib/Lex/TokenLexer.cpp index ed2b8cdabd1..3f66b7f9b76 100644 --- a/clang/lib/Lex/TokenLexer.cpp +++ b/clang/lib/Lex/TokenLexer.cpp @@ -154,12 +154,17 @@ bool TokenLexer::MaybeRemoveCommaBeforeVaArgs( // Remove the comma. ResultToks.pop_back(); - // If the comma was right after another paste (e.g. "X##,##__VA_ARGS__"), - // then removal of the comma should produce a placemarker token (in C99 - // terms) which we model by popping off the previous ##, giving us a plain - // "X" when __VA_ARGS__ is empty. - if (!ResultToks.empty() && ResultToks.back().is(tok::hashhash)) - ResultToks.pop_back(); + if (!ResultToks.empty()) { + // If the comma was right after another paste (e.g. "X##,##__VA_ARGS__"), + // then removal of the comma should produce a placemarker token (in C99 + // terms) which we model by popping off the previous ##, giving us a plain + // "X" when __VA_ARGS__ is empty. + if (ResultToks.back().is(tok::hashhash)) + ResultToks.pop_back(); + + // Remember that this comma was elided. + ResultToks.back().setFlag(Token::CommaAfterElided); + } // Never add a space, even if the comma, ##, or arg had a space. NextTokGetsSpace = false; |