Skip to content

Commit c7d7354

Browse files
committed
AST: Refactor Decl::isWeakImported() API a little bit
First, remove the AvailabilityContext parameter; it was confusing because we actually always want to use the deployment target here. Then, split this method up into three methods: - isAlwaysWeakImported(): simply checks for a @_weakLinked attribute, either on the declaration itself or one of its parent contexts. - getAvailabilityForLinkage(): returns the OS version availability when this declaration was introduced, or if the declaration does not have explicit availability, check it's storage (if its an accessor), or its parent contexts. - isWeakImported(ModuleDecl *fromModule): combines these two checks to determine if the declaration should be weak linked when referenced from the given module, or if it might be weak referenced from some module (if the module parameter is null).
1 parent e9dfb73 commit c7d7354

File tree

12 files changed

+101
-61
lines changed

12 files changed

+101
-61
lines changed

include/swift/AST/Decl.h

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -975,9 +975,31 @@ class alignas(1 << DeclAlignInBits) Decl {
975975

976976
bool isPrivateStdlibDecl(bool treatNonBuiltinProtocolsAsPublic = true) const;
977977

978-
/// Whether this declaration is weak-imported.
979-
bool isWeakImported(ModuleDecl *fromModule,
980-
AvailabilityContext fromContext) const;
978+
AvailabilityContext getAvailabilityForLinkage() const;
979+
980+
/// Whether this declaration or one of its outer contexts has the
981+
/// @_weakLinked attribute.
982+
bool isAlwaysWeakImported() const;
983+
984+
/// Whether this declaration is weak-imported from the given module,
985+
/// either because of the presence of the @_weakLinked attribute, or
986+
/// because of availability.
987+
///
988+
/// Note that \p fromModule should either be the "main module" or
989+
/// nullptr. (This is because when it is non-null, we query the
990+
/// current deployment target, and not the deployment target that
991+
/// the module was built with.)
992+
///
993+
/// If \p fromModule is the main module, this returns false when the
994+
/// declaration is part of the main module, or if the declaration is
995+
/// at least as available as the current deployment target.
996+
///
997+
/// If \p fromModule is null, we instead return true if the
998+
/// declaration is meant to be weak linked with _some_ deployment
999+
/// target; that is, the presence of the @_weakLinked attribute or
1000+
/// any kind of availability is enough, irrespective of the current
1001+
/// deployment target.
1002+
bool isWeakImported(ModuleDecl *fromModule) const;
9811003

9821004
/// Returns true if the nature of this declaration allows overrides.
9831005
/// Note that this does not consider whether it is final or whether

include/swift/AST/ProtocolConformance.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,7 @@ class RootProtocolConformance : public ProtocolConformance {
349349
bool isInvalid() const;
350350

351351
/// Whether this conformance is weak-imported.
352-
bool isWeakImported(ModuleDecl *fromModule,
353-
AvailabilityContext fromContext) const;
352+
bool isWeakImported(ModuleDecl *fromModule) const;
354353

355354
bool hasWitness(ValueDecl *requirement) const;
356355
Witness getWitness(ValueDecl *requirement, LazyResolver *resolver) const;

include/swift/IRGen/Linking.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,8 +1102,7 @@ class LinkEntity {
11021102
}
11031103

11041104
/// Determine whether this entity will be weak-imported.
1105-
bool isWeakImported(ModuleDecl *module,
1106-
AvailabilityContext fromContext) const;
1105+
bool isWeakImported(ModuleDecl *module) const;
11071106

11081107
/// Return the source file whose codegen should trigger emission of this
11091108
/// link entity, if one can be identified.
@@ -1173,7 +1172,6 @@ class LinkInfo {
11731172

11741173
static LinkInfo get(const UniversalLinkageInfo &linkInfo,
11751174
ModuleDecl *swiftModule,
1176-
AvailabilityContext availabilityContext,
11771175
const LinkEntity &entity,
11781176
ForDefinition_t forDefinition);
11791177

lib/AST/Decl.cpp

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -609,42 +609,66 @@ bool Decl::isPrivateStdlibDecl(bool treatNonBuiltinProtocolsAsPublic) const {
609609
return false;
610610
}
611611

612-
bool Decl::isWeakImported(ModuleDecl *fromModule,
613-
AvailabilityContext fromContext) const {
612+
AvailabilityContext Decl::getAvailabilityForLinkage() const {
613+
auto containingContext =
614+
AvailabilityInference::annotatedAvailableRange(this, getASTContext());
615+
if (containingContext.hasValue())
616+
return *containingContext;
617+
618+
if (auto *accessor = dyn_cast<AccessorDecl>(this))
619+
return accessor->getStorage()->getAvailabilityForLinkage();
620+
621+
auto *dc = getDeclContext();
622+
if (auto *ext = dyn_cast<ExtensionDecl>(dc))
623+
return ext->getAvailabilityForLinkage();
624+
else if (auto *nominal = dyn_cast<NominalTypeDecl>(dc))
625+
return nominal->getAvailabilityForLinkage();
626+
627+
return AvailabilityContext::alwaysAvailable();
628+
}
629+
630+
bool Decl::isAlwaysWeakImported() const {
614631
// For a Clang declaration, trust Clang.
615632
if (auto clangDecl = getClangDecl()) {
616633
return clangDecl->isWeakImported();
617634
}
618635

619-
auto *containingModule = getModuleContext();
620-
if (containingModule == fromModule)
621-
return false;
622-
623-
auto containingContext =
624-
AvailabilityInference::availableRange(this,
625-
containingModule->getASTContext());
626-
if (!fromContext.isContainedIn(containingContext))
627-
return true;
628-
629636
if (getAttrs().hasAttribute<WeakLinkedAttr>())
630637
return true;
631638

632639
if (auto *accessor = dyn_cast<AccessorDecl>(this))
633-
return accessor->getStorage()->isWeakImported(fromModule, fromContext);
634-
635-
if (auto *dtor = dyn_cast<DestructorDecl>(this))
636-
return cast<ClassDecl>(dtor->getDeclContext())->isWeakImported(
637-
fromModule, fromContext);
640+
return accessor->getStorage()->isAlwaysWeakImported();
638641

639642
auto *dc = getDeclContext();
640643
if (auto *ext = dyn_cast<ExtensionDecl>(dc))
641-
return ext->isWeakImported(fromModule, fromContext);
642-
if (auto *ntd = dyn_cast<NominalTypeDecl>(dc))
643-
return ntd->isWeakImported(fromModule, fromContext);
644+
return ext->isAlwaysWeakImported();
645+
if (auto *nominal = dyn_cast<NominalTypeDecl>(dc))
646+
return nominal->isAlwaysWeakImported();
644647

645648
return false;
646649
}
647650

651+
bool Decl::isWeakImported(ModuleDecl *fromModule) const {
652+
if (fromModule == nullptr) {
653+
return (isAlwaysWeakImported() ||
654+
!getAvailabilityForLinkage().isAlwaysAvailable());
655+
}
656+
657+
if (getModuleContext() == fromModule)
658+
return false;
659+
660+
if (isAlwaysWeakImported())
661+
return true;
662+
663+
auto containingContext = getAvailabilityForLinkage();
664+
if (containingContext.isAlwaysAvailable())
665+
return false;
666+
667+
auto fromContext = AvailabilityContext::forDeploymentTarget(
668+
fromModule->getASTContext());
669+
return !fromContext.isContainedIn(containingContext);
670+
}
671+
648672
GenericParamList::GenericParamList(SourceLoc LAngleLoc,
649673
ArrayRef<GenericTypeParamDecl *> Params,
650674
SourceLoc WhereLoc,

lib/AST/ProtocolConformance.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -395,25 +395,24 @@ SourceLoc RootProtocolConformance::getLoc() const {
395395
}
396396

397397
bool
398-
RootProtocolConformance::isWeakImported(ModuleDecl *fromModule,
399-
AvailabilityContext fromContext) const {
398+
RootProtocolConformance::isWeakImported(ModuleDecl *fromModule) const {
400399
auto *dc = getDeclContext();
401400
if (dc->getParentModule() == fromModule)
402401
return false;
403402

404403
// If the protocol is weak imported, so are any conformances to it.
405-
if (getProtocol()->isWeakImported(fromModule, fromContext))
404+
if (getProtocol()->isWeakImported(fromModule))
406405
return true;
407406

408407
// If the conforming type is weak imported, so are any of its conformances.
409408
if (auto *nominal = getType()->getAnyNominal())
410-
if (nominal->isWeakImported(fromModule, fromContext))
409+
if (nominal->isWeakImported(fromModule))
411410
return true;
412411

413412
// If the conformance is declared in an extension with the @_weakLinked
414413
// attribute, it is weak imported.
415414
if (auto *ext = dyn_cast<ExtensionDecl>(dc))
416-
if (ext->isWeakImported(fromModule, fromContext))
415+
if (ext->isWeakImported(fromModule))
417416
return true;
418417

419418
return false;

lib/IRGen/AllocStackHoisting.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,7 @@ static bool isHoistable(AllocStackInst *Inst, irgen::IRGenModule &Mod) {
6262
bool foundWeaklyImported =
6363
SILTy.getASTType().findIf([&Mod](CanType type) -> bool {
6464
if (auto nominal = type->getNominalOrBoundGenericNominal())
65-
if (nominal->isWeakImported(Mod.getSwiftModule(),
66-
Mod.getAvailabilityContext())) {
65+
if (nominal->isWeakImported(Mod.getSwiftModule())) {
6766
return true;
6867
}
6968
return false;

lib/IRGen/GenDecl.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1718,8 +1718,7 @@ void irgen::updateLinkageForDefinition(IRGenModule &IGM,
17181718
// TODO: there are probably cases where we can avoid redoing the
17191719
// entire linkage computation.
17201720
UniversalLinkageInfo linkInfo(IGM);
1721-
bool weakImported = entity.isWeakImported(IGM.getSwiftModule(),
1722-
IGM.getAvailabilityContext());
1721+
bool weakImported = entity.isWeakImported(IGM.getSwiftModule());
17231722
auto IRL =
17241723
getIRLinkage(linkInfo, entity.getLinkage(ForDefinition),
17251724
ForDefinition, weakImported);
@@ -1739,13 +1738,11 @@ LinkInfo LinkInfo::get(IRGenModule &IGM, const LinkEntity &entity,
17391738
ForDefinition_t isDefinition) {
17401739
return LinkInfo::get(UniversalLinkageInfo(IGM),
17411740
IGM.getSwiftModule(),
1742-
IGM.getAvailabilityContext(),
17431741
entity, isDefinition);
17441742
}
17451743

17461744
LinkInfo LinkInfo::get(const UniversalLinkageInfo &linkInfo,
17471745
ModuleDecl *swiftModule,
1748-
AvailabilityContext availabilityContext,
17491746
const LinkEntity &entity,
17501747
ForDefinition_t isDefinition) {
17511748
LinkInfo result;
@@ -1761,7 +1758,7 @@ LinkInfo LinkInfo::get(const UniversalLinkageInfo &linkInfo,
17611758
ForDefinition_t(swiftModule->isStdlibModule() || isDefinition);
17621759

17631760
entity.mangle(result.Name);
1764-
bool weakImported = entity.isWeakImported(swiftModule, availabilityContext);
1761+
bool weakImported = entity.isWeakImported(swiftModule);
17651762
result.IRL = getIRLinkage(linkInfo, entity.getLinkage(isStdlibOrDefinition),
17661763
isDefinition, weakImported);
17671764
result.ForDefinition = isDefinition;

lib/IRGen/GenEnum.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5465,8 +5465,7 @@ namespace {
54655465
llvm::BasicBlock *conditionalBlock = nullptr;
54665466
llvm::BasicBlock *afterConditionalBlock = nullptr;
54675467
llvm::BasicBlock *beforeNullPtrCheck = nullptr;
5468-
if (Case->isWeakImported(IGM.getSwiftModule(),
5469-
IGM.getAvailabilityContext())) {
5468+
if (Case->isWeakImported(IGM.getSwiftModule())) {
54705469
beforeNullPtrCheck = IGF.Builder.GetInsertBlock();
54715470
auto address = IGM.getAddrOfEnumCase(Case, NotForDefinition);
54725471
conditionalBlock = llvm::BasicBlock::Create(C);

lib/IRGen/Linking.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -950,21 +950,20 @@ Alignment LinkEntity::getAlignment(IRGenModule &IGM) const {
950950
}
951951
}
952952

953-
bool LinkEntity::isWeakImported(ModuleDecl *module,
954-
AvailabilityContext context) const {
953+
bool LinkEntity::isWeakImported(ModuleDecl *module) const {
955954
switch (getKind()) {
956955
case Kind::SILGlobalVariable:
957956
if (getSILGlobalVariable()->getDecl()) {
958957
return getSILGlobalVariable()->getDecl()
959-
->isWeakImported(module, context);
958+
->isWeakImported(module);
960959
}
961960
return false;
962961
case Kind::DynamicallyReplaceableFunctionKey:
963962
case Kind::DynamicallyReplaceableFunctionVariable:
964963
case Kind::SILFunction: {
965964
// For imported functions check the Clang declaration.
966965
if (auto clangOwner = getSILFunction()->getClangNodeOwner())
967-
return clangOwner->isWeakImported(module, context);
966+
return clangOwner->isWeakImported(module);
968967

969968
// For native functions check a flag on the SILFunction
970969
// itself.
@@ -980,16 +979,16 @@ bool LinkEntity::isWeakImported(ModuleDecl *module,
980979
// type stored in extra storage area is weak linked.
981980
auto assocConformance = getAssociatedConformance();
982981
auto *depMemTy = assocConformance.first->castTo<DependentMemberType>();
983-
return depMemTy->getAssocType()->isWeakImported(module, context);
982+
return depMemTy->getAssocType()->isWeakImported(module);
984983
}
985984

986985
case Kind::BaseConformanceDescriptor:
987-
return cast<ProtocolDecl>(getDecl())->isWeakImported(module, context);
986+
return cast<ProtocolDecl>(getDecl())->isWeakImported(module);
988987

989988
case Kind::TypeMetadata:
990989
case Kind::TypeMetadataAccessFunction: {
991990
if (auto *nominalDecl = getType()->getAnyNominal())
992-
return nominalDecl->isWeakImported(module, context);
991+
return nominalDecl->isWeakImported(module);
993992
return false;
994993
}
995994

@@ -1021,12 +1020,12 @@ bool LinkEntity::isWeakImported(ModuleDecl *module,
10211020
case Kind::OpaqueTypeDescriptorAccessorImpl:
10221021
case Kind::OpaqueTypeDescriptorAccessorKey:
10231022
case Kind::OpaqueTypeDescriptorAccessorVar:
1024-
return getDecl()->isWeakImported(module, context);
1023+
return getDecl()->isWeakImported(module);
10251024

10261025
case Kind::ProtocolWitnessTable:
10271026
case Kind::ProtocolConformanceDescriptor:
10281027
return getProtocolConformance()->getRootConformance()
1029-
->isWeakImported(module, context);
1028+
->isWeakImported(module);
10301029

10311030
// TODO: Revisit some of the below, for weak conformances.
10321031
case Kind::ObjCMetadataUpdateFunction:

lib/SIL/SILFunctionBuilder.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,17 @@ SILFunctionBuilder::getOrCreateFunction(SILLocation loc, SILDeclRef constant,
159159
if (constant.isForeign && decl->hasClangNode())
160160
F->setClangNodeOwner(decl);
161161

162-
if (decl->isWeakImported(/*forModule=*/nullptr, availCtx))
162+
if (decl->isAlwaysWeakImported())
163163
F->setWeakLinked();
164+
else {
165+
auto containingContext = decl->getAvailabilityForLinkage();
166+
if (!containingContext.isAlwaysAvailable()) {
167+
auto fromContext = AvailabilityContext::forDeploymentTarget(
168+
decl->getASTContext());
169+
if (!fromContext.isContainedIn(containingContext))
170+
F->setWeakLinked();
171+
}
172+
}
164173

165174
if (auto *accessor = dyn_cast<AccessorDecl>(decl)) {
166175
auto *storage = accessor->getStorage();

lib/TBDGen/TBDGen.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,7 @@ void TBDGenVisitor::addSymbol(SILDeclRef declRef) {
7070

7171
void TBDGenVisitor::addSymbol(LinkEntity entity) {
7272
auto linkage =
73-
LinkInfo::get(UniversalLinkInfo, SwiftModule, AvailCtx,
74-
entity, ForDefinition);
73+
LinkInfo::get(UniversalLinkInfo, SwiftModule, entity, ForDefinition);
7574

7675
auto externallyVisible =
7776
llvm::GlobalValue::isExternalLinkage(linkage.getLinkage()) &&
@@ -630,8 +629,6 @@ static void enumeratePublicSymbolsAndWrite(ModuleDecl *M, FileUnit *singleFile,
630629
const auto &target = ctx.LangOpts.Target;
631630
UniversalLinkageInfo linkInfo(target, opts.HasMultipleIGMs, false,
632631
isWholeModule);
633-
auto availCtx = AvailabilityContext::forDeploymentTarget(ctx);
634-
635632
tapi::internal::InterfaceFile file;
636633
file.setFileType(tapi::internal::FileType::TBD_V3);
637634
file.setApplicationExtensionSafe(
@@ -646,7 +643,7 @@ static void enumeratePublicSymbolsAndWrite(ModuleDecl *M, FileUnit *singleFile,
646643
file.setArch(arch);
647644
file.setInstallAPI();
648645

649-
TBDGenVisitor visitor(file, arch, symbols, linkInfo, M, availCtx, opts);
646+
TBDGenVisitor visitor(file, arch, symbols, linkInfo, M, opts);
650647

651648
auto visitFile = [&](FileUnit *file) {
652649
if (file == M->getFiles()[0]) {

lib/TBDGen/TBDGenVisitor.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
4848

4949
const UniversalLinkageInfo &UniversalLinkInfo;
5050
ModuleDecl *SwiftModule;
51-
AvailabilityContext AvailCtx;
5251
const TBDGenOptions &Opts;
5352

5453
private:
@@ -74,11 +73,10 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
7473
TBDGenVisitor(tapi::internal::InterfaceFile &symbols,
7574
tapi::internal::ArchitectureSet archs, StringSet *stringSymbols,
7675
const UniversalLinkageInfo &universalLinkInfo,
77-
ModuleDecl *swiftModule, AvailabilityContext availCtx,
78-
const TBDGenOptions &opts)
76+
ModuleDecl *swiftModule, const TBDGenOptions &opts)
7977
: Symbols(symbols), Archs(archs), StringSymbols(stringSymbols),
8078
UniversalLinkInfo(universalLinkInfo), SwiftModule(swiftModule),
81-
AvailCtx(availCtx), Opts(opts) {}
79+
Opts(opts) {}
8280

8381
void addMainIfNecessary(FileUnit *file) {
8482
// HACK: 'main' is a special symbol that's always emitted in SILGen if

0 commit comments

Comments
 (0)