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/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index ca67e28..3e968c7 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -121,15 +121,7 @@
   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::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<DeclContext>(this))