xref: /minix3/external/bsd/llvm/dist/clang/test/CodeGenCXX/captured-statements.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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