1- // RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -triple %itanium_abi_triple %s -o - | FileCheck %s --implicit-check-not="call void @llvm.dbg.declare"
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"
22
3+ // CHECK: define {{.*}} i32 @_Z1fv
34// CHECK: #dbg_declare(ptr %{{[a-z]+}}, ![[VAR_0:[0-9]+]], !DIExpression(),
45// CHECK: #dbg_declare(ptr %{{[0-9]+}}, ![[VAR_1:[0-9]+]], !DIExpression(),
56// CHECK: #dbg_declare(ptr %{{[0-9]+}}, ![[VAR_2:[0-9]+]], !DIExpression(DW_OP_plus_uconst, 4),
67// CHECK: #dbg_declare(ptr %{{[0-9]+}}, ![[VAR_3:[0-9]+]], !DIExpression(DW_OP_deref),
78// CHECK: #dbg_declare(ptr %{{[0-9]+}}, ![[VAR_4:[0-9]+]], !DIExpression(DW_OP_deref, DW_OP_plus_uconst, 4),
89// CHECK: #dbg_declare(ptr %z1, ![[VAR_5:[0-9]+]], !DIExpression()
910// 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, ![[VAR_8:[0-9]+]], !DIExpression()
13+ // CHECK: #dbg_declare(ptr %w, ![[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()
1018// CHECK: getelementptr inbounds nuw %struct.A, ptr {{.*}}, i32 0, i32 1, !dbg ![[Y1_DEBUG_LOC:[0-9]+]]
1119// CHECK: getelementptr inbounds nuw %struct.A, ptr {{.*}}, i32 0, i32 1, !dbg ![[Y2_DEBUG_LOC:[0-9]+]]
1220// CHECK: load ptr, ptr %z2, {{.*}}!dbg ![[Z2_DEBUG_LOC:[0-9]+]]
2028// CHECK: ![[VAR_4]] = !DILocalVariable(name: "y2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
2129// CHECK: ![[VAR_5]] = !DILocalVariable(name: "z1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
2230// 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]+}})
2338
2439struct A {
2540 int x;
@@ -34,6 +49,22 @@ struct B {
3449 template <> int get<1 >() { return z; }
3550};
3651
52+ struct 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+
60+ struct 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+
3768// Note: the following declarations are necessary for decomposition of tuple-like
3869// structured bindings
3970namespace std {
@@ -44,7 +75,35 @@ struct tuple_size<B> {
4475 static constexpr unsigned value = 2 ;
4576};
4677
78+ template <>
79+ struct tuple_size <C> {
80+ static constexpr unsigned value = 2 ;
81+ };
82+
83+ template <>
84+ struct tuple_size <D> {
85+ static constexpr unsigned value = 2 ;
86+ };
87+
4788template <unsigned , typename T> struct tuple_element { using type = int ; };
89+
90+ // Decomposition of tuple-like bindings but where the `get` methods
91+ // are declared as free functions.
92+ struct triple {
93+ int k;
94+ int v;
95+ int w;
96+ };
97+
98+ template <>
99+ struct tuple_size <triple> {
100+ static constexpr unsigned value = 3 ;
101+ };
102+
103+ template <unsigned I> int get (triple);
104+ template <> int get<0 >(triple p) { return p.k ; }
105+ template <> int get<1 >(triple p) { return p.v ; }
106+ template <> int get<2 >(triple p) { return p.w ; }
48107} // namespace std
49108
50109int f () {
@@ -58,6 +117,9 @@ int f() {
58117 auto &[c1, c2] = cmplx;
59118 int vctr __attribute__ ((vector_size (sizeof (int )*2 )))= {1 , 2 };
60119 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 };
61123 return //
62124 x1 //
63125 + //
0 commit comments