]> granicus.if.org Git - clang/commitdiff
Reclaim memory owned by ObjCForwardProtocolDecls.
authorTed Kremenek <kremenek@apple.com>
Fri, 6 Jun 2008 21:05:33 +0000 (21:05 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 6 Jun 2008 21:05:33 +0000 (21:05 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52063 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DeclObjC.h
lib/AST/DeclObjC.cpp
lib/AST/TranslationUnit.cpp

index 1582d73ee8ec62763b24073a7b63a79d23264952..be1e888242ded06c5a8f8a0afad3d074a37c1879 100644 (file)
@@ -692,6 +692,9 @@ class ObjCForwardProtocolDecl : public Decl {
       ReferencedProtocols = 0;
     }
   }
+  
+  virtual ~ObjCForwardProtocolDecl();
+  
 public:
   static ObjCForwardProtocolDecl *Create(ASTContext &C, SourceLocation L, 
                                          ObjCProtocolDecl **Elts, unsigned Num);
@@ -713,6 +716,10 @@ public:
     return ReferencedProtocols[idx];
   }
   
+  typedef ObjCProtocolDecl * const * iterator;
+  iterator begin() const { return ReferencedProtocols; }
+  iterator end() const { return ReferencedProtocols+NumReferencedProtocols; }
+  
   static bool classof(const Decl *D) {
     return D->getKind() == ObjCForwardProtocol;
   }
index 08df62d5b93a4c8e99d862df63b1ac7326548e83..ce9379f19c15956555d6132ae0af0beaa4db2797 100644 (file)
@@ -159,6 +159,10 @@ ObjCForwardProtocolDecl::Create(ASTContext &C,
   return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts);
 }
 
+ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() {
+  delete [] ReferencedProtocols;
+}
+
 ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C,
                                            SourceLocation L,
                                            IdentifierInfo *Id) {
index 5e644cf9835e91b8989da10100b0d38d15efeff6..c3d709f035b70475813bfad9802e41dd7f53a27e 100644 (file)
@@ -66,8 +66,9 @@ TranslationUnit::~TranslationUnit() {
             
       // FIXME: There is no clear ownership policy now for ObjCInterfaceDecls
       //  referenced by ObjCClassDecls.  Some of them can be forward decls that
-      //  are never later defined (in which case the ObjCClassDecl owns them)
-      //  or the ObjCInterfaceDecl later becomes a real definition later. 
+      //  are never later defined (and forward decls can be referenced by
+      //  multiple ObjCClassDecls) or the ObjCInterfaceDecl later
+      //  becomes a real definition. 
       //  Ideally we should have separate objects for forward declarations and
       //  definitions, obviating this problem.  Because of this situation,
       //  referenced ObjCInterfaceDecls are destroyed here.      
@@ -78,6 +79,23 @@ TranslationUnit::~TranslationUnit() {
           Killed.insert(*ID);
           (*ID)->Destroy(*Context);
         }
+      
+      // FIXME: There is no clear ownership policy now for ObjCProtocolDecls
+      //  referenced by ObjCForwardProtocolDecl.  Some of them can be forward 
+      //  decls that are never later defined (and forward decls can be
+      //  referenced by multiple ObjCClassDecls) or the ObjCProtocolDecl 
+      //  later becomes a real definition. 
+      //  Ideally we should have separate objects for forward declarations and
+      //  definitions, obviating this problem.  Because of this situation,
+      //  referenced ObjCProtocolDecls are destroyed here.  
+      if (ObjCForwardProtocolDecl* FDec = dyn_cast<ObjCForwardProtocolDecl>(*I))
+        for (ObjCForwardProtocolDecl::iterator ID=FDec->begin(),
+             ED=FDec->end(); ID!=ED; ++ID) {          
+          if (!*ID || Killed.count(*ID)) continue;
+          Killed.insert(*ID);
+          (*ID)->Destroy(*Context);
+        }
+      
             
       (*I)->Destroy(*Context);
     }