@@ -41,6 +41,7 @@ struct InferredAvailability {
4141 Optional<llvm::VersionTuple> Introduced;
4242 Optional<llvm::VersionTuple> Deprecated;
4343 Optional<llvm::VersionTuple> Obsoleted;
44+ bool IsSPI = false ;
4445};
4546
4647// / The type of a function that merges two version tuples.
@@ -51,17 +52,20 @@ typedef const llvm::VersionTuple &(*MergeFunction)(
5152
5253// / Apply a merge function to two optional versions, returning the result
5354// / in Inferred.
54- static void
55+ static bool
5556mergeIntoInferredVersion (const Optional<llvm::VersionTuple> &Version,
5657 Optional<llvm::VersionTuple> &Inferred,
5758 MergeFunction Merge) {
5859 if (Version.hasValue ()) {
5960 if (Inferred.hasValue ()) {
6061 Inferred = Merge (Inferred.getValue (), Version.getValue ());
62+ return *Inferred == *Version;
6163 } else {
6264 Inferred = Version;
65+ return true ;
6366 }
6467 }
68+ return false ;
6569}
6670
6771// / Merge an attribute's availability with an existing inferred availability
@@ -75,7 +79,9 @@ static void mergeWithInferredAvailability(const AvailableAttr *Attr,
7579 static_cast <unsigned >(Attr->getPlatformAgnosticAvailability ())));
7680
7781 // The merge of two introduction versions is the maximum of the two versions.
78- mergeIntoInferredVersion (Attr->Introduced , Inferred.Introduced , std::max);
82+ if (mergeIntoInferredVersion (Attr->Introduced , Inferred.Introduced , std::max)) {
83+ Inferred.IsSPI = Attr->IsSPI ;
84+ }
7985
8086 // The merge of deprecated and obsoleted versions takes the minimum.
8187 mergeIntoInferredVersion (Attr->Deprecated , Inferred.Deprecated , std::min);
@@ -103,7 +109,8 @@ createAvailableAttr(PlatformKind Platform,
103109 Introduced, /* IntroducedRange=*/ SourceRange (),
104110 Deprecated, /* DeprecatedRange=*/ SourceRange (),
105111 Obsoleted, /* ObsoletedRange=*/ SourceRange (),
106- Inferred.PlatformAgnostic , /* Implicit=*/ true );
112+ Inferred.PlatformAgnostic , /* Implicit=*/ true ,
113+ Inferred.IsSPI );
107114}
108115
109116void AvailabilityInference::applyInferredAvailableAttrs (
@@ -173,7 +180,13 @@ AvailabilityInference::annotatedAvailableRange(const Decl *D, ASTContext &Ctx) {
173180 return None;
174181
175182 return AvailabilityContext{
176- VersionRange::allGTE (bestAvailAttr->Introduced .getValue ())};
183+ VersionRange::allGTE (bestAvailAttr->Introduced .getValue ()),
184+ bestAvailAttr->IsSPI };
185+ }
186+
187+ bool Decl::isAvailableAsSPI () const {
188+ return AvailabilityInference::availableRange (this , getASTContext ())
189+ .isAvailableAsSPI ();
177190}
178191
179192AvailabilityContext
0 commit comments