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