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,70 +47,94 @@ 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; }
6079
61- std::optional<AvailabilityDomain> getDomain () const ;
80+ std::optional<AvailabilityDomain> getDomain () const { return Domain; }
6281
6382 std::optional<PlatformKind> getPlatform () const ;
6483
84+ // The platform version to compare against.
6585 llvm::VersionTuple getVersion () const ;
6686
67- SourceRange getVersionSrcRange () const ;
87+ SourceRange getVersionSrcRange () const {
88+ if (!VersionStartLoc)
89+ return SourceRange ();
90+ return SourceRange (VersionStartLoc, SrcRange.End );
91+ }
92+
93+ // Location of the macro expanded to create this spec.
94+ SourceLoc getMacroLoc () const { return MacroLoc; }
95+ void setMacroLoc (SourceLoc loc) { MacroLoc = loc; }
6896};
6997
7098// / An availability specification that guards execution based on the
7199// / run-time platform and version, e.g., OS X >= 10.10.
72100class PlatformVersionConstraintAvailabilitySpec : public AvailabilitySpec {
73- PlatformKind Platform;
74- SourceLoc PlatformLoc;
75-
76- llvm::VersionTuple Version;
77-
78- SourceRange VersionSrcRange;
79-
80- // Location of the macro expanded to create this spec.
81- SourceLoc MacroLoc;
101+ static std::optional<AvailabilityDomain>
102+ getDomainForPlatform (PlatformKind Platform) {
103+ if (Platform != PlatformKind::none)
104+ return AvailabilityDomain::forPlatform (Platform);
105+ return std::nullopt ;
106+ }
82107
83108public:
84109 PlatformVersionConstraintAvailabilitySpec (PlatformKind Platform,
85110 SourceLoc PlatformLoc,
86111 llvm::VersionTuple Version,
87112 SourceRange VersionSrcRange)
88- : AvailabilitySpec(AvailabilitySpecKind::PlatformVersionConstraint),
89- Platform (Platform), PlatformLoc(PlatformLoc), Version(Version),
90- VersionSrcRange(VersionSrcRange) {}
113+ : AvailabilitySpec(AvailabilitySpecKind::PlatformVersionConstraint,
114+ getDomainForPlatform (Platform),
115+ SourceRange(PlatformLoc, VersionSrcRange.End), Version,
116+ VersionSrcRange.Start) {}
91117
92118 // / The required platform.
93- PlatformKind getPlatform () const { return Platform; }
94- SourceLoc getPlatformLoc () const { return PlatformLoc; }
119+ PlatformKind getPlatform () const {
120+ if (auto domain = getDomain ())
121+ return domain->getPlatformKind ();
122+ return PlatformKind::none;
123+ }
124+ SourceLoc getPlatformLoc () const { return getSourceRange ().Start ; }
95125
96126 // / Returns true when the constraint is for a platform that was not
97127 // / recognized. This enables better recovery during parsing but should never
98128 // / be true after parsing is completed.
99- bool isUnrecognizedPlatform () const { return Platform == PlatformKind::none; }
100-
101- // The platform version to compare against.
102- llvm::VersionTuple getVersion () const ;
103- SourceRange getVersionSrcRange () const { return VersionSrcRange; }
129+ bool isUnrecognizedPlatform () const {
130+ return getPlatform () == PlatformKind::none;
131+ }
104132
105133 // The version to be used in codegen for version comparisons at run time.
106134 // This is required to support beta versions of macOS Big Sur that
107135 // report 10.16 at run time.
108136 llvm::VersionTuple getRuntimeVersion () const ;
109137
110- SourceRange getSourceRange () const ;
111-
112- // Location of the macro expanded to create this spec.
113- SourceLoc getMacroLoc () const { return MacroLoc; }
114- void setMacroLoc (SourceLoc loc) { MacroLoc = loc; }
115-
116138 void print (raw_ostream &OS, unsigned Indent) const ;
117139
118140 static bool classof (const AvailabilitySpec *Spec) {
@@ -130,31 +152,37 @@ class PlatformVersionConstraintAvailabilitySpec : public AvailabilitySpec {
130152// / An availability specification that guards execution based on the
131153// / compile-time platform agnostic version, e.g., swift >= 3.0.1,
132154// / package-description >= 4.0.
133- class PlatformAgnosticVersionConstraintAvailabilitySpec : public AvailabilitySpec {
134- SourceLoc PlatformAgnosticNameLoc;
135-
136- llvm::VersionTuple Version;
137- SourceRange VersionSrcRange;
155+ class PlatformAgnosticVersionConstraintAvailabilitySpec
156+ : public AvailabilitySpec {
157+
158+ static AvailabilityDomain getDomainForSpecKind (AvailabilitySpecKind Kind) {
159+ switch (Kind) {
160+ case AvailabilitySpecKind::PlatformVersionConstraint:
161+ case AvailabilitySpecKind::OtherPlatform:
162+ llvm_unreachable (" unexpected spec kind" );
163+ case AvailabilitySpecKind::LanguageVersionConstraint:
164+ return AvailabilityDomain::forSwiftLanguage ();
165+ case AvailabilitySpecKind::PackageDescriptionVersionConstraint:
166+ return AvailabilityDomain::forPackageDescription ();
167+ }
168+ }
138169
139170public:
140171 PlatformAgnosticVersionConstraintAvailabilitySpec (
141172 AvailabilitySpecKind AvailabilitySpecKind,
142173 SourceLoc PlatformAgnosticNameLoc, llvm::VersionTuple Version,
143174 SourceRange VersionSrcRange)
144- : AvailabilitySpec(AvailabilitySpecKind),
145- PlatformAgnosticNameLoc (PlatformAgnosticNameLoc), Version(Version),
146- VersionSrcRange(VersionSrcRange) {
175+ : AvailabilitySpec(
176+ AvailabilitySpecKind, getDomainForSpecKind(AvailabilitySpecKind),
177+ SourceRange (PlatformAgnosticNameLoc, VersionSrcRange.End), Version,
178+ VersionSrcRange.Start) {
147179 assert (AvailabilitySpecKind == AvailabilitySpecKind::LanguageVersionConstraint ||
148180 AvailabilitySpecKind == AvailabilitySpecKind::PackageDescriptionVersionConstraint);
149181 }
150182
151- SourceLoc getPlatformAgnosticNameLoc () const { return PlatformAgnosticNameLoc; }
152-
153- // The platform version to compare against.
154- llvm::VersionTuple getVersion () const { return Version; }
155- SourceRange getVersionSrcRange () const { return VersionSrcRange; }
156-
157- SourceRange getSourceRange () const ;
183+ SourceLoc getPlatformAgnosticNameLoc () const {
184+ return getSourceRange ().Start ;
185+ }
158186
159187 bool isLanguageVersionSpecific () const {
160188 return getKind () == AvailabilitySpecKind::LanguageVersionConstraint;
@@ -185,16 +213,14 @@ class PlatformAgnosticVersionConstraintAvailabilitySpec : public AvailabilitySpe
185213// / that we still do compile-time availability checking with '*', so the
186214// / compiler will still catch references to potentially unavailable symbols.
187215class OtherPlatformAvailabilitySpec : public AvailabilitySpec {
188- SourceLoc StarLoc;
189-
190216public:
191217 OtherPlatformAvailabilitySpec (SourceLoc StarLoc)
192- : AvailabilitySpec(AvailabilitySpecKind::OtherPlatform) ,
193- StarLoc (StarLoc) {}
194-
195- SourceLoc getStarLoc () const { return StarLoc; }
218+ : AvailabilitySpec(AvailabilitySpecKind::OtherPlatform, std:: nullopt ,
219+ StarLoc,
220+ /* Version= */ {},
221+ /* VersionStartLoc= */ {}) { }
196222
197- SourceRange getSourceRange () const { return SourceRange (StarLoc, StarLoc) ; }
223+ SourceLoc getStarLoc () const { return getSourceRange (). Start ; }
198224
199225 void print (raw_ostream &OS, unsigned Indent) const ;
200226
0 commit comments