Skip to content

Commit ac7654e

Browse files
committed
AST: Introduce some AvailabilityDomain conveniences.
One to get the active domain for the compilation target and another to get the ABI compatibility domain for a given domain. The ABI compatibility domain will be needed for queries that compute whether an unavailable declaration is still reachable at runtime. NFC.
1 parent ac27106 commit ac7654e

File tree

5 files changed

+88
-3
lines changed

5 files changed

+88
-3
lines changed

include/swift/AST/AvailabilityDomain.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "swift/AST/ASTAllocated.h"
2222
#include "swift/AST/Identifier.h"
2323
#include "swift/AST/PlatformKind.h"
24+
#include "swift/Basic/Assertions.h"
2425
#include "swift/Basic/LLVM.h"
2526
#include "llvm/ADT/FoldingSet.h"
2627
#include "llvm/ADT/PointerEmbeddedInt.h"
@@ -102,7 +103,7 @@ class AvailabilityDomain final {
102103

103104
AvailabilityDomain(Kind kind)
104105
: storage(InlineDomain(kind, PlatformKind::none).asInteger()) {
105-
assert(kind != Kind::Platform);
106+
DEBUG_ASSERT(kind != Kind::Platform);
106107
};
107108

108109
AvailabilityDomain(PlatformKind platform)
@@ -120,7 +121,7 @@ class AvailabilityDomain final {
120121
}
121122

122123
CustomAvailabilityDomain *getCustomDomain() const {
123-
assert(isCustom());
124+
ASSERT(isCustom());
124125
return storage.get<CustomAvailabilityDomain *>();
125126
}
126127

@@ -132,6 +133,8 @@ class AvailabilityDomain final {
132133
}
133134

134135
static AvailabilityDomain forPlatform(PlatformKind platformKind) {
136+
bool isPlatform = platformKind != PlatformKind::none;
137+
ASSERT(isPlatform);
135138
return AvailabilityDomain(platformKind);
136139
}
137140

@@ -151,6 +154,11 @@ class AvailabilityDomain final {
151154
return AvailabilityDomain(domain);
152155
}
153156

157+
/// Returns the most specific platform domain that applies to the compilation
158+
/// context.
159+
static std::optional<AvailabilityDomain>
160+
forTargetPlatform(const ASTContext &ctx);
161+
154162
/// Returns the built-in availability domain identified by the given string.
155163
static std::optional<AvailabilityDomain>
156164
builtinDomainForString(StringRef string, const DeclContext *declContext);
@@ -213,6 +221,11 @@ class AvailabilityDomain final {
213221
/// universal domain (`*`) is the bottom element.
214222
bool contains(const AvailabilityDomain &other) const;
215223

224+
/// Returns the root availability domain that this domain must be compatible
225+
/// with. For example, macCatalyst and visionOS must both be ABI compatible
226+
/// with iOS. The compatible domain must contain this domain.
227+
AvailabilityDomain getABICompatibilityDomain() const;
228+
216229
bool operator==(const AvailabilityDomain &other) const {
217230
return storage.getOpaqueValue() == other.storage.getOpaqueValue();
218231
}

lib/AST/AvailabilityDomain.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@
1818

1919
using namespace swift;
2020

21+
std::optional<AvailabilityDomain>
22+
AvailabilityDomain::forTargetPlatform(const ASTContext &ctx) {
23+
auto platform = swift::targetPlatform(ctx.LangOpts);
24+
if (platform == PlatformKind::none)
25+
return std::nullopt;
26+
27+
return forPlatform(platform);
28+
}
29+
2130
std::optional<AvailabilityDomain>
2231
AvailabilityDomain::builtinDomainForString(StringRef string,
2332
const DeclContext *declContext) {
@@ -136,6 +145,20 @@ bool AvailabilityDomain::contains(const AvailabilityDomain &other) const {
136145
}
137146
}
138147

148+
AvailabilityDomain AvailabilityDomain::getABICompatibilityDomain() const {
149+
if (!isPlatform())
150+
return *this;
151+
152+
auto iOSDomain = AvailabilityDomain::forPlatform(PlatformKind::iOS);
153+
if (iOSDomain.contains(*this))
154+
return iOSDomain;
155+
156+
if (auto basePlatform = basePlatformForExtensionPlatform(getPlatformKind()))
157+
return AvailabilityDomain::forPlatform(*basePlatform);
158+
159+
return *this;
160+
}
161+
139162
CustomAvailabilityDomain::CustomAvailabilityDomain(Identifier name,
140163
ModuleDecl *mod, Kind kind)
141164
: name(name), kind(kind), mod(mod) {

unittests/AST/AvailabilityContextTests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ static AvailabilityRange getAvailabilityRange(unsigned major, unsigned minor) {
3030
class AvailabilityContextTest : public ::testing::Test {
3131
public:
3232
const TestContext defaultTestContext{
33-
DoNotDeclareOptionalTypes, llvm::Triple("x86_64", "apple", "macosx10.9")};
33+
llvm::Triple("x86_64", "apple", "macosx10.9")};
3434

3535
struct {
3636
const AvailabilityDomain universal = AvailabilityDomain::forUniversal();

unittests/AST/AvailabilityDomainTests.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#include "TestContext.h"
1314
#include "swift/AST/AvailabilityDomain.h"
1415
#include "gtest/gtest.h"
1516

1617
using namespace swift;
18+
using namespace swift::unittest;
1719

1820
class AvailabilityDomainLattice : public ::testing::Test {
1921
public:
@@ -127,3 +129,47 @@ TEST_F(AvailabilityDomainLattice, Contains) {
127129
EXPECT_FALSE(visionOSAppExt.contains(macOS));
128130
EXPECT_FALSE(visionOSAppExt.contains(macOSAppExt));
129131
}
132+
133+
TEST_F(AvailabilityDomainLattice, ABICompatibilityDomain) {
134+
EXPECT_EQ(Universal.getABICompatibilityDomain(), Universal);
135+
EXPECT_EQ(Swift.getABICompatibilityDomain(), Swift);
136+
EXPECT_EQ(Package.getABICompatibilityDomain(), Package);
137+
EXPECT_EQ(Embedded.getABICompatibilityDomain(), Embedded);
138+
EXPECT_EQ(macOS.getABICompatibilityDomain(), macOS);
139+
EXPECT_EQ(macOSAppExt.getABICompatibilityDomain(), macOS);
140+
EXPECT_EQ(iOS.getABICompatibilityDomain(), iOS);
141+
EXPECT_EQ(iOSAppExt.getABICompatibilityDomain(), iOS);
142+
EXPECT_EQ(macCatalyst.getABICompatibilityDomain(), iOS);
143+
EXPECT_EQ(macCatalystAppExt.getABICompatibilityDomain(), iOS);
144+
EXPECT_EQ(visionOS.getABICompatibilityDomain(), iOS);
145+
EXPECT_EQ(visionOSAppExt.getABICompatibilityDomain(), iOS);
146+
}
147+
148+
TEST(AvailabilityDomain, TargetPlatform) {
149+
using namespace llvm;
150+
151+
struct TargetToPlatformKind {
152+
Triple target;
153+
PlatformKind platformKind;
154+
};
155+
TargetToPlatformKind tests[] = {
156+
{Triple("x86_64", "apple", "macosx10.15"), PlatformKind::macOS},
157+
{Triple("arm64", "apple", "ios13"), PlatformKind::iOS},
158+
{Triple("arm64_32", "apple", "watchos8"), PlatformKind::watchOS},
159+
{Triple("x86_64", "apple", "ios14", "macabi"), PlatformKind::macCatalyst},
160+
{Triple("x86_64", "unknown", "windows", "msvc"), PlatformKind::none},
161+
{Triple("x86_64", "unknown", "linux", "gnu"), PlatformKind::none},
162+
};
163+
164+
for (TargetToPlatformKind test : tests) {
165+
TestContext context{test.target};
166+
auto domain = AvailabilityDomain::forTargetPlatform(context.Ctx);
167+
if (test.platformKind != PlatformKind::none) {
168+
EXPECT_TRUE(domain);
169+
if (domain)
170+
EXPECT_TRUE(domain->getPlatformKind() == test.platformKind);
171+
} else {
172+
EXPECT_FALSE(domain);
173+
}
174+
}
175+
}

unittests/AST/TestContext.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ class TestContext : public TestContextBase {
6161
ShouldDeclareOptionalTypes optionals = DoNotDeclareOptionalTypes,
6262
llvm::Triple target = llvm::Triple(llvm::sys::getProcessTriple()));
6363

64+
TestContext(llvm::Triple target)
65+
: TestContext(DoNotDeclareOptionalTypes, target) {};
66+
6467
template <typename Nominal>
6568
typename std::enable_if<!std::is_same<Nominal, swift::ClassDecl>::value,
6669
Nominal *>::type

0 commit comments

Comments
 (0)