[cfe-commits] r104465 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/DeclTemplate.h lib/AST/ASTContext.cpp lib/AST/DeclTemplate.cpp

Douglas Gregor dgregor at apple.com
Sun May 23 11:26:36 PDT 2010


Author: dgregor
Date: Sun May 23 13:26:36 2010
New Revision: 104465

URL: http://llvm.org/viewvc/llvm-project?rev=104465&view=rev
Log:
Keep track of all of the class and function template's "common"
pointers in the ASTContext, so that the folding sets stored inside
them will be deallocated when the ASTContext is destroyed (under
-disable-free). <rdar://problem/7998824>.

Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/DeclTemplate.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/DeclTemplate.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=104465&r1=104464&r2=104465&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Sun May 23 13:26:36 2010
@@ -1272,6 +1272,15 @@
   TypeSourceInfo *
   getTrivialTypeSourceInfo(QualType T, SourceLocation Loc = SourceLocation());
 
+  /// \brief Add a deallocation callback that will be invoked when the 
+  /// ASTContext is destroyed.
+  ///
+  /// \brief Callback A callback function that will be invoked on destruction.
+  ///
+  /// \brief Data Pointer data that will be provided to the callback function
+  /// when it is called.
+  void AddDeallocation(void (*Callback)(void*), void *Data);
+  
 private:
   ASTContext(const ASTContext&); // DO NOT IMPLEMENT
   void operator=(const ASTContext&); // DO NOT IMPLEMENT
@@ -1286,11 +1295,15 @@
                                   const FieldDecl *Field,
                                   bool OutermostType = false,
                                   bool EncodingProperty = false);
-
+ 
   const ASTRecordLayout &getObjCLayout(const ObjCInterfaceDecl *D,
                                        const ObjCImplementationDecl *Impl);
   
 private:
+  /// \brief A set of deallocations that should be performed when the 
+  /// ASTContext is destroyed.
+  llvm::SmallVector<std::pair<void (*)(void*), void *>, 16> Deallocations;
+                                       
   // 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.

Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=104465&r1=104464&r2=104465&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Sun May 23 13:26:36 2010
@@ -460,6 +460,8 @@
   
 /// Declaration of a template function.
 class FunctionTemplateDecl : public TemplateDecl {
+  static void DeallocateCommon(void *Ptr);
+                        
 protected:
   /// \brief Data that is common to all of the declarations of a given
   /// function template.
@@ -1164,6 +1166,8 @@
 
 /// Declaration of a class template.
 class ClassTemplateDecl : public TemplateDecl {
+  static void DeallocateCommon(void *Ptr);
+  
 protected:
   /// \brief Data that is common to all of the declarations of a given
   /// class template.

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=104465&r1=104464&r2=104465&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Sun May 23 13:26:36 2010
@@ -64,6 +64,12 @@
   // FIXME: Is this the ideal solution?
   ReleaseDeclContextMaps();
 
+  if (!FreeMemory) {
+    // Call all of the deallocation functions.
+    for (unsigned I = 0, N = Deallocations.size(); I != N; ++I)
+      Deallocations[I].first(Deallocations[I].second);
+  }
+  
   // Release all of the memory associated with overridden C++ methods.
   for (llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::iterator 
          OM = OverriddenMethods.begin(), OMEnd = OverriddenMethods.end();
@@ -114,6 +120,10 @@
   TUDecl->Destroy(*this);
 }
 
+void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) {
+  Deallocations.push_back(std::make_pair(Callback, Data));
+}
+
 void
 ASTContext::setExternalSource(llvm::OwningPtr<ExternalASTSource> &Source) {
   ExternalSource.reset(Source.take());

Modified: cfe/trunk/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclTemplate.cpp?rev=104465&r1=104464&r2=104465&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Sun May 23 13:26:36 2010
@@ -94,6 +94,10 @@
 // FunctionTemplateDecl Implementation
 //===----------------------------------------------------------------------===//
 
+void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
+  static_cast<Common *>(Ptr)->~Common();
+}
+
 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
                                                    DeclContext *DC,
                                                    SourceLocation L,
@@ -129,8 +133,9 @@
     First = First->getPreviousDeclaration();
 
   if (First->CommonOrPrev.isNull()) {
-    // FIXME: Allocate with the ASTContext
-    First->CommonOrPrev = new Common;
+    Common *CommonPtr = new (getASTContext()) Common;
+    getASTContext().AddDeallocation(DeallocateCommon, CommonPtr);
+    First->CommonOrPrev = CommonPtr;
   }
   return First->CommonOrPrev.get<Common*>();
 }
@@ -139,6 +144,10 @@
 // ClassTemplateDecl Implementation
 //===----------------------------------------------------------------------===//
 
+void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
+  static_cast<Common *>(Ptr)->~Common();
+}
+
 ClassTemplateDecl *ClassTemplateDecl::getCanonicalDecl() {
   ClassTemplateDecl *Template = this;
   while (Template->getPreviousDeclaration())
@@ -156,8 +165,10 @@
   Common *CommonPtr;
   if (PrevDecl)
     CommonPtr = PrevDecl->CommonPtr;
-  else
+  else {
     CommonPtr = new (C) Common;
+    C.AddDeallocation(DeallocateCommon, CommonPtr);
+  }
 
   return new (C) ClassTemplateDecl(DC, L, Name, Params, Decl, PrevDecl,
                                    CommonPtr);





More information about the cfe-commits mailing list