Skip to content

Commit 2515f7a

Browse files
committed
Frontend: Introduce the -enable-experimental-ad-hoc-availability flag.
When developing a module for an OS or SDK, one may use declarations from other modules that were recently introduced in the in-development OS. Those declarations will be annotated as available at the deployment target of the client module and yet the symbols for that declaration are not available in all development builds of that OS. If the module strongly links those symbols, it will crash on older development builds of the OS. The `-enable-experimental-ad-hoc-availability` flag is designed to give developers the option of weakly linking all symbols in other modules that were introduced at the deployment target. This change introduces the basic change in linking behavior but does not address typechecking. Use of the declarations that are made unavailable in this mode will need to be diagnosed and developers will need a way to detect the unavailability at runtime before use. Resolves rdar://96011550
1 parent bc9e5f5 commit 2515f7a

File tree

6 files changed

+29
-8
lines changed

6 files changed

+29
-8
lines changed

include/swift/Basic/LangOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ namespace swift {
164164
/// Only check the availability of the API, ignore function bodies.
165165
bool CheckAPIAvailabilityOnly = false;
166166

167+
/// Causes the compiler to treat declarations available at the current
168+
/// runtime OS version as potentially unavailable.
169+
bool EnableAdHocAvailability = false;
170+
167171
/// Should conformance availability violations be diagnosed as errors?
168172
bool EnableConformanceAvailabilityErrors = false;
169173

include/swift/Option/FrontendOptions.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,5 +1064,9 @@ def clang_header_expose_public_decls:
10641064
Flag<["-"], "clang-header-expose-public-decls">,
10651065
HelpText<"Expose all public declarations in the generated clang header">,
10661066
Flags<[FrontendOption, HelpHidden]>;
1067+
1068+
def enable_ad_hoc_availability :
1069+
Flag<["-"], "enable-ad-hoc-availability">,
1070+
HelpText<"Enable experimental support for ad hoc availability">;
10671071

10681072
} // end let Flags = [FrontendOption, NoDriverOption, HelpHidden]

lib/AST/Decl.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,13 +1002,17 @@ bool Decl::isWeakImported(ModuleDecl *fromModule) const {
10021002
if (isAlwaysWeakImported())
10031003
return true;
10041004

1005-
auto containingContext = getAvailabilityForLinkage();
1006-
if (containingContext.isAlwaysAvailable())
1005+
auto availability = getAvailabilityForLinkage();
1006+
if (availability.isAlwaysAvailable())
10071007
return false;
10081008

1009-
auto fromContext = AvailabilityContext::forDeploymentTarget(
1010-
fromModule->getASTContext());
1011-
return !fromContext.isContainedIn(containingContext);
1009+
auto &ctx = fromModule->getASTContext();
1010+
auto deploymentTarget = AvailabilityContext::forDeploymentTarget(ctx);
1011+
1012+
if (ctx.LangOpts.EnableAdHocAvailability)
1013+
return !availability.isSupersetOf(deploymentTarget);
1014+
1015+
return !deploymentTarget.isContainedIn(availability);
10121016
}
10131017

10141018
GenericContext::GenericContext(DeclContextKind Kind, DeclContext *Parent,

lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,8 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
490490
Args.hasArg(OPT_disable_availability_checking);
491491
Opts.CheckAPIAvailabilityOnly |=
492492
Args.hasArg(OPT_check_api_availability_only);
493+
Opts.EnableAdHocAvailability |=
494+
Args.hasArg(OPT_enable_ad_hoc_availability);
493495

494496
if (auto A = Args.getLastArg(OPT_enable_conformance_availability_errors,
495497
OPT_disable_conformance_availability_errors)) {

lib/SIL/IR/SILFunction.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -385,9 +385,13 @@ bool SILFunction::isWeakImported() const {
385385
if (Availability.isAlwaysAvailable())
386386
return false;
387387

388-
auto fromContext = AvailabilityContext::forDeploymentTarget(
389-
getASTContext());
390-
return !fromContext.isContainedIn(Availability);
388+
auto deploymentTarget =
389+
AvailabilityContext::forDeploymentTarget(getASTContext());
390+
391+
if (getASTContext().LangOpts.EnableAdHocAvailability)
392+
return !Availability.isSupersetOf(deploymentTarget);
393+
394+
return !deploymentTarget.isContainedIn(Availability);
391395
}
392396

393397
SILBasicBlock *SILFunction::createBasicBlock() {

test/IRGen/weak_import_availability.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir -target %target-cpu-apple-macosx10.50 | %FileCheck %s --check-prefix=CHECK-NEW
66
// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir -target %target-cpu-apple-macosx10.60 | %FileCheck %s --check-prefix=CHECK-NEW
77

8+
// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir -target %target-cpu-apple-macosx10.50 -enable-ad-hoc-availability | %FileCheck %s --check-prefix=CHECK-OLD
9+
// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir -target %target-cpu-apple-macosx10.60 -enable-ad-hoc-availability | %FileCheck %s --check-prefix=CHECK-NEW
10+
811
// REQUIRES: OS=macosx
912

1013
import weak_import_availability_helper

0 commit comments

Comments
 (0)