2828
2929using namespace swift ;
3030
31- TypeRefinementContext::TypeRefinementContext (
32- ASTContext &Ctx, IntroNode Node, TypeRefinementContext *Parent,
33- SourceRange SrcRange, const AvailabilityRange &Info,
34- const AvailabilityRange &ExplicitInfo)
35- : Node(Node), SrcRange(SrcRange), AvailabilityInfo(Info),
36- ExplicitAvailabilityInfo(ExplicitInfo) {
31+ TypeRefinementContext::TypeRefinementContext (ASTContext &Ctx, IntroNode Node,
32+ TypeRefinementContext *Parent,
33+ SourceRange SrcRange,
34+ const AvailabilityRange &Info)
35+ : Node(Node), SrcRange(SrcRange), AvailabilityInfo(Info) {
3736 if (Parent) {
3837 assert (SrcRange.isValid ());
3938 Parent->addChild (this , Ctx);
@@ -78,18 +77,15 @@ TypeRefinementContext::createForSourceFile(SourceFile *SF,
7877 }
7978
8079 return new (Ctx)
81- TypeRefinementContext (Ctx, SF, parentContext, range, availabilityRange,
82- AvailabilityRange::alwaysAvailable ());
80+ TypeRefinementContext (Ctx, SF, parentContext, range, availabilityRange);
8381}
8482
8583TypeRefinementContext *TypeRefinementContext::createForDecl (
8684 ASTContext &Ctx, Decl *D, TypeRefinementContext *Parent,
87- const AvailabilityRange &Info, const AvailabilityRange &ExplicitInfo,
88- SourceRange SrcRange) {
85+ const AvailabilityRange &Info, SourceRange SrcRange) {
8986 assert (D);
9087 assert (Parent);
91- return new (Ctx)
92- TypeRefinementContext (Ctx, D, Parent, SrcRange, Info, ExplicitInfo);
88+ return new (Ctx) TypeRefinementContext (Ctx, D, Parent, SrcRange, Info);
9389}
9490
9591TypeRefinementContext *TypeRefinementContext::createForDeclImplicit (
@@ -98,8 +94,7 @@ TypeRefinementContext *TypeRefinementContext::createForDeclImplicit(
9894 assert (D);
9995 assert (Parent);
10096 return new (Ctx) TypeRefinementContext (
101- Ctx, IntroNode (D, Reason::DeclImplicit), Parent, SrcRange, Info,
102- AvailabilityRange::alwaysAvailable ());
97+ Ctx, IntroNode (D, Reason::DeclImplicit), Parent, SrcRange, Info);
10398}
10499
105100TypeRefinementContext *
@@ -110,8 +105,7 @@ TypeRefinementContext::createForIfStmtThen(ASTContext &Ctx, IfStmt *S,
110105 assert (Parent);
111106 return new (Ctx)
112107 TypeRefinementContext (Ctx, IntroNode (S, /* IsThen=*/ true ), Parent,
113- S->getThenStmt ()->getSourceRange (),
114- Info, /* ExplicitInfo */ Info);
108+ S->getThenStmt ()->getSourceRange (), Info);
115109}
116110
117111TypeRefinementContext *
@@ -122,8 +116,7 @@ TypeRefinementContext::createForIfStmtElse(ASTContext &Ctx, IfStmt *S,
122116 assert (Parent);
123117 return new (Ctx)
124118 TypeRefinementContext (Ctx, IntroNode (S, /* IsThen=*/ false ), Parent,
125- S->getElseStmt ()->getSourceRange (),
126- Info, /* ExplicitInfo */ Info);
119+ S->getElseStmt ()->getSourceRange (), Info);
127120}
128121
129122TypeRefinementContext *TypeRefinementContext::createForConditionFollowingQuery (
@@ -133,8 +126,7 @@ TypeRefinementContext *TypeRefinementContext::createForConditionFollowingQuery(
133126 assert (PAI);
134127 assert (Parent);
135128 SourceRange Range (PAI->getEndLoc (), LastElement.getEndLoc ());
136- return new (Ctx) TypeRefinementContext (Ctx, PAI, Parent, Range,
137- Info, /* ExplicitInfo */ Info);
129+ return new (Ctx) TypeRefinementContext (Ctx, PAI, Parent, Range, Info);
138130}
139131
140132TypeRefinementContext *TypeRefinementContext::createForGuardStmtFallthrough (
@@ -144,9 +136,8 @@ TypeRefinementContext *TypeRefinementContext::createForGuardStmtFallthrough(
144136 assert (ContainingBraceStmt);
145137 assert (Parent);
146138 SourceRange Range (RS->getEndLoc (), ContainingBraceStmt->getEndLoc ());
147- return new (Ctx) TypeRefinementContext (Ctx,
148- IntroNode (RS, /* IsFallthrough=*/ true ),
149- Parent, Range, Info, /* ExplicitInfo */ Info);
139+ return new (Ctx) TypeRefinementContext (
140+ Ctx, IntroNode (RS, /* IsFallthrough=*/ true ), Parent, Range, Info);
150141}
151142
152143TypeRefinementContext *
@@ -157,7 +148,7 @@ TypeRefinementContext::createForGuardStmtElse(ASTContext &Ctx, GuardStmt *RS,
157148 assert (Parent);
158149 return new (Ctx)
159150 TypeRefinementContext (Ctx, IntroNode (RS, /* IsFallthrough=*/ false ), Parent,
160- RS->getBody ()->getSourceRange (), Info, /* ExplicitInfo */ Info );
151+ RS->getBody ()->getSourceRange (), Info);
161152}
162153
163154TypeRefinementContext *
@@ -166,8 +157,8 @@ TypeRefinementContext::createForWhileStmtBody(ASTContext &Ctx, WhileStmt *S,
166157 const AvailabilityRange &Info) {
167158 assert (S);
168159 assert (Parent);
169- return new (Ctx) TypeRefinementContext (
170- Ctx, S, Parent, S->getBody ()->getSourceRange (), Info, /* ExplicitInfo */ Info);
160+ return new (Ctx) TypeRefinementContext (Ctx, S, Parent,
161+ S->getBody ()->getSourceRange (), Info);
171162}
172163
173164void TypeRefinementContext::addChild (TypeRefinementContext *Child,
@@ -365,6 +356,38 @@ TypeRefinementContext::getAvailabilityConditionVersionSourceRange(
365356 llvm_unreachable (" Unhandled Reason in switch." );
366357}
367358
359+ std::optional<const AvailabilityRange>
360+ TypeRefinementContext::getExplicitAvailabilityRange () const {
361+ switch (getReason ()) {
362+ case Reason::Root:
363+ return std::nullopt ;
364+
365+ case Reason::Decl: {
366+ auto decl = Node.getAsDecl ();
367+ auto &ctx = decl->getASTContext ();
368+ if (auto attr =
369+ AvailabilityInference::attrForAnnotatedAvailableRange (decl, ctx))
370+ return AvailabilityInference::availableRange (attr, ctx);
371+
372+ return std::nullopt ;
373+ }
374+
375+ case Reason::DeclImplicit:
376+ return std::nullopt ;
377+
378+ case Reason::IfStmtThenBranch:
379+ case Reason::IfStmtElseBranch:
380+ case Reason::ConditionFollowingAvailabilityQuery:
381+ case Reason::GuardStmtFallthrough:
382+ case Reason::GuardStmtElseBranch:
383+ case Reason::WhileStmtBody:
384+ // Availability is inherently explicit for all of these nodes.
385+ return getAvailabilityInfo ();
386+ }
387+
388+ llvm_unreachable (" Unhandled Reason in switch." );
389+ }
390+
368391static std::string
369392stringForAvailability (const AvailabilityRange &availability) {
370393 if (availability.isAlwaysAvailable ())
@@ -425,9 +448,8 @@ void TypeRefinementContext::print(raw_ostream &OS, SourceManager &SrcMgr,
425448 }
426449 }
427450
428- if (!ExplicitAvailabilityInfo.isAlwaysAvailable ())
429- OS << " explicit_version="
430- << stringForAvailability (ExplicitAvailabilityInfo);
451+ if (auto explicitAvailability = getExplicitAvailabilityRange ())
452+ OS << " explicit_version=" << stringForAvailability (*explicitAvailability);
431453
432454 for (TypeRefinementContext *Child : Children) {
433455 OS << ' \n ' ;
0 commit comments