[cfe-commits] r152020 - in /cfe/trunk: lib/ARCMigrate/TransBlockObjCVariable.cpp lib/ARCMigrate/Transforms.cpp lib/ARCMigrate/Transforms.h test/ARCMT/rewrite-block-var.m test/ARCMT/rewrite-block-var.m.result

Argyrios Kyrtzidis akyrtzi at gmail.com
Mon Mar 5 00:46:24 PST 2012


Author: akirtzidis
Date: Mon Mar  5 02:46:24 2012
New Revision: 152020

URL: http://llvm.org/viewvc/llvm-project?rev=152020&view=rev
Log:
[arcmt]
-Make sure we don't change to '__weak' a __block variable used as output.
-Make sure we don't apply __weak twice.

Fixes rdar://10520757&10521362

Modified:
    cfe/trunk/lib/ARCMigrate/TransBlockObjCVariable.cpp
    cfe/trunk/lib/ARCMigrate/Transforms.cpp
    cfe/trunk/lib/ARCMigrate/Transforms.h
    cfe/trunk/test/ARCMT/rewrite-block-var.m
    cfe/trunk/test/ARCMT/rewrite-block-var.m.result

Modified: cfe/trunk/lib/ARCMigrate/TransBlockObjCVariable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/TransBlockObjCVariable.cpp?rev=152020&r1=152019&r2=152020&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/TransBlockObjCVariable.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/TransBlockObjCVariable.cpp Mon Mar  5 02:46:24 2012
@@ -38,7 +38,7 @@
 class RootBlockObjCVarRewriter :
                           public RecursiveASTVisitor<RootBlockObjCVarRewriter> {
   MigrationPass &Pass;
-  llvm::DenseSet<VarDecl *> CheckedVars;
+  llvm::DenseSet<VarDecl *> &VarsToChange;
 
   class BlockVarChecker : public RecursiveASTVisitor<BlockVarChecker> {
     VarDecl *Var;
@@ -71,7 +71,9 @@
   };
 
 public:
-  RootBlockObjCVarRewriter(MigrationPass &pass) : Pass(pass) { }
+  RootBlockObjCVarRewriter(MigrationPass &pass,
+                           llvm::DenseSet<VarDecl *> &VarsToChange)
+    : Pass(pass), VarsToChange(VarsToChange) { }
 
   bool VisitBlockDecl(BlockDecl *block) {
     SmallVector<VarDecl *, 4> BlockVars;
@@ -80,7 +82,6 @@
            I = block->capture_begin(), E = block->capture_end(); I != E; ++I) {
       VarDecl *var = I->getVariable();
       if (I->isByRef() &&
-          !isAlreadyChecked(var) &&
           var->getType()->isObjCObjectPointerType() &&
           isImplicitStrong(var->getType())) {
         BlockVars.push_back(var);
@@ -89,32 +90,19 @@
 
     for (unsigned i = 0, e = BlockVars.size(); i != e; ++i) {
       VarDecl *var = BlockVars[i];
-      CheckedVars.insert(var);
 
       BlockVarChecker checker(var);
       bool onlyValueOfVarIsNeeded = checker.TraverseStmt(block->getBody());
-      if (onlyValueOfVarIsNeeded) {
-        BlocksAttr *attr = var->getAttr<BlocksAttr>();
-        if(!attr)
-          continue;
-        bool useWeak = canApplyWeak(Pass.Ctx, var->getType());
-        SourceManager &SM = Pass.Ctx.getSourceManager();
-        Transaction Trans(Pass.TA);
-        Pass.TA.replaceText(SM.getExpansionLoc(attr->getLocation()),
-                            "__block",
-                            useWeak ? "__weak" : "__unsafe_unretained");
-      }
-
+      if (onlyValueOfVarIsNeeded)
+        VarsToChange.insert(var);
+      else
+        VarsToChange.erase(var);
     }
 
     return true;
   }
 
 private:
-  bool isAlreadyChecked(VarDecl *VD) {
-    return CheckedVars.count(VD);
-  }
-
   bool isImplicitStrong(QualType ty) {
     if (isa<AttributedType>(ty.getTypePtr()))
       return false;
@@ -124,19 +112,39 @@
 
 class BlockObjCVarRewriter : public RecursiveASTVisitor<BlockObjCVarRewriter> {
   MigrationPass &Pass;
+  llvm::DenseSet<VarDecl *> &VarsToChange;
 
 public:
-  BlockObjCVarRewriter(MigrationPass &pass) : Pass(pass) { }
+  BlockObjCVarRewriter(MigrationPass &pass,
+                       llvm::DenseSet<VarDecl *> &VarsToChange)
+    : Pass(pass), VarsToChange(VarsToChange) { }
 
   bool TraverseBlockDecl(BlockDecl *block) {
-    RootBlockObjCVarRewriter(Pass).TraverseDecl(block);
+    RootBlockObjCVarRewriter(Pass, VarsToChange).TraverseDecl(block);
     return true;
   }
 };
 
 } // anonymous namespace
 
-void trans::rewriteBlockObjCVariable(MigrationPass &pass) {
-  BlockObjCVarRewriter trans(pass);
-  trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
+void BlockObjCVariableTraverser::traverseBody(BodyContext &BodyCtx) {
+  MigrationPass &Pass = BodyCtx.getMigrationContext().Pass;
+  llvm::DenseSet<VarDecl *> VarsToChange;
+
+  BlockObjCVarRewriter trans(Pass, VarsToChange);
+  trans.TraverseStmt(BodyCtx.getTopStmt());
+
+  for (llvm::DenseSet<VarDecl *>::iterator
+         I = VarsToChange.begin(), E = VarsToChange.end(); I != E; ++I) {
+    VarDecl *var = *I;
+    BlocksAttr *attr = var->getAttr<BlocksAttr>();
+    if(!attr)
+      continue;
+    bool useWeak = canApplyWeak(Pass.Ctx, var->getType());
+    SourceManager &SM = Pass.Ctx.getSourceManager();
+    Transaction Trans(Pass.TA);
+    Pass.TA.replaceText(SM.getExpansionLoc(attr->getLocation()),
+                        "__block",
+                        useWeak ? "__weak" : "__unsafe_unretained");
+  }
 }

Modified: cfe/trunk/lib/ARCMigrate/Transforms.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/Transforms.cpp?rev=152020&r1=152019&r2=152020&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/Transforms.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/Transforms.cpp Mon Mar  5 02:46:24 2012
@@ -553,6 +553,7 @@
     MigrateCtx.addTraverser(new GCAttrsTraverser());
   }
   MigrateCtx.addTraverser(new PropertyRewriteTraverser());
+  MigrateCtx.addTraverser(new BlockObjCVariableTraverser());
 
   MigrateCtx.traverse(pass.Ctx.getTranslationUnitDecl());
 }
@@ -564,7 +565,6 @@
   removeZeroOutPropsInDeallocFinalize(pass);
   makeAssignARCSafe(pass);
   rewriteUnbridgedCasts(pass);
-  rewriteBlockObjCVariable(pass);
   checkAPIUses(pass);
   traverseAST(pass);
 }

