@@ -412,10 +412,17 @@ class AvailabilityScopeBuilder : private ASTWalker {
412
412
};
413
413
std::vector<DeclBodyContextInfo> DeclBodyContextStack;
414
414
415
+ std::vector<const DeclContext *> DeclContextStack;
416
+
415
417
AvailabilityScope *getCurrentScope () {
416
418
return ContextStack.back ().Scope ;
417
419
}
418
420
421
+ const DeclContext *getCurrentDeclContext () const {
422
+ assert (!DeclContextStack.empty ());
423
+ return DeclContextStack.back ();
424
+ }
425
+
419
426
bool isCurrentScopeContainedByDeploymentTarget () {
420
427
return ContextStack.back ().ContainedByDeploymentTarget ;
421
428
}
@@ -467,6 +474,7 @@ class AvailabilityScopeBuilder : private ASTWalker {
467
474
: Context(Context) {
468
475
assert (Scope);
469
476
pushContext (Scope, ParentTy ());
477
+ DeclContextStack.push_back (Scope->getIntroductionNode ().getDeclContext ());
470
478
}
471
479
472
480
void build (Decl *D) {
@@ -588,27 +596,30 @@ class AvailabilityScopeBuilder : private ASTWalker {
588
596
589
597
// Implicit decls don't have source locations so they cannot have a scope.
590
598
// 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
+ }
604
615
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);
608
618
}
609
619
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
+ }
612
623
613
624
// If this decl is the concrete syntax decl for some abstract syntax decl,
614
625
// push it onto the stack so that the abstract syntax decls may be visited.
@@ -624,6 +635,11 @@ class AvailabilityScopeBuilder : private ASTWalker {
624
635
ConcreteDeclStack.pop_back ();
625
636
}
626
637
638
+ if (auto *DC = dyn_cast<DeclContext>(D)) {
639
+ assert (DeclContextStack.back () == DC);
640
+ DeclContextStack.pop_back ();
641
+ }
642
+
627
643
while (ContextStack.back ().ScopeNode .getAsDecl () == D) {
628
644
ContextStack.pop_back ();
629
645
}
@@ -1041,7 +1057,8 @@ class AvailabilityScopeBuilder : private ASTWalker {
1041
1057
auto AvailabilityContext =
1042
1058
constrainCurrentAvailabilityWithPlatformRange (ThenRange.value ());
1043
1059
auto *ThenScope = AvailabilityScope::createForIfStmtThen (
1044
- Context, IS, getCurrentScope (), AvailabilityContext);
1060
+ Context, IS, getCurrentDeclContext (), getCurrentScope (),
1061
+ AvailabilityContext);
1045
1062
AvailabilityScopeBuilder (ThenScope, Context).build (IS->getThenStmt ());
1046
1063
} else {
1047
1064
build (IS->getThenStmt ());
@@ -1064,7 +1081,8 @@ class AvailabilityScopeBuilder : private ASTWalker {
1064
1081
auto AvailabilityContext =
1065
1082
constrainCurrentAvailabilityWithPlatformRange (ElseRange.value ());
1066
1083
auto *ElseScope = AvailabilityScope::createForIfStmtElse (
1067
- Context, IS, getCurrentScope (), AvailabilityContext);
1084
+ Context, IS, getCurrentDeclContext (), getCurrentScope (),
1085
+ AvailabilityContext);
1068
1086
AvailabilityScopeBuilder (ElseScope, Context).build (ElseStmt);
1069
1087
} else {
1070
1088
build (IS->getElseStmt ());
@@ -1085,7 +1103,8 @@ class AvailabilityScopeBuilder : private ASTWalker {
1085
1103
auto AvailabilityContext =
1086
1104
constrainCurrentAvailabilityWithPlatformRange (BodyRange.value ());
1087
1105
auto *BodyScope = AvailabilityScope::createForWhileStmtBody (
1088
- Context, WS, getCurrentScope (), AvailabilityContext);
1106
+ Context, WS, getCurrentDeclContext (), getCurrentScope (),
1107
+ AvailabilityContext);
1089
1108
AvailabilityScopeBuilder (BodyScope, Context).build (WS->getBody ());
1090
1109
} else {
1091
1110
build (WS->getBody ());
@@ -1118,7 +1137,8 @@ class AvailabilityScopeBuilder : private ASTWalker {
1118
1137
auto AvailabilityContext =
1119
1138
constrainCurrentAvailabilityWithPlatformRange (ElseRange.value ());
1120
1139
auto *TrueScope = AvailabilityScope::createForGuardStmtElse (
1121
- Context, GS, getCurrentScope (), AvailabilityContext);
1140
+ Context, GS, getCurrentDeclContext (), getCurrentScope (),
1141
+ AvailabilityContext);
1122
1142
1123
1143
AvailabilityScopeBuilder (TrueScope, Context).build (ElseBody);
1124
1144
} else {
@@ -1135,7 +1155,8 @@ class AvailabilityScopeBuilder : private ASTWalker {
1135
1155
auto FallthroughAvailability =
1136
1156
constrainCurrentAvailabilityWithPlatformRange (FallthroughRange.value ());
1137
1157
auto *FallthroughScope = AvailabilityScope::createForGuardStmtFallthrough (
1138
- Context, GS, ParentBrace, getCurrentScope (), FallthroughAvailability);
1158
+ Context, GS, ParentBrace, getCurrentDeclContext (), getCurrentScope (),
1159
+ FallthroughAvailability);
1139
1160
1140
1161
pushContext (FallthroughScope, ParentBrace);
1141
1162
}
@@ -1293,7 +1314,8 @@ class AvailabilityScopeBuilder : private ASTWalker {
1293
1314
auto ConstrainedAvailability =
1294
1315
constrainCurrentAvailabilityWithPlatformRange (NewConstraint);
1295
1316
auto *Scope = AvailabilityScope::createForConditionFollowingQuery (
1296
- Context, Query, LastElement, CurrentScope, ConstrainedAvailability);
1317
+ Context, Query, LastElement, getCurrentDeclContext (), CurrentScope,
1318
+ ConstrainedAvailability);
1297
1319
1298
1320
pushContext (Scope, ParentTy ());
1299
1321
++NestedCount;
@@ -1399,6 +1421,11 @@ class AvailabilityScopeBuilder : private ASTWalker {
1399
1421
1400
1422
PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
1401
1423
(void )consumeDeclBodyContextIfNecessary (E);
1424
+
1425
+ if (auto CE = dyn_cast<ClosureExpr>(E)) {
1426
+ DeclContextStack.push_back (CE);
1427
+ }
1428
+
1402
1429
return Action::Continue (E);
1403
1430
}
1404
1431
@@ -1407,6 +1434,11 @@ class AvailabilityScopeBuilder : private ASTWalker {
1407
1434
ContextStack.pop_back ();
1408
1435
}
1409
1436
1437
+ if (auto *CE = dyn_cast<ClosureExpr>(E)) {
1438
+ assert (DeclContextStack.back () == CE);
1439
+ DeclContextStack.pop_back ();
1440
+ }
1441
+
1410
1442
return Action::Continue (E);
1411
1443
}
1412
1444
};
0 commit comments