AST/Sema: Resolve AvailabilityDomain in SemanticAvailableAttrRequest.

Look up the AvailabilityDomain given its name during type checking, instead of
parsing.
This commit is contained in:
Allan Shortlidge
2025-01-25 18:22:56 -08:00
parent 7b8cbd7109
commit a5d60ce35e
5 changed files with 42 additions and 2 deletions

View File

@@ -912,6 +912,12 @@ private:
private: private:
friend class SemanticAvailableAttrRequest; friend class SemanticAvailableAttrRequest;
void setCachedDomain(AvailabilityDomain domain) {
assert(!Bits.AvailableAttr.HasDomain);
Domain = domain;
Bits.AvailableAttr.HasDomain = true;
}
bool hasComputedSemanticAttr() const { bool hasComputedSemanticAttr() const {
return Bits.AvailableAttr.HasComputedSemanticAttr; return Bits.AvailableAttr.HasComputedSemanticAttr;
} }

View File

@@ -140,6 +140,10 @@ public:
return AvailabilityDomain(Kind::Embedded); return AvailabilityDomain(Kind::Embedded);
} }
/// Returns the built-in availability domain identified by the given string.
static std::optional<AvailabilityDomain>
builtinDomainForString(StringRef string);
Kind getKind() const { Kind getKind() const {
if (auto inlineDomain = getInlineDomain()) if (auto inlineDomain = getInlineDomain())
return inlineDomain->getKind(); return inlineDomain->getKind();

View File

@@ -13,9 +13,28 @@
#include "swift/AST/AvailabilityDomain.h" #include "swift/AST/AvailabilityDomain.h"
#include "swift/AST/ASTContext.h" #include "swift/AST/ASTContext.h"
#include "swift/AST/Decl.h" #include "swift/AST/Decl.h"
#include "llvm/ADT/StringSwitch.h"
using namespace swift; using namespace swift;
std::optional<AvailabilityDomain>
AvailabilityDomain::builtinDomainForString(StringRef string) {
auto domain = llvm::StringSwitch<std::optional<AvailabilityDomain>>(string)
.Case("*", AvailabilityDomain::forUniversal())
.Case("swift", AvailabilityDomain::forSwiftLanguage())
.Case("_PackageDescription",
AvailabilityDomain::forPackageDescription())
.Default(std::nullopt);
if (domain)
return domain;
if (auto platformKind = platformFromString(string))
return AvailabilityDomain::forPlatform(*platformKind);
return std::nullopt;
}
bool AvailabilityDomain::isActive(const ASTContext &ctx) const { bool AvailabilityDomain::isActive(const ASTContext &ctx) const {
switch (getKind()) { switch (getKind()) {
case Kind::Universal: case Kind::Universal:

View File

@@ -628,8 +628,8 @@ ParserResult<AvailableAttr> Parser::parseExtendedAvailabilitySpecList(
} }
auto Attr = new (Context) AvailableAttr( auto Attr = new (Context) AvailableAttr(
AtLoc, SourceRange(AttrLoc, Tok.getLoc()), Domain, PlatformLoc, AttrKind, AtLoc, SourceRange(AttrLoc, Tok.getLoc()), Platform, PlatformLoc,
Message, Renamed, Introduced.Version, Introduced.Range, AttrKind, Message, Renamed, Introduced.Version, Introduced.Range,
Deprecated.Version, Deprecated.Range, Obsoleted.Version, Obsoleted.Range, Deprecated.Version, Deprecated.Range, Obsoleted.Version, Obsoleted.Range,
/*Implicit=*/false, AttrName == SPI_AVAILABLE_ATTRNAME); /*Implicit=*/false, AttrName == SPI_AVAILABLE_ATTRNAME);
return makeParserResult(Attr); return makeParserResult(Attr);

View File

@@ -8270,6 +8270,17 @@ std::optional<SemanticAvailableAttr>
SemanticAvailableAttrRequest::evaluate(swift::Evaluator &evaluator, SemanticAvailableAttrRequest::evaluate(swift::Evaluator &evaluator,
const AvailableAttr *attr, const AvailableAttr *attr,
const Decl *decl) const { const Decl *decl) const {
if (attr->hasCachedDomain())
return SemanticAvailableAttr(attr);
auto string = attr->getDomainString();
ASSERT(string);
auto domain = AvailabilityDomain::builtinDomainForString(*string);
if (!domain)
return std::nullopt;
const_cast<AvailableAttr *>(attr)->setCachedDomain(*domain);
return SemanticAvailableAttr(attr); return SemanticAvailableAttr(attr);
} }