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;
~FooFoo13   ~Foo() {}
14 };
15 
16 struct TestClass {
17   int x;
18 
TestClassTestClass19   TestClass() : x(0) {};
MemberFuncTestClass20   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 
test1()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 
test2(int x)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 
test3(int x)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 
test4()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>
touch(const T &)107 void touch(const T &) {}
108 
109 template <typename T, unsigned id>
template_capture_var()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:
set()122   void set() {
123     #pragma clang __debug captured
124     {
125       touch<T, id>(v);
126     }
127   }
128 
129   template <typename U, int id2>
foo(U u)130   void foo(U u) {
131     #pragma clang __debug captured
132     {
133       touch<U, id + id2>(u);
134     }
135   }
136 };
137 
test_capture_var()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>
template_capture_lambda()164 void template_capture_lambda() {
165   T x, y;
166   [=, &y]() {
167     #pragma clang __debug captured
168     {
169       y += x;
170     }
171   }();
172 }
173 
test_capture_lambda()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 
test_captured_linkage()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 }
call_test_captured_linkage()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)
212