Skip to content

Commit d764db0

Browse files
committed
[Apple Silicon] Add support for triple and availability canonicalization
1 parent 0c5dc54 commit d764db0

27 files changed

+356
-18
lines changed

include/swift/AST/AvailabilitySpec.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,33 @@ class PlatformVersionConstraintAvailabilitySpec : public AvailabilitySpec {
6868
SourceLoc PlatformLoc;
6969

7070
llvm::VersionTuple Version;
71+
72+
// For macOS Big Sur, we we canonicalize 10.16 to 11.0 for compile-time
73+
// checking since clang canonicalizes availability markup. However, to
74+
// support Beta versions of macOS Big Sur where the OS
75+
// reports 10.16 at run time, we need to compare against 10.16,
76+
//
77+
// This means for:
78+
//
79+
// if #available(macOS 10.16, *) { ... }
80+
//
81+
// we need to keep around both a canonical version for use in compile-time
82+
// checks and an uncanonicalized version for the version to actually codegen
83+
// with.
84+
llvm::VersionTuple RuntimeVersion;
85+
7186
SourceRange VersionSrcRange;
7287

7388
public:
7489
PlatformVersionConstraintAvailabilitySpec(PlatformKind Platform,
7590
SourceLoc PlatformLoc,
7691
llvm::VersionTuple Version,
92+
llvm::VersionTuple RuntimeVersion,
7793
SourceRange VersionSrcRange)
7894
: AvailabilitySpec(AvailabilitySpecKind::PlatformVersionConstraint),
7995
Platform(Platform),
8096
PlatformLoc(PlatformLoc), Version(Version),
97+
RuntimeVersion(RuntimeVersion),
8198
VersionSrcRange(VersionSrcRange) {}
8299

83100
/// The required platform.
@@ -93,6 +110,11 @@ class PlatformVersionConstraintAvailabilitySpec : public AvailabilitySpec {
93110
llvm::VersionTuple getVersion() const { return Version; }
94111
SourceRange getVersionSrcRange() const { return VersionSrcRange; }
95112

113+
// The version to be used in codegen for version comparisons at run time.
114+
// This is required to support beta versions of macOS Big Sur that
115+
// report 10.16 at run time.
116+
llvm::VersionTuple getRuntimeVersion() const { return RuntimeVersion; }
117+
96118
SourceRange getSourceRange() const;
97119

98120
void print(raw_ostream &OS, unsigned Indent) const;

include/swift/AST/PlatformKind.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "swift/Basic/LLVM.h"
2121
#include "swift/Config.h"
2222
#include "llvm/ADT/StringRef.h"
23+
#include "llvm/Support/VersionTuple.h"
2324

2425
namespace swift {
2526

@@ -65,6 +66,9 @@ PlatformKind targetPlatform(LangOptions &LangOpts);
6566
/// an explicit attribute for the child.
6667
bool inheritsAvailabilityFromPlatform(PlatformKind Child, PlatformKind Parent);
6768

69+
llvm::VersionTuple canonicalizePlatformVersion(
70+
PlatformKind platform, const llvm::VersionTuple &version);
71+
6872
} // end namespace swift
6973

7074
#endif

lib/AST/Availability.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ AvailabilityContext ASTContext::getSwiftFutureAvailability() {
375375

376376
if (target.isMacOSX() ) {
377377
return AvailabilityContext(
378-
VersionRange::allGTE(llvm::VersionTuple(10, 99, 0)));
378+
VersionRange::allGTE(llvm::VersionTuple(99, 99, 0)));
379379
} else if (target.isiOS()) {
380380
return AvailabilityContext(
381381
VersionRange::allGTE(llvm::VersionTuple(99, 0, 0)));

lib/AST/PlatformKind.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "llvm/ADT/StringSwitch.h"
2121
#include "llvm/Support/ErrorHandling.h"
2222

23+
2324
using namespace swift;
2425

2526
StringRef swift::platformString(PlatformKind platform) {
@@ -155,3 +156,17 @@ bool swift::inheritsAvailabilityFromPlatform(PlatformKind Child,
155156

156157
return false;
157158
}
159+
160+
llvm::VersionTuple swift::canonicalizePlatformVersion(
161+
PlatformKind platform, const llvm::VersionTuple &version) {
162+
163+
// Canonicalize macOS version for macOS Big Sur to great
164+
// 10.16 as 11.0.
165+
if (platform == PlatformKind::OSX ||
166+
platform == PlatformKind::OSXApplicationExtension) {
167+
return llvm::Triple::getCanonicalVersionForOS(llvm::Triple::MacOSX,
168+
version);
169+
}
170+
171+
return version;
172+
}

lib/Basic/Platform.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,8 @@ swift::getSwiftRuntimeCompatibilityVersionForTarget(
399399
return llvm::VersionTuple(5, 2);
400400
}
401401
}
402+
} else if (Major == 11) {
403+
return llvm::VersionTuple(5, 3);
402404
}
403405
} else if (Triple.isiOS()) { // includes tvOS
404406
Triple.getiOSVersion(Major, Minor, Micro);

lib/Driver/DarwinToolChains.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "ToolChains.h"
1414

1515
#include "swift/AST/DiagnosticsDriver.h"
16+
#include "swift/AST/PlatformKind.h"
1617
#include "swift/Basic/Dwarf.h"
1718
#include "swift/Basic/LLVM.h"
1819
#include "swift/Basic/Platform.h"
@@ -613,9 +614,12 @@ toolchains::Darwin::addDeploymentTargetArgs(ArgStringList &Arguments,
613614

614615
// The first deployment of arm64 for macOS is version 10.16;
615616
if (triple.isAArch64() && major <= 10 && minor < 16) {
616-
major = 10;
617-
minor = 16;
618-
micro = 0;
617+
llvm::VersionTuple firstMacARM64e(10, 16, 0);
618+
firstMacARM64e = canonicalizePlatformVersion(PlatformKind::OSX,
619+
firstMacARM64e);
620+
major = firstMacARM64e.getMajor();
621+
minor = firstMacARM64e.getMinor().getValueOr(0);
622+
micro = firstMacARM64e.getSubminor().getValueOr(0);
619623
}
620624

621625
// Temporary hack: adjust macOS version passed to the linker from

lib/Parse/ParseDecl.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,20 @@ ParserResult<AvailableAttr> Parser::parseExtendedAvailabilitySpecList(
575575
return nullptr;
576576
}
577577

578+
if (PlatformKind) {
579+
if (!Introduced.empty())
580+
Introduced.Version =
581+
canonicalizePlatformVersion(*PlatformKind, Introduced.Version);
582+
583+
if (!Deprecated.empty())
584+
Deprecated.Version =
585+
canonicalizePlatformVersion(*PlatformKind, Deprecated.Version);
586+
587+
if (!Obsoleted.empty())
588+
Obsoleted.Version =
589+
canonicalizePlatformVersion(*PlatformKind, Obsoleted.Version);
590+
}
591+
578592
auto Attr = new (Context)
579593
AvailableAttr(AtLoc, SourceRange(AttrLoc, Tok.getLoc()),
580594
PlatformKind.getValue(),
@@ -1962,6 +1976,8 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
19621976
continue;
19631977
}
19641978

1979+
Version = canonicalizePlatformVersion(Platform, Version);
1980+
19651981
Attributes.add(new (Context)
19661982
AvailableAttr(AtLoc, AttrRange,
19671983
Platform,

lib/Parse/ParseExpr.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3815,6 +3815,11 @@ Parser::parsePlatformVersionConstraintSpec() {
38153815
// Register the platform name as a keyword token.
38163816
TokReceiver->registerTokenKindChange(PlatformLoc, tok::contextual_keyword);
38173817

3818+
// Keep the original version around for run-time checks to support
3819+
// macOS Big Sur betas that report 10.16 at
3820+
// at run time.
3821+
llvm::VersionTuple RuntimeVersion = Version;
3822+
Version = canonicalizePlatformVersion(*Platform, Version);
38183823
return makeParserResult(new (Context) PlatformVersionConstraintAvailabilitySpec(
3819-
Platform.getValue(), PlatformLoc, Version, VersionRange));
3824+
Platform.getValue(), PlatformLoc, Version, RuntimeVersion, VersionRange));
38203825
}

lib/Sema/DerivedConformanceRawRepresentable.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ struct RuntimeVersionCheck {
198198
// platformSpec = "\(attr.platform) \(attr.introduced)"
199199
auto platformSpec = new (C) PlatformVersionConstraintAvailabilitySpec(
200200
Platform, SourceLoc(),
201-
Version, SourceLoc()
201+
Version, Version, SourceLoc()
202202
);
203203

204204
// otherSpec = "*"

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -453,8 +453,8 @@ class TypeRefinementContextBuilder : private ASTWalker {
453453
continue;
454454
}
455455

456-
AvailabilityContext NewConstraint = contextForSpec(Spec);
457-
Query->setAvailableRange(NewConstraint.getOSVersion());
456+
AvailabilityContext NewConstraint = contextForSpec(Spec, false);
457+
Query->setAvailableRange(contextForSpec(Spec, true).getOSVersion());
458458

459459
// When compiling zippered for macCatalyst, we need to collect both
460460
// a macOS version (the target version) and an iOS/macCatalyst version
@@ -464,7 +464,8 @@ class TypeRefinementContextBuilder : private ASTWalker {
464464
if (Context.LangOpts.TargetVariant) {
465465
AvailabilitySpec *VariantSpec =
466466
bestActiveSpecForQuery(Query, /*ForTargetVariant*/ true);
467-
VersionRange VariantRange = contextForSpec(VariantSpec).getOSVersion();
467+
VersionRange VariantRange =
468+
contextForSpec(VariantSpec, true).getOSVersion();
468469
Query->setVariantAvailableRange(VariantRange);
469470
}
470471

@@ -594,13 +595,19 @@ class TypeRefinementContextBuilder : private ASTWalker {
594595
}
595596

596597
/// Return the availability context for the given spec.
597-
AvailabilityContext contextForSpec(AvailabilitySpec *Spec) {
598+
AvailabilityContext contextForSpec(AvailabilitySpec *Spec,
599+
bool GetRuntimeContext) {
598600
if (isa<OtherPlatformAvailabilitySpec>(Spec)) {
599601
return AvailabilityContext::alwaysAvailable();
600602
}
601603

602604
auto *VersionSpec = cast<PlatformVersionConstraintAvailabilitySpec>(Spec);
603-
return AvailabilityContext(VersionRange::allGTE(VersionSpec->getVersion()));
605+
606+
llvm::VersionTuple Version = (GetRuntimeContext ?
607+
VersionSpec->getRuntimeVersion() :
608+
VersionSpec->getVersion());
609+
610+
return AvailabilityContext(VersionRange::allGTE(Version));
604611
}
605612

606613
Expr *walkToExprPost(Expr *E) override {

0 commit comments

Comments
 (0)