1818#define SWIFT_AST_AVAILABILITY_SPEC_H
1919
2020#include " swift/AST/ASTAllocated.h"
21+ #include " swift/AST/AvailabilityDomain.h"
2122#include " swift/AST/Identifier.h"
2223#include " swift/AST/PlatformKind.h"
2324#include " swift/Basic/SourceLoc.h"
2728
2829namespace swift {
2930class ASTContext ;
30- class AvailabilityDomain ;
31-
32- enum class VersionComparison { GreaterThanEqual };
3331
3432enum class AvailabilitySpecKind {
3533 // / A platform-version constraint of the form "PlatformName X.Y.Z"
@@ -49,86 +47,82 @@ enum class AvailabilitySpecKind {
4947// / The root class for specifications of API availability in availability
5048// / queries.
5149class AvailabilitySpec : public ASTAllocated <AvailabilitySpec> {
50+ protected:
5251 AvailabilitySpecKind Kind;
5352
53+ std::optional<AvailabilityDomain> Domain;
54+
55+ // / The range of the entire spec, including the version if there is one.
56+ SourceRange SrcRange;
57+
58+ // / The version (may be empty if there was no version specified).
59+ llvm::VersionTuple Version;
60+
61+ // / If there is a version specified, this is its start location within the
62+ // / overall source range.
63+ SourceLoc VersionStartLoc;
64+
65+ // Location of the availability macro expanded to create this spec.
66+ SourceLoc MacroLoc;
67+
5468public:
55- AvailabilitySpec (AvailabilitySpecKind Kind) : Kind(Kind) {}
69+ AvailabilitySpec (AvailabilitySpecKind Kind,
70+ std::optional<AvailabilityDomain> Domain,
71+ SourceRange SrcRange, llvm::VersionTuple Version,
72+ SourceLoc VersionStartLoc)
73+ : Kind(Kind), Domain(Domain), SrcRange(SrcRange), Version(Version),
74+ VersionStartLoc (VersionStartLoc) {}
5675
5776 AvailabilitySpecKind getKind () const { return Kind; }
5877
59- SourceRange getSourceRange () const ;
78+ SourceRange getSourceRange () const { return SrcRange; }
79+ SourceLoc getStartLoc () const { return SrcRange.Start ; }
6080
61- std::optional<AvailabilityDomain> getDomain () const ;
81+ std::optional<AvailabilityDomain> getDomain () const { return Domain; }
6282
63- std::optional<PlatformKind> getPlatform () const ;
83+ PlatformKind getPlatform () const {
84+ if (auto domain = getDomain ())
85+ return domain->getPlatformKind ();
86+ return PlatformKind::none;
87+ }
6488
89+ // The platform version to compare against.
6590 llvm::VersionTuple getVersion () const ;
6691
67- SourceRange getVersionSrcRange () const ;
92+ SourceRange getVersionSrcRange () const {
93+ if (!VersionStartLoc)
94+ return SourceRange ();
95+ return SourceRange (VersionStartLoc, SrcRange.End );
96+ }
97+
98+ // Location of the macro expanded to create this spec.
99+ SourceLoc getMacroLoc () const { return MacroLoc; }
100+ void setMacroLoc (SourceLoc loc) { MacroLoc = loc; }
68101};
69102
70103// / An availability specification that guards execution based on the
71104// / run-time platform and version, e.g., OS X >= 10.10.
72105class PlatformVersionConstraintAvailabilitySpec : public AvailabilitySpec {
73- PlatformKind Platform;
74- SourceLoc PlatformLoc;
75-
76- llvm::VersionTuple Version;
77-
78- // For macOS Big Sur, we canonicalize 10.16 to 11.0 for compile-time
79- // checking since clang canonicalizes availability markup. However, to
80- // support Beta versions of macOS Big Sur where the OS
81- // reports 10.16 at run time, we need to compare against 10.16,
82- //
83- // This means for:
84- //
85- // if #available(macOS 10.16, *) { ... }
86- //
87- // we need to keep around both a canonical version for use in compile-time
88- // checks and an uncanonicalized version for the version to actually codegen
89- // with.
90- llvm::VersionTuple RuntimeVersion;
91-
92- SourceRange VersionSrcRange;
93-
94- // Location of the macro expanded to create this spec.
95- SourceLoc MacroLoc;
106+ static std::optional<AvailabilityDomain>
107+ getDomainForPlatform (PlatformKind Platform) {
108+ if (Platform != PlatformKind::none)
109+ return AvailabilityDomain::forPlatform (Platform);
110+ return std::nullopt ;
111+ }
96112
97113public:
98114 PlatformVersionConstraintAvailabilitySpec (PlatformKind Platform,
99115 SourceLoc PlatformLoc,
100116 llvm::VersionTuple Version,
101- llvm::VersionTuple RuntimeVersion,
102117 SourceRange VersionSrcRange)
103- : AvailabilitySpec(AvailabilitySpecKind::PlatformVersionConstraint),
104- Platform (Platform),
105- PlatformLoc(PlatformLoc), Version(Version),
106- RuntimeVersion(RuntimeVersion),
107- VersionSrcRange(VersionSrcRange) {}
108-
109- // / The required platform.
110- PlatformKind getPlatform () const { return Platform; }
111- SourceLoc getPlatformLoc () const { return PlatformLoc; }
112-
113- // / Returns true when the constraint is for a platform that was not
114- // / recognized. This enables better recovery during parsing but should never
115- // / be true after parsing is completed.
116- bool isUnrecognizedPlatform () const { return Platform == PlatformKind::none; }
117-
118- // The platform version to compare against.
119- llvm::VersionTuple getVersion () const { return Version; }
120- SourceRange getVersionSrcRange () const { return VersionSrcRange; }
121-
118+ : AvailabilitySpec(AvailabilitySpecKind::PlatformVersionConstraint,
119+ getDomainForPlatform (Platform),
120+ SourceRange(PlatformLoc, VersionSrcRange.End), Version,
121+ VersionSrcRange.Start) {}
122122 // The version to be used in codegen for version comparisons at run time.
123123 // This is required to support beta versions of macOS Big Sur that
124124 // report 10.16 at run time.
125- llvm::VersionTuple getRuntimeVersion () const { return RuntimeVersion; }
126-
127- SourceRange getSourceRange () const ;
128-
129- // Location of the macro expanded to create this spec.
130- SourceLoc getMacroLoc () const { return MacroLoc; }
131- void setMacroLoc (SourceLoc loc) { MacroLoc = loc; }
125+ llvm::VersionTuple getRuntimeVersion () const ;
132126
133127 void print (raw_ostream &OS, unsigned Indent) const ;
134128
@@ -147,36 +141,34 @@ class PlatformVersionConstraintAvailabilitySpec : public AvailabilitySpec {
147141// / An availability specification that guards execution based on the
148142// / compile-time platform agnostic version, e.g., swift >= 3.0.1,
149143// / package-description >= 4.0.
150- class PlatformAgnosticVersionConstraintAvailabilitySpec : public AvailabilitySpec {
151- SourceLoc PlatformAgnosticNameLoc;
152-
153- llvm::VersionTuple Version;
154- SourceRange VersionSrcRange;
144+ class PlatformAgnosticVersionConstraintAvailabilitySpec
145+ : public AvailabilitySpec {
146+
147+ static AvailabilityDomain getDomainForSpecKind (AvailabilitySpecKind Kind) {
148+ switch (Kind) {
149+ case AvailabilitySpecKind::PlatformVersionConstraint:
150+ case AvailabilitySpecKind::OtherPlatform:
151+ llvm_unreachable (" unexpected spec kind" );
152+ case AvailabilitySpecKind::LanguageVersionConstraint:
153+ return AvailabilityDomain::forSwiftLanguage ();
154+ case AvailabilitySpecKind::PackageDescriptionVersionConstraint:
155+ return AvailabilityDomain::forPackageDescription ();
156+ }
157+ }
155158
156159public:
157160 PlatformAgnosticVersionConstraintAvailabilitySpec (
158161 AvailabilitySpecKind AvailabilitySpecKind,
159162 SourceLoc PlatformAgnosticNameLoc, llvm::VersionTuple Version,
160163 SourceRange VersionSrcRange)
161- : AvailabilitySpec(AvailabilitySpecKind),
162- PlatformAgnosticNameLoc (PlatformAgnosticNameLoc), Version(Version),
163- VersionSrcRange(VersionSrcRange) {
164+ : AvailabilitySpec(
165+ AvailabilitySpecKind, getDomainForSpecKind(AvailabilitySpecKind),
166+ SourceRange (PlatformAgnosticNameLoc, VersionSrcRange.End), Version,
167+ VersionSrcRange.Start) {
164168 assert (AvailabilitySpecKind == AvailabilitySpecKind::LanguageVersionConstraint ||
165169 AvailabilitySpecKind == AvailabilitySpecKind::PackageDescriptionVersionConstraint);
166170 }
167171
168- SourceLoc getPlatformAgnosticNameLoc () const { return PlatformAgnosticNameLoc; }
169-
170- // The platform version to compare against.
171- llvm::VersionTuple getVersion () const { return Version; }
172- SourceRange getVersionSrcRange () const { return VersionSrcRange; }
173-
174- SourceRange getSourceRange () const ;
175-
176- bool isLanguageVersionSpecific () const {
177- return getKind () == AvailabilitySpecKind::LanguageVersionConstraint;
178- }
179-
180172 void print (raw_ostream &OS, unsigned Indent) const ;
181173
182174 static bool classof (const AvailabilitySpec *Spec) {
@@ -202,16 +194,12 @@ class PlatformAgnosticVersionConstraintAvailabilitySpec : public AvailabilitySpe
202194// / that we still do compile-time availability checking with '*', so the
203195// / compiler will still catch references to potentially unavailable symbols.
204196class OtherPlatformAvailabilitySpec : public AvailabilitySpec {
205- SourceLoc StarLoc;
206-
207197public:
208198 OtherPlatformAvailabilitySpec (SourceLoc StarLoc)
209- : AvailabilitySpec(AvailabilitySpecKind::OtherPlatform),
210- StarLoc (StarLoc) {}
211-
212- SourceLoc getStarLoc () const { return StarLoc; }
213-
214- SourceRange getSourceRange () const { return SourceRange (StarLoc, StarLoc); }
199+ : AvailabilitySpec(AvailabilitySpecKind::OtherPlatform, std::nullopt ,
200+ StarLoc,
201+ /* Version=*/ {},
202+ /* VersionStartLoc=*/ {}) {}
215203
216204 void print (raw_ostream &OS, unsigned Indent) const ;
217205
0 commit comments