Skip to content

Commit 6ecaaa4

Browse files
authored
Merge pull request #70304 from apple/egorzhdan/conforms-to-derived-class
[cxx-interop] Propagate `CONFORMS_TO` attribute to derived classes
2 parents d204d04 + 45b2254 commit 6ecaaa4

File tree

3 files changed

+52
-3
lines changed

3 files changed

+52
-3
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2828,13 +2828,24 @@ namespace {
28282828
}
28292829

28302830
if (auto *ntd = dyn_cast<NominalTypeDecl>(result))
2831-
addExplicitProtocolConformances(ntd);
2831+
addExplicitProtocolConformances(ntd, decl);
28322832

28332833
return result;
28342834
}
28352835

2836-
void addExplicitProtocolConformances(NominalTypeDecl *decl) {
2837-
auto clangDecl = decl->getClangDecl();
2836+
void
2837+
addExplicitProtocolConformances(NominalTypeDecl *decl,
2838+
const clang::CXXRecordDecl *clangDecl) {
2839+
if (Impl.isCxxInteropCompatVersionAtLeast(
2840+
version::getUpcomingCxxInteropCompatVersion())) {
2841+
// Propagate conforms_to attribute from public base classes.
2842+
for (auto base : clangDecl->bases()) {
2843+
if (base.getAccessSpecifier() != clang::AccessSpecifier::AS_public)
2844+
continue;
2845+
if (auto *baseClangDecl = base.getType()->getAsCXXRecordDecl())
2846+
addExplicitProtocolConformances(decl, baseClangDecl);
2847+
}
2848+
}
28382849

28392850
if (!clangDecl->hasAttrs())
28402851
return;

test/Interop/Cxx/class/Inputs/conforms-to.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,19 @@ struct
2222
void testImported() const;
2323
};
2424

25+
struct DerivedFromHasTest : HasTest {};
26+
struct DerivedFromDerivedFromHasTest : HasTest {};
27+
28+
struct __attribute__((swift_attr("conforms_to:SwiftTest.Testable")))
29+
DerivedFromDerivedFromHasTestWithDuplicateArg : HasTest {};
30+
31+
struct DerivedFromHasPlay : HasPlay {};
32+
struct DerivedFromDerivedFromHasPlay : HasPlay {};
33+
34+
struct HasTestAndPlay : HasPlay, HasTest {};
35+
struct DerivedFromHasTestAndPlay : HasPlay, HasTest {};
36+
37+
struct DerivedFromHasImportedConf : HasImportedConf {};
38+
struct DerivedFromDerivedFromHasImportedConf : HasImportedConf {};
39+
2540
#endif // TEST_INTEROP_CXX_CLASS_INPUTS_DESTRUCTORS_H

test/Interop/Cxx/class/conforms-to.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// RUN: %target-swift-frontend %S/Inputs/conforms-to-imported.swift -module-name ImportedModule -emit-module -emit-module-path %t/ImportedModule.swiftmodule
33

44
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %t -I %S/Inputs -module-name SwiftTest -enable-experimental-cxx-interop
5+
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %t -I %S/Inputs -module-name SwiftTest -cxx-interoperability-mode=upcoming-swift -D UPCOMING_SWIFT
56

67
import ConformsTo
78
import ImportedModule
@@ -21,6 +22,11 @@ func callee(_ _: Testable) {
2122
func caller(_ x: HasTest) {
2223
callee(x)
2324
}
25+
#if UPCOMING_SWIFT
26+
func caller(_ x: DerivedFromHasTest) { callee(x) }
27+
func caller(_ x: DerivedFromDerivedFromHasTest) { callee(x) }
28+
func caller(_ x: DerivedFromDerivedFromHasTestWithDuplicateArg) { callee(x) }
29+
#endif
2430

2531
func callee(_ _: Playable) {
2632

@@ -29,10 +35,27 @@ func callee(_ _: Playable) {
2935
func caller(_ x: Playable) {
3036
callee(x)
3137
}
38+
#if UPCOMING_SWIFT
39+
func caller(_ x: DerivedFromHasPlay) { callee(x) }
40+
func caller(_ x: DerivedFromDerivedFromHasPlay) { callee(x) }
41+
42+
func caller(_ x: HasTestAndPlay) {
43+
callee(x as Testable)
44+
callee(x as Playable)
45+
}
46+
func caller(_ x: DerivedFromHasTestAndPlay) {
47+
callee(x as Testable)
48+
callee(x as Playable)
49+
}
50+
#endif
3251

3352
func callee(_ _: ProtocolFromImportedModule) {
3453
}
3554

3655
func caller(_ x: HasImportedConf) {
3756
callee(x)
3857
}
58+
#if UPCOMING_SWIFT
59+
func caller(_ x: DerivedFromHasImportedConf) { callee(x) }
60+
func caller(_ x: DerivedFromDerivedFromHasImportedConf) { callee(x) }
61+
#endif

0 commit comments

Comments
 (0)