From: Argyrios Kyrtzidis Date: Fri, 4 Nov 2011 15:58:22 +0000 (+0000) Subject: [arcmt] For GC, cleanup and turn -finalize to -dealloc. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e7ef8556f4ee3012a0479308c993af0fbee448df;p=clang [arcmt] For GC, cleanup and turn -finalize to -dealloc. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143701 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp b/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp index 3ad05e683c..0fb7141544 100644 --- a/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp +++ b/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp @@ -196,35 +196,60 @@ static bool isBodyEmpty(CompoundStmt *body, ASTContext &Ctx, return true; } -static void removeDeallocMethod(MigrationPass &pass) { +static void cleanupDeallocOrFinalize(MigrationPass &pass) { ASTContext &Ctx = pass.Ctx; TransformActions &TA = pass.TA; DeclContext *DC = Ctx.getTranslationUnitDecl(); + Selector FinalizeSel = + Ctx.Selectors.getNullarySelector(&pass.Ctx.Idents.get("finalize")); typedef DeclContext::specific_decl_iterator impl_iterator; for (impl_iterator I = impl_iterator(DC->decls_begin()), E = impl_iterator(DC->decls_end()); I != E; ++I) { + ObjCMethodDecl *DeallocM = 0; + ObjCMethodDecl *FinalizeM = 0; for (ObjCImplementationDecl::instmeth_iterator MI = (*I)->instmeth_begin(), ME = (*I)->instmeth_end(); MI != ME; ++MI) { ObjCMethodDecl *MD = *MI; + if (!MD->hasBody()) + continue; + if (MD->getMethodFamily() == OMF_dealloc) { - if (MD->hasBody() && - isBodyEmpty(MD->getCompoundBody(), Ctx, pass.ARCMTMacroLocs)) { - Transaction Trans(TA); - TA.remove(MD->getSourceRange()); - } - break; + DeallocM = MD; + } else if (MD->isInstanceMethod() && MD->getSelector() == FinalizeSel) { + FinalizeM = MD; + } + } + + if (DeallocM) { + if (isBodyEmpty(DeallocM->getCompoundBody(), Ctx, pass.ARCMTMacroLocs)) { + Transaction Trans(TA); + TA.remove(DeallocM->getSourceRange()); + } + + if (FinalizeM) { + Transaction Trans(TA); + TA.remove(FinalizeM->getSourceRange()); + } + + } else if (FinalizeM) { + if (isBodyEmpty(FinalizeM->getCompoundBody(), Ctx, pass.ARCMTMacroLocs)) { + Transaction Trans(TA); + TA.remove(FinalizeM->getSourceRange()); + } else { + Transaction Trans(TA); + TA.replaceText(FinalizeM->getSelectorStartLoc(), "finalize", "dealloc"); } } } } -void trans::removeEmptyStatementsAndDealloc(MigrationPass &pass) { +void trans::removeEmptyStatementsAndDeallocFinalize(MigrationPass &pass) { EmptyStatementsRemover(pass).TraverseDecl(pass.Ctx.getTranslationUnitDecl()); - removeDeallocMethod(pass); + cleanupDeallocOrFinalize(pass); for (unsigned i = 0, e = pass.ARCMTMacroLocs.size(); i != e; ++i) { Transaction Trans(pass.TA); diff --git a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp index 394f8480e1..bf2517f119 100644 --- a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp +++ b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp @@ -36,13 +36,15 @@ class RetainReleaseDeallocRemover : ExprSet Removables; llvm::OwningPtr StmtMap; - Selector DelegateSel; + Selector DelegateSel, FinalizeSel; public: RetainReleaseDeallocRemover(MigrationPass &pass) : Body(0), Pass(pass) { DelegateSel = Pass.Ctx.Selectors.getNullarySelector(&Pass.Ctx.Idents.get("delegate")); + FinalizeSel = + Pass.Ctx.Selectors.getNullarySelector(&Pass.Ctx.Idents.get("finalize")); } void transformBody(Stmt *body) { @@ -55,6 +57,8 @@ public: bool VisitObjCMessageExpr(ObjCMessageExpr *E) { switch (E->getMethodFamily()) { default: + if (E->isInstanceMessage() && E->getSelector() == FinalizeSel) + break; return true; case OMF_autorelease: if (isRemovable(E)) { @@ -211,7 +215,7 @@ private: } // anonymous namespace -void trans::removeRetainReleaseDealloc(MigrationPass &pass) { +void trans::removeRetainReleaseDeallocFinalize(MigrationPass &pass) { BodyTransform trans(pass); trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl()); } diff --git a/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp b/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp index 1dbe811149..7c533bcf3a 100644 --- a/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp +++ b/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp @@ -31,9 +31,13 @@ class ZeroOutInDeallocRemover : llvm::DenseMap SynthesizedProperties; ImplicitParamDecl *SelfD; ExprSet Removables; + Selector FinalizeSel; public: - ZeroOutInDeallocRemover(MigrationPass &pass) : Pass(pass), SelfD(0) { } + ZeroOutInDeallocRemover(MigrationPass &pass) : Pass(pass), SelfD(0) { + FinalizeSel = + Pass.Ctx.Selectors.getNullarySelector(&Pass.Ctx.Idents.get("finalize")); + } bool VisitObjCMessageExpr(ObjCMessageExpr *ME) { ASTContext &Ctx = Pass.Ctx; @@ -84,7 +88,8 @@ public: } bool TraverseObjCMethodDecl(ObjCMethodDecl *D) { - if (D->getMethodFamily() != OMF_dealloc) + if (D->getMethodFamily() != OMF_dealloc && + !(D->isInstanceMethod() && D->getSelector() == FinalizeSel)) return true; if (!D->hasBody()) return true; @@ -191,7 +196,7 @@ private: } // anonymous namespace -void trans::removeZeroOutPropsInDealloc(MigrationPass &pass) { +void trans::removeZeroOutPropsInDeallocFinalize(MigrationPass &pass) { ZeroOutInDeallocRemover trans(pass); trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl()); } diff --git a/lib/ARCMigrate/Transforms.cpp b/lib/ARCMigrate/Transforms.cpp index 792bb0cc9a..0decdd6b43 100644 --- a/lib/ARCMigrate/Transforms.cpp +++ b/lib/ARCMigrate/Transforms.cpp @@ -345,9 +345,9 @@ static void traverseAST(MigrationPass &pass) { static void independentTransforms(MigrationPass &pass) { rewriteAutoreleasePool(pass); rewriteProperties(pass); - removeRetainReleaseDealloc(pass); + removeRetainReleaseDeallocFinalize(pass); rewriteUnusedInitDelegate(pass); - removeZeroOutPropsInDealloc(pass); + removeZeroOutPropsInDeallocFinalize(pass); makeAssignARCSafe(pass); rewriteUnbridgedCasts(pass); rewriteBlockObjCVariable(pass); @@ -361,7 +361,7 @@ std::vector arcmt::getAllTransformations( transforms.push_back(independentTransforms); // This depends on previous transformations removing various expressions. - transforms.push_back(removeEmptyStatementsAndDealloc); + transforms.push_back(removeEmptyStatementsAndDeallocFinalize); return transforms; } diff --git a/lib/ARCMigrate/Transforms.h b/lib/ARCMigrate/Transforms.h index 0eabb21196..d935e86ae7 100644 --- a/lib/ARCMigrate/Transforms.h +++ b/lib/ARCMigrate/Transforms.h @@ -35,14 +35,14 @@ namespace trans { void rewriteAutoreleasePool(MigrationPass &pass); void rewriteUnbridgedCasts(MigrationPass &pass); void makeAssignARCSafe(MigrationPass &pass); -void removeRetainReleaseDealloc(MigrationPass &pass); -void removeZeroOutPropsInDealloc(MigrationPass &pass); +void removeRetainReleaseDeallocFinalize(MigrationPass &pass); +void removeZeroOutPropsInDeallocFinalize(MigrationPass &pass); void rewriteProperties(MigrationPass &pass); void rewriteBlockObjCVariable(MigrationPass &pass); void rewriteUnusedInitDelegate(MigrationPass &pass); void checkAPIUses(MigrationPass &pass); -void removeEmptyStatementsAndDealloc(MigrationPass &pass); +void removeEmptyStatementsAndDeallocFinalize(MigrationPass &pass); class BodyContext { MigrationContext &MigrateCtx; diff --git a/test/ARCMT/GC.m b/test/ARCMT/GC.m index c82095c3a9..cfd22dee09 100644 --- a/test/ARCMT/GC.m +++ b/test/ARCMT/GC.m @@ -9,3 +9,32 @@ void test1(CFTypeRef *cft) { id x = NSMakeCollectable(cft); } + +@interface I1 +@end + +@implementation I1 +-(void)dealloc { + // dealloc + test1(0); +} + +-(void)finalize { + // finalize + test1(0); +} +@end + +@interface I2 +@property (retain) id prop; +@end + +@implementation I2 +@synthesize prop; + +-(void)finalize { + self.prop = 0; + // finalize + test1(0); +} +@end diff --git a/test/ARCMT/GC.m.result b/test/ARCMT/GC.m.result index cdf6431dbf..a492f02970 100644 --- a/test/ARCMT/GC.m.result +++ b/test/ARCMT/GC.m.result @@ -9,3 +9,27 @@ void test1(CFTypeRef *cft) { id x = CFBridgingRelease(cft); } + +@interface I1 +@end + +@implementation I1 +-(void)dealloc { + // dealloc + test1(0); +} + +@end + +@interface I2 +@property id prop; +@end + +@implementation I2 +@synthesize prop; + +-(void)dealloc { + // finalize + test1(0); +} +@end