]> granicus.if.org Git - clang/commitdiff
Initialize block's imported variable(s) in
authorFariborz Jahanian <fjahanian@apple.com>
Wed, 28 Jul 2010 23:27:30 +0000 (23:27 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Wed, 28 Jul 2010 23:27:30 +0000 (23:27 +0000)
block's synthesized constructor initalizer list.
Fixes radar 8240371.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109698 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Rewrite/RewriteObjC.cpp
test/Rewriter/rewrite-block-consts.mm [new file with mode: 0644]

index 7c88d49c7b9624ff85c381d2fee94a835b2af35d..9c52aa5f52c52769884bbd64a1f824627f4acaf2 100644 (file)
@@ -4309,37 +4309,48 @@ std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag,
       S += FieldName + "; // by ref\n";
     }
     // Finish writing the constructor.
-    Constructor += ", int flags=0) {\n";
-    if (GlobalVarDecl)
-      Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
-    else
-      Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
-    Constructor += "    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
-
-    Constructor += "    Desc = desc;\n";
-
+    Constructor += ", int flags=0)";
     // Initialize all "by copy" arguments.
+    bool firsTime = true;
     for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
          E = BlockByCopyDecls.end(); I != E; ++I) {
       std::string Name = (*I)->getNameAsString();
-      Constructor += "    ";
-      if (isTopLevelBlockPointerType((*I)->getType()))
-        Constructor += Name + " = (struct __block_impl *)_";
-      else
-        Constructor += Name + " = _";
-      Constructor += Name + ";\n";
+        if (firsTime) {
+          Constructor += " : ";
+          firsTime = false;
+        }
+        else
+          Constructor += ", ";
+        if (isTopLevelBlockPointerType((*I)->getType()))
+          Constructor += Name + "((struct __block_impl *)_" + Name + ")";
+        else
+          Constructor += Name + "(_" + Name + ")";
     }
     // Initialize all "by ref" arguments.
     for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
          E = BlockByRefDecls.end(); I != E; ++I) {
       std::string Name = (*I)->getNameAsString();
-      Constructor += "    ";
+      if (firsTime) {
+        Constructor += " : ";
+        firsTime = false;
+      }
+      else
+        Constructor += ", ";
       if (isTopLevelBlockPointerType((*I)->getType()))
-        Constructor += Name + " = (struct __block_impl *)_";
+        Constructor += Name + "((struct __block_impl *)_" 
+                        + Name + "->__forwarding)";
       else
-        Constructor += Name + " = _";
-      Constructor += Name + "->__forwarding;\n";
+        Constructor += Name + "(_" + Name + "->__forwarding)";
     }
+    
+    Constructor += " {\n";
+    if (GlobalVarDecl)
+      Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
+    else
+      Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
+    Constructor += "    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
+
+    Constructor += "    Desc = desc;\n";
   } else {
     // Finish writing the constructor.
     Constructor += ", int flags=0) {\n";
diff --git a/test/Rewriter/rewrite-block-consts.mm b/test/Rewriter/rewrite-block-consts.mm
new file mode 100644 (file)
index 0000000..c74873f
--- /dev/null
@@ -0,0 +1,19 @@
+// 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"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// rdar:// 8243071
+
+void x(int y) {}
+void f() {
+    const int bar = 3;
+    int baz = 4;
+    __block int bab = 4;
+    __block const int bas = 5;
+    void (^b)() = ^{
+        x(bar);
+        x(baz);
+       x(bab);
+       x(bas);
+       b();
+    };    
+    b();
+}