[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / clang / test / CodeGenCXX / blocks.cpp
blobeaab1890dfc49ba53298b49036a811ec1fa2ff58
1 // RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
3 // CHECK: @[[BLOCK_DESCRIPTOR22:.*]] = internal constant { i64, i64, ptr, ptr, ptr, ptr } { i64 0, i64 36, ptr @__copy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE, ptr @__destroy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE, ptr @{{.*}}, ptr null }, align 8
5 namespace test0 {
6 // CHECK-LABEL: define{{.*}} void @_ZN5test04testEi(
7 // CHECK: define internal void @___ZN5test04testEi_block_invoke{{.*}}(
8 // CHECK: define internal void @___ZN5test04testEi_block_invoke_2{{.*}}(
9 void test(int x) {
10 ^{ ^{ (void) x; }; };
14 extern void (^out)();
16 namespace test1 {
17 // Capturing const objects doesn't require a local block.
18 // CHECK-LABEL: define{{.*}} void @_ZN5test15test1Ev()
19 // CHECK: store ptr @__block_literal_global{{.*}}, ptr @out
20 void test1() {
21 const int NumHorsemen = 4;
22 out = ^{ (void) NumHorsemen; };
25 // That applies to structs too...
26 // CHECK-LABEL: define{{.*}} void @_ZN5test15test2Ev()
27 // CHECK: store ptr @__block_literal_global{{.*}}, ptr @out
28 struct loc { double x, y; };
29 void test2() {
30 const loc target = { 5, 6 };
31 out = ^{ (void) target; };
34 // ...unless they have mutable fields...
35 // CHECK-LABEL: define{{.*}} void @_ZN5test15test3Ev()
36 // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
37 // CHECK: store ptr [[BLOCK]], ptr @out
38 struct mut { mutable int x; };
39 void test3() {
40 const mut obj = { 5 };
41 out = ^{ (void) obj; };
44 // ...or non-trivial destructors...
45 // CHECK-LABEL: define{{.*}} void @_ZN5test15test4Ev()
46 // CHECK: [[OBJ:%.*]] = alloca
47 // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
48 // CHECK: store ptr [[BLOCK]], ptr @out
49 struct scope { int x; ~scope(); };
50 void test4() {
51 const scope obj = { 5 };
52 out = ^{ (void) obj; };
55 // ...or non-trivial copy constructors, but it's not clear how to do
56 // that and still have a constant initializer in '03.
59 namespace test2 {
60 struct A {
61 A();
62 A(const A &);
63 ~A();
66 struct B {
67 B();
68 B(const B &);
69 ~B();
72 // CHECK-LABEL: define{{.*}} void @_ZN5test24testEv()
73 void test() {
74 __block A a;
75 __block B b;
76 ^{ (void)a; (void)b; };
79 // CHECK-LABEL: define internal void @__Block_byref_object_copy
80 // CHECK: call void @_ZN5test21AC1ERKS0_(
82 // CHECK-LABEL: define internal void @__Block_byref_object_dispose
83 // CHECK: call void @_ZN5test21AD1Ev(
85 // CHECK-LABEL: define internal void @__Block_byref_object_copy
86 // CHECK: call void @_ZN5test21BC1ERKS0_(
88 // CHECK-LABEL: define internal void @__Block_byref_object_dispose
89 // CHECK: call void @_ZN5test21BD1Ev(
92 // Make sure we mark destructors for parameters captured in blocks.
93 namespace test3 {
94 struct A {
95 A(const A&);
96 ~A();
99 struct B : A {
102 void test(B b) {
103 extern void consume(void(^)());
104 consume(^{ (void) b; });
108 namespace test4 {
109 struct A {
110 A();
111 ~A();
114 void foo(A a);
116 void test() {
117 extern void consume(void(^)());
118 consume(^{ return foo(A()); });
120 // CHECK-LABEL: define{{.*}} void @_ZN5test44testEv()
121 // CHECK-LABEL: define internal void @___ZN5test44testEv_block_invoke
122 // CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1
123 // CHECK-NEXT: store ptr [[BLOCKDESC:%.*]], ptr {{.*}}, align 8
124 // CHECK: call void @_ZN5test41AC1Ev(ptr {{[^,]*}} [[TMP]])
125 // CHECK-NEXT: call void @_ZN5test43fooENS_1AE(ptr noundef [[TMP]])
126 // CHECK-NEXT: call void @_ZN5test41AD1Ev(ptr {{[^,]*}} [[TMP]])
127 // CHECK-NEXT: ret void
130 namespace test5 {
131 struct A {
132 unsigned afield;
133 A();
134 A(const A&);
135 ~A();
136 void foo() const;
139 void doWithBlock(void(^)());
141 void test(bool cond) {
142 A x;
143 void (^b)() = (cond ? ^{ x.foo(); } : (void(^)()) 0);
144 doWithBlock(b);
147 // CHECK-LABEL: define{{.*}} void @_ZN5test54testEb(
148 // CHECK: [[COND:%.*]] = alloca i8
149 // CHECK-NEXT: [[X:%.*]] = alloca [[A:%.*]], align 4
150 // CHECK-NEXT: [[B:%.*]] = alloca ptr, align 8
151 // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:.*]], align 8
152 // CHECK-NEXT: [[CLEANUP_ACTIVE:%.*]] = alloca i1
153 // CHECK-NEXT: [[COND_CLEANUP_SAVE:%.*]] = alloca ptr, align 8
154 // CHECK-NEXT: [[T0:%.*]] = zext i1
155 // CHECK-NEXT: store i8 [[T0]], ptr [[COND]], align 1
156 // CHECK-NEXT: call void @_ZN5test51AC1Ev(ptr {{[^,]*}} [[X]])
157 // CHECK-NEXT: [[T0:%.*]] = load i8, ptr [[COND]], align 1
158 // CHECK-NEXT: [[T1:%.*]] = trunc i8 [[T0]] to i1
159 // CHECK-NEXT: store i1 false, ptr [[CLEANUP_ACTIVE]]
160 // CHECK-NEXT: br i1 [[T1]],
162 // CHECK-NOT: br
163 // CHECK: [[CAPTURE:%.*]] = getelementptr inbounds [[BLOCK_T]], ptr [[BLOCK]], i32 0, i32 5
164 // CHECK-NEXT: call void @_ZN5test51AC1ERKS0_(ptr {{[^,]*}} [[CAPTURE]], ptr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[X]])
165 // CHECK-NEXT: store i1 true, ptr [[CLEANUP_ACTIVE]]
166 // CHECK-NEXT: store ptr [[CAPTURE]], ptr [[COND_CLEANUP_SAVE]], align 8
167 // CHECK-NEXT: br label
168 // CHECK: br label
169 // CHECK: phi
170 // CHECK-NEXT: store
171 // CHECK-NEXT: load
172 // CHECK-NEXT: call void @_ZN5test511doWithBlockEU13block_pointerFvvE(
173 // CHECK-NEXT: [[T0:%.*]] = load i1, ptr [[CLEANUP_ACTIVE]]
174 // CHECK-NEXT: br i1 [[T0]]
175 // CHECK: [[T3:%.*]] = load ptr, ptr [[COND_CLEANUP_SAVE]], align 8
176 // CHECK-NEXT: call void @_ZN5test51AD1Ev(ptr {{[^,]*}} [[T3]])
177 // CHECK-NEXT: br label
178 // CHECK: call void @_ZN5test51AD1Ev(ptr {{[^,]*}} [[X]])
179 // CHECK-NEXT: ret void
182 namespace test6 {
183 struct A {
184 A();
185 ~A();
188 void foo(const A &, void (^)());
189 void bar();
191 void test() {
192 // Make sure that the temporary cleanup isn't somehow captured
193 // within the block.
194 foo(A(), ^{ bar(); });
195 bar();
198 // CHECK-LABEL: define{{.*}} void @_ZN5test64testEv()
199 // CHECK: [[TEMP:%.*]] = alloca [[A:%.*]], align 1
200 // CHECK-NEXT: call void @_ZN5test61AC1Ev(ptr {{[^,]*}} [[TEMP]])
201 // CHECK-NEXT: call void @_ZN5test63fooERKNS_1AEU13block_pointerFvvE(
202 // CHECK-NEXT: call void @_ZN5test61AD1Ev(ptr {{[^,]*}} [[TEMP]])
203 // CHECK-NEXT: call void @_ZN5test63barEv()
204 // CHECK-NEXT: ret void
207 namespace test7 {
208 int f() {
209 static int n;
210 int *const p = &n;
211 return ^{ return *p; }();
215 namespace test8 {
216 // failure to capture this after skipping rebuild of the 'this' pointer.
217 struct X {
218 int x;
220 template<typename T>
221 int foo() {
222 return ^ { return x; }();
226 template int X::foo<int>();
229 namespace test9 {
230 struct B {
231 void *p;
232 B();
233 B(const B&);
234 ~B();
237 void use_block(void (^)());
238 void use_block_2(void (^)(), const B &a);
240 // Ensuring that creating a non-trivial capture copy expression
241 // doesn't end up stealing the block registration for the block we
242 // just parsed. That block must have captures or else it won't
243 // force registration. Must occur within a block for some reason.
244 void test() {
245 B x;
246 use_block(^{
247 int y;
248 use_block_2(^{ (void)y; }, x);
253 namespace test10 {
254 // Check that 'v' is included in the copy helper function name to indicate
255 // the constructor taking a volatile parameter is called to copy the captured
256 // object.
258 // CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block_8_32c16_ZTSVN6test101BE(
259 // CHECK: call void @_ZN6test101BC1ERVKS0_(
260 // CHECK-LABEL: define linkonce_odr hidden void @__destroy_helper_block_8_32c16_ZTSVN6test101BE(
261 // CHECK: call void @_ZN6test101BD1Ev(
263 struct B {
264 int a;
265 B();
266 B(const B &);
267 B(const volatile B &);
268 ~B();
271 void test() {
272 volatile B x;
273 ^{ (void)x; };
277 // Copy/dispose helper functions and block descriptors of blocks that capture
278 // objects that are non-external and non-trivial have internal linkage.
280 // CHECK-LABEL: define internal void @_ZN12_GLOBAL__N_14testEv(
281 // CHECK: store ptr @[[BLOCK_DESCRIPTOR22]], ptr %{{.*}}, align 8
283 // CHECK-LABEL: define internal void @__copy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE(
284 // CHECK-LABEL: define internal void @__destroy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE(
286 namespace {
287 struct B {
288 int a;
289 B();
290 B(const B &);
291 ~B();
294 void test() {
295 B x;
296 ^{ (void)x; };
300 void callTest() {
301 test();