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:
Chris Lattner 2006-07-26 05:22:49 +00:00
parent 6fc08bc77d
commit c1410dc1e6
3 changed files with 55 additions and 19 deletions

View File

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

View File

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

View File

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