diff options
| -rw-r--r-- | clang/Lex/MacroExpander.cpp | 45 | ||||
| -rw-r--r-- | clang/Lex/Preprocessor.cpp | 4 | ||||
| -rw-r--r-- | clang/include/clang/Lex/MacroExpander.h | 23 |
3 files changed, 54 insertions, 18 deletions
diff --git a/clang/Lex/MacroExpander.cpp b/clang/Lex/MacroExpander.cpp index cd802ee4e8a..24aab614c8a 100644 --- a/clang/Lex/MacroExpander.cpp +++ b/clang/Lex/MacroExpander.cpp @@ -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 diff --git a/clang/Lex/Preprocessor.cpp b/clang/Lex/Preprocessor.cpp index 28414d3707c..71f315d03d8 100644 --- a/clang/Lex/Preprocessor.cpp +++ b/clang/Lex/Preprocessor.cpp @@ -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 diff --git a/clang/include/clang/Lex/MacroExpander.h b/clang/include/clang/Lex/MacroExpander.h index c4948e7ae65..c001182d258 100644 --- a/clang/include/clang/Lex/MacroExpander.h +++ b/clang/include/clang/Lex/MacroExpander.h @@ -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; + + MacroArgs(unsigned NumToks) : NumUnexpArgTokens(NumToks) {} + ~MacroArgs() {} public: - /// MacroArgs ctor - This destroys the vector passed in. - MacroArgs(const MacroInfo *MI, std::vector<LexerToken> &UnexpArgTokens); + /// 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; } }; |

