diff options
-rw-r--r-- | include/clang/AST/DeclObjC.h | 11 | ||||
-rw-r--r-- | lib/AST/DeclObjC.cpp | 17 | ||||
-rw-r--r-- | lib/AST/TranslationUnit.cpp | 27 |
3 files changed, 49 insertions, 6 deletions
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index a50c08f344..1582d73ee8 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -646,7 +646,14 @@ class ObjCClassDecl : public Decl { } NumForwardDecls = nElts; } + + virtual ~ObjCClassDecl(); + public: + + /// Destroy - Call destructors and release memory. + virtual void Destroy(ASTContext& C); + static ObjCClassDecl *Create(ASTContext &C, SourceLocation L, ObjCInterfaceDecl **Elts, unsigned nElts); @@ -657,6 +664,10 @@ public: ObjCInterfaceDecl** getForwardDecls() const { return ForwardDecls; } int getNumForwardDecls() const { return NumForwardDecls; } + typedef ObjCInterfaceDecl * const * iterator; + iterator begin() const { return ForwardDecls; } + iterator end() const { return ForwardDecls+NumForwardDecls; } + static bool classof(const Decl *D) { return D->getKind() == ObjCClass; } static bool classof(const ObjCClassDecl *D) { return true; } }; diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index a0d281808e..08df62d5b9 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -134,6 +134,23 @@ ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, return new (Mem) ObjCClassDecl(L, Elts, nElts); } +ObjCClassDecl::~ObjCClassDecl() { + delete [] ForwardDecls; +} + +void ObjCClassDecl::Destroy(ASTContext& C) { + + // FIXME: There is no clear ownership policy now for referenced + // ObjCInterfaceDecls. Some of them can be forward declarations that + // are never later defined (in which case the ObjCClassDecl owns them) + // or the ObjCInterfaceDecl later becomes a real definition later. Ideally + // we should have separate objects for forward declarations and definitions, + // obviating this problem. Because of this situation, referenced + // ObjCInterfaceDecls are destroyed in ~TranslationUnit. + + Decl::Destroy(C); +} + ObjCForwardProtocolDecl * ObjCForwardProtocolDecl::Create(ASTContext &C, SourceLocation L, diff --git a/lib/AST/TranslationUnit.cpp b/lib/AST/TranslationUnit.cpp index a683625789..5e644cf983 100644 --- a/lib/AST/TranslationUnit.cpp +++ b/lib/AST/TranslationUnit.cpp @@ -57,13 +57,28 @@ TranslationUnit::~TranslationUnit() { // eventually be fixed when the ownership of ObjCPropertyDecls gets // cleaned up. if (ObjCProtocolDecl* PDecl = dyn_cast<ObjCProtocolDecl>(*I)) - for (ObjCInterfaceDecl::classprop_iterator PD=PDecl->classprop_begin(), - ED=PDecl->classprop_end(); PD!=ED; ++PD) { - if (!*PD || Killed.count(*PD)) continue; - Killed.insert(*PD); - (*PD)->Destroy(*Context); + for (ObjCProtocolDecl::classprop_iterator ID=PDecl->classprop_begin(), + ED=PDecl->classprop_end(); ID!=ED; ++ID) { + if (!*ID || Killed.count(*ID)) continue; + Killed.insert(*ID); + (*ID)->Destroy(*Context); } - + + // 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. + // Ideally we should have separate objects for forward declarations and + // definitions, obviating this problem. Because of this situation, + // referenced ObjCInterfaceDecls are destroyed here. + if (ObjCClassDecl* CDecl = dyn_cast<ObjCClassDecl>(*I)) + for (ObjCClassDecl::iterator ID=CDecl->begin(), + ED=CDecl->end(); ID!=ED; ++ID) { + if (!*ID || Killed.count(*ID)) continue; + Killed.insert(*ID); + (*ID)->Destroy(*Context); + } + (*I)->Destroy(*Context); } } |