1*67e74705SXin Li // RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm %s -o %t
2*67e74705SXin Li // RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-1
3*67e74705SXin Li // RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-2
4*67e74705SXin Li // RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-3
5*67e74705SXin Li // RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-4
6*67e74705SXin Li // RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-5
7*67e74705SXin Li // RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-6
8*67e74705SXin Li // RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-7
9*67e74705SXin Li
10*67e74705SXin Li struct Foo {
11*67e74705SXin Li int x;
12*67e74705SXin Li float y;
~FooFoo13*67e74705SXin Li ~Foo() {}
14*67e74705SXin Li };
15*67e74705SXin Li
16*67e74705SXin Li struct TestClass {
17*67e74705SXin Li int x;
18*67e74705SXin Li
TestClassTestClass19*67e74705SXin Li TestClass() : x(0) {};
MemberFuncTestClass20*67e74705SXin Li void MemberFunc() {
21*67e74705SXin Li Foo f;
22*67e74705SXin Li #pragma clang __debug captured
23*67e74705SXin Li {
24*67e74705SXin Li static double inner = x;
25*67e74705SXin Li (void)inner;
26*67e74705SXin Li f.y = x;
27*67e74705SXin Li }
28*67e74705SXin Li }
29*67e74705SXin Li };
30*67e74705SXin Li
test1()31*67e74705SXin Li void test1() {
32*67e74705SXin Li TestClass c;
33*67e74705SXin Li c.MemberFunc();
34*67e74705SXin Li // CHECK-1: %[[Capture:struct\.anon[\.0-9]*]] = type { %struct.TestClass*, %struct.Foo* }
35*67e74705SXin Li // CHECK-1: [[INNER:@.+]] = {{.+}} global double
36*67e74705SXin Li
37*67e74705SXin Li // CHECK-1: define {{.*}} void @_ZN9TestClass10MemberFuncEv
38*67e74705SXin Li // CHECK-1: alloca %struct.anon
39*67e74705SXin Li // CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* %{{[^,]*}}, i32 0, i32 0
40*67e74705SXin Li // CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* %{{[^,]*}}, i32 0, i32 1
41*67e74705SXin Li // CHECK-1: store %struct.Foo* %f, %struct.Foo**
42*67e74705SXin Li // CHECK-1: call void @[[HelperName:[\.A-Za-z0-9_]+]](%[[Capture]]*
43*67e74705SXin Li // CHECK-1: call {{.*}}FooD1Ev
44*67e74705SXin Li // CHECK-1: ret
45*67e74705SXin Li }
46*67e74705SXin Li
47*67e74705SXin Li // CHECK-1: define internal {{.*}}void @[[HelperName]]
48*67e74705SXin Li // CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* {{[^,]*}}, i32 0, i32 0
49*67e74705SXin Li // CHECK-1: call {{.*}}i32 @__cxa_guard_acquire(
50*67e74705SXin Li // CHECK-1: store double %{{.+}}, double* [[INNER]],
51*67e74705SXin Li // CHECK-1: call {{.*}}void @__cxa_guard_release(
52*67e74705SXin Li // CHECK-1: getelementptr inbounds %struct.TestClass, %struct.TestClass* {{[^,]*}}, i32 0, i32 0
53*67e74705SXin Li // CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* {{[^,]*}}, i32 0, i32 1
54*67e74705SXin Li
test2(int x)55*67e74705SXin Li void test2(int x) {
56*67e74705SXin Li int y = [&]() {
57*67e74705SXin Li #pragma clang __debug captured
58*67e74705SXin Li {
59*67e74705SXin Li x++;
60*67e74705SXin Li }
61*67e74705SXin Li return x;
62*67e74705SXin Li }();
63*67e74705SXin Li
64*67e74705SXin Li // CHECK-2-LABEL: define {{.*}}void @_Z5test2i
65*67e74705SXin Li // CHECK-2: call {{.*}} @[[Lambda:["$\w]+]]
66*67e74705SXin Li //
67*67e74705SXin Li // CHECK-2: define internal {{.*}} @[[Lambda]]
68*67e74705SXin Li // CHECK-2: call void @[[HelperName:["$_A-Za-z0-9]+]](%[[Capture:.*]]*
69*67e74705SXin Li //
70*67e74705SXin Li // CHECK-2: define internal {{.*}}void @[[HelperName]]
71*67e74705SXin Li // CHECK-2: getelementptr inbounds %[[Capture]], %[[Capture]]*
72*67e74705SXin Li // CHECK-2: load i32*, i32**
73*67e74705SXin Li // CHECK-2: load i32, i32*
74*67e74705SXin Li }
75*67e74705SXin Li
test3(int x)76*67e74705SXin Li void test3(int x) {
77*67e74705SXin Li #pragma clang __debug captured
78*67e74705SXin Li {
79*67e74705SXin Li x = [=]() { return x + 1; } ();
80*67e74705SXin Li }
81*67e74705SXin Li
82*67e74705SXin Li // CHECK-3: %[[Capture:struct\.anon[\.0-9]*]] = type { i32* }
83*67e74705SXin Li
84*67e74705SXin Li // CHECK-3-LABEL: define {{.*}}void @_Z5test3i
85*67e74705SXin Li // CHECK-3: store i32*
86*67e74705SXin Li // CHECK-3: call void @{{.*}}__captured_stmt
87*67e74705SXin Li // CHECK-3: ret void
88*67e74705SXin Li }
89*67e74705SXin Li
test4()90*67e74705SXin Li void test4() {
91*67e74705SXin Li #pragma clang __debug captured
92*67e74705SXin Li {
93*67e74705SXin Li Foo f;
94*67e74705SXin Li f.x = 5;
95*67e74705SXin Li }
96*67e74705SXin Li // CHECK-4-LABEL: define {{.*}}void @_Z5test4v
97*67e74705SXin Li // CHECK-4: call void @[[HelperName:[\."$_A-Za-z0-9]+]](%[[Capture:.*]]*
98*67e74705SXin Li // CHECK-4: ret void
99*67e74705SXin Li //
100*67e74705SXin Li // CHECK-4: define internal {{.*}}void @[[HelperName]]
101*67e74705SXin Li // CHECK-4: store i32 5, i32*
102*67e74705SXin Li // CHECK-4: call {{.*}}FooD1Ev
103*67e74705SXin Li }
104*67e74705SXin Li
105*67e74705SXin Li template <typename T, int id>
touch(const T &)106*67e74705SXin Li void touch(const T &) {}
107*67e74705SXin Li
108*67e74705SXin Li template <typename T, unsigned id>
template_capture_var()109*67e74705SXin Li void template_capture_var() {
110*67e74705SXin Li T x;
111*67e74705SXin Li #pragma clang __debug captured
112*67e74705SXin Li {
113*67e74705SXin Li touch<T, id>(x);
114*67e74705SXin Li }
115*67e74705SXin Li }
116*67e74705SXin Li
117*67e74705SXin Li template <typename T, int id>
118*67e74705SXin Li class Val {
119*67e74705SXin Li T v;
120*67e74705SXin Li public:
set()121*67e74705SXin Li void set() {
122*67e74705SXin Li #pragma clang __debug captured
123*67e74705SXin Li {
124*67e74705SXin Li touch<T, id>(v);
125*67e74705SXin Li }
126*67e74705SXin Li }
127*67e74705SXin Li
128*67e74705SXin Li template <typename U, int id2>
foo(U u)129*67e74705SXin Li void foo(U u) {
130*67e74705SXin Li #pragma clang __debug captured
131*67e74705SXin Li {
132*67e74705SXin Li touch<U, id + id2>(u);
133*67e74705SXin Li }
134*67e74705SXin Li }
135*67e74705SXin Li };
136*67e74705SXin Li
test_capture_var()137*67e74705SXin Li void test_capture_var() {
138*67e74705SXin Li // CHECK-5: define {{.*}} void @_Z20template_capture_varIiLj201EEvv
139*67e74705SXin Li // CHECK-5-NOT: }
140*67e74705SXin Li // CHECK-5: store i32*
141*67e74705SXin Li // CHECK-5: call void @__captured_stmt
142*67e74705SXin Li // CHECK-5-NEXT: ret void
143*67e74705SXin Li template_capture_var<int, 201>();
144*67e74705SXin Li
145*67e74705SXin Li // CHECK-5: define {{.*}} void @_ZN3ValIfLi202EE3setEv
146*67e74705SXin Li // CHECK-5-NOT: }
147*67e74705SXin Li // CHECK-5: store %class.Val*
148*67e74705SXin Li // CHECK-5: call void @__captured_stmt
149*67e74705SXin Li // CHECK-5-NEXT: ret void
150*67e74705SXin Li Val<float, 202> Obj;
151*67e74705SXin Li Obj.set();
152*67e74705SXin Li
153*67e74705SXin Li // CHECK-5: define {{.*}} void @_ZN3ValIfLi202EE3fooIdLi203EEEvT_
154*67e74705SXin Li // CHECK-5-NOT: }
155*67e74705SXin Li // CHECK-5: store %class.Val*
156*67e74705SXin Li // CHECK-5: store double
157*67e74705SXin Li // CHECK-5: call void @__captured_stmt
158*67e74705SXin Li // CHECK-5-NEXT: ret void
159*67e74705SXin Li Obj.foo<double, 203>(1.0);
160*67e74705SXin Li }
161*67e74705SXin Li
162*67e74705SXin Li template <typename T>
template_capture_lambda()163*67e74705SXin Li void template_capture_lambda() {
164*67e74705SXin Li T x, y;
165*67e74705SXin Li [=, &y]() {
166*67e74705SXin Li #pragma clang __debug captured
167*67e74705SXin Li {
168*67e74705SXin Li y += x;
169*67e74705SXin Li }
170*67e74705SXin Li }();
171*67e74705SXin Li }
172*67e74705SXin Li
test_capture_lambda()173*67e74705SXin Li void test_capture_lambda() {
174*67e74705SXin Li // CHECK-6: define {{.*}} void @_ZZ23template_capture_lambdaIiEvvENKUlvE_clEv
175*67e74705SXin Li // CHECK-6-NOT: }
176*67e74705SXin Li // CHECK-6: store i32*
177*67e74705SXin Li // CHECK-6: store i32*
178*67e74705SXin Li // CHECK-6: call void @__captured_stmt
179*67e74705SXin Li // CHECK-6-NEXT: ret void
180*67e74705SXin Li template_capture_lambda<int>();
181*67e74705SXin Li }
182*67e74705SXin Li
test_captured_linkage()183*67e74705SXin Li inline int test_captured_linkage() {
184*67e74705SXin Li // CHECK-7: @_ZZ21test_captured_linkagevE1i = linkonce_odr global i32 0
185*67e74705SXin Li int j;
186*67e74705SXin Li #pragma clang __debug captured
187*67e74705SXin Li {
188*67e74705SXin Li static int i = 0;
189*67e74705SXin Li j = ++i;
190*67e74705SXin Li }
191*67e74705SXin Li return j;
192*67e74705SXin Li }
call_test_captured_linkage()193*67e74705SXin Li void call_test_captured_linkage() {
194*67e74705SXin Li test_captured_linkage();
195*67e74705SXin Li }
196