212 lines · cpp
1// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm %s -o %t -debug-info-kind=limited2// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-13// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-24// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-35// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-46// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-57// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-68// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-79 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 captured23 {24 static double inner = x;25 (void)inner;26 f.y = x;27 }28 }29};30 31void test1() {32 TestClass c;33 c.MemberFunc();34 // CHECK-1: %[[Capture:struct\.anon[\.0-9]*]] = type { ptr, ptr }35 // CHECK-1: [[INNER:@.+]] = {{.+}} global double36 37 // CHECK-1: define {{.*}} void @_ZN9TestClass10MemberFuncEv38 // CHECK-1: alloca %struct.anon39 // CHECK-1: getelementptr inbounds nuw %[[Capture]], ptr %{{[^,]*}}, i32 0, i32 040 // CHECK-1: getelementptr inbounds nuw %[[Capture]], ptr %{{[^,]*}}, i32 0, i32 141 // CHECK-1: store ptr %f, ptr42 // CHECK-1: call void @[[HelperName:[\.A-Za-z0-9_]+]](ptr43 // CHECK-1: call {{.*}}FooD1Ev44 // CHECK-1: ret45}46 47// CHECK-1: define internal {{.*}}void @[[HelperName]]48// CHECK-1: getelementptr inbounds nuw %[[Capture]], ptr {{[^,]*}}, i32 0, i32 049// 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 053// CHECK-1: getelementptr inbounds nuw %[[Capture]], ptr {{[^,]*}}, i32 0, i32 154 55void test2(int x) {56 int y = [&]() {57 #pragma clang __debug captured58 {59 x++;60 }61 return x;62 }();63 64 // CHECK-2-LABEL: define {{.*}}void @_Z5test2i65 // CHECK-2: call {{.*}} @[[Lambda:["$\w]+]]66 //67 // CHECK-2: define internal {{.*}} @[[Lambda]]68 // CHECK-2: call void @[[HelperName:["$_A-Za-z0-9]+]](ptr69 //70 // CHECK-2: define internal {{.*}}void @[[HelperName]]71 // CHECK-2: getelementptr inbounds nuw %[[Capture:.*]], ptr72 // CHECK-2: load ptr, ptr73 // CHECK-2: load i32, ptr74}75 76void test3(int x) {77 #pragma clang __debug captured78 {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 @_Z5test3i86 // CHECK-3: store ptr87 // CHECK-3: call void @{{.*}}__captured_stmt88 // CHECK-3: ret void89}90 91void test4() {92 #pragma clang __debug captured93 {94 Foo f;95 f.x = 5;96 }97 // CHECK-4-LABEL: define {{.*}}void @_Z5test4v98 // CHECK-4: call void @[[HelperName:[\."$_A-Za-z0-9]+]](ptr99 // CHECK-4: ret void100 //101 // CHECK-4: define internal {{.*}}void @[[HelperName]]102 // CHECK-4: store i32 5, ptr103 // CHECK-4: call {{.*}}FooD1Ev104}105 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 captured113 {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 captured124 {125 touch<T, id>(v);126 }127 }128 129 template <typename U, int id2>130 void foo(U u) {131 #pragma clang __debug captured132 {133 touch<U, id + id2>(u);134 }135 }136};137 138void test_capture_var() {139 // CHECK-5: define {{.*}} void @_Z20template_capture_varIiLj201EEvv140 // CHECK-5-NOT: }141 // CHECK-5: store ptr142 // CHECK-5: call void @__captured_stmt143 // CHECK-5-NEXT: ret void144 template_capture_var<int, 201>();145 146 // CHECK-5: define {{.*}} void @_ZN3ValIfLi202EE3setEv147 // CHECK-5-NOT: }148 // CHECK-5: store ptr149 // CHECK-5: call void @__captured_stmt150 // CHECK-5-NEXT: ret void151 Val<float, 202> Obj;152 Obj.set();153 154 // CHECK-5: define {{.*}} void @_ZN3ValIfLi202EE3fooIdLi203EEEvT_155 // CHECK-5-NOT: }156 // CHECK-5: store ptr157 // CHECK-5: store double158 // CHECK-5: call void @__captured_stmt159 // CHECK-5-NEXT: ret void160 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 captured168 {169 y += x;170 }171 }();172}173 174void test_capture_lambda() {175 // CHECK-6: define {{.*}} void @_ZZ23template_capture_lambdaIiEvvENKUlvE_clEv176 // CHECK-6-NOT: }177 // CHECK-6: store ptr178 // CHECK-6: store ptr179 // CHECK-6: call void @__captured_stmt180 // CHECK-6-NEXT: ret void181 template_capture_lambda<int>();182}183 184inline int test_captured_linkage() {185 // CHECK-7: @_ZZ21test_captured_linkagevE1i = linkonce_odr {{(dso_local )?}}global i32 0186 int j;187 #pragma clang __debug captured188 {189 static int i = 0;190 j = ++i;191 }192 return j;193}194void 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