150
|
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
|
|
9
|
|
10 struct Foo {
|
|
11 int x;
|
|
12 float y;
|
|
13 ~Foo() {}
|
|
14 };
|
|
15
|
|
16 struct TestClass {
|
|
17 int x;
|
|
18
|
|
19 TestClass() : x(0) {};
|
|
20 void MemberFunc() {
|
|
21 Foo f;
|
|
22 #pragma clang __debug captured
|
|
23 {
|
|
24 static double inner = x;
|
|
25 (void)inner;
|
|
26 f.y = x;
|
|
27 }
|
|
28 }
|
|
29 };
|
|
30
|
|
31 void test1() {
|
|
32 TestClass c;
|
|
33 c.MemberFunc();
|
|
34 // CHECK-1: %[[Capture:struct\.anon[\.0-9]*]] = type { %struct.TestClass*, %struct.Foo* }
|
|
35 // CHECK-1: [[INNER:@.+]] = {{.+}} global double
|
|
36
|
|
37 // CHECK-1: define {{.*}} void @_ZN9TestClass10MemberFuncEv
|
|
38 // CHECK-1: alloca %struct.anon
|
|
39 // CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* %{{[^,]*}}, i32 0, i32 0
|
|
40 // CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* %{{[^,]*}}, i32 0, i32 1
|
|
41 // CHECK-1: store %struct.Foo* %f, %struct.Foo**
|
|
42 // CHECK-1: call void @[[HelperName:[\.A-Za-z0-9_]+]](%[[Capture]]*
|
|
43 // CHECK-1: call {{.*}}FooD1Ev
|
|
44 // CHECK-1: ret
|
|
45 }
|
|
46
|
|
47 // CHECK-1: define internal {{.*}}void @[[HelperName]]
|
|
48 // CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* {{[^,]*}}, i32 0, i32 0
|
|
49 // CHECK-1: call {{.*}}i32 @__cxa_guard_acquire(
|
|
50 // CHECK-1: store double %{{.+}}, double* [[INNER]],
|
|
51 // CHECK-1: call {{.*}}void @__cxa_guard_release(
|
|
52 // CHECK-1: getelementptr inbounds %struct.TestClass, %struct.TestClass* {{[^,]*}}, i32 0, i32 0
|
|
53 // CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* {{[^,]*}}, i32 0, i32 1
|
|
54
|
|
55 void test2(int x) {
|
|
56 int y = [&]() {
|
|
57 #pragma clang __debug captured
|
|
58 {
|
|
59 x++;
|
|
60 }
|
|
61 return x;
|
|
62 }();
|
|
63
|
|
64 // CHECK-2-LABEL: define {{.*}}void @_Z5test2i
|
|
65 // CHECK-2: call {{.*}} @[[Lambda:["$\w]+]]
|
|
66 //
|
|
67 // CHECK-2: define internal {{.*}} @[[Lambda]]
|
|
68 // CHECK-2: call void @[[HelperName:["$_A-Za-z0-9]+]](%[[Capture:.*]]*
|
|
69 //
|
|
70 // CHECK-2: define internal {{.*}}void @[[HelperName]]
|
|
71 // CHECK-2: getelementptr inbounds %[[Capture]], %[[Capture]]*
|
|
72 // CHECK-2: load i32*, i32**
|
|
73 // CHECK-2: load i32, i32*
|
|
74 }
|
|
75
|
|
76 void test3(int x) {
|
|
77 #pragma clang __debug captured
|
|
78 {
|
|
79 x = [=]() { return x + 1; } ();
|
|
80 }
|
|
81 x = [=]() { return x + 1; }();
|
|
82
|
|
83 // CHECK-3: %[[Capture:struct\.anon[\.0-9]*]] = type { i32* }
|
|
84
|
|
85 // CHECK-3-LABEL: define {{.*}}void @_Z5test3i
|
|
86 // CHECK-3: store i32*
|
|
87 // CHECK-3: call void @{{.*}}__captured_stmt
|
|
88 // CHECK-3: ret void
|
|
89 }
|
|
90
|
|
91 void test4() {
|
|
92 #pragma clang __debug captured
|
|
93 {
|
|
94 Foo f;
|
|
95 f.x = 5;
|
|
96 }
|
|
97 // CHECK-4-LABEL: define {{.*}}void @_Z5test4v
|
|
98 // CHECK-4: call void @[[HelperName:[\."$_A-Za-z0-9]+]](%[[Capture:.*]]*
|
|
99 // CHECK-4: ret void
|
|
100 //
|
|
101 // CHECK-4: define internal {{.*}}void @[[HelperName]]
|
|
102 // CHECK-4: store i32 5, i32*
|
|
103 // CHECK-4: call {{.*}}FooD1Ev
|
|
104 }
|
|
105
|
|
106 template <typename T, int id>
|
|
107 void touch(const T &) {}
|
|
108
|
|
109 template <typename T, unsigned id>
|
|
110 void template_capture_var() {
|
|
111 T x;
|
|
112 #pragma clang __debug captured
|
|
113 {
|
|
114 touch<T, id>(x);
|
|
115 }
|
|
116 }
|
|
117
|
|
118 template <typename T, int id>
|
|
119 class Val {
|
|
120 T v;
|
|
121 public:
|
|
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
|
|
138 void 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
|
|
163 template <typename T>
|
|
164 void template_capture_lambda() {
|
|
165 T x, y;
|
|
166 [=, &y]() {
|
|
167 #pragma clang __debug captured
|
|
168 {
|
|
169 y += x;
|
|
170 }
|
|
171 }();
|
|
172 }
|
|
173
|
|
174 void test_capture_lambda() {
|
|
175 // CHECK-6: define {{.*}} void @_ZZ23template_capture_lambdaIiEvvENKUlvE_clEv
|
|
176 // 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 }
|
|
183
|
|
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
|
|
188 {
|
|
189 static int i = 0;
|
|
190 j = ++i;
|
|
191 }
|
|
192 return j;
|
|
193 }
|
|
194 void call_test_captured_linkage() {
|
|
195 test_captured_linkage();
|
|
196 }
|
|
197
|
|
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)
|