Skip to content

Commit f623683

Browse files
committed
[interop][SwiftToCxx] do not emit direct returns/passes when Swift's value type ABI is not yet supported
1 parent 0727d04 commit f623683

File tree

3 files changed

+73
-17
lines changed

3 files changed

+73
-17
lines changed

lib/PrintAsClang/PrintClangFunction.cpp

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -556,8 +556,10 @@ static std::string encodeTypeInfo(const T &abiTypeInfo,
556556
return std::move(typeEncodingOS.str());
557557
}
558558

559+
// Returns false if the given direct type is not yet supported because
560+
// of its ABI.
559561
template <class T>
560-
static void printDirectReturnOrParamCType(
562+
static bool printDirectReturnOrParamCType(
561563
const T &abiTypeInfo, Type valueType, const ModuleDecl *emittedModule,
562564
raw_ostream &os, raw_ostream &cPrologueOS,
563565
PrimitiveTypeMapping &typeMapping,
@@ -575,20 +577,21 @@ static void printDirectReturnOrParamCType(
575577

576578
unsigned Count = 0;
577579
clang::CharUnits lastOffset;
578-
abiTypeInfo.enumerateRecordMembers(
579-
[&](clang::CharUnits offset, clang::CharUnits end, Type t) {
580+
if (abiTypeInfo.enumerateRecordMembers([&](clang::CharUnits offset,
581+
clang::CharUnits end, Type t) {
580582
lastOffset = offset;
581583
++Count;
582584
addABIRecordToTypeEncoding(typeEncodingOS, offset, end, t, typeMapping);
583-
});
585+
}))
586+
return false;
584587
assert(Count > 0 && "missing return values");
585588

586589
// FIXME: is this "prettyfying" logic sound for multiple return values?
587590
if (isKnownCType(valueType, typeMapping) ||
588591
(Count == 1 && lastOffset.isZero() && !valueType->hasTypeParameter() &&
589592
valueType->isAnyClassReferenceType())) {
590593
prettifiedValuePrinter();
591-
return;
594+
return true;
592595
}
593596

594597
os << "struct " << typeEncodingOS.str();
@@ -642,6 +645,7 @@ static void printDirectReturnOrParamCType(
642645
interopContext.runIfStubForDeclNotEmitted(typeEncodingOS.str(), [&]() {
643646
printStub(cPrologueOS, typeEncodingOS.str());
644647
});
648+
return true;
645649
}
646650

647651
/// Make adjustments to the Swift parameter name in generated C++, to
@@ -750,18 +754,20 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
750754
if (!directResultType) {
751755
os << "void";
752756
} else {
753-
printDirectReturnOrParamCType(
754-
*directResultType, resultTy, emittedModule, os, cPrologueOS,
755-
typeMapping, interopContext, [&]() {
756-
OptionalTypeKind retKind;
757-
Type objTy;
758-
std::tie(objTy, retKind) =
759-
DeclAndTypePrinter::getObjectTypeAndOptionality(FD, resultTy);
760-
761-
auto s = printClangFunctionReturnType(objTy, retKind, emittedModule,
762-
outputLang);
763-
assert(!s.isUnsupported());
764-
});
757+
if (!printDirectReturnOrParamCType(
758+
*directResultType, resultTy, emittedModule, os, cPrologueOS,
759+
typeMapping, interopContext, [&]() {
760+
OptionalTypeKind retKind;
761+
Type objTy;
762+
std::tie(objTy, retKind) =
763+
DeclAndTypePrinter::getObjectTypeAndOptionality(FD,
764+
resultTy);
765+
766+
auto s = printClangFunctionReturnType(
767+
objTy, retKind, emittedModule, outputLang);
768+
assert(!s.isUnsupported());
769+
}))
770+
return ClangRepresentation::unsupported;
765771
}
766772
} else {
767773
OptionalTypeKind retKind;

test/Inputs/clang-importer-sdk/usr/include/simd.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ typedef double __attribute__((ext_vector_type(3))) double3;
3939
typedef double __attribute__((ext_vector_type(4))) double4;
4040
typedef double __attribute__((ext_vector_type(8))) double8;
4141

42+
typedef struct { float4 columns[4]; } float4x4;
43+
4244
// Types that we should not be able to import.
4345
typedef char __attribute__((ext_vector_type(17))) char17;
4446
typedef unsigned char __attribute__((ext_vector_type(21))) uchar21;
@@ -89,6 +91,7 @@ ushort6 makes_ushort6();
8991
int128 makes_int128();
9092
uint20 makes_uint20();
9193

94+
#ifndef SIMD_NO_CODE
9295
takes_char2(char2);
9396
takes_char64(char64);
9497
takes_uchar3(uchar3);
@@ -130,3 +133,4 @@ takes_short5(short5);
130133
takes_ushort6(ushort6);
131134
takes_int128(int128);
132135
takes_uint20(uint20);
136+
#endif
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck %t/use-cxx-types.swift -typecheck -module-name UseCxxTy -emit-clang-header-path %t/UseCxxTy.h -I %t -enable-experimental-cxx-interop -disable-availability-checking -Xcc -DSIMD_NO_CODE
5+
6+
// RUN: %FileCheck %s < %t/UseCxxTy.h
7+
8+
// FIXME: remove once https://github.com/apple/swift/pull/60971 lands.
9+
// RUN: echo "#include \"header.h\"" > %t/full-cxx-swift-cxx-bridging.h
10+
// RUN: cat %t/UseCxxTy.h >> %t/full-cxx-swift-cxx-bridging.h
11+
12+
// RUN: %check-interop-cxx-header-in-clang(%t/full-cxx-swift-cxx-bridging.h -Wno-reserved-identifier -DSIMD_NO_CODE)
13+
14+
// This is required to verify that `Struct` is returned and passed directly.
15+
// REQUIRES: PTRSIZE=64
16+
17+
//--- header.h
18+
19+
#include <simd.h>
20+
21+
using simd_float4x4 = float4x4;
22+
23+
//--- module.modulemap
24+
module CxxTest {
25+
header "header.h"
26+
requires cplusplus
27+
}
28+
29+
//--- use-cxx-types.swift
30+
import CxxTest
31+
32+
public struct Struct {
33+
private let transform: simd_float4x4
34+
35+
public init() {
36+
transform = simd_float4x4()
37+
}
38+
}
39+
40+
public func passStruct(_ x : Struct) {
41+
42+
}
43+
44+
// CHECK: class SWIFT_SYMBOL("s:8UseCxxTy6StructV") Struct final {
45+
// CHECK-NOT: init(
46+
// CHECK: // Unavailable in C++: Swift global function 'passStruct(_:)'

0 commit comments

Comments
 (0)