Skip to content

Commit 2908520

Browse files
committed
AST: Introduce SemanticAvailableAttrRequest.
This request will finish type checking an AvailableAttr by resolving its domain and then enforcing any restrictions that the domain has on the attribute, like disallowing version specifications. This change just introduces the request and plumbs it through. NFC.
1 parent ab8b1cd commit 2908520

File tree

7 files changed

+83
-7
lines changed

7 files changed

+83
-7
lines changed

include/swift/AST/Attr.h

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,14 @@ class DeclAttribute : public AttributeBase {
151151
Value : 32
152152
);
153153

154-
SWIFT_INLINE_BITFIELD(AvailableAttr, DeclAttribute, 4+1+1+1,
154+
SWIFT_INLINE_BITFIELD(AvailableAttr, DeclAttribute, 4+1+1+1+1+1,
155155
/// An `AvailableAttr::Kind` value.
156156
Kind : 4,
157157

158+
/// State storage for `SemanticAvailableAttrRequest`.
159+
HasComputedSemanticAttr : 1,
160+
HasDomain : 1,
161+
158162
/// State storage for `RenamedDeclRequest`.
159163
HasComputedRenamedDecl : 1,
160164
HasRenamedDecl : 1,
@@ -806,14 +810,15 @@ class AvailableAttr : public DeclAttribute {
806810
/// Returns the `AvailabilityDomain` associated with the attribute, or
807811
/// `std::nullopt` if it has either not yet been resolved or could not be
808812
/// resolved successfully.
809-
std::optional<AvailabilityDomain> getCachedDomain() const { return Domain; }
813+
std::optional<AvailabilityDomain> getCachedDomain() const {
814+
if (hasCachedDomain())
815+
return Domain;
816+
return std::nullopt;
817+
}
810818

811819
/// Returns true if the `AvailabilityDomain` associated with the attribute
812820
/// has been resolved successfully.
813-
bool hasCachedDomain() const {
814-
// For now, domains are always set on construction of the attribute.
815-
return true;
816-
}
821+
bool hasCachedDomain() const { return Bits.AvailableAttr.HasDomain; }
817822

818823
/// Returns the kind of availability the attribute specifies.
819824
Kind getKind() const { return static_cast<Kind>(Bits.AvailableAttr.Kind); }
@@ -873,6 +878,17 @@ class AvailableAttr : public DeclAttribute {
873878
Bits.AvailableAttr.HasComputedRenamedDecl = true;
874879
Bits.AvailableAttr.HasRenamedDecl = hasRenamedDecl;
875880
}
881+
882+
private:
883+
friend class SemanticAvailableAttrRequest;
884+
885+
bool hasComputedSemanticAttr() const {
886+
return Bits.AvailableAttr.HasComputedSemanticAttr;
887+
}
888+
889+
void setComputedSemanticAttr() {
890+
Bits.AvailableAttr.HasComputedSemanticAttr = true;
891+
}
876892
};
877893

878894
/// Indicates that the given declaration is visible to Objective-C.

include/swift/AST/TypeCheckRequests.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5225,6 +5225,27 @@ class CustomDerivativesRequest
52255225
bool isCached() const { return true; }
52265226
};
52275227

5228+
class SemanticAvailableAttrRequest
5229+
: public SimpleRequest<SemanticAvailableAttrRequest,
5230+
std::optional<SemanticAvailableAttr>(
5231+
const AvailableAttr *, const Decl *),
5232+
RequestFlags::SeparatelyCached> {
5233+
public:
5234+
using SimpleRequest::SimpleRequest;
5235+
5236+
private:
5237+
friend SimpleRequest;
5238+
5239+
std::optional<SemanticAvailableAttr> evaluate(Evaluator &evaluator,
5240+
const AvailableAttr *attr,
5241+
const Decl *decl) const;
5242+
5243+
public:
5244+
bool isCached() const { return true; }
5245+
std::optional<std::optional<SemanticAvailableAttr>> getCachedResult() const;
5246+
void cacheResult(std::optional<SemanticAvailableAttr> value) const;
5247+
};
5248+
52285249
#define SWIFT_TYPEID_ZONE TypeChecker
52295250
#define SWIFT_TYPEID_HEADER "swift/AST/TypeCheckerTypeIDZone.def"
52305251
#include "swift/Basic/DefineTypeIDZone.h"

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,3 +614,8 @@ SWIFT_REQUEST(TypeChecker, CustomDerivativesRequest,
614614

615615
SWIFT_REQUEST(TypeChecker, GenericTypeParamDeclGetValueTypeRequest,
616616
Type(GenericTypeParamDecl *), Cached, NoLocationInfo)
617+
618+
SWIFT_REQUEST(TypeChecker, SemanticAvailableAttrRequest,
619+
std::optional<SemanticAvailableAttr>
620+
(const AvailableAttr *, const Decl *),
621+
SeparatelyCached, NoLocationInfo)

lib/AST/Attr.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2123,6 +2123,8 @@ AvailableAttr::AvailableAttr(
21232123
INIT_VER_TUPLE(Deprecated), DeprecatedRange(DeprecatedRange),
21242124
INIT_VER_TUPLE(Obsoleted), ObsoletedRange(ObsoletedRange) {
21252125
Bits.AvailableAttr.Kind = static_cast<uint8_t>(Kind);
2126+
Bits.AvailableAttr.HasComputedSemanticAttr = false;
2127+
Bits.AvailableAttr.HasDomain = true;
21262128
Bits.AvailableAttr.HasComputedRenamedDecl = false;
21272129
Bits.AvailableAttr.HasRenamedDecl = false;
21282130
Bits.AvailableAttr.IsSPI = IsSPI;

lib/AST/Availability.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,9 @@ Decl::getSemanticAvailableAttrs(bool includeInactive) const {
447447

448448
std::optional<SemanticAvailableAttr>
449449
Decl::getSemanticAvailableAttr(const AvailableAttr *attr) const {
450-
return SemanticAvailableAttr(attr);
450+
return evaluateOrDefault(getASTContext().evaluator,
451+
SemanticAvailableAttrRequest{attr, this},
452+
std::nullopt);
451453
}
452454

453455
std::optional<SemanticAvailableAttr>

lib/AST/TypeCheckRequests.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2730,3 +2730,26 @@ void IsUnsafeRequest::cacheResult(bool value) const {
27302730
auto *decl = std::get<0>(getStorage());
27312731
decl->setUnsafe(value);
27322732
}
2733+
2734+
//----------------------------------------------------------------------------//
2735+
// SemanticAvailableAttrRequest computation.
2736+
//----------------------------------------------------------------------------//
2737+
2738+
std::optional<std::optional<SemanticAvailableAttr>>
2739+
SemanticAvailableAttrRequest::getCachedResult() const {
2740+
const AvailableAttr *attr = std::get<0>(getStorage());
2741+
if (!attr->hasComputedSemanticAttr())
2742+
return std::nullopt;
2743+
2744+
if (!attr->hasCachedDomain()) {
2745+
return std::optional<SemanticAvailableAttr>{};
2746+
}
2747+
2748+
return SemanticAvailableAttr(attr);
2749+
}
2750+
2751+
void SemanticAvailableAttrRequest::cacheResult(
2752+
std::optional<SemanticAvailableAttr> value) const {
2753+
AvailableAttr *attr = const_cast<AvailableAttr *>(std::get<0>(getStorage()));
2754+
attr->setComputedSemanticAttr();
2755+
}

lib/Sema/TypeCheckAttr.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8252,6 +8252,13 @@ ValueDecl *RenamedDeclRequest::evaluate(Evaluator &evaluator,
82528252
return renamedDecl;
82538253
}
82548254

8255+
std::optional<SemanticAvailableAttr>
8256+
SemanticAvailableAttrRequest::evaluate(swift::Evaluator &evaluator,
8257+
const AvailableAttr *attr,
8258+
const Decl *decl) const {
8259+
return SemanticAvailableAttr(attr);
8260+
}
8261+
82558262
template <typename ATTR>
82568263
static void forEachCustomAttribute(
82578264
Decl *decl,

0 commit comments

Comments
 (0)