From 8a779314870760848e61da2c428a78971fe3f1c3 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 6 Jun 2008 16:45:15 +0000 Subject: [PATCH] Initial work on additional memory collection for ObjC AST objects. We now have Destroy methods of ObjcMethodDecl and ObjCInterfaceDecl which recursively destroy their owned Decls and Stmts. There are a few cases where it is not clear what to do (FIXMEs included in the patch). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52050 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/DeclObjC.h | 10 ++++++++ lib/AST/DeclObjC.cpp | 47 +++++++++++++++++++++++++++++++++--- lib/Parse/ParseObjc.cpp | 9 ++++--- 3 files changed, 59 insertions(+), 7 deletions(-) diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index b62027e893..7f4e303cc4 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -109,8 +109,12 @@ private: SelName(SelInfo), MethodDeclType(T), ParamInfo(0), NumMethodParams(0), MethodAttrs(M), EndLoc(endLoc), Body(0), SelfDecl(0) {} + ~ObjCMethodDecl(); public: + + /// Destroy - Call destructors and release memory. + virtual void Destroy(ASTContext& C); static ObjCMethodDecl *Create(ASTContext &C, SourceLocation beginLoc, @@ -262,8 +266,14 @@ class ObjCInterfaceDecl : public NamedDecl, public DeclContext { ClassLoc(CLoc) { AllocIntfRefProtocols(numRefProtos); } + + ~ObjCInterfaceDecl(); + public: + /// Destroy - Call destructors and release memory. + virtual void Destroy(ASTContext& C); + static ObjCInterfaceDecl *Create(ASTContext &C, SourceLocation atLoc, unsigned numRefProtos, diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index 6536df6e1e..f3d81a1aa5 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -35,6 +35,21 @@ ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C, isVariadic, isSynthesized, impControl); } +ObjCMethodDecl::~ObjCMethodDecl() { + delete [] ParamInfo; + //delete [] MethodAttrs; // FIXME: Also destroy the stored Expr*. +} + +void ObjCMethodDecl::Destroy(ASTContext& C) { + if (Body) Body->Destroy(C); + if (SelfDecl) SelfDecl->Destroy(C); + + for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I) + if (*I) (*I)->Destroy(C); + + Decl::Destroy(C); +} + ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C, SourceLocation atLoc, unsigned numRefProtos, @@ -47,6 +62,34 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C, isInternal); } +ObjCInterfaceDecl::~ObjCInterfaceDecl() { + delete [] Ivars; + delete [] InstanceMethods; + delete [] ClassMethods; + delete [] PropertyDecl; + // FIXME: CategoryList? +} + +void ObjCInterfaceDecl::Destroy(ASTContext& C) { + for (ivar_iterator I=ivar_begin(), E=ivar_end(); I!=E; ++I) + if (*I) (*I)->Destroy(C); + + for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I!=E; ++I) + if (*I) (*I)->Destroy(C); + + for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I!=E; ++I) + if (*I) (*I)->Destroy(C); + + // FIXME: Cannot destroy properties right now because the properties of + // both the super class and this class are in this array. This can + // cause double-deletions. + //for (classprop_iterator I=classprop_begin(), E=classprop_end(); I!=E; ++I) +// if (*I) (*I)->Destroy(C); +// + Decl::Destroy(C); +} + + ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L, IdentifierInfo *Id, QualType T) { void *Mem = C.getAllocator().Allocate(); @@ -135,10 +178,6 @@ void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo, } } -ObjCMethodDecl::~ObjCMethodDecl() { - delete[] ParamInfo; -} - /// FindPropertyDeclaration - Finds declaration of the property given its name /// in 'PropertyId' and returns it. It returns 0, if not found. /// diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index 17450747e0..baf2667a54 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -224,7 +224,7 @@ Parser::DeclTy *Parser::ParseObjCAtInterfaceDeclaration( /// void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl, tok::ObjCKeywordKind contextKey) { - llvm::SmallVector allMethods; + llvm::SmallVector allMethods; llvm::SmallVector allProperties; tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword; SourceLocation AtEndLoc; @@ -314,8 +314,11 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl, } } /// Insert collected methods declarations into the @interface object. - Actions.ActOnAtEnd(AtEndLoc, interfaceDecl, &allMethods[0], allMethods.size(), - &allProperties[0], allProperties.size()); + Actions.ActOnAtEnd(AtEndLoc, interfaceDecl, + allMethods.empty() ? 0 : &allMethods[0], + allMethods.size(), + allProperties.empty() ? 0 : &allProperties[0], + allProperties.size()); } /// Parse property attribute declarations. -- 2.40.0