blob: 56fe4c61c9868d7e59b4fe2b44d2435b396bc87d [file] [log] [blame]
Stephen Hines651f13c2014-04-23 16:59:28 -07001// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm %s -o %t
Ben Langmuir524387a2013-05-09 19:17:11 +00002// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-1
3// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-2
4// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-3
5// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-4
Wei Pan0b6d8462013-05-10 14:15:18 +00006// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-5
7// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-6
Eli Friedman678eca42013-06-13 21:50:44 +00008// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-7
Ben Langmuir524387a2013-05-09 19:17:11 +00009
10struct Foo {
11 int x;
12 float y;
13 ~Foo() {}
14};
15
16struct TestClass {
17 int x;
18
19 TestClass() : x(0) {};
20 void MemberFunc() {
21 Foo f;
22 #pragma clang __debug captured
23 {
24 f.y = x;
25 }
26 }
27};
28
29void test1() {
30 TestClass c;
31 c.MemberFunc();
32 // CHECK-1: %[[Capture:struct\.anon[\.0-9]*]] = type { %struct.Foo*, %struct.TestClass* }
33
34 // CHECK-1: define {{.*}} void @_ZN9TestClass10MemberFuncEv
35 // CHECK-1: alloca %struct.anon
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -070036 // CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* %{{[^,]*}}, i32 0, i32 0
Ben Langmuir524387a2013-05-09 19:17:11 +000037 // CHECK-1: store %struct.Foo* %f, %struct.Foo**
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -070038 // CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* %{{[^,]*}}, i32 0, i32 1
Ben Langmuir524387a2013-05-09 19:17:11 +000039 // CHECK-1: call void @[[HelperName:[A-Za-z0-9_]+]](%[[Capture]]*
Ben Langmuircadfe422013-05-09 20:42:43 +000040 // CHECK-1: call {{.*}}FooD1Ev
Ben Langmuir524387a2013-05-09 19:17:11 +000041 // CHECK-1: ret
42}
43
44// CHECK-1: define internal void @[[HelperName]]
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -070045// CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* {{[^,]*}}, i32 0, i32 1
46// CHECK-1: getelementptr inbounds %struct.TestClass, %struct.TestClass* {{[^,]*}}, i32 0, i32 0
47// CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* {{[^,]*}}, i32 0, i32 0
Ben Langmuir524387a2013-05-09 19:17:11 +000048
49void test2(int x) {
50 int y = [&]() {
51 #pragma clang __debug captured
52 {
53 x++;
54 }
55 return x;
56 }();
57
Stephen Lin93ab6bf2013-08-15 06:47:53 +000058 // CHECK-2-LABEL: define void @_Z5test2i
Ben Langmuir52a46932013-05-13 14:45:11 +000059 // CHECK-2: call {{.*}} @[[Lambda:["$\w]+]]
Ben Langmuir524387a2013-05-09 19:17:11 +000060 //
Ben Langmuir52a46932013-05-13 14:45:11 +000061 // CHECK-2: define internal {{.*}} @[[Lambda]]
Ben Langmuir524387a2013-05-09 19:17:11 +000062 // CHECK-2: call void @[[HelperName:["$_A-Za-z0-9]+]](%[[Capture:.*]]*
63 //
64 // CHECK-2: define internal void @[[HelperName]]
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -070065 // CHECK-2: getelementptr inbounds %[[Capture]], %[[Capture]]*
66 // CHECK-2: load i32*, i32**
67 // CHECK-2: load i32, i32*
Ben Langmuir524387a2013-05-09 19:17:11 +000068}
69
70void test3(int x) {
71 #pragma clang __debug captured
72 {
73 x = [=]() { return x + 1; } ();
74 }
75
76 // CHECK-3: %[[Capture:struct\.anon[\.0-9]*]] = type { i32* }
77
Stephen Lin93ab6bf2013-08-15 06:47:53 +000078 // CHECK-3-LABEL: define void @_Z5test3i
Ben Langmuir524387a2013-05-09 19:17:11 +000079 // CHECK-3: store i32*
80 // CHECK-3: call void @{{.*}}__captured_stmt
81 // CHECK-3: ret void
82}
83
84void test4() {
85 #pragma clang __debug captured
86 {
87 Foo f;
88 f.x = 5;
89 }
Stephen Lin93ab6bf2013-08-15 06:47:53 +000090 // CHECK-4-LABEL: define void @_Z5test4v
Ben Langmuir524387a2013-05-09 19:17:11 +000091 // CHECK-4: call void @[[HelperName:["$_A-Za-z0-9]+]](%[[Capture:.*]]*
92 // CHECK-4: ret void
93 //
94 // CHECK-4: define internal void @[[HelperName]]
95 // CHECK-4: store i32 5, i32*
Ben Langmuircadfe422013-05-09 20:42:43 +000096 // CHECK-4: call {{.*}}FooD1Ev
Ben Langmuir524387a2013-05-09 19:17:11 +000097}
Wei Pan0b6d8462013-05-10 14:15:18 +000098
99template <typename T, int id>
100void touch(const T &) {}
101
102template <typename T, unsigned id>
103void template_capture_var() {
104 T x;
105 #pragma clang __debug captured
106 {
107 touch<T, id>(x);
108 }
109}
110
111template <typename T, int id>
112class Val {
113 T v;
114public:
115 void set() {
116 #pragma clang __debug captured
117 {
118 touch<T, id>(v);
119 }
120 }
121
122 template <typename U, int id2>
123 void foo(U u) {
124 #pragma clang __debug captured
125 {
126 touch<U, id + id2>(u);
127 }
128 }
129};
130
131void test_capture_var() {
132 // CHECK-5: define {{.*}} void @_Z20template_capture_varIiLj201EEvv
133 // CHECK-5-NOT: }
134 // CHECK-5: store i32*
135 // CHECK-5: call void @__captured_stmt
136 // CHECK-5-NEXT: ret void
137 template_capture_var<int, 201>();
138
139 // CHECK-5: define {{.*}} void @_ZN3ValIfLi202EE3setEv
140 // CHECK-5-NOT: }
141 // CHECK-5: store %class.Val*
142 // CHECK-5: call void @__captured_stmt
143 // CHECK-5-NEXT: ret void
144 Val<float, 202> Obj;
145 Obj.set();
146
147 // CHECK-5: define {{.*}} void @_ZN3ValIfLi202EE3fooIdLi203EEEvT_
148 // CHECK-5-NOT: }
149 // CHECK-5: store %class.Val*
150 // CHECK-5: store double
151 // CHECK-5: call void @__captured_stmt
152 // CHECK-5-NEXT: ret void
153 Obj.foo<double, 203>(1.0);
154}
155
156template <typename T>
157void template_capture_lambda() {
158 T x, y;
159 [=, &y]() {
160 #pragma clang __debug captured
161 {
162 y += x;
163 }
164 }();
165}
166
167void test_capture_lambda() {
Eli Friedman84431882013-07-02 17:52:28 +0000168 // CHECK-6: define {{.*}} void @_ZZ23template_capture_lambdaIiEvvENKUlvE_clEv
Wei Pan0b6d8462013-05-10 14:15:18 +0000169 // CHECK-6-NOT: }
170 // CHECK-6: store i32*
171 // CHECK-6: store i32*
172 // CHECK-6: call void @__captured_stmt
173 // CHECK-6-NEXT: ret void
174 template_capture_lambda<int>();
175}
Eli Friedman678eca42013-06-13 21:50:44 +0000176
177inline int test_captured_linkage() {
Eli Friedman84431882013-07-02 17:52:28 +0000178 // CHECK-7: @_ZZ21test_captured_linkagevE1i = linkonce_odr global i32 0
Eli Friedman678eca42013-06-13 21:50:44 +0000179 int j;
180 #pragma clang __debug captured
181 {
182 static int i = 0;
183 j = ++i;
184 }
185 return j;
186}
187void call_test_captured_linkage() {
188 test_captured_linkage();
189}