mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Sema] Intro @_spiOnly attribute and import filter
Introduce the attribute and basic import filter logic.
This commit is contained in:
@@ -768,6 +768,11 @@ SIMPLE_DECL_ATTR(typeWrapper, TypeWrapper,
|
||||
ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
|
||||
134)
|
||||
|
||||
SIMPLE_DECL_ATTR(_spiOnly, SPIOnly,
|
||||
OnImport | UserInaccessible |
|
||||
ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
|
||||
135)
|
||||
|
||||
// If you're adding a new underscored attribute here, please document it in
|
||||
// docs/ReferenceGuides/UnderscoredAttributes.md.
|
||||
|
||||
|
||||
@@ -88,7 +88,11 @@ enum class ImportFlags {
|
||||
WeakLinked = 0x40,
|
||||
|
||||
/// Used for DenseMap.
|
||||
Reserved = 0x80
|
||||
Reserved = 0x80,
|
||||
|
||||
/// The imported module can only be referenced from SPI decls, or
|
||||
/// implementation details.
|
||||
SPIOnly = 0x100
|
||||
};
|
||||
|
||||
/// \see ImportFlags
|
||||
|
||||
@@ -696,11 +696,13 @@ public:
|
||||
Default = 1 << 1,
|
||||
/// Include imports declared with `@_implementationOnly`.
|
||||
ImplementationOnly = 1 << 2,
|
||||
/// Include imports of SPIs declared with `@_spi`
|
||||
/// Include imports of SPIs declared with `@_spi`.
|
||||
SPIAccessControl = 1 << 3,
|
||||
/// Include imports declared with `@_spiOnly`.
|
||||
SPIOnly = 1 << 4,
|
||||
/// Include imports shadowed by a cross-import overlay. Unshadowed imports
|
||||
/// are included whether or not this flag is specified.
|
||||
ShadowedByCrossImportOverlay = 1 << 4
|
||||
ShadowedByCrossImportOverlay = 1 << 5
|
||||
};
|
||||
/// \sa getImportedModules
|
||||
using ImportFilter = OptionSet<ImportFilterKind>;
|
||||
|
||||
@@ -195,6 +195,7 @@ ImportSet &ImportCache::getImportSet(const DeclContext *dc) {
|
||||
file->getImportedModules(imports,
|
||||
{ModuleDecl::ImportFilterKind::Default,
|
||||
ModuleDecl::ImportFilterKind::ImplementationOnly,
|
||||
ModuleDecl::ImportFilterKind::SPIOnly,
|
||||
ModuleDecl::ImportFilterKind::SPIAccessControl});
|
||||
}
|
||||
|
||||
@@ -279,6 +280,7 @@ ImportCache::getAllAccessPathsNotShadowedBy(const ModuleDecl *mod,
|
||||
file->getImportedModules(stack,
|
||||
{ModuleDecl::ImportFilterKind::Default,
|
||||
ModuleDecl::ImportFilterKind::ImplementationOnly,
|
||||
ModuleDecl::ImportFilterKind::SPIOnly,
|
||||
ModuleDecl::ImportFilterKind::SPIAccessControl});
|
||||
}
|
||||
|
||||
|
||||
@@ -1596,6 +1596,8 @@ SourceFile::getImportedModules(SmallVectorImpl<ImportedModule> &modules,
|
||||
requiredFilter |= ModuleDecl::ImportFilterKind::Exported;
|
||||
else if (desc.options.contains(ImportFlags::ImplementationOnly))
|
||||
requiredFilter |= ModuleDecl::ImportFilterKind::ImplementationOnly;
|
||||
else if (desc.options.contains(ImportFlags::SPIOnly))
|
||||
requiredFilter |= ModuleDecl::ImportFilterKind::SPIOnly;
|
||||
else if (desc.options.contains(ImportFlags::SPIAccessControl))
|
||||
requiredFilter |= ModuleDecl::ImportFilterKind::SPIAccessControl;
|
||||
else
|
||||
@@ -1904,6 +1906,7 @@ SourceFile::collectLinkLibraries(ModuleDecl::LinkLibraryCallback callback) const
|
||||
|
||||
ModuleDecl::ImportFilter topLevelFilter = filter;
|
||||
topLevelFilter |= ModuleDecl::ImportFilterKind::ImplementationOnly;
|
||||
topLevelFilter |= ModuleDecl::ImportFilterKind::SPIOnly;
|
||||
topLevel->getImportedModules(stack, topLevelFilter);
|
||||
|
||||
// Make sure the top-level module is first; we want pre-order-ish traversal.
|
||||
@@ -2600,6 +2603,7 @@ canBeUsedForCrossModuleOptimization(DeclContext *ctxt) const {
|
||||
// @_implementationOnly or @_spi.
|
||||
ModuleDecl::ImportFilter filter = {
|
||||
ModuleDecl::ImportFilterKind::ImplementationOnly,
|
||||
ModuleDecl::ImportFilterKind::SPIOnly,
|
||||
ModuleDecl::ImportFilterKind::SPIAccessControl
|
||||
};
|
||||
SmallVector<ImportedModule, 4> results;
|
||||
|
||||
@@ -536,6 +536,9 @@ UnboundImport::UnboundImport(ImportDecl *ID)
|
||||
if (ID->getAttrs().hasAttribute<ImplementationOnlyAttr>())
|
||||
import.options |= ImportFlags::ImplementationOnly;
|
||||
|
||||
if (ID->getAttrs().hasAttribute<SPIOnlyAttr>())
|
||||
import.options |= ImportFlags::SPIOnly;
|
||||
|
||||
if (auto *privateImportAttr =
|
||||
ID->getAttrs().getAttribute<PrivateImportAttr>()) {
|
||||
import.options |= ImportFlags::PrivateImport;
|
||||
|
||||
@@ -296,6 +296,7 @@ public:
|
||||
void visitResultBuilderAttr(ResultBuilderAttr *attr);
|
||||
|
||||
void visitImplementationOnlyAttr(ImplementationOnlyAttr *attr);
|
||||
void visitSPIOnlyAttr(SPIOnlyAttr *attr);
|
||||
void visitNonEphemeralAttr(NonEphemeralAttr *attr);
|
||||
void checkOriginalDefinedInAttrs(ArrayRef<OriginallyDefinedInAttr *> Attrs);
|
||||
|
||||
@@ -3908,6 +3909,10 @@ AttributeChecker::visitImplementationOnlyAttr(ImplementationOnlyAttr *attr) {
|
||||
// it won't necessarily be able to say why.
|
||||
}
|
||||
|
||||
void
|
||||
AttributeChecker::visitSPIOnlyAttr(SPIOnlyAttr *attr) {
|
||||
}
|
||||
|
||||
void AttributeChecker::visitTypeSequenceAttr(TypeSequenceAttr *attr) {
|
||||
if (!isa<GenericTypeParamDecl>(D)) {
|
||||
attr->setInvalid();
|
||||
|
||||
@@ -1582,6 +1582,7 @@ namespace {
|
||||
UNINTERESTING_ATTR(Frozen)
|
||||
UNINTERESTING_ATTR(HasInitialValue)
|
||||
UNINTERESTING_ATTR(ImplementationOnly)
|
||||
UNINTERESTING_ATTR(SPIOnly)
|
||||
UNINTERESTING_ATTR(Custom)
|
||||
UNINTERESTING_ATTR(PropertyWrapper)
|
||||
UNINTERESTING_ATTR(TypeWrapper)
|
||||
|
||||
Reference in New Issue
Block a user