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 { ptr, ptr } 35 // CHECK-1: [[INNER:@.+]] = {{.+}} global double 36 37 // CHECK-1: define {{.*}} void @_ZN9TestClass10MemberFuncEv 38 // CHECK-1: alloca %struct.anon 39 // CHECK-1: getelementptr inbounds nuw %[[Capture]], ptr %{{[^,]*}}, i32 0, i32 0 40 // CHECK-1: getelementptr inbounds nuw %[[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 45 } 46 47 // CHECK-1: define internal {{.*}}void @[[HelperName]] 48 // CHECK-1: getelementptr inbounds nuw %[[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 nuw %struct.TestClass, ptr {{[^,]*}}, i32 0, i32 0 53 // CHECK-1: getelementptr inbounds nuw %[[Capture]], ptr {{[^,]*}}, 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]+]](ptr 69 // 70 // CHECK-2: define internal {{.*}}void @[[HelperName]] 71 // CHECK-2: getelementptr inbounds nuw %[[Capture:.*]], ptr 72 // CHECK-2: load ptr, ptr 73 // CHECK-2: load i32, ptr 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 { ptr } 84 85 // CHECK-3-LABEL: define {{.*}}void @_Z5test3i 86 // CHECK-3: store ptr 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]+]](ptr 99 // CHECK-4: ret void 100 // 101 // CHECK-4: define internal {{.*}}void @[[HelperName]] 102 // CHECK-4: store i32 5, ptr 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 ptr 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 ptr 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 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); 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 ptr 178 // CHECK-6: store ptr 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) 212