Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / CodeGenCXX / captured-statements.cpp
blobfa30f46f1be8a3d54d7ca8916faeb57067ee72d4
1 // RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm %s -o %t -debug-info-kind=limited
2 // 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
6 // RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-5
7 // RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-6
8 // RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-7
10 struct Foo {
11 int x;
12 float y;
13 ~Foo() {}
16 struct TestClass {
17 int x;
19 TestClass() : x(0) {};
20 void MemberFunc() {
21 Foo f;
22 #pragma clang __debug captured
24 static double inner = x;
25 (void)inner;
26 f.y = x;
31 void test1() {
32 TestClass c;
33 c.MemberFunc();
34 // CHECK-1: %[[Capture:struct\.anon[\.0-9]*]] = type { ptr, ptr }
35 // CHECK-1: [[INNER:@.+]] = {{.+}} global double
37 // CHECK-1: define {{.*}} void @_ZN9TestClass10MemberFuncEv
38 // CHECK-1: alloca %struct.anon
39 // CHECK-1: getelementptr inbounds %[[Capture]], ptr %{{[^,]*}}, i32 0, i32 0
40 // CHECK-1: getelementptr inbounds %[[Capture]], ptr %{{[^,]*}}, i32 0, i32 1
41 // CHECK-1: store ptr %f, ptr
42 // CHECK-1: call void @[[HelperName:[\.A-Za-z0-9_]+]](ptr
43 // CHECK-1: call {{.*}}FooD1Ev
44 // CHECK-1: ret
47 // CHECK-1: define internal {{.*}}void @[[HelperName]]
48 // CHECK-1: getelementptr inbounds %[[Capture]], ptr {{[^,]*}}, i32 0, i32 0
49 // CHECK-1: call {{.*}}i32 @__cxa_guard_acquire(
50 // CHECK-1: store double %{{.+}}, ptr [[INNER]],
51 // CHECK-1: call {{.*}}void @__cxa_guard_release(
52 // CHECK-1: getelementptr inbounds %struct.TestClass, ptr {{[^,]*}}, i32 0, i32 0
53 // CHECK-1: getelementptr inbounds %[[Capture]], ptr {{[^,]*}}, i32 0, i32 1
55 void test2(int x) {
56 int y = [&]() {
57 #pragma clang __debug captured
59 x++;
61 return x;
62 }();
64 // CHECK-2-LABEL: define {{.*}}void @_Z5test2i
65 // CHECK-2: call {{.*}} @[[Lambda:["$\w]+]]
67 // CHECK-2: define internal {{.*}} @[[Lambda]]
68 // CHECK-2: call void @[[HelperName:["$_A-Za-z0-9]+]](ptr
70 // CHECK-2: define internal {{.*}}void @[[HelperName]]
71 // CHECK-2: getelementptr inbounds %[[Capture:.*]], ptr
72 // CHECK-2: load ptr, ptr
73 // CHECK-2: load i32, ptr
76 void test3(int x) {
77 #pragma clang __debug captured
79 x = [=]() { return x + 1; } ();
81 x = [=]() { return x + 1; }();
83 // CHECK-3: %[[Capture:struct\.anon[\.0-9]*]] = type { ptr }
85 // CHECK-3-LABEL: define {{.*}}void @_Z5test3i
86 // CHECK-3: store ptr
87 // CHECK-3: call void @{{.*}}__captured_stmt
88 // CHECK-3: ret void
91 void test4() {
92 #pragma clang __debug captured
94 Foo f;
95 f.x = 5;
97 // CHECK-4-LABEL: define {{.*}}void @_Z5test4v
98 // CHECK-4: call void @[[HelperName:[\."$_A-Za-z0-9]+]](ptr
99 // CHECK-4: ret void
101 // CHECK-4: define internal {{.*}}void @[[HelperName]]
102 // CHECK-4: store i32 5, ptr
103 // CHECK-4: call {{.*}}FooD1Ev
106 template <typename T, int id>
107 void touch(const T &) {}
109 template <typename T, unsigned id>
110 void template_capture_var() {
111 T x;
112 #pragma clang __debug captured
114 touch<T, id>(x);
118 template <typename T, int id>
119 class Val {
120 T v;
121 public:
122 void set() {
123 #pragma clang __debug captured
125 touch<T, id>(v);
129 template <typename U, int id2>
130 void foo(U u) {
131 #pragma clang __debug captured
133 touch<U, id + id2>(u);
138 void test_capture_var() {
139 // CHECK-5: define {{.*}} void @_Z20template_capture_varIiLj201EEvv
140 // CHECK-5-NOT: }
141 // CHECK-5: store ptr
142 // CHECK-5: call void @__captured_stmt
143 // CHECK-5-NEXT: ret void
144 template_capture_var<int, 201>();
146 // CHECK-5: define {{.*}} void @_ZN3ValIfLi202EE3setEv
147 // CHECK-5-NOT: }
148 // CHECK-5: store ptr
149 // CHECK-5: call void @__captured_stmt
150 // CHECK-5-NEXT: ret void
151 Val<float, 202> Obj;
152 Obj.set();
154 // CHECK-5: define {{.*}} void @_ZN3ValIfLi202EE3fooIdLi203EEEvT_
155 // CHECK-5-NOT: }
156 // CHECK-5: store ptr
157 // CHECK-5: store double
158 // CHECK-5: call void @__captured_stmt
159 // CHECK-5-NEXT: ret void
160 Obj.foo<double, 203>(1.0);
163 template <typename T>
164 void template_capture_lambda() {
165 T x, y;
166 [=, &y]() {
167 #pragma clang __debug captured
169 y += x;
171 }();
174 void test_capture_lambda() {
175 // CHECK-6: define {{.*}} void @_ZZ23template_capture_lambdaIiEvvENKUlvE_clEv
176 // CHECK-6-NOT: }
177 // CHECK-6: store ptr
178 // CHECK-6: store ptr
179 // CHECK-6: call void @__captured_stmt
180 // CHECK-6-NEXT: ret void
181 template_capture_lambda<int>();
184 inline int test_captured_linkage() {
185 // CHECK-7: @_ZZ21test_captured_linkagevE1i = linkonce_odr {{(dso_local )?}}global i32 0
186 int j;
187 #pragma clang __debug captured
189 static int i = 0;
190 j = ++i;
192 return j;
194 void call_test_captured_linkage() {
195 test_captured_linkage();
198 // CHECK-1-DAG: !DILocalVariable(name: "this", {{.*}}, flags: DIFlagArtificial | DIFlagObjectPointer)
199 // CHECK-1-DAG: !DILocalVariable(name: "__context", {{.*}}, flags: DIFlagArtificial)
200 // CHECK-2-DAG: !DILocalVariable(name: "this", {{.*}}, flags: DIFlagArtificial | DIFlagObjectPointer)
201 // CHECK-2-DAG: !DILocalVariable(name: "__context", {{.*}}, flags: DIFlagArtificial)
202 // CHECK-3-DAG: !DILocalVariable(name: "this", {{.*}}, flags: DIFlagArtificial | DIFlagObjectPointer)
203 // CHECK-3-DAG: !DILocalVariable(name: "__context", {{.*}}, flags: DIFlagArtificial)
204 // CHECK-4-DAG: !DILocalVariable(name: "this", {{.*}}, flags: DIFlagArtificial | DIFlagObjectPointer)
205 // CHECK-4-DAG: !DILocalVariable(name: "__context", {{.*}}, flags: DIFlagArtificial)
206 // CHECK-5-DAG: !DILocalVariable(name: "this", {{.*}}, flags: DIFlagArtificial | DIFlagObjectPointer)
207 // CHECK-5-DAG: !DILocalVariable(name: "__context", {{.*}}, flags: DIFlagArtificial)
208 // CHECK-6-DAG: !DILocalVariable(name: "this", {{.*}}, flags: DIFlagArtificial | DIFlagObjectPointer)
209 // CHECK-6-DAG: !DILocalVariable(name: "__context", {{.*}}, flags: DIFlagArtificial)
210 // CHECK-7-DAG: !DILocalVariable(name: "this", {{.*}}, flags: DIFlagArtificial | DIFlagObjectPointer)
211 // CHECK-7-DAG: !DILocalVariable(name: "__context", {{.*}}, flags: DIFlagArtificial)