1818#ifndef SWIFT_AST_AVAILABILITY_DOMAIN_H
1919#define SWIFT_AST_AVAILABILITY_DOMAIN_H
2020
21+ #include " swift/AST/ASTAllocated.h"
22+ #include " swift/AST/Identifier.h"
2123#include " swift/AST/PlatformKind.h"
2224#include " swift/Basic/LLVM.h"
2325#include " llvm/ADT/FoldingSet.h"
2628
2729namespace swift {
2830class ASTContext ;
31+ class CustomAvailabilityDomain ;
2932class DeclContext ;
33+ class ModuleDecl ;
3034
3135// / Represents a dimension of availability (e.g. macOS platform or Swift
3236// / language mode).
@@ -48,6 +52,10 @@ class AvailabilityDomain final {
4852
4953 // / Represents availability for a specific operating system platform.
5054 Platform,
55+
56+ // / Represents availability for an arbitrary domain that is defined at
57+ // / compile time by a module.
58+ Custom,
5159 };
5260
5361private:
@@ -86,13 +94,10 @@ class AvailabilityDomain final {
8694 PlatformKind getPlatform () { return platform; }
8795 };
8896
89- // / This will eventually be a class storing information about externally
90- // / defined availability domains.
91- using ExternalDomain = void ;
92-
9397 using InlineDomainPtr =
9498 llvm::PointerEmbeddedInt<uint32_t , InlineDomain::ReprBits>;
95- using Storage = llvm::PointerUnion<ExternalDomain *, InlineDomainPtr>;
99+ using Storage =
100+ llvm::PointerUnion<CustomAvailabilityDomain *, InlineDomainPtr>;
96101 Storage storage;
97102
98103 AvailabilityDomain (Kind kind)
@@ -103,6 +108,8 @@ class AvailabilityDomain final {
103108 AvailabilityDomain (PlatformKind platform)
104109 : storage(InlineDomain(Kind::Platform, platform).asInteger()) {};
105110
111+ AvailabilityDomain (CustomAvailabilityDomain *domain) : storage(domain) {};
112+
106113 AvailabilityDomain (Storage storage) : storage(storage) {};
107114
108115 static AvailabilityDomain fromOpaque (void *opaque) {
@@ -118,6 +125,11 @@ class AvailabilityDomain final {
118125 : std::nullopt ;
119126 }
120127
128+ CustomAvailabilityDomain *getCustomDomain () const {
129+ assert (isCustom ());
130+ return storage.get <CustomAvailabilityDomain *>();
131+ }
132+
121133public:
122134 AvailabilityDomain () {}
123135
@@ -141,6 +153,10 @@ class AvailabilityDomain final {
141153 return AvailabilityDomain (Kind::Embedded);
142154 }
143155
156+ static AvailabilityDomain forCustom (CustomAvailabilityDomain *domain) {
157+ return AvailabilityDomain (domain);
158+ }
159+
144160 // / Returns the built-in availability domain identified by the given string.
145161 static std::optional<AvailabilityDomain>
146162 builtinDomainForString (StringRef string, const DeclContext *declContext);
@@ -149,7 +165,7 @@ class AvailabilityDomain final {
149165 if (auto inlineDomain = getInlineDomain ())
150166 return inlineDomain->getKind ();
151167
152- llvm_unreachable ( " unimplemented " ) ;
168+ return Kind::Custom ;
153169 }
154170
155171 bool isUniversal () const { return getKind () == Kind::Universal; }
@@ -164,6 +180,8 @@ class AvailabilityDomain final {
164180
165181 bool isEmbedded () const { return getKind () == Kind::Embedded; }
166182
183+ bool isCustom () const { return getKind () == Kind::Custom; }
184+
167185 // / Returns the platform kind for this domain if applicable.
168186 PlatformKind getPlatformKind () const {
169187 if (auto inlineDomain = getInlineDomain ())
@@ -183,6 +201,9 @@ class AvailabilityDomain final {
183201 // / Returns the string to use when printing an `@available` attribute.
184202 llvm::StringRef getNameForAttributePrinting () const ;
185203
204+ // / Returns the module that the domain belongs to, if it is a custom domain.
205+ ModuleDecl *getModule () const ;
206+
186207 // / Returns true if availability in `other` is a subset of availability in
187208 // / this domain. The set of all availability domains form a lattice where the
188209 // / universal domain (`*`) is the bottom element.
@@ -201,6 +222,34 @@ class AvailabilityDomain final {
201222 }
202223};
203224
225+ // / Represents an availability domain that has been defined in a module.
226+ class CustomAvailabilityDomain : public ASTAllocated <CustomAvailabilityDomain> {
227+ public:
228+ enum class Kind {
229+ // / A domain that is known to be enabled at compile time.
230+ Enabled,
231+ // / A domain that is known to be disabled at compile time.
232+ Disabled,
233+ // / A domain with an enablement state that must be queried at runtime.
234+ Dynamic,
235+ };
236+
237+ private:
238+ Identifier name;
239+ Kind kind;
240+ ModuleDecl *mod;
241+
242+ CustomAvailabilityDomain (Identifier name, ModuleDecl *mod, Kind kind);
243+
244+ public:
245+ static CustomAvailabilityDomain *create (const ASTContext &ctx, StringRef name,
246+ ModuleDecl *mod, Kind kind);
247+
248+ Identifier getName () const { return name; }
249+ Kind getKind () const { return kind; }
250+ ModuleDecl *getModule () const { return mod; }
251+ };
252+
204253} // end namespace swift
205254
206255namespace llvm {
0 commit comments