1// RUN: %clang_cc1 -no-opaque-pointers -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -fblocks -Wno-strict-prototypes -o - %s | FileCheck %s
2
3// CHECK: %[[STRUCT_BLOCK_DESCRIPTOR:.*]] = type { i32, i32 }
4
5// Check that there is only one capture (20o) in the copy/dispose function
6// names.
7
8// CHECK: @[[BLOCK_DESCRIPTOR0:.*]] = linkonce_odr hidden unnamed_addr constant { i32, i32, i8*, i8*, i8*, i32 } { i32 0, i32 28, i8* bitcast (void (i8*, i8*)* @__copy_helper_block_4_20o to i8*), i8* bitcast (void (i8*)* @__destroy_helper_block_4_20o to i8*), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @{{.*}}, i32 0, i32 0), i32 512 },
9
10void (^gb0)(void);
11
12// test1.  All of this is somehow testing rdar://6676764
13struct S {
14  void (^F)(struct S*);
15} P;
16
17
18@interface T
19  - (int)foo: (T* (^)(T*)) x;
20@end
21
22void foo(T *P) {
23 [P foo: 0];
24}
25
26@interface A
27-(void) im0;
28@end
29
30// CHECK: define internal i32 @"__8-[A im0]_block_invoke"(
31@implementation A
32-(void) im0 {
33  (void) ^{ return 1; }();
34}
35@end
36
37@interface B : A @end
38@implementation B
39-(void) im1 {
40  ^(void) { [self im0]; }();
41}
42-(void) im2 {
43  ^{ [super im0]; }();
44}
45-(void) im3 {
46  ^{ ^{[super im0];}(); }();
47}
48@end
49
50// rdar://problem/9006315
51// In-depth test for the initialization of a __weak __block variable.
52@interface Test2 -(void) destroy; @end
53void test2(Test2 *x) {
54  extern void test2_helper(void (^)(void));
55  // CHECK-LABEL:    define{{.*}} void @test2(
56  // CHECK:      [[X:%.*]] = alloca [[TEST2:%.*]]*,
57  // CHECK-NEXT: [[WEAKX:%.*]] = alloca [[WEAK_T:%.*]],
58  // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
59  // CHECK-NEXT: store [[TEST2]]*
60
61  // isa=1 for weak byrefs.
62  // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[WEAK_T]], [[WEAK_T]]* [[WEAKX]], i32 0, i32 0
63  // CHECK-NEXT: store i8* inttoptr (i32 1 to i8*), i8** [[T0]]
64
65  // Forwarding.
66  // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[WEAK_T]], [[WEAK_T]]* [[WEAKX]], i32 0, i32 1
67  // CHECK-NEXT: store [[WEAK_T]]* [[WEAKX]], [[WEAK_T]]** [[T1]]
68
69  // Flags.  This is just BLOCK_HAS_COPY_DISPOSE BLOCK_BYREF_LAYOUT_UNRETAINED
70  // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[WEAK_T]], [[WEAK_T]]* [[WEAKX]], i32 0, i32 2
71  // CHECK-NEXT: store i32 1375731712, i32* [[T2]]
72
73  // Size.
74  // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[WEAK_T]], [[WEAK_T]]* [[WEAKX]], i32 0, i32 3
75  // CHECK-NEXT: store i32 28, i32* [[T3]]
76
77  // Copy and dispose helpers.
78  // CHECK-NEXT: [[T4:%.*]] = getelementptr inbounds [[WEAK_T]], [[WEAK_T]]* [[WEAKX]], i32 0, i32 4
79  // CHECK-NEXT: store i8* bitcast (void (i8*, i8*)* @__Block_byref_object_copy_{{.*}} to i8*), i8** [[T4]]
80  // CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds [[WEAK_T]], [[WEAK_T]]* [[WEAKX]], i32 0, i32 5
81  // CHECK-NEXT: store i8* bitcast (void (i8*)* @__Block_byref_object_dispose_{{.*}} to i8*), i8** [[T5]]
82
83  // Actually capture the value.
84  // CHECK-NEXT: [[T6:%.*]] = getelementptr inbounds [[WEAK_T]], [[WEAK_T]]* [[WEAKX]], i32 0, i32 6
85  // CHECK-NEXT: [[CAPTURE:%.*]] = load [[TEST2]]*, [[TEST2]]** [[X]]
86  // CHECK-NEXT: store [[TEST2]]* [[CAPTURE]], [[TEST2]]** [[T6]]
87
88  // Then we initialize the block, blah blah blah.
89  // CHECK:      call void @test2_helper(
90
91  // Finally, kill the variable with BLOCK_FIELD_IS_BYREF.
92  // CHECK:      [[T0:%.*]] = bitcast [[WEAK_T]]* [[WEAKX]] to i8*
93  // CHECK:      call void @_Block_object_dispose(i8* [[T0]], i32 24)
94
95  __attribute__((objc_gc(weak))) __block Test2 *weakX = x;
96  test2_helper(^{ [weakX destroy]; });
97}
98
99// rdar://problem/9124263
100// In the test above, check that the use in the invocation function
101// doesn't require a read barrier.
102// CHECK-LABEL:    define internal void @__test2_block_invoke
103// CHECK:      [[BLOCK:%.*]] = bitcast i8* {{%.*}} to [[BLOCK_T]]*
104// CHECK-NOT:  bitcast
105// CHECK:      [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
106// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]]
107// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[WEAK_T]]{{.*}}*
108// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[WEAK_T]]{{.*}}, [[WEAK_T]]{{.*}}* [[T2]], i32 0, i32 1
109// CHECK-NEXT: [[T4:%.*]] = load [[WEAK_T]]{{.*}}*, [[WEAK_T]]{{.*}}** [[T3]]
110// CHECK-NEXT: [[WEAKX:%.*]] = getelementptr inbounds [[WEAK_T]]{{.*}}, [[WEAK_T]]{{.*}}* [[T4]], i32 0, i32 6
111// CHECK-NEXT: [[T0:%.*]] = load [[TEST2]]*, [[TEST2]]** [[WEAKX]], align 4
112
113// rdar://problem/12722954
114// Make sure that ... is appropriately positioned in a block call.
115void test3(void (^block)(int, ...)) {
116  block(0, 1, 2, 3);
117}
118// CHECK-LABEL:    define{{.*}} void @test3(
119// CHECK:      [[BLOCK:%.*]] = alloca void (i32, ...)*, align 4
120// CHECK-NEXT: store void (i32, ...)*
121// CHECK-NEXT: [[T0:%.*]] = load void (i32, ...)*, void (i32, ...)** [[BLOCK]], align 4
122// CHECK-NEXT: [[T1:%.*]] = bitcast void (i32, ...)* [[T0]] to [[BLOCK_T:%.*]]*
123// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[T1]], i32 0, i32 3
124// CHECK-NEXT: [[T3:%.*]] = bitcast [[BLOCK_T]]* [[T1]] to i8*
125// CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T2]]
126// CHECK-NEXT: [[T5:%.*]] = bitcast i8* [[T4]] to void (i8*, i32, ...)*
127// CHECK-NEXT: call void (i8*, i32, ...) [[T5]](i8* noundef [[T3]], i32 noundef 0, i32 noundef 1, i32 noundef 2, i32 noundef 3)
128// CHECK-NEXT: ret void
129
130void test4(void (^block)()) {
131  block(0, 1, 2, 3);
132}
133// CHECK-LABEL:    define{{.*}} void @test4(
134// CHECK:      [[BLOCK:%.*]] = alloca void (...)*, align 4
135// CHECK-NEXT: store void (...)*
136// CHECK-NEXT: [[T0:%.*]] = load void (...)*, void (...)** [[BLOCK]], align 4
137// CHECK-NEXT: [[T1:%.*]] = bitcast void (...)* [[T0]] to [[BLOCK_T:%.*]]*
138// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[T1]], i32 0, i32 3
139// CHECK-NEXT: [[T3:%.*]] = bitcast [[BLOCK_T]]* [[T1]] to i8*
140// CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T2]]
141// CHECK-NEXT: [[T5:%.*]] = bitcast i8* [[T4]] to void (i8*, i32, i32, i32, i32)*
142// CHECK-NEXT: call void [[T5]](i8* noundef [[T3]], i32 noundef 0, i32 noundef 1, i32 noundef 2, i32 noundef 3)
143// CHECK-NEXT: ret void
144
145void test5(A *a) {
146  __unsafe_unretained A *t = a;
147  gb0 = ^{ (void)a; (void)t; };
148}
149
150// CHECK-LABEL: define void @test5(
151// CHECK: %[[V0:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, {{.*}}*, {{.*}}* }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, {{.*}}*, {{.*}}* }>* %{{.*}}, i32 0, i32 4
152// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i32, i32, i8*, i8*, i8*, i32 }* @[[BLOCK_DESCRIPTOR0]] to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[V0]],
153
154void test6(id a, long long b) {
155  void (^block)() = ^{ (void)b; (void)a; };
156}
157
158// Check that the block literal doesn't have two fields for capture 'a'.
159
160// CHECK-LABEL: define void @test6(
161// CHECK: alloca <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i64 }>,
162