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,86 +47,82 @@ 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; }
79
+ SourceLoc getStartLoc () const { return SrcRange.Start ; }
60
80
61
- std::optional<AvailabilityDomain> getDomain () const ;
81
+ std::optional<AvailabilityDomain> getDomain () const { return Domain; }
62
82
63
- std::optional<PlatformKind> getPlatform () const ;
83
+ PlatformKind getPlatform () const {
84
+ if (auto domain = getDomain ())
85
+ return domain->getPlatformKind ();
86
+ return PlatformKind::none;
87
+ }
64
88
89
+ // The platform version to compare against.
65
90
llvm::VersionTuple getVersion () const ;
66
91
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; }
68
101
};
69
102
70
103
// / An availability specification that guards execution based on the
71
104
// / run-time platform and version, e.g., OS X >= 10.10.
72
105
class 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
+ }
96
112
97
113
public:
98
114
PlatformVersionConstraintAvailabilitySpec (PlatformKind Platform,
99
115
SourceLoc PlatformLoc,
100
116
llvm::VersionTuple Version,
101
- llvm::VersionTuple RuntimeVersion,
102
117
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) {}
122
122
// The version to be used in codegen for version comparisons at run time.
123
123
// This is required to support beta versions of macOS Big Sur that
124
124
// 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 ;
132
126
133
127
void print (raw_ostream &OS, unsigned Indent) const ;
134
128
@@ -147,36 +141,34 @@ class PlatformVersionConstraintAvailabilitySpec : public AvailabilitySpec {
147
141
// / An availability specification that guards execution based on the
148
142
// / compile-time platform agnostic version, e.g., swift >= 3.0.1,
149
143
// / 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
+ }
155
158
156
159
public:
157
160
PlatformAgnosticVersionConstraintAvailabilitySpec (
158
161
AvailabilitySpecKind AvailabilitySpecKind,
159
162
SourceLoc PlatformAgnosticNameLoc, llvm::VersionTuple Version,
160
163
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) {
164
168
assert (AvailabilitySpecKind == AvailabilitySpecKind::LanguageVersionConstraint ||
165
169
AvailabilitySpecKind == AvailabilitySpecKind::PackageDescriptionVersionConstraint);
166
170
}
167
171
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
-
180
172
void print (raw_ostream &OS, unsigned Indent) const ;
181
173
182
174
static bool classof (const AvailabilitySpec *Spec) {
@@ -202,16 +194,12 @@ class PlatformAgnosticVersionConstraintAvailabilitySpec : public AvailabilitySpe
202
194
// / that we still do compile-time availability checking with '*', so the
203
195
// / compiler will still catch references to potentially unavailable symbols.
204
196
class OtherPlatformAvailabilitySpec : public AvailabilitySpec {
205
- SourceLoc StarLoc;
206
-
207
197
public:
208
198
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=*/ {}) {}
215
203
216
204
void print (raw_ostream &OS, unsigned Indent) const ;
217
205
0 commit comments