objective-C blocks: Provide layout map for byref
variables captured in a block. // rdar://12184410



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167931 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CodeGenObjC/arc-blocks.m b/test/CodeGenObjC/arc-blocks.m
index e776517..63bb7a3 100644
--- a/test/CodeGenObjC/arc-blocks.m
+++ b/test/CodeGenObjC/arc-blocks.m
@@ -111,8 +111,8 @@
   // CHECK:      [[VAR:%.*]] = alloca [[BYREF_T:%.*]],
   // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
   // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]]* [[VAR]], i32 0, i32 2
-  // 0x02000000 - has copy/dispose helpers
-  // CHECK-NEXT: store i32 33554432, i32* [[T0]]
+  // 0x02000000 - has copy/dispose helpers strong
+  // CHECK-NEXT: store i32 838860800, i32* [[T0]]
   // CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]]* [[VAR]], i32 0, i32 6
   // CHECK-NEXT: [[T0:%.*]] = call i8* @test4_source()
   // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
@@ -190,8 +190,8 @@
   // CHECK:      [[VAR:%.*]] = alloca [[BYREF_T:%.*]],
   // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
   // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]]* [[VAR]], i32 0, i32 2
-  // 0x02000000 - has copy/dispose helpers
-  // CHECK-NEXT: store i32 33554432, i32* [[T0]]
+  // 0x02000000 - has copy/dispose helpers weak
+  // CHECK-NEXT: store i32 1107296256, i32* [[T0]]
   // CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]]* [[VAR]], i32 0, i32 6
   // CHECK-NEXT: [[T0:%.*]] = call i8* @test6_source()
   // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
diff --git a/test/CodeGenObjC/block-byref-variable-layout.m b/test/CodeGenObjC/block-byref-variable-layout.m
new file mode 100644
index 0000000..1e8bcbc
--- /dev/null
+++ b/test/CodeGenObjC/block-byref-variable-layout.m
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple x86_64-apple-darwin -O0 -emit-llvm %s -o - | FileCheck %s
+
+int main() {
+  __block __weak id wid;
+  __block long XXX;
+  __block id ID;
+  __block struct S {
+     int iS;
+     double iD;
+     void *pv;
+     __unsafe_unretained id unsunr;
+  } import;
+  void (^c)() = ^{
+// Inline flag for BYREF variable layout (1107296256): BLOCK_BYREF_HAS_COPY_DISPOSE BLOCK_BYREF_LAYOUT_WEAK
+// CHECK: store i32 1107296256, i32* [[T0:%.*]]
+  wid = 0;
+
+// Inline flag for BYREF variable layout (536870912): BLOCK_BYREF_LAYOUT_NON_OBJECT
+// CHECK: store i32 536870912, i32* [[T1:%.*]]
+    XXX = 12345;
+
+// Inline flag for BYREF variable layout (838860800): BLOCK_BYREF_HAS_COPY_DISPOSE BLOCK_BYREF_LAYOUT_STRONG
+// CHECK: store i32 838860800, i32* [[T2:%.*]]
+    ID = 0;
+
+// Inline flag for BYREF variable layout (268435456): BLOCK_BYREF_LAYOUT_EXTENDED
+// BYREF variable layout: BL_NON_OBJECT_WORD:3, BL_UNRETAINED:1, BL_OPERATOR:0
+// CHECK: store i32 268435456, i32* [[T3:%.*]]
+    import.iD = 3.14;
+
+  };
+  c();
+}
diff --git a/test/CodeGenObjC/blocks.m b/test/CodeGenObjC/blocks.m
index 6c85da9..830f377 100644
--- a/test/CodeGenObjC/blocks.m
+++ b/test/CodeGenObjC/blocks.m
@@ -57,9 +57,9 @@
   // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[WEAK_T]]* [[WEAKX]], i32 0, i32 1
   // CHECK-NEXT: store [[WEAK_T]]* [[WEAKX]], [[WEAK_T]]** [[T1]]
 
-  // Flags.  This is just BLOCK_HAS_COPY_DISPOSE.
+  // Flags.  This is just BLOCK_HAS_COPY_DISPOSE BLOCK_BYREF_LAYOUT_UNRETAINED
   // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[WEAK_T]]* [[WEAKX]], i32 0, i32 2
-  // CHECK-NEXT: store i32 33554432, i32* [[T2]]
+  // CHECK-NEXT: store i32 1375731712, i32* [[T2]]
 
   // Size.
   // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[WEAK_T]]* [[WEAKX]], i32 0, i32 3
diff --git a/test/CodeGenObjC/mrr-captured-block-var-inlined-layout.m b/test/CodeGenObjC/mrr-captured-block-var-inlined-layout.m
index f1e02dd..0be4553 100644
--- a/test/CodeGenObjC/mrr-captured-block-var-inlined-layout.m
+++ b/test/CodeGenObjC/mrr-captured-block-var-inlined-layout.m
@@ -16,25 +16,28 @@
     __block id byref_bab = (id)0;
     __block id bl_var1;
 
-// block variable layout: BL_UNRETAINED:1, BL_OPERATOR:0
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [2 x i8] c"`\00"
-// CHECK-i386: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [2 x i8] c"`\00"
+// block variable layout: BL_STRONG:1, BL_OPERATOR:0
+// Inline instruction for block variable layout: 0x0100
+// CHECK: internal constant{{.*}}i64 256
+// CHECK-i386: internal constant{{.*}}i32 256
     void (^b)() = ^{
         x(bar);
     };    
 
-// block variable layout: BL_UNRETAINED:2, BL_BYREF:1, BL_OPERATOR:0
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"a@\00"
-// CHECK-i386: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"a@\00"
+// block variable layout: BL_STRONG:2, BL_BYREF:1, BL_OPERATOR:0
+// Inline instruction for block variable layout: 0x0210
+// CHECK: internal constant{{.*}}i64 528
+// CHECK-i386: internal constant{{.*}}i32 528
     void (^c)() = ^{
         x(bar);
         x(baz);
         byref_int = 1;
     };    
 
-// block variable layout: BL_UNRETAINED:2, BL_BYREF:3, BL_OPERATOR:0
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"aB\00
-// CHECK-i386: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"aB\00
+// block variable layout: BL_STRONG:2, BL_BYREF:3, BL_OPERATOR:0
+// Inline instruction for block variable layout: 0x0230
+// CHECK: internal constant{{.*}}i64 560
+// CHECK-i386: internal constant{{.*}}i32 560
     void (^d)() = ^{
         x(bar);
         x(baz);
@@ -43,9 +46,10 @@
         byref_bab = 0;
     };
 
-// block variable layout: BL_UNRETAINED:2, BL_BYREF:3, BL_OPERATOR:0
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"aB\00"
-// CHECK-i386: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"aB\00"
+// block variable layout: BL_STRONG:2, BL_BYREF:3, BL_OPERATOR:0
+// Inline instruction for block variable layout: 0x0230
+// CHECK: internal constant{{.*}}i64 560
+// CHECK-i386: internal constant{{.*}}i32 560
     id (^e)() = ^{
         x(bar);
         x(baz);
@@ -56,8 +60,8 @@
     };
 
 // Inline instruction for block variable layout: 0x020
-// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 32 }
-// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 32 }
+// CHECK: internal constant{{.*}}i64 32
+// CHECK-i386: internal constant{{.*}}i32 32
     void (^ii)() = ^{
        byref_int = 1;
        byref_bab = 0;