Skip to content

Commit b4dafae

Browse files
authored
Merge pull request #22729 from slavapestov/availability-weak-import
Weakly import declarations with conditional availability
2 parents 430a3bd + 3bf5a17 commit b4dafae

21 files changed

+193
-42
lines changed

include/swift/AST/Availability.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,10 @@ class AvailabilityContext {
240240
/// Creates a context that requires certain versions of the target OS.
241241
explicit AvailabilityContext(VersionRange OSVersion) : OSVersion(OSVersion) {}
242242

243+
/// Creates a context that imposes the constraints of the ASTContext's
244+
/// deployment target.
245+
static AvailabilityContext forDeploymentTarget(ASTContext &Ctx);
246+
243247
/// Creates a context that imposes no constraints.
244248
///
245249
/// \see isAlwaysAvailable

include/swift/AST/Decl.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ namespace swift {
4747
enum class AccessSemantics : unsigned char;
4848
class AccessorDecl;
4949
class ApplyExpr;
50+
class AvailabilityContext;
5051
class GenericEnvironment;
5152
class ArchetypeType;
5253
class ASTContext;
@@ -940,7 +941,8 @@ class alignas(1 << DeclAlignInBits) Decl {
940941
bool isPrivateStdlibDecl(bool treatNonBuiltinProtocolsAsPublic = true) const;
941942

942943
/// Whether this declaration is weak-imported.
943-
bool isWeakImported(ModuleDecl *fromModule) const;
944+
bool isWeakImported(ModuleDecl *fromModule,
945+
AvailabilityContext fromContext) const;
944946

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

include/swift/AST/ProtocolConformance.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,8 @@ class RootProtocolConformance : public ProtocolConformance {
348348
bool isInvalid() const;
349349

350350
/// Whether this conformance is weak-imported.
351-
bool isWeakImported(ModuleDecl *fromModule) const;
351+
bool isWeakImported(ModuleDecl *fromModule,
352+
AvailabilityContext fromContext) const;
352353

353354
bool hasWitness(ValueDecl *requirement) const;
354355
Witness getWitness(ValueDecl *requirement, LazyResolver *resolver) const;

include/swift/IRGen/Linking.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ class Triple;
3232
}
3333

3434
namespace swift {
35+
class AvailabilityContext;
36+
3537
namespace irgen {
3638
class IRGenModule;
3739
class Alignment;
@@ -1021,7 +1023,8 @@ class LinkEntity {
10211023
}
10221024

10231025
/// Determine whether this entity will be weak-imported.
1024-
bool isWeakImported(ModuleDecl *module) const;
1026+
bool isWeakImported(ModuleDecl *module,
1027+
AvailabilityContext fromContext) const;
10251028

10261029
/// Return the source file whose codegen should trigger emission of this
10271030
/// link entity, if one can be identified.
@@ -1089,7 +1092,9 @@ class LinkInfo {
10891092
ForDefinition_t forDefinition);
10901093

10911094
static LinkInfo get(const UniversalLinkageInfo &linkInfo,
1092-
ModuleDecl *swiftModule, const LinkEntity &entity,
1095+
ModuleDecl *swiftModule,
1096+
AvailabilityContext availabilityContext,
1097+
const LinkEntity &entity,
10931098
ForDefinition_t forDefinition);
10941099

10951100
static LinkInfo get(const UniversalLinkageInfo &linkInfo, StringRef name,

include/swift/SIL/SILFunctionBuilder.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#ifndef SWIFT_SIL_SILFUNCTIONBUILDER_H
1414
#define SWIFT_SIL_SILFUNCTIONBUILDER_H
1515

16+
#include "swift/AST/Availability.h"
1617
#include "swift/SIL/SILModule.h"
1718

1819
namespace swift {
@@ -42,13 +43,20 @@ class SILGenFunctionBuilder;
4243
/// code-reuse in between these different SILFunction creation sites.
4344
class SILFunctionBuilder {
4445
SILModule &mod;
46+
AvailabilityContext availCtx;
4547

4648
friend class SILParserFunctionBuilder;
4749
friend class SILSerializationFunctionBuilder;
4850
friend class SILOptFunctionBuilder;
4951
friend class Lowering::SILGenFunctionBuilder;
5052

51-
SILFunctionBuilder(SILModule &mod) : mod(mod) {}
53+
SILFunctionBuilder(SILModule &mod)
54+
: SILFunctionBuilder(mod,
55+
AvailabilityContext::forDeploymentTarget(
56+
mod.getASTContext())) {}
57+
58+
SILFunctionBuilder(SILModule &mod, AvailabilityContext availCtx)
59+
: mod(mod), availCtx(availCtx) {}
5260

5361
/// Return the declaration of a utility function that can, but needn't, be
5462
/// shared between different parts of a program.

lib/AST/Availability.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
//
1515
//===----------------------------------------------------------------------===//
1616

17+
#include "swift/AST/ASTContext.h"
1718
#include "swift/AST/Attr.h"
1819
#include "swift/AST/Decl.h"
1920
#include "swift/AST/Types.h"
@@ -24,6 +25,11 @@
2425

2526
using namespace swift;
2627

28+
AvailabilityContext AvailabilityContext::forDeploymentTarget(ASTContext &Ctx) {
29+
return AvailabilityContext(
30+
VersionRange::allGTE(Ctx.LangOpts.getMinPlatformVersion()));
31+
}
32+
2733
namespace {
2834

2935
/// The inferred availability required to access a group of declarations

lib/AST/Decl.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,8 @@ bool Decl::isPrivateStdlibDecl(bool treatNonBuiltinProtocolsAsPublic) const {
536536
return false;
537537
}
538538

539-
bool Decl::isWeakImported(ModuleDecl *fromModule) const {
539+
bool Decl::isWeakImported(ModuleDecl *fromModule,
540+
AvailabilityContext fromContext) const {
540541
// For a Clang declaration, trust Clang.
541542
if (auto clangDecl = getClangDecl()) {
542543
return clangDecl->isWeakImported();
@@ -546,22 +547,27 @@ bool Decl::isWeakImported(ModuleDecl *fromModule) const {
546547
if (containingModule == fromModule)
547548
return false;
548549

550+
auto containingContext =
551+
AvailabilityInference::availableRange(this, fromModule->getASTContext());
552+
if (!fromContext.isContainedIn(containingContext))
553+
return true;
554+
549555
if (getAttrs().hasAttribute<WeakLinkedAttr>())
550556
return true;
551557

552558
if (auto *accessor = dyn_cast<AccessorDecl>(this))
553-
return accessor->getStorage()->isWeakImported(fromModule);
559+
return accessor->getStorage()->isWeakImported(fromModule, fromContext);
554560

555561
if (auto *dtor = dyn_cast<DestructorDecl>(this))
556-
return cast<ClassDecl>(dtor->getDeclContext())->isWeakImported(fromModule);
562+
return cast<ClassDecl>(dtor->getDeclContext())->isWeakImported(
563+
fromModule, fromContext);
557564

558565
auto *dc = getDeclContext();
559566
if (auto *ext = dyn_cast<ExtensionDecl>(dc))
560-
return ext->isWeakImported(fromModule);
567+
return ext->isWeakImported(fromModule, fromContext);
561568
if (auto *ntd = dyn_cast<NominalTypeDecl>(dc))
562-
return ntd->isWeakImported(fromModule);
569+
return ntd->isWeakImported(fromModule, fromContext);
563570

564-
// FIXME: Also check availability when containingModule is resilient.
565571
return false;
566572
}
567573

lib/AST/ProtocolConformance.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "ConformanceLookupTable.h"
1818
#include "swift/AST/ASTContext.h"
19+
#include "swift/AST/Availability.h"
1920
#include "swift/AST/Decl.h"
2021
#include "swift/AST/LazyResolver.h"
2122
#include "swift/AST/GenericEnvironment.h"
@@ -383,24 +384,26 @@ SourceLoc RootProtocolConformance::getLoc() const {
383384
ROOT_CONFORMANCE_SUBCLASS_DISPATCH(getLoc, ())
384385
}
385386

386-
bool RootProtocolConformance::isWeakImported(ModuleDecl *fromModule) const {
387+
bool
388+
RootProtocolConformance::isWeakImported(ModuleDecl *fromModule,
389+
AvailabilityContext fromContext) const {
387390
auto *dc = getDeclContext();
388391
if (dc->getParentModule() == fromModule)
389392
return false;
390393

391394
// If the protocol is weak imported, so are any conformances to it.
392-
if (getProtocol()->isWeakImported(fromModule))
395+
if (getProtocol()->isWeakImported(fromModule, fromContext))
393396
return true;
394397

395398
// If the conforming type is weak imported, so are any of its conformances.
396399
if (auto *nominal = getType()->getAnyNominal())
397-
if (nominal->isWeakImported(fromModule))
400+
if (nominal->isWeakImported(fromModule, fromContext))
398401
return true;
399402

400403
// If the conformance is declared in an extension with the @_weakLinked
401404
// attribute, it is weak imported.
402405
if (auto *ext = dyn_cast<ExtensionDecl>(dc))
403-
if (ext->isWeakImported(fromModule))
406+
if (ext->isWeakImported(fromModule, fromContext))
404407
return true;
405408

406409
return false;

lib/IRGen/AllocStackHoisting.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#define DEBUG_TYPE "alloc-stack-hoisting"
1414

1515
#include "swift/IRGen/IRGenSILPasses.h"
16+
#include "swift/AST/Availability.h"
1617
#include "swift/SILOptimizer/Analysis/Analysis.h"
1718
#include "swift/SILOptimizer/PassManager/Passes.h"
1819
#include "swift/SILOptimizer/PassManager/Transforms.h"
@@ -61,7 +62,8 @@ static bool isHoistable(AllocStackInst *Inst, irgen::IRGenModule &Mod) {
6162
bool foundWeaklyImported =
6263
SILTy.getASTType().findIf([&Mod](CanType type) -> bool {
6364
if (auto nominal = type->getNominalOrBoundGenericNominal())
64-
if (nominal->isWeakImported(Mod.getSILModule().getSwiftModule())) {
65+
if (nominal->isWeakImported(Mod.getSwiftModule(),
66+
Mod.getAvailabilityContext())) {
6567
return true;
6668
}
6769
return false;

lib/IRGen/GenDecl.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,9 +1499,11 @@ void irgen::updateLinkageForDefinition(IRGenModule &IGM,
14991499
// TODO: there are probably cases where we can avoid redoing the
15001500
// entire linkage computation.
15011501
UniversalLinkageInfo linkInfo(IGM);
1502+
bool weakImported = entity.isWeakImported(IGM.getSwiftModule(),
1503+
IGM.getAvailabilityContext());
15021504
auto IRL =
15031505
getIRLinkage(linkInfo, entity.getLinkage(ForDefinition),
1504-
ForDefinition, entity.isWeakImported(IGM.getSwiftModule()));
1506+
ForDefinition, weakImported);
15051507
ApplyIRLinkage(IRL).to(global);
15061508

15071509
// Everything externally visible is considered used in Swift.
@@ -1516,12 +1518,16 @@ void irgen::updateLinkageForDefinition(IRGenModule &IGM,
15161518

15171519
LinkInfo LinkInfo::get(IRGenModule &IGM, const LinkEntity &entity,
15181520
ForDefinition_t isDefinition) {
1519-
return LinkInfo::get(UniversalLinkageInfo(IGM), IGM.getSwiftModule(), entity,
1520-
isDefinition);
1521+
return LinkInfo::get(UniversalLinkageInfo(IGM),
1522+
IGM.getSwiftModule(),
1523+
IGM.getAvailabilityContext(),
1524+
entity, isDefinition);
15211525
}
15221526

15231527
LinkInfo LinkInfo::get(const UniversalLinkageInfo &linkInfo,
1524-
ModuleDecl *swiftModule, const LinkEntity &entity,
1528+
ModuleDecl *swiftModule,
1529+
AvailabilityContext availabilityContext,
1530+
const LinkEntity &entity,
15251531
ForDefinition_t isDefinition) {
15261532
LinkInfo result;
15271533
// FIXME: For anything in the standard library, we assume is locally defined.
@@ -1536,8 +1542,9 @@ LinkInfo LinkInfo::get(const UniversalLinkageInfo &linkInfo,
15361542
ForDefinition_t(swiftModule->isStdlibModule() || isDefinition);
15371543

15381544
entity.mangle(result.Name);
1545+
bool weakImported = entity.isWeakImported(swiftModule, availabilityContext);
15391546
result.IRL = getIRLinkage(linkInfo, entity.getLinkage(isStdlibOrDefinition),
1540-
isDefinition, entity.isWeakImported(swiftModule));
1547+
isDefinition, weakImported);
15411548
result.ForDefinition = isDefinition;
15421549
return result;
15431550
}

lib/IRGen/GenEnum.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5429,7 +5429,8 @@ namespace {
54295429
llvm::BasicBlock *conditionalBlock = nullptr;
54305430
llvm::BasicBlock *afterConditionalBlock = nullptr;
54315431
llvm::BasicBlock *beforeNullPtrCheck = nullptr;
5432-
if (Case->isWeakImported(IGM.getSwiftModule())) {
5432+
if (Case->isWeakImported(IGM.getSwiftModule(),
5433+
IGM.getAvailabilityContext())) {
54335434
beforeNullPtrCheck = IGF.Builder.GetInsertBlock();
54345435
auto address = IGM.getAddrOfEnumCase(Case, NotForDefinition);
54355436
conditionalBlock = llvm::BasicBlock::Create(C);

lib/IRGen/IRGenModule.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
//
1515
//===----------------------------------------------------------------------===//
1616

17+
#include "swift/AST/Availability.h"
1718
#include "swift/AST/ASTContext.h"
1819
#include "swift/AST/Module.h"
1920
#include "swift/AST/DiagnosticsIRGen.h"
@@ -723,6 +724,10 @@ ModuleDecl *IRGenModule::getSwiftModule() const {
723724
return IRGen.SIL.getSwiftModule();
724725
}
725726

727+
AvailabilityContext IRGenModule::getAvailabilityContext() const {
728+
return AvailabilityContext::forDeploymentTarget(Context);
729+
}
730+
726731
Lowering::TypeConverter &IRGenModule::getSILTypes() const {
727732
return IRGen.SIL.Types;
728733
}

lib/IRGen/IRGenModule.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,7 @@ class IRGenModule {
474474
const llvm::Triple Triple;
475475
std::unique_ptr<llvm::TargetMachine> TargetMachine;
476476
ModuleDecl *getSwiftModule() const;
477+
AvailabilityContext getAvailabilityContext() const;
477478
Lowering::TypeConverter &getSILTypes() const;
478479
SILModule &getSILModule() const { return IRGen.SIL; }
479480
const IRGenOptions &getOptions() const { return IRGen.Opts; }

lib/IRGen/Linking.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "IRGenMangler.h"
1919
#include "IRGenModule.h"
2020
#include "swift/AST/ASTMangler.h"
21+
#include "swift/AST/Availability.h"
2122
#include "swift/ClangImporter/ClangModule.h"
2223
#include "swift/SIL/SILGlobalVariable.h"
2324
#include "swift/SIL/FormalLinkage.h"
@@ -888,18 +889,21 @@ Alignment LinkEntity::getAlignment(IRGenModule &IGM) const {
888889
}
889890
}
890891

891-
bool LinkEntity::isWeakImported(ModuleDecl *module) const {
892+
bool LinkEntity::isWeakImported(ModuleDecl *module,
893+
AvailabilityContext context) const {
892894
switch (getKind()) {
893895
case Kind::SILGlobalVariable:
894-
if (getSILGlobalVariable()->getDecl())
895-
return getSILGlobalVariable()->getDecl()->isWeakImported(module);
896+
if (getSILGlobalVariable()->getDecl()) {
897+
return getSILGlobalVariable()->getDecl()
898+
->isWeakImported(module, context);
899+
}
896900
return false;
897901
case Kind::DynamicallyReplaceableFunctionKey:
898902
case Kind::DynamicallyReplaceableFunctionVariable:
899903
case Kind::SILFunction: {
900904
// For imported functions check the Clang declaration.
901905
if (auto clangOwner = getSILFunction()->getClangNodeOwner())
902-
return clangOwner->isWeakImported(module);
906+
return clangOwner->isWeakImported(module, context);
903907

904908
// For native functions check a flag on the SILFunction
905909
// itself.
@@ -915,16 +919,16 @@ bool LinkEntity::isWeakImported(ModuleDecl *module) const {
915919
// type stored in extra storage area is weak linked.
916920
auto assocConformance = getAssociatedConformance();
917921
auto *depMemTy = assocConformance.first->castTo<DependentMemberType>();
918-
return depMemTy->getAssocType()->isWeakImported(module);
922+
return depMemTy->getAssocType()->isWeakImported(module, context);
919923
}
920924

921925
case Kind::BaseConformanceDescriptor:
922-
return cast<ProtocolDecl>(getDecl())->isWeakImported(module);
926+
return cast<ProtocolDecl>(getDecl())->isWeakImported(module, context);
923927

924928
case Kind::TypeMetadata:
925929
case Kind::TypeMetadataAccessFunction: {
926930
if (auto *nominalDecl = getType()->getAnyNominal())
927-
return nominalDecl->isWeakImported(module);
931+
return nominalDecl->isWeakImported(module, context);
928932
return false;
929933
}
930934

@@ -952,12 +956,12 @@ bool LinkEntity::isWeakImported(ModuleDecl *module) const {
952956
case Kind::DynamicallyReplaceableFunctionKeyAST:
953957
case Kind::DynamicallyReplaceableFunctionVariableAST:
954958
case Kind::DynamicallyReplaceableFunctionImpl:
955-
return getDecl()->isWeakImported(module);
959+
return getDecl()->isWeakImported(module, context);
956960

957961
case Kind::ProtocolWitnessTable:
958962
case Kind::ProtocolConformanceDescriptor:
959963
return getProtocolConformance()->getRootConformance()
960-
->isWeakImported(module);
964+
->isWeakImported(module, context);
961965

962966
// TODO: Revisit some of the below, for weak conformances.
963967
case Kind::TypeMetadataPattern:

lib/SIL/SILFunctionBuilder.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "swift/SIL/SILFunctionBuilder.h"
14+
#include "swift/AST/Availability.h"
1415
#include "swift/AST/Decl.h"
1516
using namespace swift;
1617

@@ -154,7 +155,7 @@ SILFunctionBuilder::getOrCreateFunction(SILLocation loc, SILDeclRef constant,
154155
if (constant.isForeign && decl->hasClangNode())
155156
F->setClangNodeOwner(decl);
156157

157-
if (decl->isWeakImported(/*fromModule=*/nullptr))
158+
if (decl->isWeakImported(mod.getSwiftModule(), availCtx))
158159
F->setWeakLinked();
159160

160161
if (auto *accessor = dyn_cast<AccessorDecl>(decl)) {

0 commit comments

Comments
 (0)