Change MacroArgs to allocate space for the unexpanded tokens immediately after
the MacroArgs object itself. This is a bit more efficient and will be even more so shortly. llvm-svn: 38756
This commit is contained in:
parent
6fc08bc77d
commit
c1410dc1e6
|
@ -24,12 +24,37 @@ using namespace clang;
|
|||
// MacroArgs Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
MacroArgs::MacroArgs(const MacroInfo *MI, std::vector<LexerToken> &UnexpArgs) {
|
||||
/// MacroArgs ctor function - This destroys the vector passed in.
|
||||
MacroArgs *MacroArgs::create(const MacroInfo *MI,
|
||||
const std::vector<LexerToken> &UnexpArgTokens) {
|
||||
assert(MI->isFunctionLike() &&
|
||||
"Can't have args for an object-like macro!");
|
||||
UnexpArgTokens.swap(UnexpArgs);
|
||||
|
||||
// Allocate memory for the MacroArgs object with the lexer tokens at the end.
|
||||
unsigned NumToks = UnexpArgTokens.size();
|
||||
MacroArgs *Result = (MacroArgs*)malloc(sizeof(MacroArgs) +
|
||||
NumToks*sizeof(LexerToken));
|
||||
// Construct the macroargs object.
|
||||
new (Result) MacroArgs(NumToks);
|
||||
|
||||
// Copy the actual unexpanded tokens to immediately after the result ptr.
|
||||
if (NumToks)
|
||||
memcpy(const_cast<LexerToken*>(Result->getUnexpArgument(0)),
|
||||
&UnexpArgTokens[0], NumToks*sizeof(LexerToken));
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
/// destroy - Destroy and deallocate the memory for this object.
|
||||
///
|
||||
void MacroArgs::destroy() {
|
||||
// Run the dtor to deallocate the vectors.
|
||||
this->~MacroArgs();
|
||||
// Release the memory for the object.
|
||||
free(this);
|
||||
}
|
||||
|
||||
|
||||
/// getArgLength - Given a pointer to an expanded or unexpanded argument,
|
||||
/// return the number of tokens, not counting the EOF, that make up the
|
||||
/// argument.
|
||||
|
@ -44,11 +69,13 @@ unsigned MacroArgs::getArgLength(const LexerToken *ArgPtr) {
|
|||
/// getUnexpArgument - Return the unexpanded tokens for the specified formal.
|
||||
///
|
||||
const LexerToken *MacroArgs::getUnexpArgument(unsigned Arg) const {
|
||||
// Scan to find Arg.
|
||||
const LexerToken *Start = &UnexpArgTokens[0];
|
||||
// The unexpanded argument tokens start immediately after the MacroArgs object
|
||||
// in memory.
|
||||
const LexerToken *Start = (const LexerToken *)(this+1);
|
||||
const LexerToken *Result = Start;
|
||||
// Scan to find Arg.
|
||||
for (; Arg; ++Result) {
|
||||
assert(Result < Start+UnexpArgTokens.size() && "Invalid arg #");
|
||||
assert(Result < Start+NumUnexpArgTokens && "Invalid arg #");
|
||||
if (Result->getKind() == tok::eof)
|
||||
--Arg;
|
||||
}
|
||||
|
@ -75,11 +102,11 @@ bool MacroArgs::ArgNeedsPreexpansion(const LexerToken *ArgTok) const {
|
|||
/// argument.
|
||||
const std::vector<LexerToken> &
|
||||
MacroArgs::getPreExpArgument(unsigned Arg, Preprocessor &PP) {
|
||||
assert(Arg < UnexpArgTokens.size() && "Invalid argument number!");
|
||||
assert(Arg < NumUnexpArgTokens && "Invalid argument number!");
|
||||
|
||||
// If we have already computed this, return it.
|
||||
if (PreExpArgTokens.empty())
|
||||
PreExpArgTokens.resize(UnexpArgTokens.size());
|
||||
PreExpArgTokens.resize(NumUnexpArgTokens);
|
||||
|
||||
std::vector<LexerToken> &Result = PreExpArgTokens[Arg];
|
||||
if (!Result.empty()) return Result;
|
||||
|
@ -189,7 +216,7 @@ static LexerToken StringifyArgument(const LexerToken *ArgToks,
|
|||
/// that has been 'stringified' as required by the # operator.
|
||||
const LexerToken &MacroArgs::getStringifiedArgument(unsigned ArgNo,
|
||||
Preprocessor &PP) {
|
||||
assert(ArgNo < UnexpArgTokens.size() && "Invalid argument number!");
|
||||
assert(ArgNo < NumUnexpArgTokens && "Invalid argument number!");
|
||||
if (StringifiedArgs.empty()) {
|
||||
StringifiedArgs.resize(getNumArguments());
|
||||
memset(&StringifiedArgs[0], 0,
|
||||
|
@ -252,7 +279,7 @@ MacroExpander::~MacroExpander() {
|
|||
delete [] MacroTokens;
|
||||
|
||||
// MacroExpander owns its formal arguments.
|
||||
delete ActualArgs;
|
||||
if (ActualArgs) ActualArgs->destroy();
|
||||
}
|
||||
|
||||
/// Expand the arguments of a function-like macro so that we can quickly
|
||||
|
|
|
@ -627,7 +627,7 @@ bool Preprocessor::HandleMacroExpandedIdentifier(LexerToken &Identifier,
|
|||
// expansion stack, only to take it right back off.
|
||||
if (MI->getNumTokens() == 0) {
|
||||
// No need for arg info.
|
||||
delete Args;
|
||||
if (Args) Args->destroy();
|
||||
|
||||
// Ignore this macro use, just return the next token in the current
|
||||
// buffer.
|
||||
|
@ -808,7 +808,7 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(LexerToken &MacroName,
|
|||
}
|
||||
}
|
||||
|
||||
return new MacroArgs(MI, ArgTokens);
|
||||
return MacroArgs::create(MI, ArgTokens);
|
||||
}
|
||||
|
||||
/// ComputeDATE_TIME - Compute the current time, enter it into the specified
|
||||
|
|
|
@ -26,10 +26,11 @@ namespace clang {
|
|||
/// MacroArgs - An instance of this class captures information about
|
||||
/// the formal arguments specified to a function-like macro invocation.
|
||||
class MacroArgs {
|
||||
/// UnexpArgTokens - Raw, unexpanded tokens for the arguments. This is all of
|
||||
/// the arguments concatenated together, with 'EOF' markers at the end of each
|
||||
/// argument.
|
||||
std::vector<LexerToken> UnexpArgTokens;
|
||||
/// NumUnexpArgTokens - The number of raw, unexpanded tokens for the
|
||||
/// arguments. All of the actual argument tokens are allocated immediately
|
||||
/// after the MacroArgs object in memory. This is all of the arguments
|
||||
/// concatenated together, with 'EOF' markers at the end of each argument.
|
||||
unsigned NumUnexpArgTokens;
|
||||
|
||||
/// PreExpArgTokens - Pre-expanded tokens for arguments that need them. Empty
|
||||
/// if not yet computed. This includes the EOF marker at the end of the
|
||||
|
@ -39,10 +40,18 @@ class MacroArgs {
|
|||
/// 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;
|
||||
public:
|
||||
/// MacroArgs ctor - This destroys the vector passed in.
|
||||
MacroArgs(const MacroInfo *MI, std::vector<LexerToken> &UnexpArgTokens);
|
||||
|
||||
MacroArgs(unsigned NumToks) : NumUnexpArgTokens(NumToks) {}
|
||||
~MacroArgs() {}
|
||||
public:
|
||||
/// MacroArgs ctor function - Create a new MacroArgs object with the specified
|
||||
/// macro and argument info.
|
||||
static MacroArgs *create(const MacroInfo *MI,
|
||||
const std::vector<LexerToken> &UnexpArgTokens);
|
||||
|
||||
/// destroy - Destroy and deallocate the memory for this object.
|
||||
///
|
||||
void destroy();
|
||||
|
||||
/// ArgNeedsPreexpansion - If we can prove that the argument won't be affected
|
||||
/// by pre-expansion, return false. Otherwise, conservatively return true.
|
||||
|
@ -69,7 +78,7 @@ public:
|
|||
|
||||
/// getNumArguments - Return the number of arguments passed into this macro
|
||||
/// invocation.
|
||||
unsigned getNumArguments() const { return UnexpArgTokens.size(); }
|
||||
unsigned getNumArguments() const { return NumUnexpArgTokens; }
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue