mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
AST: Functions nested in exportable functions are also exportable.
Centralize the exportability checking logic for nested functions in the `DeclExportabilityVisitor` utility. This logic was previously added to SILGen but there should not be special casing for nested functions at that layer.
This commit is contained in:
@@ -50,6 +50,20 @@ public:
|
||||
bool visitDecl(const Decl *D) = delete;
|
||||
bool visitValueDecl(const ValueDecl *valueDecl) = delete;
|
||||
|
||||
bool visitAbstractFunctionDecl(const AbstractFunctionDecl *afd) {
|
||||
// If this function is nested within another function that is exportable to
|
||||
// clients then it is also exportable.
|
||||
auto dc = afd->getDeclContext();
|
||||
do {
|
||||
if (auto parent = dyn_cast<AbstractFunctionDecl>(dc)) {
|
||||
if (DeclExportabilityVisitor().visit(parent))
|
||||
return true;
|
||||
}
|
||||
} while ((dc = dc->getParent()));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool visitExtensionDecl(const ExtensionDecl *ext) {
|
||||
// Extensions must extend exportable types to be exportable.
|
||||
auto nominalType = ext->getExtendedNominal();
|
||||
@@ -135,7 +149,6 @@ public:
|
||||
DEFAULT_TO_ACCESS_LEVEL(TypeAlias);
|
||||
DEFAULT_TO_ACCESS_LEVEL(AssociatedType);
|
||||
DEFAULT_TO_ACCESS_LEVEL(AbstractStorage);
|
||||
DEFAULT_TO_ACCESS_LEVEL(AbstractFunction);
|
||||
DEFAULT_TO_ACCESS_LEVEL(Macro);
|
||||
DEFAULT_TO_ACCESS_LEVEL(EnumElement);
|
||||
|
||||
|
||||
@@ -784,20 +784,6 @@ bool SILGenModule::shouldSkipDecl(Decl *D) {
|
||||
if (D->isExposedToClients())
|
||||
return false;
|
||||
|
||||
if (isa<AbstractFunctionDecl>(D)) {
|
||||
// If this function is nested within another function that is exposed to
|
||||
// clients then it should be emitted.
|
||||
auto dc = D->getDeclContext();
|
||||
do {
|
||||
if (auto afd = dyn_cast<AbstractFunctionDecl>(dc))
|
||||
if (afd->isExposedToClients())
|
||||
return false;
|
||||
} while ((dc = dc->getParent()));
|
||||
|
||||
// We didn't find a parent function that is exposed.
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,11 +70,20 @@ public struct PublicStruct {
|
||||
// SAFETY-PRIVATE: Serialization safety, unsafe: 'init(fileprivateInit:)'
|
||||
|
||||
@inlinable public func inlinableFunc() {
|
||||
typealias localTypealias = Int
|
||||
}
|
||||
// SAFETY-PRIVATE: Serialization safety, safe: 'inlinableFunc()'
|
||||
public func publicFunc() {}
|
||||
typealias localTypealias = Int
|
||||
|
||||
func inlinableFunc_nested() {}
|
||||
// SAFETY-PRIVATE-NOT: inlinableFunc_nested()
|
||||
inlinableFunc_nested()
|
||||
}
|
||||
|
||||
public func publicFunc() {
|
||||
// SAFETY-PRIVATE: Serialization safety, safe: 'publicFunc()'
|
||||
func publicFunc_nested() {}
|
||||
// SAFETY-PRIVATE-NOT: publicFunc_nested()
|
||||
publicFunc_nested()
|
||||
}
|
||||
|
||||
@available(SwiftStdlib 5.1, *) // for the `some` keyword.
|
||||
public func opaqueTypeFunc() -> some PublicProto {
|
||||
|
||||
Reference in New Issue
Block a user