Skip to content

Commit e1d812a

Browse files
committed
[interop][SwiftToCxx] pass class parameter types by 'inout'
1 parent 51c0a3f commit e1d812a

File tree

4 files changed

+32
-4
lines changed

4 files changed

+32
-4
lines changed

lib/PrintAsClang/PrintClangClassType.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ void ClangClassTypePrinter::printClassTypeDecl(
7676
os << "static inline void * _Nonnull getOpaquePointer(const ";
7777
printer.printBaseName(typeDecl);
7878
os << " &object) noexcept { return object._opaquePointer; }\n";
79+
os << "static inline void * _Nonnull &getOpaquePointerRef(";
80+
printer.printBaseName(typeDecl);
81+
os << " &object) noexcept { return object._opaquePointer; }\n";
7982
os << "};\n";
8083
});
8184
}
@@ -96,12 +99,16 @@ void ClangClassTypePrinter::printClassTypeReturnScaffold(
9699
void ClangClassTypePrinter::printParameterCxxtoCUseScaffold(
97100
raw_ostream &os, const ClassDecl *type, const ModuleDecl *moduleContext,
98101
llvm::function_ref<void(void)> bodyPrinter, bool isInOut) {
99-
// FIXME: Handle isInOut
102+
if (isInOut)
103+
os << '&';
100104
ClangSyntaxPrinter(os).printModuleNamespaceQualifiersIfNeeded(
101105
type->getModuleContext(), moduleContext);
102106
os << cxx_synthesis::getCxxImplNamespaceName() << "::";
103107
ClangValueTypePrinter::printCxxImplClassName(os, type);
104-
os << "::getOpaquePointer(";
108+
os << "::getOpaquePointer";
109+
if (isInOut)
110+
os << "Ref";
111+
os << '(';
105112
bodyPrinter();
106113
os << ')';
107114
}

lib/PrintAsClang/PrintClangFunction.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,13 @@ class CFunctionSignatureTypePrinter
151151
void visitClassType(ClassType *CT, Optional<OptionalTypeKind> optionalKind,
152152
bool isInOutParam) {
153153
// FIXME: handle optionalKind.
154-
// FIXME: handle isInOutParam.
155154
if (languageMode != OutputLanguageMode::Cxx) {
156155
os << "void * _Nonnull";
156+
if (isInOutParam)
157+
os << " * _Nonnull";
157158
return;
158159
}
159-
if (typeUseKind == FunctionSignatureTypeUse::ParamType)
160+
if (typeUseKind == FunctionSignatureTypeUse::ParamType && !isInOutParam)
160161
os << "const ";
161162
ClangSyntaxPrinter(os).printBaseName(CT->getDecl());
162163
if (typeUseKind == FunctionSignatureTypeUse::ParamType)

test/Interop/SwiftToCxx/class/swift-class-execution.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,19 @@ int main() {
5050
// CHECK-NEXT: ClassWithIntField: 0;
5151
// CHECK-NEXT: ClassWithIntField: 42;
5252
// CHECK-NEXT: ClassWithIntField: 42;
53+
// CHECK-NEXT: destroy ClassWithIntField
54+
55+
{
56+
auto x = returnClassWithIntField();
57+
assert(getRetainCount(x) == 1);
58+
takeClassWithIntFieldInout(x);
59+
assert(getRetainCount(x) == 1);
60+
takeClassWithIntField(x);
61+
}
62+
// CHECK-NEXT: init ClassWithIntField
63+
// CHECK-NEXT: init ClassWithIntField
64+
// CHECK-NEXT: destroy ClassWithIntField
65+
// CHECK-NEXT: ClassWithIntField: -11;
5366
// CHECK-NEXT: destroy ClassWithIntField
5467
return 0;
5568
}

test/Interop/SwiftToCxx/class/swift-class-in-cxx.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public final class ClassWithIntField {
2121
// CHECK: SWIFT_EXTERN void * _Nonnull $s5Class011passThroughA12WithIntFieldyAA0adeF0CADF(void * _Nonnull x) SWIFT_NOEXCEPT SWIFT_CALL; // passThroughClassWithIntField(_:)
2222
// CHECK-NEXT: SWIFT_EXTERN void * _Nonnull $s5Class06returnA12WithIntFieldAA0acdE0CyF(void) SWIFT_NOEXCEPT SWIFT_CALL; // returnClassWithIntField()
2323
// CHECK-NEXT: SWIFT_EXTERN void $s5Class04takeA12WithIntFieldyyAA0acdE0CF(void * _Nonnull x) SWIFT_NOEXCEPT SWIFT_CALL; // takeClassWithIntField(_:)
24+
// CHECK-NEXT: SWIFT_EXTERN void $s5Class04takeA17WithIntFieldInoutyyAA0acdE0CzF(void * _Nonnull * _Nonnull x) SWIFT_NOEXCEPT SWIFT_CALL; // takeClassWithIntFieldInout(_:)
2425

2526
// CHECK: namespace Class {
2627

@@ -47,6 +48,7 @@ public final class ClassWithIntField {
4748
// CHECK-NEXT:public:
4849
// CHECK-NEXT:static inline ClassWithIntField makeRetained(void * _Nonnull ptr) noexcept { return ClassWithIntField(ptr); }
4950
// CHECK-NEXT:static inline void * _Nonnull getOpaquePointer(const ClassWithIntField &object) noexcept { return object._opaquePointer; }
51+
// CHECK-NEXT:static inline void * _Nonnull &getOpaquePointerRef(ClassWithIntField &object) noexcept { return object._opaquePointer; }
5052
// CHECK-NEXT:};
5153
// CHECK-EMPTY:
5254
// CHECK-NEXT:} // namespace _impl
@@ -73,6 +75,11 @@ public func takeClassWithIntField(_ x: ClassWithIntField) {
7375
print("ClassWithIntField: \(x.field);")
7476
}
7577

78+
public func takeClassWithIntFieldInout(_ x: inout ClassWithIntField) {
79+
x = ClassWithIntField()
80+
x.field = -11
81+
}
82+
7683
// CHECK: inline ClassWithIntField returnClassWithIntField() noexcept SWIFT_WARN_UNUSED_RESULT {
7784
// CHECK-NEXT: return _impl::_impl_ClassWithIntField::makeRetained(_impl::$s5Class06returnA12WithIntFieldAA0acdE0CyF());
7885
// CHECK-NEXT: }

0 commit comments

Comments
 (0)