@@ -797,6 +797,13 @@ class AvailableAttr : public DeclAttribute {
797797 // / resolved successfully.
798798 std::optional<AvailabilityDomain> getCachedDomain () const { return Domain; }
799799
800+ // / Returns true if the `AvailabilityDomain` associated with the attribute
801+ // / has been resolved successfully.
802+ bool hasCachedDomain () const {
803+ // For now, domains are always set on construction of the attribute.
804+ return true ;
805+ }
806+
800807 // / Returns the kind of availability the attribute specifies.
801808 Kind getKind () const { return static_cast <Kind>(Bits.AvailableAttr .Kind ); }
802809
@@ -3189,20 +3196,24 @@ class ParsedDeclAttributes {
31893196 }
31903197};
31913198
3192- // / A wrapper for `AvailableAttr` that is enriched with additional semantic
3193- // / informaton, like its corresponding `AvailabilityDomain`.
3199+ // / A wrapper for `AvailableAttr` that enriches it with additional semantic
3200+ // / informaton that can only be determined using the `AvailabilityDomain`
3201+ // / associated with the attribute. A `SemanticAvailableAttr` can only be
3202+ // / constructed with an `AvailableAttr` that has a resolved
3203+ // / `AvailabilityDomain`.
31943204class SemanticAvailableAttr final {
31953205 const AvailableAttr *attr;
3196- AvailabilityDomain domain;
31973206
31983207public:
3199- SemanticAvailableAttr (const AvailableAttr *attr, AvailabilityDomain domain)
3200- : attr(attr), domain(domain) {
3208+ SemanticAvailableAttr (const AvailableAttr *attr) : attr(attr) {
32013209 assert (attr);
3210+ assert (attr->hasCachedDomain ());
32023211 }
32033212
32043213 const AvailableAttr *getParsedAttr () const { return attr; }
3205- const AvailabilityDomain getDomain () const { return domain; }
3214+ const AvailabilityDomain getDomain () const {
3215+ return attr->getCachedDomain ().value ();
3216+ }
32063217
32073218 // / The version tuple written in source for the `introduced:` component.
32083219 std::optional<llvm::VersionTuple> getIntroduced () const {
@@ -3640,6 +3651,32 @@ struct EnumTraits<TypeAttrKind> {
36403651
36413652} // end namespace swift
36423653
3654+ namespace llvm {
3655+ using swift::AvailableAttr;
3656+ using swift::SemanticAvailableAttr;
3657+
3658+ // A SemanticAvailableAttr just wraps an `AvailableAttr *` and is therefore
3659+ // "pointer like".
3660+ template <typename T>
3661+ struct PointerLikeTypeTraits ;
3662+ template <>
3663+ struct PointerLikeTypeTraits <SemanticAvailableAttr> {
3664+ public:
3665+ static inline void *getAsVoidPointer (SemanticAvailableAttr attr) {
3666+ return reinterpret_cast <void *>(
3667+ const_cast <AvailableAttr *>(attr.getParsedAttr ()));
3668+ }
3669+ static inline SemanticAvailableAttr getFromVoidPointer (void *P) {
3670+ return SemanticAvailableAttr (static_cast <AvailableAttr *>(P));
3671+ }
3672+ enum {
3673+ NumLowBitsAvailable =
3674+ PointerLikeTypeTraits<AvailableAttr *>::NumLowBitsAvailable
3675+ };
3676+ };
3677+
3678+ } // end namespace llvm
3679+
36433680#undef UNIMPLEMENTED_CLONE
36443681
36453682#endif
0 commit comments