summaryrefslogtreecommitdiffstats
path: root/clang/Lex/MacroExpander.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-07-29 04:39:41 +0000
committerChris Lattner <sabre@nondot.org>2006-07-29 04:39:41 +0000
commit775d83211094907e33d6ba09d07dc2c9f9424eb2 (patch)
treed80dc56f5332a778cafc1c1253aa51fa00f414d0 /clang/Lex/MacroExpander.cpp
parentd480b9c0ed26c3f30dda96a10211cbfee24235b4 (diff)
downloadbcm5719-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.cpp17
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;
}
OpenPOWER on IntegriCloud