@@ -30,18 +30,19 @@ namespace swift {
30
30
class ASTContext ;
31
31
32
32
enum class AvailabilitySpecKind {
33
- // / A platform-version constraint of the form "PlatformName X.Y.Z"
34
- PlatformVersionConstraint,
33
+ // / A platform-version constraint of the form "PlatformName X.Y.Z"
34
+ PlatformVersionConstraint,
35
35
36
- // / A wildcard constraint, spelled '*', that is equivalent
37
- // / to CurrentPlatformName >= MinimumDeploymentTargetVersion
38
- OtherPlatform ,
36
+ // / A wildcard constraint, spelled '*', that is equivalent
37
+ // / to CurrentPlatformName >= MinimumDeploymentTargetVersion
38
+ Wildcard ,
39
39
40
- // / A language-version constraint of the form "swift X.Y.Z"
41
- LanguageVersionConstraint,
40
+ // / A language-version constraint of the form "swift X.Y.Z"
41
+ LanguageVersionConstraint,
42
42
43
- // / A PackageDescription version constraint of the form "_PackageDescription X.Y.Z"
44
- PackageDescriptionVersionConstraint,
43
+ // / A PackageDescription version constraint of the form "_PackageDescription
44
+ // / X.Y.Z"
45
+ PackageDescriptionVersionConstraint,
45
46
};
46
47
47
48
// / The root class for specifications of API availability in availability
@@ -65,16 +66,51 @@ class AvailabilitySpec : public ASTAllocated<AvailabilitySpec> {
65
66
// Location of the availability macro expanded to create this spec.
66
67
SourceLoc MacroLoc;
67
68
68
- public:
69
69
AvailabilitySpec (AvailabilitySpecKind Kind,
70
70
std::optional<AvailabilityDomain> Domain,
71
71
SourceRange SrcRange, llvm::VersionTuple Version,
72
72
SourceLoc VersionStartLoc)
73
73
: Kind(Kind), Domain(Domain), SrcRange(SrcRange), Version(Version),
74
74
VersionStartLoc (VersionStartLoc) {}
75
75
76
+ public:
77
+ // / Creates a wildcard availability specification that guards execution
78
+ // / by checking that the run-time version is greater than the minimum
79
+ // / deployment target. This specification is designed to ease porting
80
+ // / to new platforms. Because new platforms typically branch from
81
+ // / existing platforms, the wildcard allows an #available() check to do the
82
+ // / "right" thing (executing the guarded branch) on the new platform without
83
+ // / requiring a modification to every availability guard in the program. Note
84
+ // / that we still do compile-time availability checking with '*', so the
85
+ // / compiler will still catch references to potentially unavailable symbols.
86
+ static AvailabilitySpec *createWildcard (ASTContext &ctx, SourceLoc starLoc);
87
+
88
+ // / Creates an availability specification that guards execution based on the
89
+ // / compile-time platform agnostic version, e.g., swift >= 3.0.1,
90
+ // / package-description >= 4.0.
91
+ static AvailabilitySpec *createPlatformAgnostic (ASTContext &ctx,
92
+ AvailabilitySpecKind kind,
93
+ SourceLoc nameLoc,
94
+ llvm::VersionTuple version,
95
+ SourceRange versionRange);
96
+
97
+ // / Creates an availability specification that guards execution based on the
98
+ // / run-time platform and version, e.g., macOS >= 10.10.
99
+ static AvailabilitySpec *createPlatformVersioned (ASTContext &ctx,
100
+ PlatformKind platform,
101
+ SourceLoc platformLoc,
102
+ llvm::VersionTuple version,
103
+ SourceRange versionRange);
104
+
105
+ AvailabilitySpec *clone (ASTContext &ctx) const {
106
+ return new (ctx)
107
+ AvailabilitySpec (Kind, Domain, SrcRange, Version, VersionStartLoc);
108
+ }
109
+
76
110
AvailabilitySpecKind getKind () const { return Kind; }
77
111
112
+ bool isWildcard () { return getKind () == AvailabilitySpecKind::Wildcard; }
113
+
78
114
SourceRange getSourceRange () const { return SrcRange; }
79
115
SourceLoc getStartLoc () const { return SrcRange.Start ; }
80
116
@@ -89,6 +125,11 @@ class AvailabilitySpec : public ASTAllocated<AvailabilitySpec> {
89
125
// The platform version to compare against.
90
126
llvm::VersionTuple getVersion () const ;
91
127
128
+ // The version to be used in codegen for version comparisons at run time.
129
+ // This is required to support beta versions of macOS Big Sur that
130
+ // report 10.16 at run time.
131
+ llvm::VersionTuple getRuntimeVersion () const { return Version; }
132
+
92
133
SourceRange getVersionSrcRange () const {
93
134
if (!VersionStartLoc)
94
135
return SourceRange ();
@@ -100,121 +141,6 @@ class AvailabilitySpec : public ASTAllocated<AvailabilitySpec> {
100
141
void setMacroLoc (SourceLoc loc) { MacroLoc = loc; }
101
142
};
102
143
103
- // / An availability specification that guards execution based on the
104
- // / run-time platform and version, e.g., OS X >= 10.10.
105
- class PlatformVersionConstraintAvailabilitySpec : public AvailabilitySpec {
106
- static std::optional<AvailabilityDomain>
107
- getDomainForPlatform (PlatformKind Platform) {
108
- if (Platform != PlatformKind::none)
109
- return AvailabilityDomain::forPlatform (Platform);
110
- return std::nullopt;
111
- }
112
-
113
- public:
114
- PlatformVersionConstraintAvailabilitySpec (PlatformKind Platform,
115
- SourceLoc PlatformLoc,
116
- llvm::VersionTuple Version,
117
- SourceRange VersionSrcRange)
118
- : AvailabilitySpec(AvailabilitySpecKind::PlatformVersionConstraint,
119
- getDomainForPlatform (Platform),
120
- SourceRange(PlatformLoc, VersionSrcRange.End), Version,
121
- VersionSrcRange.Start) {}
122
- // The version to be used in codegen for version comparisons at run time.
123
- // This is required to support beta versions of macOS Big Sur that
124
- // report 10.16 at run time.
125
- llvm::VersionTuple getRuntimeVersion () const ;
126
-
127
- void print (raw_ostream &OS, unsigned Indent) const ;
128
-
129
- static bool classof (const AvailabilitySpec *Spec) {
130
- return Spec->getKind () == AvailabilitySpecKind::PlatformVersionConstraint;
131
- }
132
-
133
- void *
134
- operator new (size_t Bytes, ASTContext &C,
135
- unsigned Alignment = alignof (PlatformVersionConstraintAvailabilitySpec)){
136
- return AvailabilitySpec::operator new (Bytes, C, AllocationArena::Permanent,
137
- Alignment);
138
- }
139
- };
140
-
141
- // / An availability specification that guards execution based on the
142
- // / compile-time platform agnostic version, e.g., swift >= 3.0.1,
143
- // / package-description >= 4.0.
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
- }
158
-
159
- public:
160
- PlatformAgnosticVersionConstraintAvailabilitySpec (
161
- AvailabilitySpecKind AvailabilitySpecKind,
162
- SourceLoc PlatformAgnosticNameLoc, llvm::VersionTuple Version,
163
- SourceRange VersionSrcRange)
164
- : AvailabilitySpec(
165
- AvailabilitySpecKind, getDomainForSpecKind(AvailabilitySpecKind),
166
- SourceRange (PlatformAgnosticNameLoc, VersionSrcRange.End), Version,
167
- VersionSrcRange.Start) {
168
- assert (AvailabilitySpecKind == AvailabilitySpecKind::LanguageVersionConstraint ||
169
- AvailabilitySpecKind == AvailabilitySpecKind::PackageDescriptionVersionConstraint);
170
- }
171
-
172
- void print (raw_ostream &OS, unsigned Indent) const ;
173
-
174
- static bool classof (const AvailabilitySpec *Spec) {
175
- return Spec->getKind () == AvailabilitySpecKind::LanguageVersionConstraint ||
176
- Spec->getKind () == AvailabilitySpecKind::PackageDescriptionVersionConstraint;
177
- }
178
-
179
- void *
180
- operator new (size_t Bytes, ASTContext &C,
181
- unsigned Alignment = alignof (PlatformAgnosticVersionConstraintAvailabilitySpec)){
182
- return AvailabilitySpec::operator new (Bytes, C, AllocationArena::Permanent,
183
- Alignment);
184
- }
185
- };
186
-
187
- // / A wildcard availability specification that guards execution
188
- // / by checking that the run-time version is greater than the minimum
189
- // / deployment target. This specification is designed to ease porting
190
- // / to new platforms. Because new platforms typically branch from
191
- // / existing platforms, the wildcard allows an #available() check to do the
192
- // / "right" thing (executing the guarded branch) on the new platform without
193
- // / requiring a modification to every availability guard in the program. Note
194
- // / that we still do compile-time availability checking with '*', so the
195
- // / compiler will still catch references to potentially unavailable symbols.
196
- class OtherPlatformAvailabilitySpec : public AvailabilitySpec {
197
- public:
198
- OtherPlatformAvailabilitySpec (SourceLoc StarLoc)
199
- : AvailabilitySpec(AvailabilitySpecKind::OtherPlatform, std::nullopt,
200
- StarLoc,
201
- /* Version=*/ {},
202
- /* VersionStartLoc=*/ {}) {}
203
-
204
- void print (raw_ostream &OS, unsigned Indent) const ;
205
-
206
- static bool classof (const AvailabilitySpec *Spec) {
207
- return Spec->getKind () == AvailabilitySpecKind::OtherPlatform;
208
- }
209
-
210
- void *
211
- operator new (size_t Bytes, ASTContext &C,
212
- unsigned Alignment = alignof (OtherPlatformAvailabilitySpec)) {
213
- return AvailabilitySpec::operator new (Bytes, C, AllocationArena::Permanent,
214
- Alignment);
215
- }
216
- };
217
-
218
144
// / Maps of macro name and version to availability specifications.
219
145
// / Organized as two nested \c DenseMap keyed first on the macro name then
220
146
// / the macro version. This structure allows to peek at macro names before
0 commit comments