Skip to content

Commit 9e867e9

Browse files
committed
[interop][SwiftToCxx] support returning class values in enum's generic associated value getter
1 parent 773a043 commit 9e867e9

File tree

3 files changed

+40
-14
lines changed

3 files changed

+40
-14
lines changed

lib/PrintAsClang/PrintClangFunction.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -928,26 +928,26 @@ void DeclAndTypeClangFunctionPrinter::printGenericReturnSequence(
928928
os << " if constexpr (std::is_base_of<::swift::"
929929
<< cxx_synthesis::getCxxImplNamespaceName() << "::RefCountedClass, "
930930
<< resultTyName << ">::value) {\n";
931+
os << " void *returnValue;\n ";
931932
if (!initializeWithTakeFromValue) {
932-
os << " void *returnValue;\n ";
933933
invocationPrinter(/*additionalParam=*/StringRef(ros.str()));
934+
} else {
935+
os << "returnValue = *reinterpret_cast<void **>("
936+
<< *initializeWithTakeFromValue << ")";
937+
}
934938
os << ";\n";
935939
os << " return ::swift::" << cxx_synthesis::getCxxImplNamespaceName()
936940
<< "::implClassFor<" << resultTyName
937941
<< ">::type::makeRetained(returnValue);\n";
938-
} else {
939-
// FIXME: support taking a class pointer.
940-
os << "abort();\n";
941-
}
942-
os << " } else if constexpr (::swift::"
943-
<< cxx_synthesis::getCxxImplNamespaceName() << "::isValueType<"
944-
<< resultTyName << ">) {\n";
942+
os << " } else if constexpr (::swift::"
943+
<< cxx_synthesis::getCxxImplNamespaceName() << "::isValueType<"
944+
<< resultTyName << ">) {\n";
945945

946-
os << " return ::swift::" << cxx_synthesis::getCxxImplNamespaceName()
947-
<< "::implClassFor<" << resultTyName
948-
<< ">::type::returnNewValue([&](void * _Nonnull returnValue) {\n";
949-
if (!initializeWithTakeFromValue) {
950-
invocationPrinter(/*additionalParam=*/StringRef("returnValue"));
946+
os << " return ::swift::" << cxx_synthesis::getCxxImplNamespaceName()
947+
<< "::implClassFor<" << resultTyName
948+
<< ">::type::returnNewValue([&](void * _Nonnull returnValue) {\n";
949+
if (!initializeWithTakeFromValue) {
950+
invocationPrinter(/*additionalParam=*/StringRef("returnValue"));
951951
} else {
952952
os << " return ::swift::" << cxx_synthesis::getCxxImplNamespaceName()
953953
<< "::implClassFor<" << resultTyName

test/Interop/SwiftToCxx/generics/generic-enum-execution.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@
1414
#include <cassert>
1515
#include <cstdio>
1616

17+
extern "C" size_t swift_retainCount(void * _Nonnull obj);
18+
19+
size_t getRetainCount(const Generics::TracksDeinit & swiftClass) {
20+
void *p = swift::_impl::_impl_RefCountedClass::getOpaquePointer(swiftClass);
21+
return swift_retainCount(p);
22+
}
23+
1724
int main() {
1825
using namespace Generics;
1926

@@ -65,6 +72,21 @@ int main() {
6572
// CHECK-NEXT: init-TracksDeinit
6673
// CHECK-NEXT: destroy-TracksDeinit
6774
}
75+
{
76+
auto ptr = constructTracksDeinit();
77+
// CHECK-NEXT: init-TracksDeinit
78+
assert(getRetainCount(ptr) == 1);
79+
{
80+
auto x = makeGenericOpt<TracksDeinit>(ptr);
81+
assert(getRetainCount(ptr) == 2);
82+
auto ptr2 = x.getSome();
83+
assert(getRetainCount(ptr) == 3);
84+
}
85+
puts("after some");
86+
assert(getRetainCount(ptr) == 1);
87+
// CHECK-NEXT: after some
88+
// CHECK-NEXT: destroy-TracksDeinit
89+
}
6890
puts("EOF");
6991
// CHECK-NEXT: EOF
7092
return 0;

test/Interop/SwiftToCxx/generics/generic-enum-in-cxx.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
// FIXME: remove the need for -Wno-reserved-identifier
1212

13-
class TracksDeinit {
13+
public class TracksDeinit {
1414
init() {
1515
print("init-TracksDeinit")
1616
}
@@ -19,6 +19,10 @@ class TracksDeinit {
1919
}
2020
}
2121

22+
public func constructTracksDeinit() -> TracksDeinit {
23+
return TracksDeinit()
24+
}
25+
2226
@frozen
2327
public struct StructForEnum {
2428
let x: TracksDeinit

0 commit comments

Comments
 (0)