Skip to content

Commit 3ca33e6

Browse files
authored
Merge pull request #61305 from hyp/eng/class-inits
[interop][SwiftToCxx] support initializers for classes
2 parents d4b690c + 5736daf commit 3ca33e6

File tree

3 files changed

+66
-0
lines changed

3 files changed

+66
-0
lines changed

lib/PrintAsClang/PrintClangFunction.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,6 +1059,20 @@ void DeclAndTypeClangFunctionPrinter::printCxxThunkBody(
10591059
emitNewParam();
10601060
std::string paramName;
10611061
if (param.isSelfParameter()) {
1062+
bool needsStaticSelf = isa<ConstructorDecl>(FD);
1063+
if (needsStaticSelf) {
1064+
os << "swift::TypeMetadataTrait<";
1065+
CFunctionSignatureTypePrinter typePrinter(
1066+
os, cPrologueOS, typeMapping, OutputLanguageMode::Cxx,
1067+
interopContext, CFunctionSignatureTypePrinterModifierDelegate(),
1068+
moduleContext, declPrinter,
1069+
FunctionSignatureTypeUse::TypeReference);
1070+
auto result = typePrinter.visit(param.getType(), OTK_None,
1071+
/*isInOutParam=*/false);
1072+
assert(!result.isUnsupported());
1073+
os << ">::getTypeMetadata()";
1074+
return;
1075+
}
10621076
paramName = "*this";
10631077
} else if (param.getName().empty()) {
10641078
llvm::raw_string_ostream paramOS(paramName);

test/Interop/SwiftToCxx/initializers/init-in-cxx-execution.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,20 @@ int main() {
4646
// CHECK-NEXT: create RefCountedClass 22
4747
// CHECK-NEXT: destroy RefCountedClass 22
4848
// CHECK-NEXT: destroy RefCountedClass -1
49+
50+
{
51+
auto x = FinalClass::init(FirstSmallStruct::init(78));
52+
assert(x.getProp().getX() == 78);
53+
}
54+
55+
{
56+
auto x = DerivedClass::init(1, 2);
57+
assert(x.getX() == 5);
58+
}
59+
60+
{
61+
auto x = DerivedClassTwo::init(1, 2);
62+
assert(x.getX() == 3);
63+
}
4964
return 0;
5065
}

test/Interop/SwiftToCxx/initializers/init-in-cxx.swift

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
// RUN: %check-interop-cxx-header-in-clang(%t/inits.h -Wno-unused-function)
66

77

8+
// CHECK: SWIFT_EXTERN void * _Nonnull $s4Init9BaseClassCyACSi_SitcfC(ptrdiff_t x, ptrdiff_t y, SWIFT_CONTEXT void * _Nonnull _self) SWIFT_NOEXCEPT SWIFT_CALL; // init(_:_:)
9+
// CHECK-NEXT: SWIFT_EXTERN void * _Nonnull $s4Init12DerivedClassCyACSi_SitcfC(ptrdiff_t x, ptrdiff_t y, SWIFT_CONTEXT void * _Nonnull _self) SWIFT_NOEXCEPT SWIFT_CALL; // init(_:_:)
10+
811
// CHECK: SWIFT_EXTERN struct swift_interop_returnStub_Init_uint32_t_0_4 $s4Init16FirstSmallStructVACycfC(void) SWIFT_NOEXCEPT SWIFT_CALL; // init()
912
// CHECK-NEXT: SWIFT_EXTERN struct swift_interop_returnStub_Init_uint32_t_0_4 $s4Init16FirstSmallStructVyACSicfC(ptrdiff_t x) SWIFT_NOEXCEPT SWIFT_CALL; // init(_:)
1013

@@ -94,6 +97,40 @@ public struct StructWithRefCountStoredProp {
9497
// CHECK-NEXT: static inline StructWithRefCountStoredProp init(swift::Int x);
9598

9699

100+
public final class FinalClass {
101+
public var prop: FirstSmallStruct
102+
103+
public init(_ prop: FirstSmallStruct) { self.prop = prop }
104+
}
105+
106+
public class BaseClass {
107+
public var x: Int
108+
109+
public init(_ x: Int, _ y: Int) { self.x = x + y }
110+
}
111+
112+
public class DerivedClass: BaseClass {
113+
override public init(_ x: Int, _ y: Int) {
114+
super.init(x + 1, y + 1)
115+
}
116+
}
117+
118+
public class DerivedClassTwo: BaseClass {
119+
}
120+
121+
// CHECK: BaseClass BaseClass::init(swift::Int x, swift::Int y) {
122+
// CHECK-NEXT: return _impl::_impl_BaseClass::makeRetained(_impl::$s4Init9BaseClassCyACSi_SitcfC(x, y, swift::TypeMetadataTrait<BaseClass>::getTypeMetadata()));
123+
124+
// CHECK: DerivedClass DerivedClass::init(swift::Int x, swift::Int y) {
125+
// CHECK-NEXT: _impl::_impl_DerivedClass::makeRetained(_impl::$s4Init12DerivedClassCyACSi_SitcfC(x, y, swift::TypeMetadataTrait<DerivedClass>::getTypeMetadata()));
126+
127+
// CHECK: DerivedClassTwo DerivedClassTwo::init(swift::Int x, swift::Int y) {
128+
// CHECK-NEXT: return _impl::_impl_DerivedClassTwo::makeRetained(_impl::$s4Init15DerivedClassTwoCyACSi_SitcfC(x, y, swift::TypeMetadataTrait<DerivedClassTwo>::getTypeMetadata()));
129+
130+
// CHECK: FinalClass FinalClass::init(const FirstSmallStruct& prop) {
131+
// CHECK-NEXT: return _impl::_impl_FinalClass::makeRetained(_impl::$s4Init10FinalClassCyAcA16FirstSmallStructVcfC(_impl::swift_interop_passDirect_Init_uint32_t_0_4(_impl::_impl_FirstSmallStruct::getOpaquePointer(prop)), swift::TypeMetadataTrait<FinalClass>::getTypeMetadata()));
132+
133+
97134
// CHECK: inline uint32_t FirstSmallStruct::getX() const {
98135
// CHECK-NEXT: return _impl::$s4Init16FirstSmallStructV1xs6UInt32Vvg(_impl::swift_interop_passDirect_Init_uint32_t_0_4(_getOpaquePointer()));
99136
// CHECK-NEXT: }

0 commit comments

Comments
 (0)