blob: cfa693611151c1c98aa47207ce4875a7b6929349 [file] [log] [blame]
Ben Langmuir3b4c30b2013-05-09 19:17:11 +00001// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o %t
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
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
Ben Langmuir3b4c30b2013-05-09 19:17:11 +00008
9struct Foo {
10 int x;
11 float y;
12 ~Foo() {}
13};
14
15struct TestClass {
16 int x;
17
18 TestClass() : x(0) {};
19 void MemberFunc() {
20 Foo f;
21 #pragma clang __debug captured
22 {
23 f.y = x;
24 }
25 }
26};
27
28void test1() {
29 TestClass c;
30 c.MemberFunc();
31 // CHECK-1: %[[Capture:struct\.anon[\.0-9]*]] = type { %struct.Foo*, %struct.TestClass* }
32
33 // CHECK-1: define {{.*}} void @_ZN9TestClass10MemberFuncEv
34 // CHECK-1: alloca %struct.anon
35 // CHECK-1: getelementptr inbounds %[[Capture]]* %{{[^,]*}}, i32 0, i32 0
36 // CHECK-1: store %struct.Foo* %f, %struct.Foo**
37 // CHECK-1: getelementptr inbounds %[[Capture]]* %{{[^,]*}}, i32 0, i32 1
38 // CHECK-1: call void @[[HelperName:[A-Za-z0-9_]+]](%[[Capture]]*
Ben Langmuir06987872013-05-09 20:42:43 +000039 // CHECK-1: call {{.*}}FooD1Ev
Ben Langmuir3b4c30b2013-05-09 19:17:11 +000040 // CHECK-1: ret
41}
42
43// CHECK-1: define internal void @[[HelperName]]
44// CHECK-1: getelementptr inbounds %[[Capture]]* {{[^,]*}}, i32 0, i32 1
45// CHECK-1: getelementptr inbounds %struct.TestClass* {{[^,]*}}, i32 0, i32 0
46// CHECK-1: getelementptr inbounds %[[Capture]]* {{[^,]*}}, i32 0, i32 0
47
48void test2(int x) {
49 int y = [&]() {
50 #pragma clang __debug captured
51 {
52 x++;
53 }
54 return x;
55 }();
56
57 // CHECK-2: define void @_Z5test2i
Ben Langmuir82dec972013-05-13 14:45:11 +000058 // CHECK-2: call {{.*}} @[[Lambda:["$\w]+]]
Ben Langmuir3b4c30b2013-05-09 19:17:11 +000059 //
Ben Langmuir82dec972013-05-13 14:45:11 +000060 // CHECK-2: define internal {{.*}} @[[Lambda]]
Ben Langmuir3b4c30b2013-05-09 19:17:11 +000061 // CHECK-2: call void @[[HelperName:["$_A-Za-z0-9]+]](%[[Capture:.*]]*
62 //
63 // CHECK-2: define internal void @[[HelperName]]
64 // CHECK-2: getelementptr inbounds %[[Capture]]*
65 // CHECK-2: load i32**
66 // CHECK-2: load i32*
67}
68
69void test3(int x) {
70 #pragma clang __debug captured
71 {
72 x = [=]() { return x + 1; } ();
73 }
74
75 // CHECK-3: %[[Capture:struct\.anon[\.0-9]*]] = type { i32* }
76
Ben Langmuir82dec972013-05-13 14:45:11 +000077 // CHECK-3: define void @_Z5test3i
Ben Langmuir3b4c30b2013-05-09 19:17:11 +000078 // CHECK-3: store i32*
79 // CHECK-3: call void @{{.*}}__captured_stmt
80 // CHECK-3: ret void
81}
82
83void test4() {
84 #pragma clang __debug captured
85 {
86 Foo f;
87 f.x = 5;
88 }
Ben Langmuir82dec972013-05-13 14:45:11 +000089 // CHECK-4: define void @_Z5test4v
Ben Langmuir3b4c30b2013-05-09 19:17:11 +000090 // CHECK-4: call void @[[HelperName:["$_A-Za-z0-9]+]](%[[Capture:.*]]*
91 // CHECK-4: ret void
92 //
93 // CHECK-4: define internal void @[[HelperName]]
94 // CHECK-4: store i32 5, i32*
Ben Langmuir06987872013-05-09 20:42:43 +000095 // CHECK-4: call {{.*}}FooD1Ev
Ben Langmuir3b4c30b2013-05-09 19:17:11 +000096}
Wei Pan655d3fa2013-05-10 14:15:18 +000097
98template <typename T, int id>
99void touch(const T &) {}
100
101template <typename T, unsigned id>
102void template_capture_var() {
103 T x;
104 #pragma clang __debug captured
105 {
106 touch<T, id>(x);
107 }
108}
109
110template <typename T, int id>
111class Val {
112 T v;
113public:
114 void set() {
115 #pragma clang __debug captured
116 {
117 touch<T, id>(v);
118 }
119 }
120
121 template <typename U, int id2>
122 void foo(U u) {
123 #pragma clang __debug captured
124 {
125 touch<U, id + id2>(u);
126 }
127 }
128};
129
130void test_capture_var() {
131 // CHECK-5: define {{.*}} void @_Z20template_capture_varIiLj201EEvv
132 // CHECK-5-NOT: }
133 // CHECK-5: store i32*
134 // CHECK-5: call void @__captured_stmt
135 // CHECK-5-NEXT: ret void
136 template_capture_var<int, 201>();
137
138 // CHECK-5: define {{.*}} void @_ZN3ValIfLi202EE3setEv
139 // CHECK-5-NOT: }
140 // CHECK-5: store %class.Val*
141 // CHECK-5: call void @__captured_stmt
142 // CHECK-5-NEXT: ret void
143 Val<float, 202> Obj;
144 Obj.set();
145
146 // CHECK-5: define {{.*}} void @_ZN3ValIfLi202EE3fooIdLi203EEEvT_
147 // CHECK-5-NOT: }
148 // CHECK-5: store %class.Val*
149 // CHECK-5: store double
150 // CHECK-5: call void @__captured_stmt
151 // CHECK-5-NEXT: ret void
152 Obj.foo<double, 203>(1.0);
153}
154
155template <typename T>
156void template_capture_lambda() {
157 T x, y;
158 [=, &y]() {
159 #pragma clang __debug captured
160 {
161 y += x;
162 }
163 }();
164}
165
166void test_capture_lambda() {
167 // CHECK-6: define {{.*}} void @_ZZ23template_capture_lambdaIiEvvENKS_IiEUlvE_clEv
168 // CHECK-6-NOT: }
169 // CHECK-6: store i32*
170 // CHECK-6: store i32*
171 // CHECK-6: call void @__captured_stmt
172 // CHECK-6-NEXT: ret void
173 template_capture_lambda<int>();
174}