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>.

llvm-svn: 104465
This commit is contained in:
Douglas Gregor 2010-05-23 18:26:36 +00:00
parent 5773205a8d
commit 1a80933d24
4 changed files with 42 additions and 4 deletions

View File

@ -1272,6 +1272,15 @@ public:
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 @@ private:
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.

View File

@ -460,6 +460,8 @@ public:
/// 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 @@ public:
/// 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.

View File

@ -64,6 +64,12 @@ ASTContext::~ASTContext() {
// 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 @@ ASTContext::~ASTContext() {
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());

View File

@ -94,6 +94,10 @@ TemplateDecl::~TemplateDecl() {
// 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 @@ FunctionTemplateDecl::Common *FunctionTemplateDecl::getCommonPtr() {
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 @@ FunctionTemplateDecl::Common *FunctionTemplateDecl::getCommonPtr() {
// 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 @@ ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
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);