From: Chris Lattner Date: Wed, 4 Mar 2009 06:05:19 +0000 (+0000) Subject: add an a Attr::Destroy method and force clients to go through it. As part of X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cc5814732edc0c382d0136ab57ec6149566043e2;p=clang add an a Attr::Destroy method and force clients to go through it. As part of this, make DeclBase::Destroy destroy attributes instead of the DeclBase dtor. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66020 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index e814c5c719..89fe0f0416 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -20,6 +20,7 @@ #include namespace clang { + class ASTContext; /// Attr - This represents one attribute. class Attr { @@ -69,10 +70,14 @@ private: protected: Attr(Kind AK) : Next(0), AttrKind(AK), Inherited(false) {} -public: virtual ~Attr() { delete Next; } +public: + + void Destroy(ASTContext &C) { + delete this; + } /// \brief Whether this attribute should be merged to new /// declarations. diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index ca67e28c71..3e968c7896 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -121,15 +121,7 @@ Decl::~Decl() { if (isOutOfSemaDC()) delete getMultipleDC(); - if (!HasAttrs) - return; - - DeclAttrMapTy::iterator it = DeclAttrs->find(this); - assert(it != DeclAttrs->end() && "No attrs found but HasAttrs is true!"); - - // release attributes. - delete it->second; - invalidateAttrs(); + assert(!HasAttrs && "attributes should have been freed by Destroy"); } void Decl::addAttr(Attr *NewAttr) { @@ -189,7 +181,18 @@ void Decl::swapAttrs(Decl *RHS) { } -void Decl::Destroy(ASTContext& C) { +void Decl::Destroy(ASTContext &C) { + // Free attributes for this decl. + if (HasAttrs) { + DeclAttrMapTy::iterator it = DeclAttrs->find(this); + assert(it != DeclAttrs->end() && "No attrs found but HasAttrs is true!"); + + // release attributes. + it->second->Destroy(C); + invalidateAttrs(); + HasAttrs = false; + } + #if 0 // FIXME: Once ownership is fully understood, we can enable this code if (DeclContext *DC = dyn_cast(this)) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 8d32578c98..6a6628f748 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -482,11 +482,11 @@ static bool DeclHasAttr(const Decl *decl, const Attr *target) { } /// MergeAttributes - append attributes from the Old decl to the New one. -static void MergeAttributes(Decl *New, Decl *Old) { - Attr *attr = const_cast(Old->getAttrs()), *tmp; +static void MergeAttributes(Decl *New, Decl *Old, ASTContext &C) { + Attr *attr = const_cast(Old->getAttrs()); while (attr) { - tmp = attr; + Attr *tmp = attr; attr = attr->getNext(); if (!DeclHasAttr(New, tmp) && tmp->isMerged()) { @@ -494,7 +494,7 @@ static void MergeAttributes(Decl *New, Decl *Old) { New->addAttr(tmp); } else { tmp->setNext(0); - delete(tmp); + tmp->Destroy(C); } } @@ -678,7 +678,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) { /// \returns false bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old) { // Merge the attributes - MergeAttributes(New, Old); + MergeAttributes(New, Old, Context); // Merge the storage class. New->setStorageClass(Old->getStorageClass()); @@ -767,7 +767,7 @@ bool Sema::MergeVarDecl(VarDecl *New, Decl *OldD) { return true; } - MergeAttributes(New, Old); + MergeAttributes(New, Old, Context); // Merge the types QualType MergedT = Context.mergeTypes(New->getType(), Old->getType());