18
18
#define SWIFT_AST_AVAILABILITY_SPEC_H
19
19
20
20
#include " swift/AST/ASTAllocated.h"
21
+ #include " swift/AST/AvailabilityDomain.h"
21
22
#include " swift/AST/Identifier.h"
22
23
#include " swift/AST/PlatformKind.h"
23
24
#include " swift/Basic/SourceLoc.h"
27
28
28
29
namespace swift {
29
30
class ASTContext ;
30
- class AvailabilityDomain ;
31
-
32
- enum class VersionComparison { GreaterThanEqual };
33
31
34
32
enum class AvailabilitySpecKind {
35
33
// / A platform-version constraint of the form "PlatformName X.Y.Z"
@@ -49,70 +47,94 @@ enum class AvailabilitySpecKind {
49
47
// / The root class for specifications of API availability in availability
50
48
// / queries.
51
49
class AvailabilitySpec : public ASTAllocated <AvailabilitySpec> {
50
+ protected:
52
51
AvailabilitySpecKind Kind;
53
52
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
+
54
68
public:
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) {}
56
75
57
76
AvailabilitySpecKind getKind () const { return Kind; }
58
77
59
- SourceRange getSourceRange () const ;
78
+ SourceRange getSourceRange () const { return SrcRange; }
60
79
61
- std::optional<AvailabilityDomain> getDomain () const ;
80
+ std::optional<AvailabilityDomain> getDomain () const { return Domain; }
62
81
63
82
std::optional<PlatformKind> getPlatform () const ;
64
83
84
+ // The platform version to compare against.
65
85
llvm::VersionTuple getVersion () const ;
66
86
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; }
68
96
};
69
97
70
98
// / An availability specification that guards execution based on the
71
99
// / run-time platform and version, e.g., OS X >= 10.10.
72
100
class 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
+ }
82
107
83
108
public:
84
109
PlatformVersionConstraintAvailabilitySpec (PlatformKind Platform,
85
110
SourceLoc PlatformLoc,
86
111
llvm::VersionTuple Version,
87
112
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) {}
91
117
92
118
// / 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 ; }
95
125
96
126
// / Returns true when the constraint is for a platform that was not
97
127
// / recognized. This enables better recovery during parsing but should never
98
128
// / 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
+ }
104
132
105
133
// The version to be used in codegen for version comparisons at run time.
106
134
// This is required to support beta versions of macOS Big Sur that
107
135
// report 10.16 at run time.
108
136
llvm::VersionTuple getRuntimeVersion () const ;
109
137
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
-
116
138
void print (raw_ostream &OS, unsigned Indent) const ;
117
139
118
140
static bool classof (const AvailabilitySpec *Spec) {
@@ -130,31 +152,37 @@ class PlatformVersionConstraintAvailabilitySpec : public AvailabilitySpec {
130
152
// / An availability specification that guards execution based on the
131
153
// / compile-time platform agnostic version, e.g., swift >= 3.0.1,
132
154
// / 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
+ }
138
169
139
170
public:
140
171
PlatformAgnosticVersionConstraintAvailabilitySpec (
141
172
AvailabilitySpecKind AvailabilitySpecKind,
142
173
SourceLoc PlatformAgnosticNameLoc, llvm::VersionTuple Version,
143
174
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) {
147
179
assert (AvailabilitySpecKind == AvailabilitySpecKind::LanguageVersionConstraint ||
148
180
AvailabilitySpecKind == AvailabilitySpecKind::PackageDescriptionVersionConstraint);
149
181
}
150
182
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
+ }
158
186
159
187
bool isLanguageVersionSpecific () const {
160
188
return getKind () == AvailabilitySpecKind::LanguageVersionConstraint;
@@ -185,16 +213,14 @@ class PlatformAgnosticVersionConstraintAvailabilitySpec : public AvailabilitySpe
185
213
// / that we still do compile-time availability checking with '*', so the
186
214
// / compiler will still catch references to potentially unavailable symbols.
187
215
class OtherPlatformAvailabilitySpec : public AvailabilitySpec {
188
- SourceLoc StarLoc;
189
-
190
216
public:
191
217
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= */ {}) { }
196
222
197
- SourceRange getSourceRange () const { return SourceRange (StarLoc, StarLoc) ; }
223
+ SourceLoc getStarLoc () const { return getSourceRange (). Start ; }
198
224
199
225
void print (raw_ostream &OS, unsigned Indent) const ;
200
226
0 commit comments