@@ -972,7 +972,7 @@ bool ASTContext::supportsVersionedAvailability() const {
972972 return minimumAvailableOSVersionForTriple (LangOpts.Target ).has_value ();
973973}
974974
975- bool swift::isExported (const Decl *D) {
975+ ExportedLevel swift::isExported (const Decl *D) {
976976 if (auto *VD = dyn_cast<ValueDecl>(D)) {
977977 return isExported (VD);
978978 }
@@ -982,32 +982,36 @@ bool swift::isExported(const Decl *D) {
982982 return isExported (VD);
983983 }
984984
985- return false ;
985+ return ExportedLevel::None ;
986986 }
987987 if (auto *ED = dyn_cast<ExtensionDecl>(D)) {
988988 return isExported (ED);
989989 }
990990
991- return true ;
991+ return ExportedLevel::Exported ;
992992}
993993
994- bool swift::isExported (const ValueDecl *VD) {
994+ ExportedLevel swift::isExported (const ValueDecl *VD) {
995995 if (VD->getAttrs ().hasAttribute <ImplementationOnlyAttr>())
996- return false ;
996+ return ExportedLevel::None ;
997997 if (VD->isObjCMemberImplementation ())
998- return false ;
998+ return ExportedLevel::None ;
999999
10001000 // Is this part of the module's API or ABI?
10011001 AccessScope accessScope =
10021002 VD->getFormalAccessScope (nullptr ,
10031003 /* treatUsableFromInlineAsPublic*/ true );
10041004 if (accessScope.isPublic ())
1005- return true ;
1005+ return ExportedLevel::Exported ;
10061006
10071007 // Is this a stored property in a @frozen struct or class?
10081008 if (auto *property = dyn_cast<VarDecl>(VD))
10091009 if (property->isLayoutExposedToClients (/* applyImplicit=*/ true ))
1010- return true ;
1010+ return ExportedLevel::Exported;
1011+
1012+ // Case of an enum not marked @_implementationOnly in a non-resilient module?
1013+ if (auto *EED = dyn_cast<EnumElementDecl>(VD))
1014+ return isExported (EED->getParentEnum ());
10111015
10121016 // Is this a type exposed by default in a non-resilient module?
10131017 if (isa<NominalTypeDecl>(VD) &&
@@ -1016,13 +1020,9 @@ bool swift::isExported(const ValueDecl *VD) {
10161020 VD->getDeclContext ()->getParentModule ()->getResilienceStrategy () !=
10171021 ResilienceStrategy::Resilient &&
10181022 !VD->getAttrs ().hasAttribute <ImplementationOnlyAttr>())
1019- return true ;
1020-
1021- // Case of an enum not marked @_implementationOnly in a non-resilient module?
1022- if (auto *EED = dyn_cast<EnumElementDecl>(VD))
1023- return isExported (EED->getParentEnum ());
1023+ return ExportedLevel::Exported;
10241024
1025- return false ;
1025+ return ExportedLevel::None ;
10261026}
10271027
10281028bool swift::hasConformancesToPublicProtocols (const ExtensionDecl *ED) {
@@ -1046,23 +1046,22 @@ bool swift::hasConformancesToPublicProtocols(const ExtensionDecl *ED) {
10461046 return false ;
10471047}
10481048
1049- bool swift::isExported (const ExtensionDecl *ED) {
1049+ ExportedLevel swift::isExported (const ExtensionDecl *ED) {
10501050 // An extension can only be exported if it extends an exported type.
10511051 if (auto *NTD = ED->getExtendedNominal ()) {
1052- if (!isExported (NTD))
1053- return false ;
1054- }
1055-
1056- // If there are any exported members then the extension is exported.
1057- for (const Decl *D : ED->getMembers ()) {
1058- if (isExported (D))
1059- return true ;
1052+ if (isExported (NTD) == ExportedLevel::None)
1053+ return ExportedLevel::None;
10601054 }
10611055
10621056 // If the extension declares a conformance to a public protocol then the
10631057 // extension is exported.
10641058 if (hasConformancesToPublicProtocols (ED))
1065- return true ;
1059+ return ExportedLevel::Exported ;
10661060
1067- return false ;
1061+ // If there are any exported members then the extension is exported.
1062+ ExportedLevel exported = ExportedLevel::None;
1063+ for (const Decl *D : ED->getMembers ())
1064+ exported = std::max (exported, isExported (D));
1065+
1066+ return exported;
10681067}
0 commit comments