]> granicus.if.org Git - clang/commitdiff
Have ~ASTContext() delete StoredDeclsMap (internal to DeclContext) by
authorTed Kremenek <kremenek@apple.com>
Thu, 11 Feb 2010 07:12:28 +0000 (07:12 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 11 Feb 2010 07:12:28 +0000 (07:12 +0000)
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>
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95861 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ASTContext.h
lib/AST/ASTContext.cpp
lib/AST/DeclBase.cpp

index ad9444b68b915647875339b84fca41d8778c8a69..d02fe9ffb76c7536d2c9f4856bf2c669c6fcfdda 100644 (file)
@@ -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<void*> SDMs; 
+  friend class DeclContext;
+  void *CreateStoredDeclsMap();
+  void ReleaseDeclContextMaps();
 };
   
 /// @brief Utility function for constructing a nullary selector.
index c92a7d14cc6df60c2bfd37dc8a3219e01474915d..6ac989041ab7ff5221750a079e87ffbebad1d60b 100644 (file)
@@ -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()) {
index 84aa81ca76db6d05d53c63bd06dc19ba23b70af1..863a1cbd03c4c12f3c03968de44a0757d63397d8 100644 (file)
@@ -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;
+}