]> granicus.if.org Git - clang/commitdiff
Adding couple of Block API, a bug fix and
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 11 Nov 2010 00:11:38 +0000 (00:11 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 11 Nov 2010 00:11:38 +0000 (00:11 +0000)
a test change, all for blocks. wip.

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

lib/CodeGen/CGBlocks.cpp
lib/CodeGen/CGBlocks.h
lib/Sema/SemaExpr.cpp
test/CodeGenObjC/block-var-layout.m
test/CodeGenObjCXX/block-var-layout.mm [new file with mode: 0644]

index 44e0833daf560cc32dd003c4593d9fc7d3ad4ca8..33646871e087f0ace363210a414b0e01f1c689cc 100644 (file)
@@ -311,11 +311,10 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
       }
 
       const BlockDeclRefExpr *BDRE = cast<BlockDeclRefExpr>(E);
+      Note.RequiresCopying = BlockRequiresCopying(BDRE);
+      
       const ValueDecl *VD = BDRE->getDecl();
       QualType T = VD->getType();
-
-      Note.RequiresCopying = BlockRequiresCopying(T);
-
       if (BDRE->isByRef()) {
         Note.flag = BLOCK_FIELD_IS_BYREF;
         if (T.isObjCGCWeak())
@@ -563,7 +562,7 @@ void CodeGenFunction::AllocateBlockDecl(const BlockDeclRefExpr *E) {
   // Don't run the expensive check, unless we have to.
   if (!BlockHasCopyDispose)
     if (E->isByRef()
-        || BlockRequiresCopying(E->getType()))
+        || BlockRequiresCopying(E))
       BlockHasCopyDispose = true;
 
   const ValueDecl *D = cast<ValueDecl>(E->getDecl());
index 743e3c83be331b27155197769e7b8cb57c4080a4..ce721a46408f7bb81d67372cc3188a57179e16d9 100644 (file)
@@ -103,6 +103,9 @@ public:
 
   bool BlockRequiresCopying(QualType Ty)
     { return getContext().BlockRequiresCopying(Ty); }
+  bool BlockRequiresCopying(const BlockDeclRefExpr *E)
+  { return E->getCopyConstructorExpr() != 0 ||
+           getContext().BlockRequiresCopying(E->getType()); }
 };
 
 class BlockFunction : public BlockBase {
@@ -197,6 +200,9 @@ public:
 
   bool BlockRequiresCopying(QualType Ty)
     { return getContext().BlockRequiresCopying(Ty); }
+  bool BlockRequiresCopying(const BlockDeclRefExpr *E)
+  { return E->getCopyConstructorExpr() != 0 ||
+           getContext().BlockRequiresCopying(E->getType()); }
 };
 
 }  // end namespace CodeGen
index 790f8831d2dd24dbe6719bac1a47f7b381a6ceee..8da3846f691c6764287298735c829b6e7fe9125e 100644 (file)
@@ -1911,16 +1911,18 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
         Expr *E = new (Context) 
                     DeclRefExpr(const_cast<ValueDecl*>(BDRE->getDecl()), T,
                                           SourceLocation());
-      
-        ExprResult Res = PerformCopyInitialization(
+        if (T->getAs<RecordType>())
+          if (!T->isUnionType()) {
+            ExprResult Res = PerformCopyInitialization(
                           InitializedEntity::InitializeBlock(VD->getLocation(), 
                                                          T, false),
                                                          SourceLocation(),
                                                          Owned(E));
-        if (!Res.isInvalid()) {
-          Res = MaybeCreateCXXExprWithTemporaries(Res.get());
-          Expr *Init = Res.takeAs<Expr>();
-          BDRE->setCopyConstructorExpr(Init);
+            if (!Res.isInvalid()) {
+              Res = MaybeCreateCXXExprWithTemporaries(Res.get());
+              Expr *Init = Res.takeAs<Expr>();
+              BDRE->setCopyConstructorExpr(Init);
+            }
         }
       }
     }
index 7031224d06eff8de5274f99642ea1d290a4fa2ce..fa131f63bee5cb52782aea29fcc7b37ec66c32e4 100644 (file)
@@ -1,7 +1,5 @@
 // RUN: %clang_cc1 -fblocks -fobjc-gc -triple x86_64-apple-darwin -O0 -S %s -o %t-64.s
 // RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
