]> granicus.if.org Git - clang/commitdiff
[arcmt] For GC, cleanup and turn -finalize to -dealloc.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Fri, 4 Nov 2011 15:58:22 +0000 (15:58 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Fri, 4 Nov 2011 15:58:22 +0000 (15:58 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143701 91177308-0d34-0410-b5e6-96231b3b80d8

lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
lib/ARCMigrate/TransRetainReleaseDealloc.cpp
lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
lib/ARCMigrate/Transforms.cpp
lib/ARCMigrate/Transforms.h
test/ARCMT/GC.m
test/ARCMT/GC.m.result

index 3ad05e683c7885ecd8b75f0d7e5638fe1b9320a0..0fb7141544aa170fcce9a49d1e4c28a3a26e8f55 100644 (file)
@@ -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<ObjCImplementationDecl>
     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);
index 394f8480e112eb69dbaf9bc14bf8a8d2185c529c..bf2517f1198142cab2f72b3113dd8da61aa18cc4 100644 (file)
@@ -36,13 +36,15 @@ class RetainReleaseDeallocRemover :
   ExprSet Removables;
   llvm::OwningPtr<ParentMap> 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<RetainReleaseDeallocRemover> trans(pass);
   trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
 }
index 1dbe811149474041340eb6d70183996f44f75d5b..7c533bcf3a09f91dfa78a70abe97c085fac45f91 100644 (file)
@@ -31,9 +31,13 @@ class ZeroOutInDeallocRemover :
   llvm::DenseMap<ObjCPropertyDecl*, ObjCPropertyImplDecl*> 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());
 }
index 792bb0cc9a8e151125f86d74945615c64eae02ca..0decdd6b43be537787b4d80e73e83286d7e69ec6 100644 (file)
@@ -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<TransformFn> arcmt::getAllTransformations(
 
   transforms.push_back(independentTransforms);
   // This depends on previous transformations removing various expressions.
-  transforms.push_back(removeEmptyStatementsAndDealloc);
+  transforms.push_back(removeEmptyStatementsAndDeallocFinalize);
 
   return transforms;
 }
index 0eabb211962ecb71dcfc4de5e23b9af604a6dd4a..d935e86ae7348a54cf312109cc507986736e8902 100644 (file)
@@ -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;
index c82095c3a9d3d7a063ba87f26384ffd3bd539ebe..cfd22dee09d9e7ec9d9fefd357ee01e5930ff39a 100644 (file)
@@ -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
index cdf6431dbf6cacb54513985393edd0a6d50b404c..a492f02970b2c75dc6d911b8c69f95b7cf5b2b96 100644 (file)
@@ -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