diff --git a/clang/Lex/MacroExpander.cpp b/clang/Lex/MacroExpander.cpp index 27b4cc805553..e129ed69e972 100644 --- a/clang/Lex/MacroExpander.cpp +++ b/clang/Lex/MacroExpander.cpp @@ -246,7 +246,7 @@ MacroExpander::MacroExpander(LexerToken &Tok, MacroArgs *Actuals, // If this is a function-like macro, expand the arguments and change // MacroTokens to point to the expanded tokens. - if (Macro->isFunctionLike() && Macro->getNumArgs()) + if (Macro->isFunctionLike() && Macro->getNumArgs() || Macro->isC99Varargs()) ExpandFunctionArguments(); // Mark the macro as currently disabled, so that it is not recursively @@ -288,6 +288,8 @@ MacroExpander::~MacroExpander() { void MacroExpander::ExpandFunctionArguments() { SmallVector ResultToks; + IdentifierInfo *VAARGSii = PP.get__VA_ARGS__Identifier(); + // Loop through the MacroTokens tokens, expanding them into ResultToks. Keep // track of whether we change anything. If not, no need to keep them. If so, // we install the newly expanded sequence as MacroTokens. @@ -325,8 +327,14 @@ void MacroExpander::ExpandFunctionArguments() { IdentifierInfo *II = CurTok.getIdentifierInfo(); int ArgNo = II ? Macro->getArgumentNum(II) : -1; if (ArgNo == -1) { - ResultToks.push_back(CurTok); - continue; + if (II != VAARGSii || !Macro->isC99Varargs()) { + // This isn't an argument and isn't __VA_ARGS__. Just add it. + ResultToks.push_back(CurTok); + continue; + } + + // Otherwise, this *is* __VA_ARGS__. Set ArgNo to the last argument. + ArgNo = Macro->getNumArgs(); } // An argument is expanded somehow, the result is different than the diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 0ebd9c41c1bf..2d8e74bd1cb9 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -387,6 +387,12 @@ public: SourceLocation CreateString(const char *Buf, unsigned Len, SourceLocation SourceLoc = SourceLocation()); + /// get__VA_ARGS__Identifier - Return the identifier info for the __VA_ARGS__ + /// identifier. + IdentifierInfo *get__VA_ARGS__Identifier() const { + return Ident__VA_ARGS__; + } + /// DumpToken - Print the token to stderr, used for debugging. /// void DumpToken(const LexerToken &Tok, bool DumpFlags = false) const;