-// RUN: %clang_cc1 -x objective-c++ -fblocks -fobjc-gc -triple x86_64-apple-darwin -O0 -S %s -o %t-64.s
-// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
 
 struct S {
     int i1;
diff --git a/test/CodeGenObjCXX/block-var-layout.mm b/test/CodeGenObjCXX/block-var-layout.mm
new file mode 100644 (file)
index 0000000..0a9a817
--- /dev/null
@@ -0,0 +1,150 @@
+// RUN: %clang_cc1 -x objective-c++ -fblocks -fobjc-gc -triple x86_64-apple-darwin -O0 -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
+
+
+struct S {
+    int i1;
+    id o1;
+    struct V {
+     int i2;
+     id o2;
+    } v1;
+    int i3;
+    id o3;
+};
+
+__weak id wid;
+void x(id y) {}
+void y(int a) {}
+
+void f() {
+    __block int byref_int = 0;
+    char ch = 'a';
+    char ch1 = 'b';
+    char ch2 = 'c';
+    short sh = 2;
+    const id bar = (id)0;
+    id baz = 0;
+    __strong void *strong_void_sta;
+    __block id byref_bab = (id)0;
+    __block void *bl_var1;
+    int i; double dob;
+
+    void (^b)() = ^{
+        byref_int = sh + ch+ch1+ch2 ;
+        x(bar);
+        x(baz);
+        x((id)strong_void_sta);
+        x(byref_bab);
+    };    
+    b();
+
+// Test 2
+    void (^c)() = ^{
+        byref_int = sh + ch+ch1+ch2 ;
+        x(bar);
+        x(baz);
+        x((id)strong_void_sta);
+        x(wid);
+        bl_var1 = 0;
+        x(byref_bab);
+    };    
+    c();
+
+// Test 3
+void (^d)() = ^{
+        byref_int = sh + ch+ch1+ch2 ;
+        x(bar);
+        x(baz);
+        x(wid);
+        bl_var1 = 0; 
+        y(i + dob);
+        x(byref_bab);
+    };    
+    d();
+
+// Test4
+    struct S s2;
+    void (^e)() = ^{
+        x(s2.o1);
+    };    
+    e();
+}
+
+// Test 5 (unions/structs and their nesting):
+void Test5() {
+struct S5 {
+    int i1;
+    id o1;
+    struct V {
+     int i2;
+     id o2;
+    } v1;
+    int i3;
+    union UI {
+        void * i1;
+        id o1;
+        int i3;
+        id o3;
+    }ui;
+};
+
+union U {
+        void * i1;
+        id o1;
+        int i3;
+        id o3;
+}ui;
+
+struct S5 s2;
+union U u2;
+void (^c)() = ^{
+    x(s2.ui.o1);
+    x(u2.o1);
+};
+c();
+
+}
+
+// rdar: //8417746
+void CFRelease(id);
+void notifyBlock(id dependentBlock) {
+ id singleObservationToken;
+ id token;
+ void (^b)();
+ void (^wrapperBlock)() = ^() {
+     CFRelease(singleObservationToken);
+     CFRelease(singleObservationToken);
+     CFRelease(token);
+     CFRelease(singleObservationToken);
+     b();
+    };
+ wrapperBlock();
+}
+
+void test_empty_block() {
+ void (^wrapperBlock)() = ^() {
+    };
+ wrapperBlock();
+}
+
+// CHECK-LP64: L_OBJC_CLASS_NAME_:
+// CHECK-LP64-NEXT: .asciz      "\0011\024"
+
+// CHECK-LP64: L_OBJC_CLASS_NAME_1:
+// CHECK-LP64-NEXT: .asciz   "\0011\025"
+
+// CHECK-LP64: L_OBJC_CLASS_NAME_6:
+// CHECK-LP64-NEXT: .asciz   "\0011\023!"
+
+// CHECK-LP64: L_OBJC_CLASS_NAME_11:
+// CHECK-LP64-NEXT: .asciz   "\001A\021\021"
+
+// CHECK-LP64: L_OBJC_CLASS_NAME_16:
+// CHECK-LP64-NEXT: .asciz   "\001A\021\022p"
+
+// CHECK-LP64: L_OBJC_CLASS_NAME_20:
+// CHECK-LP64-NEXT: .asciz   "\0013"
+
+// CHECK-LP64: L_OBJC_CLASS_NAME_24:
+// CHECK-LP64-NEXT: .asciz   "\001"