From: Ted Kremenek Date: Thu, 11 Feb 2010 07:12:28 +0000 (+0000) Subject: Have ~ASTContext() delete StoredDeclsMap (internal to DeclContext) by X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3478eb6872d836600caf45b0f81c2065d685d6e0;p=clang 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: git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95861 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index ad9444b68b..d02fe9ffb7 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -46,6 +46,7 @@ namespace clang { class SourceManager; class TargetInfo; // Decls + class DeclContext; class CXXMethodDecl; class CXXRecordDecl; class Decl; @@ -1212,6 +1213,15 @@ private: const ASTRecordLayout &getObjCLayout(const ObjCInterfaceDecl *D, const ObjCImplementationDecl *Impl); + +private: + // FIXME: This currently contains the set of StoredDeclMaps used + // by DeclContext objects. This probably should not be in ASTContext, + // but we include it here so that ASTContext can quickly deallocate them. + std::vector SDMs; + friend class DeclContext; + void *CreateStoredDeclsMap(); + void ReleaseDeclContextMaps(); }; /// @brief Utility function for constructing a nullary selector. diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index c92a7d14cc..6ac989041a 100644 --- a/lib/AST/ASTContext.cpp +++ b/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/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 84aa81ca76..863a1cbd03 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -448,7 +448,10 @@ bool DeclContext::classof(const Decl *D) { } DeclContext::~DeclContext() { - delete static_cast(LookupPtr); + // FIXME: Currently ~ASTContext will delete the StoredDeclsMaps because + // ~DeclContext() is not guaranteed to be called when ASTContext uses + // a BumpPtrAllocator. + // delete static_cast(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(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(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::iterator I = SDMs.begin(), E = SDMs.end(); I!=E; ++I) + delete (StoredDeclsMap*) *I; +}