blob: 95e73e548399b2d76c10a7dc1e9a6c217dade794 [file] [log] [blame]
Alexey Bataev56223232017-06-09 13:40:18 +00001// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm %s -o %t -debug-info-kind=limited
Ben Langmuir3b4c30b2013-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 Pan655d3fa2013-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 Friedmand4b6e7a92013-06-13 21:50:44 +00008// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-7
Ben Langmuir3b4c30b2013-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 {
Alexey Bataev43f74392015-05-07 06:28:46 +000024 static double inner = x;
25 (void)inner;
Ben Langmuir3b4c30b2013-05-09 19:17:11 +000026 f.y = x;
27 }
28 }
29};
30
31void test1() {
32 TestClass c;
33 c.MemberFunc();
Alexey Bataev43f74392015-05-07 06:28:46 +000034 // CHECK-1: %[[Capture:struct\.anon[\.0-9]*]] = type { %struct.TestClass*, %struct.Foo* }
35 // CHECK-1: [[INNER:@.+]] = {{.+}} global double
Ben Langmuir3b4c30b2013-05-09 19:17:11 +000036
37 // CHECK-1: define {{.*}} void @_ZN9TestClass10MemberFuncEv
38 // CHECK-1: alloca %struct.anon
David Blaikie218b7832015-02-27 19:18:17 +000039 // CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* %{{[^,]*}}, i32 0, i32 0
David Blaikie218b7832015-02-27 19:18:17 +000040 // CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* %{{[^,]*}}, i32 0, i32 1
Alexey Bataev43f74392015-05-07 06:28:46 +000041 // CHECK-1: store %struct.Foo* %f, %struct.Foo**
Sunil Srivastava3acf6272015-05-12 16:48:43 +000042 // CHECK-1: call void @[[HelperName:[\.A-Za-z0-9_]+]](%[[Capture]]*
Ben Langmuir06987872013-05-09 20:42:43 +000043 // CHECK-1: call {{.*}}FooD1Ev
Ben Langmuir3b4c30b2013-05-09 19:17:11 +000044 // CHECK-1: ret
45}
46
David Blaikieea3e51d2015-06-29 17:29:50 +000047// CHECK-1: define internal {{.*}}void @[[HelperName]]
David Blaikie218b7832015-02-27 19:18:17 +000048// CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* {{[^,]*}}, i32 0, i32 0
David Blaikieea3e51d2015-06-29 17:29:50 +000049// CHECK-1: call {{.*}}i32 @__cxa_guard_acquire(
Alexey Bataev43f74392015-05-07 06:28:46 +000050// CHECK-1: store double %{{.+}}, double* [[INNER]],
David Blaikieea3e51d2015-06-29 17:29:50 +000051// CHECK-1: call {{.*}}void @__cxa_guard_release(
Alexey Bataev43f74392015-05-07 06:28:46 +000052// CHECK-1: getelementptr inbounds %struct.TestClass, %struct.TestClass* {{[^,]*}}, i32 0, i32 0
53// CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* {{[^,]*}}, i32 0, i32 1
Ben Langmuir3b4c30b2013-05-09 19:17:11 +000054
55void test2(int x) {
56 int y = [&]() {
57 #pragma clang __debug captured
58 {
59 x++;
60 }
61 return x;
62 }();
63
David Blaikieea3e51d2015-06-29 17:29:50 +000064 // CHECK-2-LABEL: define {{.*}}void @_Z5test2i
Ben Langmuir82dec972013-05-13 14:45:11 +000065 // CHECK-2: call {{.*}} @[[Lambda:["$\w]+]]
Ben Langmuir3b4c30b2013-05-09 19:17:11 +000066 //
Ben Langmuir82dec972013-05-13 14:45:11 +000067 // CHECK-2: define internal {{.*}} @[[Lambda]]
Ben Langmuir3b4c30b2013-05-09 19:17:11 +000068 // CHECK-2: call void @[[HelperName:["$_A-Za-z0-9]+]](%[[Capture:.*]]*
69 //
David Blaikieea3e51d2015-06-29 17:29:50 +000070 // CHECK-2: define internal {{.*}}void @[[HelperName]]
David Blaikie218b7832015-02-27 19:18:17 +000071 // CHECK-2: getelementptr inbounds %[[Capture]], %[[Capture]]*
David Blaikiea953f282015-02-27 21:19:58 +000072 // CHECK-2: load i32*, i32**
73 // CHECK-2: load i32, i32*
Ben Langmuir3b4c30b2013-05-09 19:17:11 +000074}
75
76void test3(int x) {
77 #pragma clang __debug captured
78 {
79 x = [=]() { return x + 1; } ();
80 }
Alexey Bataevbef6aa62016-10-14 12:43:59 +000081 x = [=]() { return x + 1; }();
Ben Langmuir3b4c30b2013-05-09 19:17:11 +000082
83 // CHECK-3: %[[Capture:struct\.anon[\.0-9]*]] = type { i32* }
84
David Blaikieea3e51d2015-06-29 17:29:50 +000085 // CHECK-3-LABEL: define {{.*}}void @_Z5test3i
Ben Langmuir3b4c30b2013-05-09 19:17:11 +000086 // CHECK-3: store i32*
87 // CHECK-3: call void @{{.*}}__captured_stmt
88 // CHECK-3: ret void
89}
90
91void test4() {
92 #pragma clang __debug captured
93 {
94 Foo f;
95 f.x = 5;
96 }
David Blaikieea3e51d2015-06-29 17:29:50 +000097 // CHECK-4-LABEL: define {{.*}}void @_Z5test4v
Sunil Srivastava3acf6272015-05-12 16:48:43 +000098 // CHECK-4: call void @[[HelperName:[\."$_A-Za-z0-9]+]](%[[Capture:.*]]*
Ben Langmuir3b4c30b2013-05-09 19:17:11 +000099 // CHECK-4: ret void
100 //
David Blaikieea3e51d2015-06-29 17:29:50 +0000101 // CHECK-4: define internal {{.*}}void @[[HelperName]]
Ben Langmuir3b4c30b2013-05-09 19:17:11 +0000102 // CHECK-4: store i32 5, i32*
Ben Langmuir06987872013-05-09 20:42:43 +0000103 // CHECK-4: call {{.*}}FooD1Ev
Ben Langmuir3b4c30b2013-05-09 19:17:11 +0000104}
Wei Pan655d3fa2013-05-10 14:15:18 +0000105
106template <typename T, int id>
107void touch(const T &) {}
108
109template <typename T, unsigned id>
110void template_capture_var() {
111 T x;
112 #pragma clang __debug captured
113 {
114 touch<T, id>(x);
115 }
116}
117
118template <typename T, int id>
119class Val {
120 T v;
121public:
122 void set() {
123 #pragma clang __debug captured
124 {
125 touch<T, id>(v);
126 }
127 }
128
129 template <typename U, int id2>
130 void foo(U u) {
131 #pragma clang __debug captured
132 {
133 touch<U, id + id2>(u);
134 }
135 }
136};
137
138void test_capture_var() {
139 // CHECK-5: define {{.*}} void @_Z20template_capture_varIiLj201EEvv
140 // CHECK-5-NOT: }
141 // CHECK-5: store i32*
142 // CHECK-5: call void @__captured_stmt
143 // CHECK-5-NEXT: ret void
144 template_capture_var<int, 201>();
145
146 // CHECK-5: define {{.*}} void @_ZN3ValIfLi202EE3setEv
147 // CHECK-5-NOT: }
148 // CHECK-5: store %class.Val*
149 // CHECK-5: call void @__captured_stmt
150 // CHECK-5-NEXT: ret void
151 Val<float, 202> Obj;
152 Obj.set();
153
154 // CHECK-5: define {{.*}} void @_ZN3ValIfLi202EE3fooIdLi203EEEvT_
155 // CHECK-5-NOT: }
156 // CHECK-5: store %class.Val*
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);
161}
162
163template <typename T>
164void template_capture_lambda() {
165 T x, y;
166 [=, &y]() {
167 #pragma clang __debug captured
168 {
169 y += x;
170 }
171 }();
172}
173
174void test_capture_lambda() {
Eli Friedman95f50122013-07-02 17:52:28 +0000175 // CHECK-6: define {{.*}} void @_ZZ23template_capture_lambdaIiEvvENKUlvE_clEv
Wei Pan655d3fa2013-05-10 14:15:18 +0000176 // CHECK-6-NOT: }
177 // CHECK-6: store i32*
178 // CHECK-6: store i32*
179 // CHECK-6: call void @__captured_stmt
180 // CHECK-6-NEXT: ret void
181 template_capture_lambda<int>();
182}
Eli Friedmand4b6e7a92013-06-13 21:50:44 +0000183
184inline int test_captured_linkage() {
Eli Friedman95f50122013-07-02 17:52:28 +0000185 // CHECK-7: @_ZZ21test_captured_linkagevE1i = linkonce_odr global i32 0
Eli Friedmand4b6e7a92013-06-13 21:50:44 +0000186 int j;
187 #pragma clang __debug captured
188 {
189 static int i = 0;
190 j = ++i;
191 }
192 return j;
193}
194void call_test_captured_linkage() {
195 test_captured_linkage();
196}
Alexey Bataev56223232017-06-09 13:40:18 +0000197
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)