Skip to content

Commit 934183f

Browse files
committed
[cxx-interop] Emit IR for std::get in structured bindings declaration
1 parent d0e5372 commit 934183f

File tree

4 files changed

+75
-0
lines changed

4 files changed

+75
-0
lines changed

lib/IRGen/GenClangDecl.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,14 @@ class ClangDeclFinder
8787
return true;
8888
}
8989

90+
bool VisitBindingDecl(clang::BindingDecl *BD) {
91+
if (auto *holdingVar = BD->getHoldingVar()) {
92+
if (holdingVar->hasInit())
93+
TraverseStmt(holdingVar->getInit());
94+
}
95+
return true;
96+
}
97+
9098
// Do not traverse unevaluated expressions. Doing to might result in compile
9199
// errors if we try to instantiate an un-instantiatable template.
92100

test/Interop/Cxx/class/Inputs/module.modulemap

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ module ProtocolConformance {
7878
requires cplusplus
7979
}
8080

81+
module StructuredBindingsGetMethod {
82+
header "structured-bindings-get-method.h"
83+
requires cplusplus
84+
}
85+
8186
module SynthesizedInitializers {
8287
header "synthesized-initializers.h"
8388
requires cplusplus
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#ifndef TEST_INTEROP_CXX_CLASS_STRUCTURED_BINDINGS_H
2+
#define TEST_INTEROP_CXX_CLASS_STRUCTURED_BINDINGS_H
3+
4+
namespace std {
5+
6+
template<class X, class Y>
7+
struct pear {
8+
pear(X x, Y y) {}
9+
10+
X getX() const {
11+
return 0;
12+
}
13+
Y getY() const {
14+
return 42;
15+
}
16+
};
17+
18+
template<class T>
19+
struct tuple_size {
20+
constexpr static const int value = 2;
21+
};
22+
23+
template<int n, class T>
24+
struct tuple_element {
25+
};
26+
27+
template<class X, class Y>
28+
struct tuple_element<0, pear<X, Y>> {
29+
using type = X;
30+
};
31+
32+
template<class X, class Y>
33+
struct tuple_element<1, pear<X, Y>> {
34+
using type = Y;
35+
};
36+
37+
template<int N, class X, class Y>
38+
inline typename tuple_element<N, pear<X, Y>>::type get(const pear<X, Y> & value) {
39+
if constexpr (N == 0) {
40+
return value.getX();
41+
} else {
42+
return value.getY();
43+
}
44+
}
45+
46+
} // namespace std
47+
48+
inline int testDestructure(int x) {
49+
auto val = std::pear<int, int>( x, x + 2 );
50+
auto [y,z] = val;
51+
return z;
52+
}
53+
54+
#endif // TEST_INTEROP_CXX_CLASS_STRUCTURED_BINDINGS_H
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %target-swiftxx-frontend -I %S/Inputs %s -emit-ir -Xcc -std=c++17 | %FileCheck %s
2+
3+
import StructuredBindingsGetMethod
4+
5+
let x = testDestructure(20)
6+
7+
// Make sure the definition of `std::get` is emitted.
8+
// CHECK: define {{.*}} @{{_ZSt3getILi0EiiENSt13tuple_elementIXT_ESt4pearIT0_T1_EE4typeERKS4_|"\?\?\$get@\$0A@HH@std@@YAHAEBU\?\$pear@HH@0@@Z"}}

0 commit comments

Comments
 (0)