blob: d66debea2b9a21a47a8b5ea5335ed18f932ede26 [file] [log] [blame]
John McCall93be3f72011-02-07 18:37:40 +00001// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
2
3namespace test0 {
4 // CHECK: define void @_ZN5test04testEi(
5 // CHECK: define internal void @__test_block_invoke_{{.*}}(
6 // CHECK: define internal void @__block_global_{{.*}}(
7 void test(int x) {
8 ^{ ^{ (void) x; }; };
9 }
10}
John McCallb0a3ecb2011-02-08 03:07:00 +000011
12extern void (^out)();
13
14namespace test1 {
15 // Capturing const objects doesn't require a local block.
16 // CHECK: define void @_ZN5test15test1Ev()
17 // CHECK: store void ()* bitcast ({{.*}} @__block_literal_global{{.*}} to void ()*), void ()** @out
18 void test1() {
19 const int NumHorsemen = 4;
20 out = ^{ (void) NumHorsemen; };
21 }
22
23 // That applies to structs too...
24 // CHECK: define void @_ZN5test15test2Ev()
25 // CHECK: store void ()* bitcast ({{.*}} @__block_literal_global{{.*}} to void ()*), void ()** @out
26 struct loc { double x, y; };
27 void test2() {
28 const loc target = { 5, 6 };
29 out = ^{ (void) target; };
30 }
31
32 // ...unless they have mutable fields...
33 // CHECK: define void @_ZN5test15test3Ev()
34 // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:%.*]],
35 // CHECK: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
36 // CHECK: store void ()* [[T0]], void ()** @out
37 struct mut { mutable int x; };
38 void test3() {
39 const mut obj = { 5 };
40 out = ^{ (void) obj; };
41 }
42
43 // ...or non-trivial destructors...
44 // CHECK: define void @_ZN5test15test4Ev()
45 // CHECK: [[OBJ:%.*]] = alloca
46 // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:%.*]],
47 // CHECK: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
48 // CHECK: store void ()* [[T0]], void ()** @out
49 struct scope { int x; ~scope(); };
50 void test4() {
51 const scope obj = { 5 };
52 out = ^{ (void) obj; };
53 }
54
55 // ...or non-trivial copy constructors, but it's not clear how to do
56 // that and still have a constant initializer in '03.
57}
John McCallf9b056b2011-03-31 08:03:29 +000058
59namespace test2 {
60 struct A {
61 A();
62 A(const A &);
63 ~A();
64 };
65
66 struct B {
67 B();
68 B(const B &);
69 ~B();
70 };
71
72 // CHECK: define void @_ZN5test24testEv()
73 void test() {
74 __block A a;
75 __block B b;
76 }
77
78 // CHECK: define internal void @__Block_byref_object_copy
79 // CHECK: call void @_ZN5test21AC1ERKS0_(
80
81 // CHECK: define internal void @__Block_byref_object_dispose
82 // CHECK: call void @_ZN5test21AD1Ev(
83
84 // CHECK: define internal void @__Block_byref_object_copy
85 // CHECK: call void @_ZN5test21BC1ERKS0_(
86
87 // CHECK: define internal void @__Block_byref_object_dispose
88 // CHECK: call void @_ZN5test21BD1Ev(
89}