1 // RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
2 
3 namespace 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 }
11 
12 extern void (^out)();
13 
14 namespace 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 }
58 
59 namespace 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 }
90