@@ -30,18 +30,19 @@ namespace swift {
3030class ASTContext ;
3131
3232enum 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,
3535
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 ,
3939
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,
4242
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,
4546};
4647
4748// / The root class for specifications of API availability in availability
@@ -65,16 +66,51 @@ class AvailabilitySpec : public ASTAllocated<AvailabilitySpec> {
6566 // Location of the availability macro expanded to create this spec.
6667 SourceLoc MacroLoc;
6768
68- public:
6969 AvailabilitySpec (AvailabilitySpecKind Kind,
7070 std::optional<AvailabilityDomain> Domain,
7171 SourceRange SrcRange, llvm::VersionTuple Version,
7272 SourceLoc VersionStartLoc)
7373 : Kind(Kind), Domain(Domain), SrcRange(SrcRange), Version(Version),
7474 VersionStartLoc (VersionStartLoc) {}
7575
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+
76110 AvailabilitySpecKind getKind () const { return Kind; }
77111
112+ bool isWildcard () { return getKind () == AvailabilitySpecKind::Wildcard; }
113+
78114 SourceRange getSourceRange () const { return SrcRange; }
79115 SourceLoc getStartLoc () const { return SrcRange.Start ; }
80116
@@ -89,6 +125,11 @@ class AvailabilitySpec : public ASTAllocated<AvailabilitySpec> {
89125 // The platform version to compare against.
90126 llvm::VersionTuple getVersion () const ;
91127
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+
92133 SourceRange getVersionSrcRange () const {
93134 if (!VersionStartLoc)
94135 return SourceRange ();
@@ -100,121 +141,6 @@ class AvailabilitySpec : public ASTAllocated<AvailabilitySpec> {
100141 void setMacroLoc (SourceLoc loc) { MacroLoc = loc; }
101142};
102143
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-
218144// / Maps of macro name and version to availability specifications.
219145// / Organized as two nested \c DenseMap keyed first on the macro name then
220146// / the macro version. This structure allows to peek at macro names before
0 commit comments