[cfe-commits] r38780 - in /cfe/cfe/trunk: Lex/MacroExpander.cpp Lex/Preprocessor.cpp include/clang/Lex/MacroExpander.h
sabre at cs.uiuc.edu
sabre at cs.uiuc.edu
Wed Jul 11 09:24:33 PDT 2007
Author: sabre
Date: Wed Jul 11 11:24:33 2007
New Revision: 38780
URL: http://llvm.org/viewvc/llvm-project?rev=38780&view=rev
Log:
Implement the GNU comma swallowing extension. This implements
test/Preprocessor/macro_fn_comma_swallow.c
Modified:
cfe/cfe/trunk/Lex/MacroExpander.cpp
cfe/cfe/trunk/Lex/Preprocessor.cpp
cfe/cfe/trunk/include/clang/Lex/MacroExpander.h
Modified: cfe/cfe/trunk/Lex/MacroExpander.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/MacroExpander.cpp?rev=38780&r1=38779&r2=38780&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/MacroExpander.cpp (original)
+++ cfe/cfe/trunk/Lex/MacroExpander.cpp Wed Jul 11 11:24:33 2007
@@ -28,7 +28,7 @@
/// 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 *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 @@
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 @@
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;
}
Modified: cfe/cfe/trunk/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/Preprocessor.cpp?rev=38780&r1=38779&r2=38780&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/Preprocessor.cpp (original)
+++ cfe/cfe/trunk/Lex/Preprocessor.cpp Wed Jul 11 11:24:33 2007
@@ -785,6 +785,9 @@
// the count.
MinArgsExpected += MI->isC99Varargs();
+ // See MacroArgs instance var for description of this.
+ bool isVarargsElided = false;
+
if (NumActuals < MinArgsExpected) {
// There are several cases where too few arguments is ok, handle them now.
if (NumActuals+1 == MinArgsExpected && MI->isVariadic()) {
@@ -792,6 +795,10 @@
// #define A(x, ...)
// A("blah")
Diag(Tok, diag::ext_missing_varargs_arg);
+
+ // Remember this occurred if this is a C99 macro invocation with at least
+ // one actual argument.
+ isVarargsElided = (MI->isC99Varargs() && MI->getNumArgs());
} else if (MI->getNumArgs() == 1) {
// #define A(x)
// A()
@@ -816,7 +823,7 @@
ArgTokens.push_back(Tok);
}
- return MacroArgs::create(MI, &ArgTokens[0], ArgTokens.size());
+ return MacroArgs::create(MI, &ArgTokens[0], ArgTokens.size(),isVarargsElided);
}
/// ComputeDATE_TIME - Compute the current time, enter it into the specified
Modified: cfe/cfe/trunk/include/clang/Lex/MacroExpander.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Lex/MacroExpander.h?rev=38780&r1=38779&r2=38780&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/MacroExpander.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/MacroExpander.h Wed Jul 11 11:24:33 2007
@@ -40,15 +40,23 @@
/// StringifiedArgs - This contains arguments in 'stringified' form. If the
/// stringified form of an argument has not yet been computed, this is empty.
std::vector<LexerToken> StringifiedArgs;
+
+ /// VarargsElided - True if this is a C99 style varargs macro invocation and
+ /// there was no argument specified for the "..." argument. If the argument
+ /// was specified (even empty) or this isn't a C99 style varargs function, or
+ /// if in strict mode and the C99 varargs macro had only a ... argument, this
+ /// is false.
+ bool VarargsElided;
- MacroArgs(unsigned NumToks) : NumUnexpArgTokens(NumToks) {}
+ MacroArgs(unsigned NumToks, bool varargsElided)
+ : NumUnexpArgTokens(NumToks), VarargsElided(varargsElided) {}
~MacroArgs() {}
public:
/// MacroArgs ctor function - Create a new MacroArgs object with the specified
/// macro and argument info.
static MacroArgs *create(const MacroInfo *MI,
const LexerToken *UnexpArgTokens,
- unsigned NumArgTokens);
+ unsigned NumArgTokens, bool VarargsElided);
/// destroy - Destroy and deallocate the memory for this object.
///
@@ -80,6 +88,14 @@
/// getNumArguments - Return the number of arguments passed into this macro
/// invocation.
unsigned getNumArguments() const { return NumUnexpArgTokens; }
+
+
+ /// isVarargsElidedUse - Return true if this is a C99 style varargs macro
+ /// invocation and there was no argument specified for the "..." argument. If
+ /// the argument was specified (even empty) or this isn't a C99 style varargs
+ /// function, or if in strict mode and the C99 varargs macro had only a ...
+ /// argument, this returns false.
+ bool isVarargsElidedUse() const { return VarargsElided; }
};
More information about the cfe-commits
mailing list