@@ -194,30 +194,7 @@ class VersionRange {
194
194
}
195
195
};
196
196
197
- // / Records the reason a declaration is potentially unavailable.
198
- class UnavailabilityReason {
199
- private:
200
- VersionRange RequiredDeploymentRange;
201
-
202
- explicit UnavailabilityReason (const VersionRange RequiredDeploymentRange)
203
- : RequiredDeploymentRange(RequiredDeploymentRange) {}
204
-
205
- public:
206
- static UnavailabilityReason requiresVersionRange (const VersionRange Range) {
207
- return UnavailabilityReason (Range);
208
- }
209
-
210
- const VersionRange &getRequiredOSVersionRange () const {
211
- return RequiredDeploymentRange;
212
- }
213
-
214
- // / Returns true if the required OS version range's lower endpoint is at or
215
- // / below the deployment target of the given ASTContext.
216
- bool requiresDeploymentTargetOrEarlier (ASTContext &Ctx) const ;
217
- };
218
-
219
- // / Represents everything that a particular chunk of code may assume about its
220
- // / runtime environment.
197
+ // / Represents a version range in which something is available.
221
198
// /
222
199
// / The AvailabilityContext structure forms a [lattice][], which allows it to
223
200
// / have meaningful union and intersection operations ("join" and "meet"),
@@ -229,14 +206,10 @@ class UnavailabilityReason {
229
206
// / NOTE: Generally you should use the utilities on \c AvailabilityInference
230
207
// / to create an \c AvailabilityContext, rather than creating one directly.
231
208
class AvailabilityContext {
232
- VersionRange OSVersion;
233
- std::optional<bool > SPI;
209
+ VersionRange Range;
234
210
235
211
public:
236
- // / Creates a context that requires certain versions of the target OS.
237
- explicit AvailabilityContext (VersionRange OSVersion,
238
- std::optional<bool > SPI = std::nullopt )
239
- : OSVersion(OSVersion), SPI(SPI) {}
212
+ explicit AvailabilityContext (VersionRange Range) : Range(Range) {}
240
213
241
214
// / Creates a context that imposes the constraints of the ASTContext's
242
215
// / deployment target.
@@ -264,21 +237,34 @@ class AvailabilityContext {
264
237
return AvailabilityContext (VersionRange::empty ());
265
238
}
266
239
267
- // / Returns the range of possible OS versions required by this context.
268
- VersionRange getOSVersion () const { return OSVersion; }
240
+ // / Returns the range of possible versions required by this context.
241
+ VersionRange getRawVersionRange () const { return Range; }
242
+
243
+ // / Returns true if there is a version tuple for this context.
244
+ bool hasMinimumVersion () const { return Range.hasLowerEndpoint (); }
245
+
246
+ // / Returns the minimum version required by this context. This convenience
247
+ // / is meant for debugging, diagnostics, serialization, etc. Use of the set
248
+ // / algebra operations on `AvailabilityContext` should be preferred over
249
+ // / direct comparison of raw versions.
250
+ // /
251
+ // / Only call when `hasMinimumVersion()` returns true.
252
+ llvm::VersionTuple getRawMinimumVersion () const {
253
+ return Range.getLowerEndpoint ();
254
+ }
269
255
270
256
// / Returns true if \p other makes stronger guarantees than this context.
271
257
// /
272
258
// / That is, `a.isContainedIn(b)` implies `a.union(b) == b`.
273
259
bool isContainedIn (const AvailabilityContext &other) const {
274
- return OSVersion .isContainedIn (other.OSVersion );
260
+ return Range .isContainedIn (other.Range );
275
261
}
276
262
277
263
// / Returns true if \p other is a strict subset of this context.
278
264
// /
279
265
// / That is, `a.isSupersetOf(b)` implies `a != b` and `a.union(b) == a`.
280
266
bool isSupersetOf (const AvailabilityContext &other) const {
281
- return OSVersion .isSupersetOf (other.OSVersion );
267
+ return Range .isSupersetOf (other.Range );
282
268
}
283
269
284
270
// / Returns true if this context has constraints that make it impossible to
@@ -287,13 +273,13 @@ class AvailabilityContext {
287
273
// / For example, the else branch of a `#available` check for iOS 8.0 when the
288
274
// / containing function already requires iOS 9.
289
275
bool isKnownUnreachable () const {
290
- return OSVersion .isEmpty ();
276
+ return Range .isEmpty ();
291
277
}
292
278
293
279
// / Returns true if there are no constraints on this context; that is,
294
280
// / nothing can be assumed.
295
281
bool isAlwaysAvailable () const {
296
- return OSVersion .isAll ();
282
+ return Range .isAll ();
297
283
}
298
284
299
285
// / Produces an under-approximation of the intersection of the two
@@ -306,7 +292,7 @@ class AvailabilityContext {
306
292
// / As an example, this is used when figuring out the required availability
307
293
// / for a type that references multiple nominal decls.
308
294
void intersectWith (const AvailabilityContext &other) {
309
- OSVersion .intersectWith (other.getOSVersion () );
295
+ Range .intersectWith (other.Range );
310
296
}
311
297
312
298
// / Produces an over-approximation of the intersection of the two
@@ -317,7 +303,7 @@ class AvailabilityContext {
317
303
// /
318
304
// / As an example, this is used for the true branch of `#available`.
319
305
void constrainWith (const AvailabilityContext &other) {
320
- OSVersion .constrainWith (other.getOSVersion () );
306
+ Range .constrainWith (other.Range );
321
307
}
322
308
323
309
// / Produces an over-approximation of the union of two availability contexts.
@@ -329,15 +315,19 @@ class AvailabilityContext {
329
315
// / As an example, this is used for the else branch of a conditional with
330
316
// / multiple `#available` checks.
331
317
void unionWith (const AvailabilityContext &other) {
332
- OSVersion .unionWith (other.getOSVersion () );
318
+ Range .unionWith (other.Range );
333
319
}
334
320
335
- bool isAvailableAsSPI () const { return SPI && *SPI; }
336
-
337
321
// / Returns a representation of this range as a string for debugging purposes.
338
322
std::string getAsString () const {
339
- return " AvailabilityContext(" + OSVersion.getAsString () +
340
- (isAvailableAsSPI () ? " , spi" : " " ) + " )" ;
323
+ return " AvailabilityContext(" + getVersionString () + " )" ;
324
+ }
325
+
326
+ // / Returns a representation of the raw version range as a string for
327
+ // / debugging purposes.
328
+ std::string getVersionString () const {
329
+ assert (Range.hasLowerEndpoint ());
330
+ return Range.getLowerEndpoint ().getAsString ();
341
331
}
342
332
};
343
333
@@ -358,9 +348,12 @@ class AvailabilityInference {
358
348
static AvailabilityContext inferForType (Type t);
359
349
360
350
// / Returns the context where a declaration is available
361
- // / We assume a declaration without an annotation is always available.
351
+ // / We assume a declaration without an annotation is always available.
362
352
static AvailabilityContext availableRange (const Decl *D, ASTContext &C);
363
353
354
+ // / Returns true is the declaration is `@_spi_available`.
355
+ static bool isAvailableAsSPI (const Decl *D, ASTContext &C);
356
+
364
357
// / Returns the availability context for a declaration with the given
365
358
// / @available attribute.
366
359
// /
0 commit comments