Implement support for __VA_ARGS__, allowing test/Preprocessor/macro_fn_varargs_iso.c

to pass.

llvm-svn: 38776
This commit is contained in:
Chris Lattner 2006-07-29 04:04:22 +00:00
parent 2bc48570b7
commit 21c8b8f71e
2 changed files with 17 additions and 3 deletions

View File

@ -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<LexerToken, 128> 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

View File

@ -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;