From: Ted Kremenek Date: Tue, 19 Oct 2010 18:16:54 +0000 (+0000) Subject: Simplify lifetime management of MacroInfo objects in Preprocessor by having the Prepr... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=af8fa25c0d4e0540952a50bbd06dc1558954ccd9;p=clang Simplify lifetime management of MacroInfo objects in Preprocessor by having the Preprocessor maintain them in a linked list of allocated MacroInfos. This requires only 1 extra pointer per MacroInfo object, and allows us to blow them away in one place. This fixes an elusive memory leak with MacroInfos (whose exact location I couldn't still figure out despite substantial digging). Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116842 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 752cbed7b3..a1a68dce45 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_LEX_PREPROCESSOR_H #define LLVM_CLANG_LEX_PREPROCESSOR_H +#include "clang/Lex/MacroInfo.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/PTHLexer.h" #include "clang/Lex/PPCallbacks.h" @@ -251,6 +252,15 @@ private: // Cached tokens state. /// invoked (at which point the last position is popped). std::vector BacktrackPositions; + struct MacroInfoChain { + MacroInfo MI; + MacroInfoChain *Next; + }; + + /// MacroInfos are managed as a chain for easy disposal. This is the head + /// of that list. + MacroInfoChain *MIChainHead; + public: Preprocessor(Diagnostic &diags, const LangOptions &opts, const TargetInfo &target, diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index 5e3b16e60d..ffdc6ae589 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -33,8 +33,12 @@ MacroInfo *Preprocessor::AllocateMacroInfo() { if (!MICache.empty()) { MI = MICache.back(); MICache.pop_back(); - } else - MI = (MacroInfo*) BP.Allocate(); + } else { + MacroInfoChain *MIChain = BP.Allocate(); + MIChain->Next = MIChainHead; + MIChainHead = MIChain; + MI = &(MIChainHead->MI); + } return MI; } diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp index 56ed765924..9a695004c9 100644 --- a/lib/Lex/Preprocessor.cpp +++ b/lib/Lex/Preprocessor.cpp @@ -56,7 +56,7 @@ Preprocessor::Preprocessor(Diagnostic &diags, const LangOptions &opts, SourceMgr(SM), HeaderInfo(Headers), ExternalSource(0), Identifiers(opts, IILookup), BuiltinInfo(Target), CodeComplete(0), CodeCompletionFile(0), SkipMainFilePreamble(0, true), CurPPLexer(0), - CurDirLookup(0), Callbacks(0), MacroArgCache(0), Record(0) { + CurDirLookup(0), Callbacks(0), MacroArgCache(0), Record(0), MIChainHead(0) { ScratchBuf = new ScratchBuffer(SourceMgr); CounterValue = 0; // __COUNTER__ starts at 0. OwnsHeaderSearch = OwnsHeaders; @@ -106,29 +106,10 @@ Preprocessor::~Preprocessor() { } // Free any macro definitions. - for (llvm::DenseMap::iterator I = - Macros.begin(), E = Macros.end(); I != E; ++I) { - // We don't need to free the MacroInfo objects directly. These - // will be released when the BumpPtrAllocator 'BP' object gets - // destroyed. We still need to run the dtor, however, to free - // memory alocated by MacroInfo. - I->second->Destroy(); - I->first->setHasMacroDefinition(false); - } - for (std::vector::iterator I = MICache.begin(), - E = MICache.end(); I != E; ++I) { - // We don't need to free the MacroInfo objects directly. These - // will be released when the BumpPtrAllocator 'BP' object gets - // destroyed. We still need to run the dtor, however, to free - // memory alocated by MacroInfo. - (*I)->Destroy(); - } - for (llvm::DenseMap >::iterator I = - PragmaPushMacroInfo.begin(), E = PragmaPushMacroInfo.end(); I!=E; ++I){ - for (std::vector::iterator I2 = I->second.begin(), E2 = I->second.end(); - I2 != E2; ++I2) { - (*I2)->Destroy(); - } + for (MacroInfoChain *I = MIChainHead ; I ; ) { + MacroInfoChain *Next = I->Next; + I->MI.Destroy(); + I = Next; } // Free any cached macro expanders.