Skip to content

Commit 9df531a

Browse files
authored
Merge pull request #78485 from tshortli/adopt-semantic-available-attr-part-3
AST: Remove most platform queries from `AvailableAttr`
2 parents 0634bab + 9edd9ee commit 9df531a

14 files changed

+140
-169
lines changed

include/swift/AST/Attr.h

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -813,23 +813,6 @@ class AvailableAttr : public DeclAttribute {
813813
Bits.AvailableAttr.PlatformAgnostic);
814814
}
815815

816-
/// Returns true if the availability applies to a specific
817-
/// platform.
818-
bool hasPlatform() const { return getPlatform() != PlatformKind::none; }
819-
820-
/// Returns the string for the platform of the attribute.
821-
StringRef platformString() const {
822-
return swift::platformString(getPlatform());
823-
}
824-
825-
/// Returns the human-readable string for the platform of the attribute.
826-
StringRef prettyPlatformString() const {
827-
return swift::prettyPlatformString(getPlatform());
828-
}
829-
830-
/// Returns true if this attribute is active given the current platform.
831-
bool isActivePlatform(const ASTContext &ctx) const;
832-
833816
/// Create an AvailableAttr that indicates specific availability
834817
/// for all platforms.
835818
static AvailableAttr *
@@ -3239,7 +3222,7 @@ class SemanticAvailableAttr final {
32393222

32403223
/// Returns the effective range in which the declaration with this attribute
32413224
/// was introduced.
3242-
AvailabilityRange getIntroducedRange(ASTContext &Ctx) const;
3225+
AvailabilityRange getIntroducedRange(const ASTContext &Ctx) const;
32433226

32443227
/// The version tuple written in source for the `deprecated:` component.
32453228
std::optional<llvm::VersionTuple> getDeprecated() const {
@@ -3313,6 +3296,9 @@ class SemanticAvailableAttr final {
33133296
/// compilation context.
33143297
bool isActive(ASTContext &ctx) const;
33153298

3299+
/// Whether this attribute was spelled `@_spi_available`.
3300+
bool isSPI() const { return attr->isSPI(); }
3301+
33163302
bool operator==(const SemanticAvailableAttr &other) const {
33173303
return other.attr == attr;
33183304
}

include/swift/AST/AvailabilityDomain.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class AvailabilityDomain final {
8888

8989
/// Returns true if this domain is considered active in the current
9090
/// compilation context.
91-
bool isActive(ASTContext &ctx) const;
91+
bool isActive(const ASTContext &ctx) const;
9292

9393
/// Returns the string to use in diagnostics to identify the domain. May
9494
/// return an empty string.

include/swift/AST/AvailabilityInference.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424

2525
namespace swift {
2626
class ASTContext;
27-
class AvailableAttr;
2827
class BackDeployedAttr;
2928
class Decl;
29+
class SemanticAvailableAttr;
3030

3131
class AvailabilityInference {
3232
public:
@@ -63,26 +63,26 @@ class AvailabilityInference {
6363
/// values to the re-mapped platform's, if using a fallback platform.
6464
/// Returns `true` if a remap occured.
6565
static bool updateIntroducedPlatformForFallback(
66-
const AvailableAttr *attr, const ASTContext &Ctx,
66+
const SemanticAvailableAttr &attr, const ASTContext &Ctx,
6767
llvm::StringRef &Platform, llvm::VersionTuple &PlatformVer);
6868

6969
/// For the attribute's deprecation version, update the platform and version
7070
/// values to the re-mapped platform's, if using a fallback platform.
7171
/// Returns `true` if a remap occured.
7272
static bool updateDeprecatedPlatformForFallback(
73-
const AvailableAttr *attr, const ASTContext &Ctx,
73+
const SemanticAvailableAttr &attr, const ASTContext &Ctx,
7474
llvm::StringRef &Platform, llvm::VersionTuple &PlatformVer);
7575

7676
/// For the attribute's obsoletion version, update the platform and version
7777
/// values to the re-mapped platform's, if using a fallback platform.
7878
/// Returns `true` if a remap occured.
7979
static bool updateObsoletedPlatformForFallback(
80-
const AvailableAttr *attr, const ASTContext &Ctx,
80+
const SemanticAvailableAttr &attr, const ASTContext &Ctx,
8181
llvm::StringRef &Platform, llvm::VersionTuple &PlatformVer);
8282

83-
static void updatePlatformStringForFallback(
84-
const AvailableAttr *attr, const ASTContext &Ctx,
85-
llvm::StringRef &Platform);
83+
static void updatePlatformStringForFallback(const SemanticAvailableAttr &attr,
84+
const ASTContext &Ctx,
85+
llvm::StringRef &Platform);
8686

8787
/// For the attribute's before version, update the platform and version
8888
/// values to the re-mapped platform's, if using a fallback platform.

lib/APIDigester/ModuleAnalyzerNodes.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,16 +1339,14 @@ std::optional<uint8_t> SDKContext::getFixedBinaryOrder(ValueDecl *VD) const {
13391339
// check for if it has @available(macOS 9999, iOS 9999, tvOS 9999, watchOS 9999, *)
13401340
static bool isABIPlaceHolder(Decl *D) {
13411341
llvm::SmallSet<PlatformKind, 4> Platforms;
1342-
for (auto semanticAttr : D->getSemanticAvailableAttrs()) {
1343-
auto attr = semanticAttr.getParsedAttr();
1344-
auto domain = semanticAttr.getDomain();
1345-
if (domain.isPlatform() && attr->Introduced &&
1346-
attr->Introduced->getMajor() == 9999) {
1347-
Platforms.insert(attr->getPlatform());
1342+
for (auto attr : D->getSemanticAvailableAttrs()) {
1343+
if (attr.isPlatformSpecific() && attr.getIntroduced().has_value() &&
1344+
attr.getIntroduced()->getMajor() == 9999) {
1345+
Platforms.insert(attr.getPlatform());
13481346
}
13491347
}
13501348

1351-
// FIXME: This probably isn't correct anymore, now that visionOS exists
1349+
// FIXME: [availability] This probably isn't correct now that visionOS exists
13521350
return Platforms.size() == 4;
13531351
}
13541352

lib/AST/Attr.cpp

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ void DeclAttributes::dump(const Decl *D) const {
421421
LLVM_READONLY
422422
static bool isShortAvailable(const SemanticAvailableAttr &attr) {
423423
auto parsedAttr = attr.getParsedAttr();
424-
if (parsedAttr->isSPI())
424+
if (attr.isSPI())
425425
return false;
426426

427427
if (!attr.getIntroduced().has_value())
@@ -741,11 +741,16 @@ static void printDifferentiableAttrArguments(
741741

742742
/// Returns the `PlatformKind` referenced by \p attr if applicable, or
743743
/// `std::nullopt` otherwise.
744-
static std::optional<PlatformKind>
745-
referencedPlatform(const DeclAttribute *attr) {
744+
static std::optional<PlatformKind> referencedPlatform(const DeclAttribute *attr,
745+
const Decl *D) {
746746
switch (attr->getKind()) {
747747
case DeclAttrKind::Available:
748-
return static_cast<const AvailableAttr *>(attr)->getPlatform();
748+
if (auto semanticAttr = D->getSemanticAvailableAttr(
749+
static_cast<const AvailableAttr *>(attr))) {
750+
if (semanticAttr->isPlatformSpecific())
751+
return semanticAttr->getPlatform();
752+
}
753+
return std::nullopt;
749754
case DeclAttrKind::BackDeployed:
750755
return static_cast<const BackDeployedAttr *>(attr)->Platform;
751756
case DeclAttrKind::OriginallyDefinedIn:
@@ -757,8 +762,8 @@ referencedPlatform(const DeclAttribute *attr) {
757762

758763
/// Returns true if \p attr contains a reference to a `PlatformKind` that should
759764
/// be considered SPI.
760-
static bool referencesSPIPlatform(const DeclAttribute *attr) {
761-
if (auto platform = referencedPlatform(attr))
765+
static bool referencesSPIPlatform(const DeclAttribute *attr, const Decl *D) {
766+
if (auto platform = referencedPlatform(attr, D))
762767
return isPlatformSPI(*platform);
763768
return false;
764769
}
@@ -805,7 +810,7 @@ void DeclAttributes::print(ASTPrinter &Printer, const PrintOptions &Options,
805810
// In the public interfaces of -library-level=api modules, skip attributes
806811
// that reference SPI platforms.
807812
if (Options.printPublicInterface() && libraryLevelAPI &&
808-
referencesSPIPlatform(DA))
813+
referencesSPIPlatform(DA, D))
809814
continue;
810815

811816
// If we're supposed to suppress expanded macros, check whether this is
@@ -1172,21 +1177,20 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
11721177
}
11731178

11741179
case DeclAttrKind::Available: {
1175-
auto Attr = cast<AvailableAttr>(this);
1176-
auto SemanticAttr = D->getSemanticAvailableAttr(Attr);
1177-
if (!SemanticAttr)
1180+
auto Attr = D->getSemanticAvailableAttr(cast<AvailableAttr>(this));
1181+
if (!Attr)
11781182
return false;
11791183

11801184
if (Options.printPublicInterface() && Attr->isSPI()) {
1181-
assert(Attr->hasPlatform());
1182-
assert(Attr->Introduced.has_value());
1185+
assert(Attr->isPlatformSpecific());
1186+
assert(Attr->getIntroduced().has_value());
11831187
Printer.printAttrName("@available");
11841188
Printer << "(";
1185-
Printer << Attr->platformString();
1189+
Printer << Attr->getDomain().getNameForAttributePrinting();
11861190
Printer << ", unavailable)";
11871191
break;
11881192
}
1189-
if (Attr->isForEmbedded()) {
1193+
if (Attr->getParsedAttr()->isForEmbedded()) {
11901194
std::string atUnavailableInEmbedded =
11911195
(llvm::Twine("@") + UNAVAILABLE_IN_EMBEDDED_ATTRNAME).str();
11921196
Printer.printAttrName(atUnavailableInEmbedded);
@@ -1200,7 +1204,7 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
12001204
Printer.printAttrName("@available");
12011205
}
12021206
Printer << "(";
1203-
printAvailableAttr(D, *SemanticAttr, Printer, Options);
1207+
printAvailableAttr(D, *Attr, Printer, Options);
12041208
Printer << ")";
12051209
break;
12061210
}
@@ -2148,10 +2152,6 @@ AvailableAttr::createPlatformAgnostic(ASTContext &C,
21482152
/*SPI=*/false);
21492153
}
21502154

2151-
bool AvailableAttr::isActivePlatform(const ASTContext &ctx) const {
2152-
return isPlatformActive(getPlatform(), ctx.LangOpts);
2153-
}
2154-
21552155
bool BackDeployedAttr::isActivePlatform(const ASTContext &ctx,
21562156
bool forTargetVariant) const {
21572157
return isPlatformActive(Platform, ctx.LangOpts, forTargetVariant);
@@ -2261,7 +2261,7 @@ SemanticAvailableAttr::getVersionAvailability(const ASTContext &ctx) const {
22612261
StringRef ObsoletedPlatform;
22622262
llvm::VersionTuple RemappedObsoletedVersion;
22632263
if (AvailabilityInference::updateObsoletedPlatformForFallback(
2264-
attr, ctx, ObsoletedPlatform, RemappedObsoletedVersion))
2264+
*this, ctx, ObsoletedPlatform, RemappedObsoletedVersion))
22652265
ObsoletedVersion = RemappedObsoletedVersion;
22662266

22672267
// If this entity was obsoleted before or at the query platform version,
@@ -2273,7 +2273,7 @@ SemanticAvailableAttr::getVersionAvailability(const ASTContext &ctx) const {
22732273
StringRef IntroducedPlatform;
22742274
llvm::VersionTuple RemappedIntroducedVersion;
22752275
if (AvailabilityInference::updateIntroducedPlatformForFallback(
2276-
attr, ctx, IntroducedPlatform, RemappedIntroducedVersion))
2276+
*this, ctx, IntroducedPlatform, RemappedIntroducedVersion))
22772277
IntroducedVersion = RemappedIntroducedVersion;
22782278

22792279
// If this entity was introduced after the query version and we're doing a

lib/AST/Availability.cpp

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ static void mergeWithInferredAvailability(SemanticAvailableAttr Attr,
156156
// The merge of two introduction versions is the maximum of the two versions.
157157
if (mergeIntoInferredVersion(Attr.getIntroduced(), Inferred.Introduced,
158158
std::max)) {
159-
Inferred.IsSPI = ParsedAttr->isSPI();
159+
Inferred.IsSPI = Attr.isSPI();
160160
}
161161

162162
// The merge of deprecated and obsoleted versions takes the minimum.
@@ -345,10 +345,10 @@ getRemappedDeprecatedObsoletedVersionForFallbackPlatform(
345345
}
346346

347347
bool AvailabilityInference::updateIntroducedPlatformForFallback(
348-
const AvailableAttr *attr, const ASTContext &Ctx, llvm::StringRef &Platform,
349-
llvm::VersionTuple &PlatformVer) {
350-
std::optional<llvm::VersionTuple> IntroducedVersion = attr->Introduced;
351-
if (attr->getPlatform() == PlatformKind::iOS &&
348+
const SemanticAvailableAttr &attr, const ASTContext &Ctx,
349+
llvm::StringRef &Platform, llvm::VersionTuple &PlatformVer) {
350+
std::optional<llvm::VersionTuple> IntroducedVersion = attr.getIntroduced();
351+
if (attr.getPlatform() == PlatformKind::iOS &&
352352
IntroducedVersion.has_value() &&
353353
isPlatformActive(PlatformKind::visionOS, Ctx.LangOpts)) {
354354
// We re-map the iOS introduced version to the corresponding visionOS version
@@ -365,10 +365,10 @@ bool AvailabilityInference::updateIntroducedPlatformForFallback(
365365
}
366366

367367
bool AvailabilityInference::updateDeprecatedPlatformForFallback(
368-
const AvailableAttr *attr, const ASTContext &Ctx, llvm::StringRef &Platform,
369-
llvm::VersionTuple &PlatformVer) {
370-
std::optional<llvm::VersionTuple> DeprecatedVersion = attr->Deprecated;
371-
if (attr->getPlatform() == PlatformKind::iOS &&
368+
const SemanticAvailableAttr &attr, const ASTContext &Ctx,
369+
llvm::StringRef &Platform, llvm::VersionTuple &PlatformVer) {
370+
std::optional<llvm::VersionTuple> DeprecatedVersion = attr.getDeprecated();
371+
if (attr.getPlatform() == PlatformKind::iOS &&
372372
DeprecatedVersion.has_value() &&
373373
isPlatformActive(PlatformKind::visionOS, Ctx.LangOpts)) {
374374
// We re-map the iOS deprecated version to the corresponding visionOS version
@@ -385,11 +385,10 @@ bool AvailabilityInference::updateDeprecatedPlatformForFallback(
385385
}
386386

387387
bool AvailabilityInference::updateObsoletedPlatformForFallback(
388-
const AvailableAttr *attr, const ASTContext &Ctx, llvm::StringRef &Platform,
389-
llvm::VersionTuple &PlatformVer) {
390-
std::optional<llvm::VersionTuple> ObsoletedVersion = attr->Obsoleted;
391-
if (attr->getPlatform() == PlatformKind::iOS &&
392-
ObsoletedVersion.has_value() &&
388+
const SemanticAvailableAttr &attr, const ASTContext &Ctx,
389+
llvm::StringRef &Platform, llvm::VersionTuple &PlatformVer) {
390+
std::optional<llvm::VersionTuple> ObsoletedVersion = attr.getObsoleted();
391+
if (attr.getPlatform() == PlatformKind::iOS && ObsoletedVersion.has_value() &&
393392
isPlatformActive(PlatformKind::visionOS, Ctx.LangOpts)) {
394393
// We re-map the iOS obsoleted version to the corresponding visionOS version
395394
auto PotentiallyRemappedObsoletedVersion =
@@ -405,8 +404,9 @@ bool AvailabilityInference::updateObsoletedPlatformForFallback(
405404
}
406405

407406
void AvailabilityInference::updatePlatformStringForFallback(
408-
const AvailableAttr *attr, const ASTContext &Ctx, llvm::StringRef &Platform) {
409-
if (attr->getPlatform() == PlatformKind::iOS &&
407+
const SemanticAvailableAttr &attr, const ASTContext &Ctx,
408+
llvm::StringRef &Platform) {
409+
if (attr.getPlatform() == PlatformKind::iOS &&
410410
isPlatformActive(PlatformKind::visionOS, Ctx.LangOpts)) {
411411
Platform = swift::prettyPlatformString(PlatformKind::visionOS);
412412
}
@@ -468,8 +468,9 @@ Decl::getSemanticAvailableAttrs(bool includeInactive) const {
468468
std::optional<SemanticAvailableAttr>
469469
Decl::getSemanticAvailableAttr(const AvailableAttr *attr) const {
470470
auto domainForAvailableAttr = [](const AvailableAttr *attr) {
471-
if (attr->hasPlatform())
472-
return AvailabilityDomain::forPlatform(attr->getPlatform());
471+
auto platform = attr->getPlatform();
472+
if (platform != PlatformKind::none)
473+
return AvailabilityDomain::forPlatform(platform);
473474

474475
switch (attr->getPlatformAgnosticAvailability()) {
475476
case PlatformAgnosticAvailabilityKind::Deprecated:
@@ -530,8 +531,7 @@ std::optional<SemanticAvailableAttr> Decl::getDeprecatedAttr() const {
530531
StringRef deprecatedPlatform;
531532
llvm::VersionTuple remappedDeprecatedVersion;
532533
if (AvailabilityInference::updateDeprecatedPlatformForFallback(
533-
attr.getParsedAttr(), ctx, deprecatedPlatform,
534-
remappedDeprecatedVersion))
534+
attr, ctx, deprecatedPlatform, remappedDeprecatedVersion))
535535
deprecatedVersion = remappedDeprecatedVersion;
536536

537537
if (!deprecatedVersion.has_value())
@@ -821,21 +821,24 @@ AvailabilityRange AvailabilityInference::availableRange(const Decl *D) {
821821

822822
bool AvailabilityInference::isAvailableAsSPI(const Decl *D) {
823823
if (auto attr = D->getAvailableAttrForPlatformIntroduction())
824-
return attr->getParsedAttr()->isSPI();
824+
return attr->isSPI();
825825

826826
return false;
827827
}
828828

829829
AvailabilityRange
830-
SemanticAvailableAttr::getIntroducedRange(ASTContext &Ctx) const {
830+
SemanticAvailableAttr::getIntroducedRange(const ASTContext &Ctx) const {
831+
assert(domain.isActive(Ctx));
832+
831833
auto *attr = getParsedAttr();
832-
assert(attr->isActivePlatform(Ctx));
834+
if (!attr->Introduced.has_value())
835+
return AvailabilityRange::alwaysAvailable();
833836

834837
llvm::VersionTuple IntroducedVersion = attr->Introduced.value();
835-
StringRef Platform = attr->prettyPlatformString();
838+
StringRef Platform;
836839
llvm::VersionTuple RemappedIntroducedVersion;
837840
if (AvailabilityInference::updateIntroducedPlatformForFallback(
838-
attr, Ctx, Platform, RemappedIntroducedVersion))
841+
*this, Ctx, Platform, RemappedIntroducedVersion))
839842
IntroducedVersion = RemappedIntroducedVersion;
840843

841844
return AvailabilityRange{VersionRange::allGTE(IntroducedVersion)};

lib/AST/AvailabilityDomain.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
using namespace swift;
1818

19-
bool AvailabilityDomain::isActive(ASTContext &ctx) const {
19+
bool AvailabilityDomain::isActive(const ASTContext &ctx) const {
2020
switch (kind) {
2121
case Kind::Universal:
2222
case Kind::SwiftLanguage:

0 commit comments

Comments
 (0)