summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/Lex/MacroExpander.cpp45
-rw-r--r--clang/Lex/Preprocessor.cpp4
-rw-r--r--clang/include/clang/Lex/MacroExpander.h23
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; }
};
OpenPOWER on IntegriCloud