@@ -412,10 +412,17 @@ class AvailabilityScopeBuilder : private ASTWalker {
412412 };
413413 std::vector<DeclBodyContextInfo> DeclBodyContextStack;
414414
415+ std::vector<const DeclContext *> DeclContextStack;
416+
415417 AvailabilityScope *getCurrentScope () {
416418 return ContextStack.back ().Scope ;
417419 }
418420
421+ const DeclContext *getCurrentDeclContext () const {
422+ assert (!DeclContextStack.empty ());
423+ return DeclContextStack.back ();
424+ }
425+
419426 bool isCurrentScopeContainedByDeploymentTarget () {
420427 return ContextStack.back ().ContainedByDeploymentTarget ;
421428 }
@@ -467,6 +474,7 @@ class AvailabilityScopeBuilder : private ASTWalker {
467474 : Context(Context) {
468475 assert (Scope);
469476 pushContext (Scope, ParentTy ());
477+ DeclContextStack.push_back (Scope->getIntroductionNode ().getDeclContext ());
470478 }
471479
472480 void build (Decl *D) {
@@ -588,27 +596,30 @@ class AvailabilityScopeBuilder : private ASTWalker {
588596
589597 // Implicit decls don't have source locations so they cannot have a scope.
590598 // However, some implicit nodes contain non-implicit nodes (e.g. defer
591- // blocks) so continue rather than skipping the node entirely.
592- if (D->isImplicit ())
593- return Action::Continue ();
594-
595- if (shouldSkipDecl (D))
596- return Action::SkipNode ();
597-
598- // The AST of this decl may not be ready to traverse yet if it hasn't been
599- // full typechecked. If that's the case, we leave a placeholder node in the
600- // tree to indicate that the subtree should be expanded lazily when it
601- // needs to be traversed.
602- if (buildLazyContextForDecl (D))
603- return Action::SkipNode ();
599+ // blocks) so we must continue through them.
600+ if (!D->isImplicit ()) {
601+ if (shouldSkipDecl (D))
602+ return Action::SkipNode ();
603+
604+ // The AST of this decl may not be ready to traverse yet if it hasn't been
605+ // full typechecked. If that's the case, we leave a placeholder node in
606+ // the tree to indicate that the subtree should be expanded lazily when it
607+ // needs to be traversed.
608+ if (buildLazyContextForDecl (D))
609+ return Action::SkipNode ();
610+
611+ // Adds in a scope that covers the entire declaration.
612+ if (auto DeclScope = getNewContextForSignatureOfDecl (D)) {
613+ pushContext (DeclScope, D);
614+ }
604615
605- // Adds in a scope that covers the entire declaration.
606- if (auto DeclScope = getNewContextForSignatureOfDecl (D)) {
607- pushContext (DeclScope, D);
616+ // Create scopes that cover only the body of the declaration.
617+ buildContextsForBodyOfDecl (D);
608618 }
609619
610- // Create scopes that cover only the body of the declaration.
611- buildContextsForBodyOfDecl (D);
620+ if (auto *DC = dyn_cast<DeclContext>(D)) {
621+ DeclContextStack.push_back (DC);
622+ }
612623
613624 // If this decl is the concrete syntax decl for some abstract syntax decl,
614625 // push it onto the stack so that the abstract syntax decls may be visited.
@@ -624,6 +635,11 @@ class AvailabilityScopeBuilder : private ASTWalker {
624635 ConcreteDeclStack.pop_back ();
625636 }
626637
638+ if (auto *DC = dyn_cast<DeclContext>(D)) {
639+ assert (DeclContextStack.back () == DC);
640+ DeclContextStack.pop_back ();
641+ }
642+
627643 while (ContextStack.back ().ScopeNode .getAsDecl () == D) {
628644 ContextStack.pop_back ();
629645 }
@@ -1041,7 +1057,8 @@ class AvailabilityScopeBuilder : private ASTWalker {
10411057 auto AvailabilityContext =
10421058 constrainCurrentAvailabilityWithPlatformRange (ThenRange.value ());
10431059 auto *ThenScope = AvailabilityScope::createForIfStmtThen (
1044- Context, IS, getCurrentScope (), AvailabilityContext);
1060+ Context, IS, getCurrentDeclContext (), getCurrentScope (),
1061+ AvailabilityContext);
10451062 AvailabilityScopeBuilder (ThenScope, Context).build (IS->getThenStmt ());
10461063 } else {
10471064 build (IS->getThenStmt ());
@@ -1064,7 +1081,8 @@ class AvailabilityScopeBuilder : private ASTWalker {
10641081 auto AvailabilityContext =
10651082 constrainCurrentAvailabilityWithPlatformRange (ElseRange.value ());
10661083 auto *ElseScope = AvailabilityScope::createForIfStmtElse (
1067- Context, IS, getCurrentScope (), AvailabilityContext);
1084+ Context, IS, getCurrentDeclContext (), getCurrentScope (),
1085+ AvailabilityContext);
10681086 AvailabilityScopeBuilder (ElseScope, Context).build (ElseStmt);
10691087 } else {
10701088 build (IS->getElseStmt ());
@@ -1085,7 +1103,8 @@ class AvailabilityScopeBuilder : private ASTWalker {
10851103 auto AvailabilityContext =
10861104 constrainCurrentAvailabilityWithPlatformRange (BodyRange.value ());
10871105 auto *BodyScope = AvailabilityScope::createForWhileStmtBody (
1088- Context, WS, getCurrentScope (), AvailabilityContext);
1106+ Context, WS, getCurrentDeclContext (), getCurrentScope (),
1107+ AvailabilityContext);
10891108 AvailabilityScopeBuilder (BodyScope, Context).build (WS->getBody ());
10901109 } else {
10911110 build (WS->getBody ());
@@ -1118,7 +1137,8 @@ class AvailabilityScopeBuilder : private ASTWalker {
11181137 auto AvailabilityContext =
11191138 constrainCurrentAvailabilityWithPlatformRange (ElseRange.value ());
11201139 auto *TrueScope = AvailabilityScope::createForGuardStmtElse (
1121- Context, GS, getCurrentScope (), AvailabilityContext);
1140+ Context, GS, getCurrentDeclContext (), getCurrentScope (),
1141+ AvailabilityContext);
11221142
11231143 AvailabilityScopeBuilder (TrueScope, Context).build (ElseBody);
11241144 } else {
@@ -1135,7 +1155,8 @@ class AvailabilityScopeBuilder : private ASTWalker {
11351155 auto FallthroughAvailability =
11361156 constrainCurrentAvailabilityWithPlatformRange (FallthroughRange.value ());
11371157 auto *FallthroughScope = AvailabilityScope::createForGuardStmtFallthrough (
1138- Context, GS, ParentBrace, getCurrentScope (), FallthroughAvailability);
1158+ Context, GS, ParentBrace, getCurrentDeclContext (), getCurrentScope (),
1159+ FallthroughAvailability);
11391160
11401161 pushContext (FallthroughScope, ParentBrace);
11411162 }
@@ -1293,7 +1314,8 @@ class AvailabilityScopeBuilder : private ASTWalker {
12931314 auto ConstrainedAvailability =
12941315 constrainCurrentAvailabilityWithPlatformRange (NewConstraint);
12951316 auto *Scope = AvailabilityScope::createForConditionFollowingQuery (
1296- Context, Query, LastElement, CurrentScope, ConstrainedAvailability);
1317+ Context, Query, LastElement, getCurrentDeclContext (), CurrentScope,
1318+ ConstrainedAvailability);
12971319
12981320 pushContext (Scope, ParentTy ());
12991321 ++NestedCount;
@@ -1399,6 +1421,11 @@ class AvailabilityScopeBuilder : private ASTWalker {
13991421
14001422 PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
14011423 (void )consumeDeclBodyContextIfNecessary (E);
1424+
1425+ if (auto CE = dyn_cast<ClosureExpr>(E)) {
1426+ DeclContextStack.push_back (CE);
1427+ }
1428+
14021429 return Action::Continue (E);
14031430 }
14041431
@@ -1407,6 +1434,11 @@ class AvailabilityScopeBuilder : private ASTWalker {
14071434 ContextStack.pop_back ();
14081435 }
14091436
1437+ if (auto *CE = dyn_cast<ClosureExpr>(E)) {
1438+ assert (DeclContextStack.back () == CE);
1439+ DeclContextStack.pop_back ();
1440+ }
1441+
14101442 return Action::Continue (E);
14111443 }
14121444};
0 commit comments