Skip to content

Commit 9a80d78

Browse files
committed
[interop][SwiftToCxx] pass and return UnsafePointer/UnsafeMutablePointer types
1 parent 3b4c6bf commit 9a80d78

File tree

3 files changed

+76
-0
lines changed

3 files changed

+76
-0
lines changed

lib/PrintAsClang/PrintClangFunction.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ getKnownTypeInfo(const TypeDecl *typeDecl, PrimitiveTypeMapping &typeMapping,
4242
bool isKnownType(Type t, PrimitiveTypeMapping &typeMapping,
4343
OutputLanguageMode languageMode) {
4444
const TypeDecl *typeDecl;
45+
if (auto *bgt = dyn_cast<BoundGenericStructType>(
46+
t->isOptional() ? t->getOptionalObjectType()->getDesugaredType()
47+
: t->getDesugaredType())) {
48+
return bgt->isUnsafePointer() || bgt->isUnsafeMutablePointer();
49+
}
50+
4551
if (auto *typeAliasType = dyn_cast<TypeAliasType>(t.getPointer()))
4652
typeDecl = typeAliasType->getDecl();
4753
else if (auto *structDecl = t->getStructOrBoundGenericStruct())
@@ -177,6 +183,35 @@ class CFunctionSignatureTypePrinter
177183
.printValueTypeReturnType(decl, languageMode, moduleContext);
178184
}
179185

186+
bool printIfKnownGenericStruct(const BoundGenericStructType *BGT,
187+
Optional<OptionalTypeKind> optionalKind,
188+
bool isInOutParam) {
189+
auto bgsTy = Type(const_cast<BoundGenericStructType *>(BGT));
190+
bool isConst;
191+
if (bgsTy->isUnsafePointer())
192+
isConst = true;
193+
else if (bgsTy->isUnsafeMutablePointer())
194+
isConst = false;
195+
else
196+
return false;
197+
198+
auto args = BGT->getGenericArgs();
199+
assert(args.size() == 1);
200+
visitPart(args.front(), OTK_None, /*isInOutParam=*/false);
201+
if (isConst)
202+
os << " const";
203+
os << " *";
204+
printNullability(optionalKind);
205+
return true;
206+
}
207+
208+
void visitBoundGenericStructType(BoundGenericStructType *BGT,
209+
Optional<OptionalTypeKind> optionalKind,
210+
bool isInOutParam) {
211+
if (printIfKnownGenericStruct(BGT, optionalKind, isInOutParam))
212+
return;
213+
}
214+
180215
void visitPart(Type Ty, Optional<OptionalTypeKind> optionalKind,
181216
bool isInOutParam) {
182217
TypeVisitor::visit(Ty, optionalKind, isInOutParam);

test/Interop/SwiftToCxx/functions/swift-primitive-functions-cxx-bridging.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,22 @@
131131
// CHECK-NEXT: return _impl::$s9Functions16passThroughUInt8ys0D0VADF(x);
132132
// CHECK-NEXT: }
133133

134+
// CHECK: inline int32_t * _Nullable passThroughUnsafeGenericMutableOptionalPointer(int32_t * _Nullable x) noexcept SWIFT_WARN_UNUSED_RESULT {
135+
// CHECK-NEXT: return _impl::$s9Functions46passThroughUnsafeGenericMutableOptionalPointerySpys5Int32VGSgAFF(x);
136+
// CHECK-NEXT: }
137+
138+
// CHECK: inline int32_t * _Nonnull passThroughUnsafeGenericMutablePointer(int32_t * _Nonnull x) noexcept SWIFT_WARN_UNUSED_RESULT {
139+
// CHECK-NEXT: return _impl::$s9Functions38passThroughUnsafeGenericMutablePointerySpys5Int32VGAEF(x);
140+
// CHECK-NEXT: }
141+
142+
// CHECK: inline int32_t const * _Nullable passThroughUnsafeGenericOptionalPointer(int32_t const * _Nullable x) noexcept SWIFT_WARN_UNUSED_RESULT {
143+
// CHECK-NEXT: return _impl::$s9Functions39passThroughUnsafeGenericOptionalPointerySPys5Int32VGSgAFF(x);
144+
// CHECK-NEXT: }
145+
146+
// CHECK: inline int32_t const * _Nonnull passThroughUnsafeGenericPointer(int32_t const * _Nonnull x) noexcept SWIFT_WARN_UNUSED_RESULT {
147+
// CHECK-NEXT: return _impl::$s9Functions31passThroughUnsafeGenericPointerySPys5Int32VGAEF(x);
148+
// CHECK-NEXT: }
149+
134150
// CHECK: inline void * _Nonnull passThroughUnsafeMutableRawPointer(void * _Nonnull x) noexcept SWIFT_WARN_UNUSED_RESULT {
135151
// CHECK-NEXT: return _impl::$s9Functions34passThroughUnsafeMutableRawPointeryS2vF(x);
136152
// CHECK-NEXT: }
@@ -189,3 +205,19 @@ public func passThroughUnsafeRawPointer(_ x: UnsafeRawPointer) -> UnsafeRawPoint
189205
public func passThroughUnsafeMutableRawPointer(_ x: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer { return x }
190206

191207
public func roundTwoPassThroughUnsafeMutableRawPointer(_ x: UnsafeMutableRawPointer?) -> UnsafeMutableRawPointer? { return x }
208+
209+
public func passThroughUnsafeGenericPointer(_ x: UnsafePointer<Int32>) -> UnsafePointer<Int32> {
210+
return x
211+
}
212+
213+
public func passThroughUnsafeGenericOptionalPointer(_ x: UnsafePointer<Int32>?) -> UnsafePointer<Int32>? {
214+
return x
215+
}
216+
217+
public func passThroughUnsafeGenericMutablePointer(_ x: UnsafeMutablePointer<Int32>) -> UnsafeMutablePointer<Int32> {
218+
return x
219+
}
220+
221+
public func passThroughUnsafeGenericMutableOptionalPointer(_ x: UnsafeMutablePointer<Int32>?) -> UnsafeMutablePointer<Int32>? {
222+
return x
223+
}

test/Interop/SwiftToCxx/functions/swift-primitive-functions-execution.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,13 @@ int main() {
6363
VERIFY_PASSTHROUGH_VALUE(passThroughUnsafeRawPointer, &x);
6464
VERIFY_PASSTHROUGH_VALUE(passThroughUnsafeMutableRawPointer, &x);
6565
VERIFY_PASSTHROUGH_VALUE(roundTwoPassThroughUnsafeMutableRawPointer, nullptr);
66+
67+
VERIFY_PASSTHROUGH_VALUE(passThroughUnsafeGenericMutableOptionalPointer, &x);
68+
VERIFY_PASSTHROUGH_VALUE(passThroughUnsafeGenericMutableOptionalPointer,
69+
nullptr);
70+
VERIFY_PASSTHROUGH_VALUE(passThroughUnsafeGenericMutablePointer, &x);
71+
const int y = 0;
72+
VERIFY_PASSTHROUGH_VALUE(passThroughUnsafeGenericOptionalPointer, &x);
73+
VERIFY_PASSTHROUGH_VALUE(passThroughUnsafeGenericOptionalPointer, nullptr);
74+
VERIFY_PASSTHROUGH_VALUE(passThroughUnsafeGenericPointer, &x);
6675
}

0 commit comments

Comments
 (0)