Modified: cfe/trunk/lib/ARCMigrate/Transforms.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/Transforms.h?rev=152020&r1=152019&r2=152020&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/Transforms.h (original)
+++ cfe/trunk/lib/ARCMigrate/Transforms.h Mon Mar  5 02:46:24 2012
@@ -37,7 +37,6 @@
 void makeAssignARCSafe(MigrationPass &pass);
 void removeRetainReleaseDeallocFinalize(MigrationPass &pass);
 void removeZeroOutPropsInDeallocFinalize(MigrationPass &pass);
-void rewriteBlockObjCVariable(MigrationPass &pass);
 void rewriteUnusedInitDelegate(MigrationPass &pass);
 void checkAPIUses(MigrationPass &pass);
 
@@ -130,6 +129,11 @@
   virtual void traverseObjCImplementation(ObjCImplementationContext &ImplCtx);
 };
 
+class BlockObjCVariableTraverser : public ASTTraverser {
+public:
+  virtual void traverseBody(BodyContext &BodyCtx);
+};
+
 // GC transformations
 
 class GCAttrsTraverser : public ASTTraverser {

Modified: cfe/trunk/test/ARCMT/rewrite-block-var.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/rewrite-block-var.m?rev=152020&r1=152019&r2=152020&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/rewrite-block-var.m (original)
+++ cfe/trunk/test/ARCMT/rewrite-block-var.m Mon Mar  5 02:46:24 2012
@@ -23,3 +23,23 @@
     x = [p something];
   });
 }
+
+void test3(Foo *p) {
+  __block Foo *x; // __block used as output variable.
+  bar(^{
+    [x something];
+  });
+  bar(^{
+    x = 0;
+  });
+}
+
+void test4(Foo *p) {
+  __block Foo *x = p; // __block used just to break cycle.
+  bar(^{
+    [x something];
+  });
+  bar(^{
+    [x something];
+  });
+}

Modified: cfe/trunk/test/ARCMT/rewrite-block-var.m.result
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/rewrite-block-var.m.result?rev=152020&r1=152019&r2=152020&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/rewrite-block-var.m.result (original)
+++ cfe/trunk/test/ARCMT/rewrite-block-var.m.result Mon Mar  5 02:46:24 2012
@@ -23,3 +23,23 @@
     x = [p something];
   });
 }
+
+void test3(Foo *p) {
+  __block Foo *x; // __block used as output variable.
+  bar(^{
+    [x something];
+  });
+  bar(^{
+    x = 0;
+  });
+}
+
+void test4(Foo *p) {
+  __weak Foo *x = p; // __block used just to break cycle.
+  bar(^{
+    [x something];
+  });
+  bar(^{
+    [x something];
+  });
+}





More information about the cfe-commits mailing list