forked from OSchip/llvm-project
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 <rdar://problem/8361834>. llvm-svn: 116842
This commit is contained in:
parent
6162f9774a
commit
1f1e4bdbf7
|
@ -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<CachedTokensTy::size_type> 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,
|
||||
|
|
|
@ -33,8 +33,12 @@ MacroInfo *Preprocessor::AllocateMacroInfo() {
|
|||
if (!MICache.empty()) {
|
||||
MI = MICache.back();
|
||||
MICache.pop_back();
|
||||
} else
|
||||
MI = (MacroInfo*) BP.Allocate<MacroInfo>();
|
||||
} else {
|
||||
MacroInfoChain *MIChain = BP.Allocate<MacroInfoChain>();
|
||||
MIChain->Next = MIChainHead;
|
||||
MIChainHead = MIChain;
|
||||
MI = &(MIChainHead->MI);
|
||||
}
|
||||
return MI;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<IdentifierInfo*, MacroInfo*>::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<MacroInfo*>::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<IdentifierInfo*, std::vector<MacroInfo*> >::iterator I =
|
||||
PragmaPushMacroInfo.begin(), E = PragmaPushMacroInfo.end(); I!=E; ++I){
|
||||
for (std::vector<MacroInfo*>::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.
|
||||
|
|
Loading…
Reference in New Issue