diff options
author | Chris Lattner <sabre@nondot.org> | 2006-07-29 04:39:41 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-07-29 04:39:41 +0000 |
commit | 775d83211094907e33d6ba09d07dc2c9f9424eb2 (patch) | |
tree | d80dc56f5332a778cafc1c1253aa51fa00f414d0 /clang/Lex/MacroExpander.cpp | |
parent | d480b9c0ed26c3f30dda96a10211cbfee24235b4 (diff) | |
download | bcm5719-llvm-775d83211094907e33d6ba09d07dc2c9f9424eb2.tar.gz bcm5719-llvm-775d83211094907e33d6ba09d07dc2c9f9424eb2.zip |
Implement the GNU comma swallowing extension. This implements
test/Preprocessor/macro_fn_comma_swallow.c
llvm-svn: 38780
Diffstat (limited to 'clang/Lex/MacroExpander.cpp')
-rw-r--r-- | clang/Lex/MacroExpander.cpp | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/clang/Lex/MacroExpander.cpp b/clang/Lex/MacroExpander.cpp index dc7ddd271f4..cec0501b2f7 100644 --- a/clang/Lex/MacroExpander.cpp +++ b/clang/Lex/MacroExpander.cpp @@ -28,7 +28,7 @@ using namespace clang; /// MacroArgs ctor function - This destroys the vector passed in. MacroArgs *MacroArgs::create(const MacroInfo *MI, const LexerToken *UnexpArgTokens, - unsigned NumToks) { + unsigned NumToks, bool VarargsElided) { assert(MI->isFunctionLike() && "Can't have args for an object-like macro!"); @@ -36,7 +36,7 @@ MacroArgs *MacroArgs::create(const MacroInfo *MI, MacroArgs *Result = (MacroArgs*)malloc(sizeof(MacroArgs) + NumToks*sizeof(LexerToken)); // Construct the macroargs object. - new (Result) MacroArgs(NumToks); + new (Result) MacroArgs(NumToks, VarargsElided); // Copy the actual unexpanded tokens to immediately after the result ptr. if (NumToks) @@ -410,8 +410,6 @@ void MacroExpander::ExpandFunctionArguments() { continue; } - // FIXME: Handle comma swallowing GNU extension. - // If an empty argument is on the LHS or RHS of a paste, the standard (C99 // 6.10.3.3p2,3) calls for a bunch of placemarker stuff to occur. We // implement this by eating ## operators when a LHS or RHS expands to @@ -430,6 +428,17 @@ void MacroExpander::ExpandFunctionArguments() { assert(PasteBefore && ResultToks.back().getKind() == tok::hashhash); NextTokGetsSpace |= ResultToks.back().hasLeadingSpace(); ResultToks.pop_back(); + + // If this is the __VA_ARGS__ token, and if the argument wasn't provided, + // and if the macro had at least one real argument, and if the token before + // the ## was a comma, remove the comma. + if ((unsigned)ArgNo == Macro->getNumArgs() && // is __VA_ARGS__ + ActualArgs->isVarargsElidedUse() && // Argument elided. + !ResultToks.empty() && ResultToks.back().getKind() == tok::comma) { + // Never add a space, even if the comma, ##, or arg had a space. + NextTokGetsSpace = false; + ResultToks.pop_back(); + } continue; } |