@@ -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 ,
@@ -750,26 +754,32 @@ class AvailableAttr : public DeclAttribute {
750754 const StringRef Message;
751755 const StringRef Rename;
752756
753- const std::optional< llvm::VersionTuple> Introduced;
757+ const llvm::VersionTuple Introduced;
754758 const SourceRange IntroducedRange;
755- const std::optional< llvm::VersionTuple> Deprecated;
759+ const llvm::VersionTuple Deprecated;
756760 const SourceRange DeprecatedRange;
757- const std::optional< llvm::VersionTuple> Obsoleted;
761+ const llvm::VersionTuple Obsoleted;
758762 const SourceRange ObsoletedRange;
759763
760764public:
761765 // / Returns the parsed version for `introduced:`.
762766 std::optional<llvm::VersionTuple> getRawIntroduced () const {
767+ if (Introduced.empty ())
768+ return std::nullopt ;
763769 return Introduced;
764770 }
765771
766772 // / Returns the parsed version for `deprecated:`.
767773 std::optional<llvm::VersionTuple> getRawDeprecated () const {
774+ if (Deprecated.empty ())
775+ return std::nullopt ;
768776 return Deprecated;
769777 }
770778
771779 // / Returns the parsed version for `obsoleted:`.
772780 std::optional<llvm::VersionTuple> getRawObsoleted () const {
781+ if (Obsoleted.empty ())
782+ return std::nullopt ;
773783 return Obsoleted;
774784 }
775785
@@ -806,14 +816,15 @@ class AvailableAttr : public DeclAttribute {
806816 // / Returns the `AvailabilityDomain` associated with the attribute, or
807817 // / `std::nullopt` if it has either not yet been resolved or could not be
808818 // / resolved successfully.
809- std::optional<AvailabilityDomain> getCachedDomain () const { return Domain; }
819+ std::optional<AvailabilityDomain> getCachedDomain () const {
820+ if (hasCachedDomain ())
821+ return Domain;
822+ return std::nullopt ;
823+ }
810824
811825 // / Returns true if the `AvailabilityDomain` associated with the attribute
812826 // / has been resolved successfully.
813- bool hasCachedDomain () const {
814- // For now, domains are always set on construction of the attribute.
815- return true ;
816- }
827+ bool hasCachedDomain () const { return Bits.AvailableAttr .HasDomain ; }
817828
818829 // / Returns the kind of availability the attribute specifies.
819830 Kind getKind () const { return static_cast <Kind>(Bits.AvailableAttr .Kind ); }
@@ -873,6 +884,17 @@ class AvailableAttr : public DeclAttribute {
873884 Bits.AvailableAttr .HasComputedRenamedDecl = true ;
874885 Bits.AvailableAttr .HasRenamedDecl = hasRenamedDecl;
875886 }
887+
888+ private:
889+ friend class SemanticAvailableAttrRequest ;
890+
891+ bool hasComputedSemanticAttr () const {
892+ return Bits.AvailableAttr .HasComputedSemanticAttr ;
893+ }
894+
895+ void setComputedSemanticAttr () {
896+ Bits.AvailableAttr .HasComputedSemanticAttr = true ;
897+ }
876898};
877899
878900// / Indicates that the given declaration is visible to Objective-C.
@@ -3252,7 +3274,7 @@ class SemanticAvailableAttr final {
32523274
32533275 // / The version tuple written in source for the `introduced:` component.
32543276 std::optional<llvm::VersionTuple> getIntroduced () const {
3255- return attr->Introduced ;
3277+ return attr->getRawIntroduced () ;
32563278 }
32573279
32583280 // / The source range of the `introduced:` component.
@@ -3264,12 +3286,12 @@ class SemanticAvailableAttr final {
32643286
32653287 // / The version tuple written in source for the `deprecated:` component.
32663288 std::optional<llvm::VersionTuple> getDeprecated () const {
3267- return attr->Deprecated ;
3289+ return attr->getRawDeprecated () ;
32683290 }
32693291
32703292 // / The version tuple written in source for the `obsoleted:` component.
32713293 std::optional<llvm::VersionTuple> getObsoleted () const {
3272- return attr->Obsoleted ;
3294+ return attr->getRawObsoleted () ;
32733295 }
32743296
32753297 // / Returns the `message:` field of the attribute, or an empty string.
@@ -3302,7 +3324,8 @@ class SemanticAvailableAttr final {
33023324 // / Whether this attribute has an introduced, deprecated, or obsoleted
33033325 // / version.
33043326 bool isVersionSpecific () const {
3305- return attr->Introduced || attr->Deprecated || attr->Obsoleted ;
3327+ return getIntroduced ().has_value () || getDeprecated ().has_value () ||
3328+ getObsoleted ().has_value ();
33063329 }
33073330
33083331 // / Whether this is a language mode specific attribute.
0 commit comments