|
19 | 19 |
|
20 | 20 | #include "swift/AST/AvailabilityContext.h"
|
21 | 21 | #include "llvm/ADT/FoldingSet.h"
|
22 |
| -#include <optional> |
| 22 | +#include "llvm/Support/TrailingObjects.h" |
23 | 23 |
|
24 | 24 | namespace swift {
|
25 | 25 |
|
26 | 26 | class DeclAvailabilityConstraints;
|
27 | 27 |
|
28 |
| -/// Summarizes availability the constraints contained by an AvailabilityContext. |
29 |
| -class AvailabilityContext::Info { |
30 |
| -public: |
31 |
| - /// The introduction version. |
32 |
| - AvailabilityRange PlatformRange; |
| 28 | +/// A wrapper for storing an `AvailabilityDomain` and its associated information |
| 29 | +/// in `AvailabilityContext::Storage`. |
| 30 | +class AvailabilityContext::DomainInfo final { |
| 31 | + AvailabilityDomain domain; |
| 32 | + AvailabilityRange range; |
33 | 33 |
|
34 |
| - /// A sorted collection of disjoint domains that are known to be |
35 |
| - /// unavailable in this context. |
36 |
| - llvm::SmallVector<AvailabilityDomain, 1> UnavailableDomains; |
| 34 | +public: |
| 35 | + DomainInfo(AvailabilityDomain domain, const AvailabilityRange &range) |
| 36 | + : domain(domain), range(range) {}; |
37 | 37 |
|
38 |
| - /// Whether or not the context is considered deprecated on the current |
39 |
| - /// platform. |
40 |
| - unsigned IsDeprecated : 1; |
41 |
| - |
42 |
| - /// Sets each field to the value of the corresponding field in `other` if the |
43 |
| - /// other is more restrictive. Returns true if any field changed as a result |
44 |
| - /// of adding this constraint. |
45 |
| - bool constrainWith(const Info &other); |
46 |
| - |
47 |
| - /// Constrains each field using the given constraints if they are more |
48 |
| - /// restrictive than the current values. Returns true if any field was |
49 |
| - /// updated. |
50 |
| - bool constrainWith(const DeclAvailabilityConstraints &constraints, |
51 |
| - const ASTContext &ctx); |
52 |
| - |
53 |
| - bool constrainUnavailability( |
54 |
| - const llvm::SmallVectorImpl<AvailabilityDomain> &domains); |
55 |
| - bool constrainUnavailability(AvailabilityDomain domain) { |
56 |
| - return constrainUnavailability( |
57 |
| - llvm::SmallVector<AvailabilityDomain>{domain}); |
| 38 | + static DomainInfo unavailable(AvailabilityDomain domain) { |
| 39 | + return DomainInfo(domain, AvailabilityRange::neverAvailable()); |
58 | 40 | }
|
59 | 41 |
|
60 |
| - /// Returns true if `other` is as available or is more available. |
61 |
| - bool isContainedIn(const Info &other) const; |
62 |
| - |
63 |
| - void Profile(llvm::FoldingSetNodeID &ID) const; |
| 42 | + AvailabilityDomain getDomain() const { return domain; } |
| 43 | + AvailabilityRange getRange() const { return range; } |
| 44 | + bool isUnavailable() const { return range.isKnownUnreachable(); } |
64 | 45 |
|
65 |
| - /// Returns true if all internal invariants are satisfied. |
66 |
| - bool verify(const ASTContext &ctx) const; |
| 46 | + void Profile(llvm::FoldingSetNodeID &ID) const { |
| 47 | + ID.AddPointer(domain.getOpaqueValue()); |
| 48 | + range.getRawVersionRange().Profile(ID); |
| 49 | + } |
67 | 50 | };
|
68 | 51 |
|
69 | 52 | /// As an implementation detail, the values that make up an `Availability`
|
70 | 53 | /// context are uniqued and stored as folding set nodes.
|
71 |
| -class AvailabilityContext::Storage final : public llvm::FoldingSetNode { |
72 |
| - Storage(const Info &info) : info(info){}; |
| 54 | +class AvailabilityContext::Storage final |
| 55 | + : public llvm::FoldingSetNode, |
| 56 | + public llvm::TrailingObjects<Storage, DomainInfo> { |
| 57 | + friend TrailingObjects; |
| 58 | + |
| 59 | + Storage(const AvailabilityRange &platformRange, bool isDeprecated, |
| 60 | + unsigned domainInfoCount) |
| 61 | + : platformRange(platformRange), isDeprecated(isDeprecated), |
| 62 | + domainInfoCount(domainInfoCount) {}; |
73 | 63 |
|
74 | 64 | public:
|
75 |
| - Info info; |
| 65 | + /// The introduction version for the current platform. |
| 66 | + const AvailabilityRange platformRange; |
76 | 67 |
|
77 |
| - static const Storage *get(const Info &info, const ASTContext &ctx); |
| 68 | + /// Whether or not the context is considered deprecated on the current |
| 69 | + /// platform. |
| 70 | + const unsigned isDeprecated : 1; |
78 | 71 |
|
79 |
| - void Profile(llvm::FoldingSetNodeID &ID) const { info.Profile(ID); } |
| 72 | + /// The number of `DomainInfo` objects in trailing storage. |
| 73 | + const unsigned domainInfoCount; |
| 74 | + |
| 75 | + /// Retrieves the unique storage instance from the `ASTContext` for the given |
| 76 | + /// parameters. |
| 77 | + static const Storage *get(const AvailabilityRange &platformRange, |
| 78 | + bool isDeprecated, |
| 79 | + llvm::ArrayRef<DomainInfo> domainInfos, |
| 80 | + const ASTContext &ctx); |
| 81 | + |
| 82 | + llvm::ArrayRef<DomainInfo> getDomainInfos() const { |
| 83 | + return llvm::ArrayRef(getTrailingObjects<DomainInfo>(), domainInfoCount); |
| 84 | + } |
| 85 | + |
| 86 | + llvm::SmallVector<DomainInfo, 4> copyDomainInfos() const { |
| 87 | + return llvm::SmallVector<DomainInfo, 4>{getDomainInfos()}; |
| 88 | + } |
| 89 | + |
| 90 | + /// Uniquing for `ASTContext`. |
| 91 | + static void Profile(llvm::FoldingSetNodeID &ID, |
| 92 | + const AvailabilityRange &platformRange, bool isDeprecated, |
| 93 | + llvm::ArrayRef<DomainInfo> domainInfos); |
| 94 | + |
| 95 | + void Profile(llvm::FoldingSetNodeID &ID) const { |
| 96 | + Profile(ID, platformRange, static_cast<bool>(isDeprecated), |
| 97 | + getDomainInfos()); |
| 98 | + } |
80 | 99 | };
|
81 | 100 |
|
82 | 101 | } // end namespace swift
|
|
0 commit comments