[cfe-commits] r97520 - in /cfe/trunk: lib/Frontend/RewriteObjC.cpp test/Rewriter/rewrite-nested-blocks-1.mm

Fariborz Jahanian fjahanian at apple.com
Mon Mar 1 15:36:21 PST 2010


Author: fjahanian
Date: Mon Mar  1 17:36:21 2010
New Revision: 97520

URL: http://llvm.org/viewvc/llvm-project?rev=97520&view=rev
Log:
More rewriter of nested blocks fun stuff.
Radar 7696893.

Added:
    cfe/trunk/test/Rewriter/rewrite-nested-blocks-1.mm
Modified:
    cfe/trunk/lib/Frontend/RewriteObjC.cpp

Modified: cfe/trunk/lib/Frontend/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/RewriteObjC.cpp?rev=97520&r1=97519&r2=97520&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/RewriteObjC.cpp (original)
+++ cfe/trunk/lib/Frontend/RewriteObjC.cpp Mon Mar  1 17:36:21 2010
@@ -26,6 +26,7 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/DenseSet.h"
+
 using namespace clang;
 using llvm::utostr;
 
@@ -390,7 +391,7 @@
     void GetBlockDeclRefExprs(Stmt *S);
     void GetInnerBlockDeclRefExprs(Stmt *S, 
                 llvm::SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs,
-                llvm::SmallPtrSet<ValueDecl *, 8> &InnerBlockValueDecls);
+                llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts);
 
     // We avoid calling Type::isBlockPointerType(), since it operates on the
     // canonical type. We only care if the top-level type is a closure pointer.
@@ -4264,16 +4265,23 @@
   if (CurFunctionDeclToDeclareForBlock && !Blocks.empty())
     RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock);
   // Insert closures that were part of the function.
-  for (unsigned i = 0; i < Blocks.size(); i++) {
+  for (unsigned i = 0, count=0; i < Blocks.size(); i++) {
+    CollectBlockDeclRefInfo(Blocks[i]);
     // Need to copy-in the inner copied-in variables not actually used in this
     // block.
-    for (int j = 0; j < InnerDeclRefsCount[i]; j++)
-      BlockDeclRefs.push_back(InnerDeclRefs[j]);
-    CollectBlockDeclRefInfo(Blocks[i]);
-    llvm::SmallPtrSet<ValueDecl *, 8> InnerBlockValueDecls;
-    llvm::SmallVector<BlockDeclRefExpr *, 8> InnerBlockDeclRefs;
-    GetInnerBlockDeclRefExprs(Blocks[i]->getBody(),
-                              InnerBlockDeclRefs, InnerBlockValueDecls);
+    for (int j = 0; j < InnerDeclRefsCount[i]; j++) {
+      BlockDeclRefExpr *Exp = InnerDeclRefs[count++];
+      ValueDecl *VD = Exp->getDecl();
+      BlockDeclRefs.push_back(Exp);
+      if (!Exp->isByRef() && !BlockByCopyDeclsPtrSet.count(VD)) {
+        BlockByCopyDeclsPtrSet.insert(VD);
+        BlockByCopyDecls.push_back(VD);
+      }
+      if (Exp->isByRef() && !BlockByRefDeclsPtrSet.count(VD)) {
+        BlockByRefDeclsPtrSet.insert(VD);
+        BlockByRefDecls.push_back(VD);
+      }
+    }
 
     std::string ImplTag = "__" + std::string(FunName) + "_block_impl_" + utostr(i);
     std::string DescTag = "__" + std::string(FunName) + "_block_desc_" + utostr(i);
@@ -4353,28 +4361,28 @@
 
 void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S, 
                 llvm::SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs,
-                llvm::SmallPtrSet<ValueDecl *, 8> &InnerBlockValueDecls) {
+                llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts) {
   for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
        CI != E; ++CI)
     if (*CI) {
-      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI))
+      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) {
+        InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
         GetInnerBlockDeclRefExprs(CBE->getBody(),
                                   InnerBlockDeclRefs,
-                                  InnerBlockValueDecls);
+                                  InnerContexts);
+      }
       else
         GetInnerBlockDeclRefExprs(*CI,
                                   InnerBlockDeclRefs,
-                                  InnerBlockValueDecls);
+                                  InnerContexts);
 
     }
   // Handle specific things.
   if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(S))
     if (!isa<FunctionDecl>(CDRE->getDecl()) &&
-        !isa<ParmVarDecl>(CDRE->getDecl()) &&
-        !InnerBlockValueDecls.count(CDRE->getDecl())) {
-      InnerBlockValueDecls.insert(CDRE->getDecl());
+        !InnerContexts.count(CDRE->getDecl()->getDeclContext()))
       InnerBlockDeclRefs.push_back(CDRE);
-    }
+  
   return;
 }
 
@@ -5166,10 +5174,11 @@
     }
 
   if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
-    llvm::SmallPtrSet<ValueDecl *, 8> InnerBlockValueDecls;
     llvm::SmallVector<BlockDeclRefExpr *, 8> InnerBlockDeclRefs;
+    llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
+    InnerContexts.insert(BE->getBlockDecl());
     GetInnerBlockDeclRefExprs(BE->getBody(),
-                              InnerBlockDeclRefs, InnerBlockValueDecls);
+                              InnerBlockDeclRefs, InnerContexts);
     // Rewrite the block body in place.
     RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
 

Added: cfe/trunk/test/Rewriter/rewrite-nested-blocks-1.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/rewrite-nested-blocks-1.mm?rev=97520&view=auto
==============================================================================
--- cfe/trunk/test/Rewriter/rewrite-nested-blocks-1.mm (added)
+++ cfe/trunk/test/Rewriter/rewrite-nested-blocks-1.mm Mon Mar  1 17:36:21 2010
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// radar 7696893
+
+void *sel_registerName(const char *);
+
+void f(void (^block)(void));
+void f2(id);
+void f3(int);
+char f4(id, id);
+
+ at interface Baz
+- (void)b:(void (^)(void))block;
+ at end
+
+ at interface Bar
+ at end
+
+ at interface Foo {
+	int _x;
+}
+ at end
+
+ at implementation Foo
+- (void)method:(Bar *)up {
+    Baz *down;
+	int at;
+    id cq;
+    __block char didit = 'a';
+    __block char upIsFinished = 'b';
+    f(^{
+            id old_cq;
+			f2(cq);
+            [down b:^{
+                    [down b:^{
+                            f(^{
+                                    didit = f4(up, down);
+									upIsFinished = 'c';
+                                    self->_x++;
+                                });
+                        }];
+                }];
+				f2(old_cq);
+			f3(at);
+    });
+}
+ at end





More information about the cfe-commits mailing list