summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2010-02-11 07:12:28 +0000
committerTed Kremenek <kremenek@apple.com>2010-02-11 07:12:28 +0000
commitda4e0d350c00dfa40a6e443c25660f3f13f676d4 (patch)
treec67d034d45f1af3fed040b2c51374cd8221af3a4 /clang/lib/AST
parent6bb2463f855b0737acce40432c7d98ea517c0b7d (diff)
downloadbcm5719-llvm-da4e0d350c00dfa40a6e443c25660f3f13f676d4.tar.gz
bcm5719-llvm-da4e0d350c00dfa40a6e443c25660f3f13f676d4.zip
Have ~ASTContext() delete StoredDeclsMap (internal to DeclContext) by
storing the set of StoredDeclsMaps in an internal vector of void*. This isn't an ideal solution, but for the time being this fixes a major memory leak with these DenseMaps not being freed. Fixes: <rdar://problem/7634755> llvm-svn: 95861
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/ASTContext.cpp4
-rw-r--r--clang/lib/AST/DeclBase.cpp35
2 files changed, 34 insertions, 5 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index c92a7d14cc6..6ac989041ab 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -56,6 +56,10 @@ ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM,
}
ASTContext::~ASTContext() {
+ // Release the DenseMaps associated with DeclContext objects.
+ // FIXME: Is this the ideal solution?
+ ReleaseDeclContextMaps();
+
if (FreeMemory) {
// Deallocate all the types.
while (!Types.empty()) {
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 84aa81ca76d..863a1cbd03c 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -448,7 +448,10 @@ bool DeclContext::classof(const Decl *D) {
}
DeclContext::~DeclContext() {
- delete static_cast<StoredDeclsMap*>(LookupPtr);
+ // FIXME: Currently ~ASTContext will delete the StoredDeclsMaps because
+ // ~DeclContext() is not guaranteed to be called when ASTContext uses
+ // a BumpPtrAllocator.
+ // delete static_cast<StoredDeclsMap*>(LookupPtr);
}
void DeclContext::DestroyDecls(ASTContext &C) {
@@ -622,7 +625,8 @@ DeclContext::LoadVisibleDeclsFromExternalStorage() const {
// Load the declaration IDs for all of the names visible in this
// context.
assert(!LookupPtr && "Have a lookup map before de-serialization?");
- StoredDeclsMap *Map = new StoredDeclsMap;
+ StoredDeclsMap *Map =
+ (StoredDeclsMap*) getParentASTContext().CreateStoredDeclsMap();
LookupPtr = Map;
for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
(*Map)[Decls[I].Name].setFromDeclIDs(Decls[I].Declarations);
@@ -830,8 +834,11 @@ void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D) {
if (isa<ClassTemplateSpecializationDecl>(D))
return;
- if (!LookupPtr)
- LookupPtr = new StoredDeclsMap;
+ ASTContext *C = 0;
+ if (!LookupPtr) {
+ C = &getParentASTContext();
+ LookupPtr = (StoredDeclsMap*) C->CreateStoredDeclsMap();
+ }
// Insert this declaration into the map.
StoredDeclsMap &Map = *static_cast<StoredDeclsMap*>(LookupPtr);
@@ -844,7 +851,10 @@ void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D) {
// If it is possible that this is a redeclaration, check to see if there is
// already a decl for which declarationReplaces returns true. If there is
// one, just replace it and return.
- if (DeclNameEntries.HandleRedeclaration(getParentASTContext(), D))
+ if (!C)
+ C = &getParentASTContext();
+
+ if (DeclNameEntries.HandleRedeclaration(*C, D))
return;
// Put this declaration into the appropriate slot.
@@ -896,3 +906,18 @@ void StoredDeclsList::materializeDecls(ASTContext &Context) {
}
}
}
+
+//===----------------------------------------------------------------------===//
+// Creation and Destruction of StoredDeclsMaps. //
+//===----------------------------------------------------------------------===//
+
+void *ASTContext::CreateStoredDeclsMap() {
+ StoredDeclsMap *M = new StoredDeclsMap();
+ SDMs.push_back(M);
+ return M;
+}
+
+void ASTContext::ReleaseDeclContextMaps() {
+ for (std::vector<void*>::iterator I = SDMs.begin(), E = SDMs.end(); I!=E; ++I)
+ delete (StoredDeclsMap*) *I;
+}
OpenPOWER on IntegriCloud