|
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