Skip to content

Commit 1233c4e

Browse files
authored
Merge pull request #78627 from tshortli/availability-domain-external-definition-refactor
AST: Refactor AvailabilityDomain to prepare for external definitions
2 parents ff7c331 + 06443b9 commit 1233c4e

File tree

3 files changed

+99
-16
lines changed

3 files changed

+99
-16
lines changed

include/swift/AST/AvailabilityDomain.h

Lines changed: 96 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
#include "swift/AST/PlatformKind.h"
2222
#include "swift/Basic/LLVM.h"
23+
#include "llvm/ADT/PointerEmbeddedInt.h"
24+
#include "llvm/ADT/PointerUnion.h"
2325

2426
namespace swift {
2527
class ASTContext;
@@ -44,17 +46,66 @@ class AvailabilityDomain final {
4446
};
4547

4648
private:
47-
Kind kind;
48-
PlatformKind platform;
49+
friend struct llvm::PointerLikeTypeTraits<AvailabilityDomain>;
50+
51+
/// For a subset of domain kinds, all the information needed to represent the
52+
/// domain can be encapsulated inline in this class.
53+
class InlineDomain {
54+
Kind kind;
55+
PlatformKind platform;
56+
57+
public:
58+
using IntReprType = uint32_t;
59+
enum : uintptr_t {
60+
ReprBits = sizeof(IntReprType) * CHAR_BIT - 8,
61+
KindShift = ReprBits - sizeof(Kind) * CHAR_BIT,
62+
PlatformShift = KindShift - sizeof(PlatformKind) * CHAR_BIT,
63+
};
64+
65+
InlineDomain(Kind kind, PlatformKind platform)
66+
: kind(kind), platform(platform) {};
67+
InlineDomain(IntReprType value)
68+
: kind(static_cast<Kind>(value >> KindShift)),
69+
platform(static_cast<PlatformKind>(value >> PlatformShift)) {}
70+
71+
/// Serializes the domain into an integer value that must be smaller than a
72+
/// a pointer.
73+
IntReprType asInteger() const {
74+
return static_cast<IntReprType>(kind) << KindShift |
75+
static_cast<IntReprType>(platform) << PlatformShift;
76+
}
77+
78+
Kind getKind() const { return kind; }
79+
PlatformKind getPlatform() { return platform; }
80+
};
4981

50-
AvailabilityDomain(Kind kind) : kind(kind), platform(PlatformKind::none) {
82+
/// This will eventually be a class storing information about externally
83+
/// defined availability domains.
84+
using ExternalDomain = void;
85+
86+
using InlineDomainPtr = llvm::PointerEmbeddedInt<uint32_t, InlineDomain::ReprBits>;
87+
using Storage = llvm::PointerUnion<ExternalDomain *, InlineDomainPtr>;
88+
Storage storage;
89+
90+
AvailabilityDomain(Kind kind)
91+
: storage(InlineDomain(kind, PlatformKind::none).asInteger()) {
5192
assert(kind != Kind::Platform);
5293
};
5394

5495
AvailabilityDomain(PlatformKind platform)
55-
: kind(Kind::Platform), platform(platform) {
56-
assert(platform != PlatformKind::none);
57-
};
96+
: storage(InlineDomain(Kind::Platform, platform).asInteger()) {};
97+
98+
AvailabilityDomain(void *opaque)
99+
: storage(Storage::getFromOpaqueValue(opaque)) {};
100+
101+
void *getOpaqueValue() const { return storage.getOpaqueValue(); }
102+
103+
std::optional<InlineDomain> getInlineDomain() const {
104+
return storage.is<InlineDomainPtr>()
105+
? static_cast<std::optional<InlineDomain>>(
106+
storage.get<InlineDomainPtr>())
107+
: std::nullopt;
108+
}
58109

59110
public:
60111
AvailabilityDomain() {}
@@ -75,18 +126,30 @@ class AvailabilityDomain final {
75126
return AvailabilityDomain(Kind::PackageDescription);
76127
}
77128

78-
Kind getKind() const { return kind; }
129+
Kind getKind() const {
130+
if (auto inlineDomain = getInlineDomain())
131+
return inlineDomain->getKind();
132+
133+
llvm_unreachable("unimplemented");
134+
}
79135

80-
bool isUniversal() const { return kind == Kind::Universal; }
136+
bool isUniversal() const { return getKind() == Kind::Universal; }
81137

82-
bool isPlatform() const { return kind == Kind::Platform; }
138+
bool isPlatform() const { return getKind() == Kind::Platform; }
83139

84-
bool isSwiftLanguage() const { return kind == Kind::SwiftLanguage; }
140+
bool isSwiftLanguage() const { return getKind() == Kind::SwiftLanguage; }
85141

86-
bool isPackageDescription() const { return kind == Kind::PackageDescription; }
142+
bool isPackageDescription() const {
143+
return getKind() == Kind::PackageDescription;
144+
}
87145

88146
/// Returns the platform kind for this domain if applicable.
89-
PlatformKind getPlatformKind() const { return platform; }
147+
PlatformKind getPlatformKind() const {
148+
if (auto inlineDomain = getInlineDomain())
149+
return inlineDomain->getPlatform();
150+
151+
return PlatformKind::none;
152+
}
90153

91154
/// Returns true if this domain is considered active in the current
92155
/// compilation context.
@@ -136,4 +199,25 @@ class AvailabilityDomain final {
136199

137200
} // end namespace swift
138201

202+
namespace llvm {
203+
// An AvailabilityDomain is "pointer like".
204+
template <typename T>
205+
struct PointerLikeTypeTraits;
206+
template <>
207+
struct PointerLikeTypeTraits<swift::AvailabilityDomain> {
208+
public:
209+
static inline void *getAsVoidPointer(swift::AvailabilityDomain domain) {
210+
return domain.storage.getOpaqueValue();
211+
}
212+
static inline swift::AvailabilityDomain getFromVoidPointer(void *P) {
213+
return swift::AvailabilityDomain(P);
214+
}
215+
enum {
216+
NumLowBitsAvailable = PointerLikeTypeTraits<
217+
swift::AvailabilityDomain::Storage>::NumLowBitsAvailable
218+
};
219+
};
220+
221+
} // end namespace llvm
222+
139223
#endif

include/swift/AST/AvailabilityScope.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include "swift/Basic/LLVM.h"
2828
#include "swift/Basic/STLExtras.h"
2929
#include "swift/Basic/SourceLoc.h"
30-
#include "llvm/ADT/PointerUnion.h"
3130
#include "llvm/Support/ErrorHandling.h"
3231

3332
namespace swift {

lib/AST/AvailabilityDomain.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
using namespace swift;
1818

1919
bool AvailabilityDomain::isActive(const ASTContext &ctx) const {
20-
switch (kind) {
20+
switch (getKind()) {
2121
case Kind::Universal:
2222
case Kind::SwiftLanguage:
2323
case Kind::PackageDescription:
@@ -28,7 +28,7 @@ bool AvailabilityDomain::isActive(const ASTContext &ctx) const {
2828
}
2929

3030
llvm::StringRef AvailabilityDomain::getNameForDiagnostics() const {
31-
switch (kind) {
31+
switch (getKind()) {
3232
case Kind::Universal:
3333
return "";
3434
case Kind::SwiftLanguage:
@@ -41,7 +41,7 @@ llvm::StringRef AvailabilityDomain::getNameForDiagnostics() const {
4141
}
4242

4343
llvm::StringRef AvailabilityDomain::getNameForAttributePrinting() const {
44-
switch (kind) {
44+
switch (getKind()) {
4545
case Kind::Universal:
4646
return "*";
4747
case Kind::SwiftLanguage:

0 commit comments

Comments
 (0)