155 lines · cpp
1// RUN: %clang_cc1 -std=c++23 -emit-llvm -debug-info-kind=standalone -triple %itanium_abi_triple %s -o - | FileCheck %s --implicit-check-not="call void @llvm.dbg.declare"2 3// CHECK: define {{.*}} i32 @_Z1fv4// CHECK: #dbg_declare(ptr %{{[a-z]+}}, ![[VAR_0:[0-9]+]], !DIExpression(),5// CHECK: #dbg_declare(ptr %{{[0-9]+}}, ![[VAR_1:[0-9]+]], !DIExpression(),6// CHECK: #dbg_declare(ptr %{{[0-9]+}}, ![[VAR_2:[0-9]+]], !DIExpression(DW_OP_plus_uconst, 4),7// CHECK: #dbg_declare(ptr %{{[0-9]+}}, ![[VAR_3:[0-9]+]], !DIExpression(DW_OP_deref),8// CHECK: #dbg_declare(ptr %{{[0-9]+}}, ![[VAR_4:[0-9]+]], !DIExpression(DW_OP_deref, DW_OP_plus_uconst, 4),9// CHECK: #dbg_declare(ptr %z1, ![[VAR_5:[0-9]+]], !DIExpression()10// CHECK: #dbg_declare(ptr %z2, ![[VAR_6:[0-9]+]], !DIExpression()11// CHECK: #dbg_declare(ptr %k, ![[VAR_7:[0-9]+]], !DIExpression()12// CHECK: #dbg_declare(ptr %v{{[0-9]*}}, ![[VAR_8:[0-9]+]], !DIExpression()13// CHECK: #dbg_declare(ptr %w{{[0-9]*}}, ![[VAR_9:[0-9]+]], !DIExpression()14// CHECK: #dbg_declare(ptr %m, ![[VAR_10:[0-9]+]], !DIExpression()15// CHECK: #dbg_declare(ptr %n, ![[VAR_11:[0-9]+]], !DIExpression()16// CHECK: #dbg_declare(ptr %s, ![[VAR_12:[0-9]+]], !DIExpression()17// CHECK: #dbg_declare(ptr %p, ![[VAR_13:[0-9]+]], !DIExpression()18// CHECK: getelementptr inbounds nuw %struct.A, ptr {{.*}}, i32 0, i32 1, !dbg ![[Y1_DEBUG_LOC:[0-9]+]]19// CHECK: getelementptr inbounds nuw %struct.A, ptr {{.*}}, i32 0, i32 1, !dbg ![[Y2_DEBUG_LOC:[0-9]+]]20// CHECK: load ptr, ptr %z2, {{.*}}!dbg ![[Z2_DEBUG_LOC:[0-9]+]]21// CHECK: getelementptr inbounds [2 x i32], ptr {{.*}}, i{{64|32}} 0, i{{64|32}} 1, !dbg ![[A2_DEBUG_LOC:[0-9]+]]22// CHECK: getelementptr inbounds nuw { i32, i32 }, ptr {{.*}}, i32 0, i32 1, !dbg ![[C2_DEBUG_LOC:[0-9]+]]23// CHECK: extractelement <2 x i32> {{.*}}, i32 1, !dbg ![[V2_DEBUG_LOC:[0-9]+]]24// CHECK: ![[VAR_0]] = !DILocalVariable(name: "a"25// CHECK: ![[VAR_1]] = !DILocalVariable(name: "x1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})26// CHECK: ![[VAR_2]] = !DILocalVariable(name: "y1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})27// CHECK: ![[VAR_3]] = !DILocalVariable(name: "x2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})28// CHECK: ![[VAR_4]] = !DILocalVariable(name: "y2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})29// CHECK: ![[VAR_5]] = !DILocalVariable(name: "z1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})30// CHECK: ![[VAR_6]] = !DILocalVariable(name: "z2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})31// CHECK: ![[VAR_7]] = !DILocalVariable(name: "k", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})32// CHECK: ![[VAR_8]] = !DILocalVariable(name: "v", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})33// CHECK: ![[VAR_9]] = !DILocalVariable(name: "w", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})34// CHECK: ![[VAR_10]] = !DILocalVariable(name: "m", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})35// CHECK: ![[VAR_11]] = !DILocalVariable(name: "n", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})36// CHECK: ![[VAR_12]] = !DILocalVariable(name: "s", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})37// CHECK: ![[VAR_13]] = !DILocalVariable(name: "p", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})38 39struct A {40 int x;41 int y;42};43 44struct B {45 int w;46 int z;47 template<int> int get();48 template<> int get<0>() { return w; }49 template<> int get<1>() { return z; }50};51 52struct C {53 int w;54 int z;55 template<int> int get(this C&& self);56 template<> int get<0>(this C&& self) { return self.w; }57 template<> int get<1>(this C&& self) { return self.z; }58};59 60struct D {61 int w;62 int z;63 template<int> int get(int unused = 0);64 template<> int get<0>(int unused) { return w; }65 template<> int get<1>(int unused) { return z; }66};67 68// Note: the following declarations are necessary for decomposition of tuple-like69// structured bindings70namespace std {71template<typename T> struct tuple_size {72};73template<>74struct tuple_size<B> {75 static constexpr unsigned value = 2;76};77 78template<>79struct tuple_size<C> {80 static constexpr unsigned value = 2;81};82 83template<>84struct tuple_size<D> {85 static constexpr unsigned value = 2;86};87 88template<unsigned, typename T> struct tuple_element { using type = int; };89 90// Decomposition of tuple-like bindings but where the `get` methods91// are declared as free functions.92struct triple {93 int k;94 int v;95 int w;96};97 98template<>99struct tuple_size<triple> {100 static constexpr unsigned value = 3;101};102 103template <unsigned I> int get(triple);104template <> int get<0>(triple p) { return p.k; }105template <> int get<1>(triple p) { return p.v; }106template <> int get<2>(triple p) { return p.w; }107} // namespace std108 109int f() {110 A a{10, 20};111 auto [x1, y1] = a;112 auto &[x2, y2] = a;113 auto [z1, z2] = B{1, 2};114 int array[2] = {3, 4};115 auto &[a1, a2] = array;116 _Complex int cmplx = {1, 2};117 auto &[c1, c2] = cmplx;118 int vctr __attribute__ ((vector_size (sizeof(int)*2)))= {1, 2};119 auto &[v1, v2] = vctr;120 auto [k, v, w] = std::triple{3, 4, 5};121 auto [m, n] = C{2, 3};122 auto [s, p] = D{2, 3};123 return //124 x1 //125 + //126// CHECK: ![[Y1_DEBUG_LOC]] = !DILocation(line: [[@LINE+1]]127 y1 //128 + //129 x2 //130 + //131// CHECK: ![[Y2_DEBUG_LOC]] = !DILocation(line: [[@LINE+1]]132 y2 //133 + //134 z1 //135 + //136// CHECK: ![[Z2_DEBUG_LOC]] = !DILocation(line: [[@LINE+1]]137 z2 //138 + //139 a1 //140 + //141// CHECK: ![[A2_DEBUG_LOC]] = !DILocation(line: [[@LINE+1]]142 a2 //143 + //144 c1 //145 + //146// CHECK: ![[C2_DEBUG_LOC]] = !DILocation(line: [[@LINE+1]]147 c2 //148 + //149 v1 //150 + //151// CHECK: ![[V2_DEBUG_LOC]] = !DILocation(line: [[@LINE+1]]152 v2 //153 ;154}155