1
- // RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm -std=c++11 -fblocks -fobjc-arc -o - %s | FileCheck %s
1
+ // RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm -std=c++14 -fblocks -fobjc-arc -o - %s | FileCheck %s
2
2
3
3
// CHECK: %[[STRUCT_BLOCK_DESCRIPTOR:.*]] = type { i64, i64 }
4
+ // CHECK: %[[S:.*]] = type { i32 }
5
+ // CHECK: %[[CLASS_ANON_2:.*]] = type { %[[S]]* }
6
+ // CHECK: %[[CLASS_ANON_3:.*]] = type { %[[S]] }
4
7
5
8
// CHECK: %[[BLOCK_CAPTURED0:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32*, i32* }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32*, i32* }>* %[[BLOCK:.*]], i32 0, i32 5
6
9
// CHECK: %[[V0:.*]] = getelementptr inbounds %[[LAMBDA_CLASS:.*]], %[[LAMBDA_CLASS]]* %[[THIS:.*]], i32 0, i32 0
@@ -33,7 +36,7 @@ void block_in_lambda(int &s1, int &s2) {
33
36
// reference.
34
37
35
38
// CHECK-LABEL: define void @_ZN18CaptureByReference5test0Ev(
36
- // CHECK-LABEL: define internal void @"_ZZN18CaptureByReference5test0EvENK3$_1clEv "(
39
+ // CHECK-LABEL: define internal void @"_ZZN18CaptureByReference5test0EvENK3$_3clEv "(
37
40
// CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8** }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8** }>* %{{.*}}, i32 0, i32 4
38
41
// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i64 }* @"__block_descriptor_40_e5_v8\01?0ls32l8" to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8
39
42
@@ -46,10 +49,60 @@ void test0() {
46
49
// is captured by reference.
47
50
48
51
// CHECK-LABEL: define void @_ZN18CaptureByReference5test1Ev(
49
- // CHECK-LABEL: define internal void @"_ZZN18CaptureByReference5test1EvENK3$_2clEv "(
52
+ // CHECK-LABEL: define internal void @"_ZZN18CaptureByReference5test1EvENK3$_4clEv "(
50
53
// CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>* %{{.*}}, i32 0, i32 4
51
54
// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8*, i8*, i64 }* @"__block_descriptor_56_8_32s40s_e5_v8\01?0l" to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8
52
55
56
+ void test1 () {
57
+ id a = getObj (), b = getObj (), c = getObj ();
58
+ [&a, b, c]{ ^{ a = 0 ; use (b); use (c); }(); }();
59
+ }
60
+
61
+ struct S {
62
+ int val () const ;
63
+ int a;
64
+ S ();
65
+ S (const S&);
66
+ S &operator =(const S&);
67
+ S (S&&);
68
+ S &operator =(S&&);
69
+ };
70
+
71
+ S getS ();
72
+
73
+ // CHECK: define internal i32 @"_ZZN18CaptureByReference5test2EvENK3$_1clIiEEDaT_"(%[[CLASS_ANON_2]]* %{{.*}}, i32 %{{.*}})
74
+ // CHECK: %[[BLOCK:.*]] = alloca <{ i8*, i32, i32, i8*, %{{.*}}, %[[S]]* }>, align 8
75
+ // CHECK: %[[BLOCK_CAPTURED:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %{{.*}}, %[[S]]* }>, <{ i8*, i32, i32, i8*, %{{.*}}, %[[S]]* }>* %[[BLOCK]], i32 0, i32 5
76
+ // CHECK: %[[V0:.*]] = getelementptr inbounds %[[CLASS_ANON_2]], %[[CLASS_ANON_2]]* %{{.*}}, i32 0, i32 0
77
+ // CHECK: %[[V1:.*]] = load %[[S]]*, %[[S]]** %[[V0]], align 8
78
+ // CHECK: store %[[S]]* %[[V1]], %[[S]]** %[[BLOCK_CAPTURED]], align 8
79
+
80
+ int test2 () {
81
+ S s;
82
+ auto fn = [&](const auto a){
83
+ return ^{
84
+ return s.val ();
85
+ }();
86
+ };
87
+ return fn (123 );
88
+ }
89
+
90
+ // CHECK: define internal i32 @"_ZZN18CaptureByReference5test3EvENK3$_2clIiEEDaT_"(%[[CLASS_ANON_3]]* %{{.*}}, i32 %{{.*}})
91
+ // CHECK: %[[BLOCK:.*]] = alloca <{ i8*, i32, i32, i8*, %{{.*}}*, %[[S]] }>, align 8
92
+ // CHECK: %[[BLOCK_CAPTURED:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %{{.*}}*, %[[S]] }>, <{ i8*, i32, i32, i8*, %{{.*}}*, %[[S]] }>* %[[BLOCK]], i32 0, i32 5
93
+ // CHECK: %[[V0:.*]] = getelementptr inbounds %[[CLASS_ANON_3]], %[[CLASS_ANON_3]]* %{{.*}}, i32 0, i32 0
94
+ // CHECK: call void @_ZN18CaptureByReference1SC1ERKS0_(%[[S]]* %[[BLOCK_CAPTURED]], %[[S]]* {{.*}} %[[V0]])
95
+
96
+ int test3 () {
97
+ const S &s = getS ();
98
+ auto fn = [=](const auto a){
99
+ return ^{
100
+ return s.val ();
101
+ }();
102
+ };
103
+ return fn (123 );
104
+ }
105
+
53
106
// CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block_8_32s40s(
54
107
// CHECK-NOT: call void @llvm.objc.storeStrong(
55
108
// CHECK: %[[V4:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8*, i8** }>* %{{.*}}, i32 0, i32 5
@@ -74,9 +127,4 @@ void test0() {
74
127
// CHECK-NOT: call void @llvm.objc.storeStrong(
75
128
// CHECK: ret void
76
129
77
- void test1 () {
78
- id a = getObj (), b = getObj (), c = getObj ();
79
- [&a, b, c]{ ^{ a = 0 ; use (b); use (c); }(); }();
80
- }
81
-
82
130
}
0 commit comments