Skip to content

Commit 9d6305c

Browse files
authored
Merge pull request swiftlang#80270 from swiftlang/gaborh/opt-foreign-reference-type
[cxx-interop] Support foreing reference types in generic context
2 parents 84d313f + d631b9a commit 9d6305c

File tree

4 files changed

+30
-7
lines changed

4 files changed

+30
-7
lines changed

lib/PrintAsClang/ModuleContentsWriter.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -579,8 +579,9 @@ class ModuleWriter {
579579
forwardDeclareCxxValueTypeIfNeeded(NTD);
580580
else if (isa<StructDecl>(TD) && NTD->hasClangNode())
581581
emitReferencedClangTypeMetadata(NTD);
582-
else if (isa<ClassDecl>(TD) && TD->isObjC())
583-
emitReferencedClangTypeMetadata(NTD);
582+
else if (const auto *cd = dyn_cast<ClassDecl>(TD))
583+
if (cd->isObjC() || cd->isForeignReferenceType())
584+
emitReferencedClangTypeMetadata(NTD);
584585
} else if (auto TAD = dyn_cast<TypeAliasDecl>(TD)) {
585586
if (TAD->hasClangNode())
586587
emitReferencedClangTypeMetadata(TAD);

lib/PrintAsClang/PrintClangFunction.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,15 @@ static bool isOptionalObjCExistential(Type ty) {
618618
return false;
619619
}
620620

621+
static bool isOptionalForeignReferenceType(Type ty) {
622+
if (auto obj = ty->getOptionalObjectType()) {
623+
if (const auto *cd =
624+
dyn_cast_or_null<ClassDecl>(obj->getNominalOrBoundGenericNominal()))
625+
return cd->isForeignReferenceType();
626+
}
627+
return false;
628+
}
629+
621630
// Returns false if the given direct type is not yet supported because
622631
// of its ABI.
623632
template <class T>
@@ -658,7 +667,8 @@ static bool printDirectReturnOrParamCType(
658667
if (isKnownCType(valueType, typeMapping) ||
659668
(Count == 1 && lastOffset.isZero() && !valueType->hasTypeParameter() &&
660669
(valueType->isAnyClassReferenceType() ||
661-
isOptionalObjCExistential(valueType)))) {
670+
isOptionalObjCExistential(valueType) ||
671+
isOptionalForeignReferenceType(valueType)))) {
662672
prettifiedValuePrinter();
663673
return true;
664674
}
@@ -1506,10 +1516,9 @@ void DeclAndTypeClangFunctionPrinter::printCxxThunkBody(
15061516
if (!nonOptResultType)
15071517
nonOptResultType = resultTy;
15081518
if (auto *classDecl = nonOptResultType->getClassOrBoundGenericClass();
1509-
classDecl || nonOptResultType->isObjCExistentialType()) {
1519+
(classDecl && isa<clang::ObjCContainerDecl>(classDecl->getClangDecl())) ||
1520+
nonOptResultType->isObjCExistentialType()) {
15101521
assert(!classDecl || classDecl->hasClangNode());
1511-
assert(!classDecl ||
1512-
isa<clang::ObjCContainerDecl>(classDecl->getClangDecl()));
15131522
os << "return (__bridge_transfer ";
15141523
declPrinter.withOutputStream(os).print(nonOptResultType);
15151524
os << ")(__bridge void *)";
@@ -1766,6 +1775,9 @@ bool DeclAndTypeClangFunctionPrinter::hasKnownOptionalNullableCxxMapping(
17661775
optionalObjectType->getNominalOrBoundGenericNominal())) {
17671776
return typeInfo->canBeNullable;
17681777
}
1778+
if (const auto *cd = dyn_cast<ClassDecl>(nominal))
1779+
if (cd->isForeignReferenceType())
1780+
return true;
17691781
return isa_and_nonnull<clang::ObjCInterfaceDecl>(nominal->getClangDecl());
17701782
}
17711783
}

lib/PrintAsClang/PrintClangValueType.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,9 @@ void ClangValueTypePrinter::printTypeGenericTraits(
641641
typeDecl, typeMetadataFuncName, typeMetadataFuncRequirements);
642642
});
643643
}
644-
bool addPointer = typeDecl->isObjC();
644+
auto classDecl = dyn_cast<ClassDecl>(typeDecl);
645+
bool addPointer =
646+
typeDecl->isObjC() || (classDecl && classDecl->isForeignReferenceType());
645647

646648
os << "#pragma clang diagnostic push\n";
647649
os << "#pragma clang diagnostic ignored \"-Wc++17-extensions\"\n";

test/Interop/CxxToSwiftToCxx/allow-shared-frt-back-to-cxx.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
// RUN: split-file %s %t
33

44
// RUN: %target-swift-frontend %t/use-cxx-types.swift -module-name UseCxxTy -typecheck -verify -emit-clang-header-path %t/UseCxxTy.h -I %t -enable-experimental-cxx-interop -clang-header-expose-decls=all-public -disable-availability-checking
5+
// RUN: cat %t/header.h >> %t/full-header.h
6+
// RUN: cat %t/UseCxxTy.h >> %t/full-header.h
7+
// RUN: %target-interop-build-clangxx -std=c++20 -c -xc++-header %t/full-header.h -o %t/o.o
58

69
// RUN: %FileCheck %s < %t/UseCxxTy.h
710

@@ -29,6 +32,11 @@ import CxxTest
2932
public func consumeSharedFRT(_ x: consuming SharedFRT) {}
3033
public func takeSharedFRT(_ x: SharedFRT) {}
3134

35+
public func takeSharedFRTGeneric(_ x: [SharedFRT]) {}
36+
public func returnSharedFRTGeneric() -> [SharedFRT] { [] }
37+
public func takeSharedFRTOptional(_ x: SharedFRT?) {}
38+
public func returnSharedFRTOptional() -> SharedFRT? { nil }
39+
3240
// CHECK: SWIFT_EXTERN void $s8UseCxxTy16consumeSharedFRTyySo0eF0VnF(SharedFRT *_Nonnull x) SWIFT_NOEXCEPT SWIFT_CALL; // consumeSharedFRT(_:)
3341

3442
// CHECK: SWIFT_EXTERN void $s8UseCxxTy13takeSharedFRTyySo0eF0VF(SharedFRT *_Nonnull x) SWIFT_NOEXCEPT SWIFT_CALL; // takeSharedFRT(_:)

0 commit comments

Comments
 (0)