mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
SIL: Introduce '@_alwaysEmitIntoClient' attribute for use by standard library
This is like '@inlinable', except that the symbol does not have a public entry point in the generated binary at all; it is deserialized and a copy is always emitted into the client binary, with shared linkage. Just like '@inlinable', if you apply this to an internal declaration it becomes '@usableFromInline' automatically. This uses the same mechanism as default arguments ever since Swift 4, so it should work reasonably well, but there are rough edges with diagnostics and such. Don't use this if you are not the standard library. Fixes <rdar://problem/33767512>, <https://bugs.swift.org/browse/SR-5646>.
This commit is contained in:
@@ -290,10 +290,18 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
|
||||
/// or shared linkage.
|
||||
OnDemand,
|
||||
/// The declaration should never be made public.
|
||||
NeverPublic
|
||||
NeverPublic,
|
||||
/// The declaration should always be emitted into the client,
|
||||
AlwaysEmitIntoClient,
|
||||
};
|
||||
auto limit = Limit::None;
|
||||
|
||||
// @_alwaysEmitIntoClient declarations are like the default arguments of
|
||||
// public functions; they are roots for dead code elimination and have
|
||||
// serialized bodies, but no public symbol in the generated binary.
|
||||
if (d->getAttrs().hasAttribute<AlwaysEmitIntoClientAttr>())
|
||||
limit = Limit::AlwaysEmitIntoClient;
|
||||
|
||||
// ivar initializers and destroyers are completely contained within the class
|
||||
// from which they come, and never get seen externally.
|
||||
if (isIVarInitializerOrDestroyer()) {
|
||||
@@ -369,6 +377,8 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
|
||||
return SILLinkage::Shared;
|
||||
if (limit == Limit::NeverPublic)
|
||||
return maybeAddExternal(SILLinkage::Hidden);
|
||||
if (limit == Limit::AlwaysEmitIntoClient)
|
||||
return maybeAddExternal(SILLinkage::PublicNonABI);
|
||||
return maybeAddExternal(SILLinkage::Public);
|
||||
}
|
||||
llvm_unreachable("unhandled access");
|
||||
@@ -464,8 +474,8 @@ IsSerialized_t SILDeclRef::isSerialized() const {
|
||||
|
||||
auto *d = getDecl();
|
||||
|
||||
// Default argument generators are serialized if the function was
|
||||
// type-checked in Swift 4 mode.
|
||||
// Default argument generators are serialized if the containing
|
||||
// declaration is public.
|
||||
if (isDefaultArgGenerator()) {
|
||||
ResilienceExpansion expansion;
|
||||
if (auto *EED = dyn_cast<EnumElementDecl>(d)) {
|
||||
|
||||
Reference in New Issue
Block a user