@@ -213,14 +213,17 @@ class ScopeCreator final {
213
213
214
214
// / Given an array of ASTNodes or Decl pointers, add them
215
215
// / Return the resultant insertionPoint
216
+ // /
217
+ // / \param endLoc The end location for any "scopes until the end" that
218
+ // / we introduce here, such as PatternEntryDeclScope and GuardStmtScope
216
219
ASTScopeImpl *
217
220
addSiblingsToScopeTree (ASTScopeImpl *const insertionPoint,
218
- ASTScopeImpl * const organicInsertionPoint ,
219
- ArrayRef<ASTNode> nodesOrDeclsToAdd ) {
221
+ ArrayRef<ASTNode> nodesOrDeclsToAdd ,
222
+ Optional<SourceLoc> endLoc ) {
220
223
auto *ip = insertionPoint;
221
224
for (auto nd : nodesOrDeclsToAdd) {
222
225
auto *const newIP =
223
- addToScopeTreeAndReturnInsertionPoint (nd, ip).getPtrOr (ip);
226
+ addToScopeTreeAndReturnInsertionPoint (nd, ip, endLoc ).getPtrOr (ip);
224
227
ip = newIP;
225
228
}
226
229
return ip;
@@ -229,12 +232,16 @@ class ScopeCreator final {
229
232
public:
230
233
// / For each of searching, call this unless the insertion point is needed
231
234
void addToScopeTree (ASTNode n, ASTScopeImpl *parent) {
232
- (void )addToScopeTreeAndReturnInsertionPoint (n, parent);
235
+ (void )addToScopeTreeAndReturnInsertionPoint (n, parent, None );
233
236
}
234
237
// / Return new insertion point if the scope was not a duplicate
235
238
// / For ease of searching, don't call unless insertion point is needed
239
+ // /
240
+ // / \param endLoc The end location for any "scopes until the end" that
241
+ // / we introduce here, such as PatternEntryDeclScope and GuardStmtScope
236
242
NullablePtr<ASTScopeImpl>
237
- addToScopeTreeAndReturnInsertionPoint (ASTNode, ASTScopeImpl *parent);
243
+ addToScopeTreeAndReturnInsertionPoint (ASTNode, ASTScopeImpl *parent,
244
+ Optional<SourceLoc> endLoc);
238
245
239
246
bool isWorthTryingToCreateScopeFor (ASTNode n) const {
240
247
if (!n)
@@ -419,6 +426,18 @@ class ScopeCreator final {
419
426
void addChildrenForKnownAttributes (ValueDecl *decl,
420
427
ASTScopeImpl *parent);
421
428
429
+ // / Add PatternEntryDeclScopes for each pattern binding entry.
430
+ // /
431
+ // / Returns the new insertion point.
432
+ // /
433
+ // / \param endLoc Must be valid iff the pattern binding is in a local
434
+ // / scope, in which case this is the last source location where the
435
+ // / pattern bindings are going to be visible.
436
+ NullablePtr<ASTScopeImpl>
437
+ addPatternBindingToScopeTree (PatternBindingDecl *patternBinding,
438
+ ASTScopeImpl *parent,
439
+ Optional<SourceLoc> endLoc);
440
+
422
441
// / Remove VarDecls because we'll find them when we expand the
423
442
// / PatternBindingDecls. Remove EnunCases
424
443
// / because they overlap EnumElements and AST includes the elements in the
@@ -541,7 +560,10 @@ class NodeAdder
541
560
: public ASTVisitor<NodeAdder, NullablePtr<ASTScopeImpl>,
542
561
NullablePtr<ASTScopeImpl>, NullablePtr<ASTScopeImpl>,
543
562
void , void , void , ASTScopeImpl *, ScopeCreator &> {
563
+ Optional<SourceLoc> endLoc;
564
+
544
565
public:
566
+ explicit NodeAdder (Optional<SourceLoc> endLoc) : endLoc(endLoc) {}
545
567
546
568
#pragma mark ASTNodes that do not create scopes
547
569
@@ -633,7 +655,9 @@ class NodeAdder
633
655
// the deferred nodes.
634
656
NullablePtr<ASTScopeImpl> visitGuardStmt (GuardStmt *e, ASTScopeImpl *p,
635
657
ScopeCreator &scopeCreator) {
636
- return scopeCreator.ifUniqueConstructExpandAndInsert <GuardStmtScope>(p, e);
658
+ ASTScopeAssert (endLoc.hasValue (), " GuardStmt outside of a BraceStmt?" );
659
+ return scopeCreator.ifUniqueConstructExpandAndInsert <GuardStmtScope>(
660
+ p, e, *endLoc);
637
661
}
638
662
NullablePtr<ASTScopeImpl> visitTopLevelCodeDecl (TopLevelCodeDecl *d,
639
663
ASTScopeImpl *p,
@@ -694,28 +718,8 @@ class NodeAdder
694
718
visitPatternBindingDecl (PatternBindingDecl *patternBinding,
695
719
ASTScopeImpl *parentScope,
696
720
ScopeCreator &scopeCreator) {
697
- if (auto *var = patternBinding->getSingleVar ())
698
- scopeCreator.addChildrenForKnownAttributes (var, parentScope);
699
-
700
- auto *insertionPoint = parentScope;
701
- for (auto i : range (patternBinding->getNumPatternEntries ())) {
702
- bool isLocalBinding = false ;
703
- if (auto *varDecl = patternBinding->getAnchoringVarDecl (i)) {
704
- isLocalBinding = varDecl->getDeclContext ()->isLocalContext ();
705
- }
706
-
707
- insertionPoint =
708
- scopeCreator
709
- .ifUniqueConstructExpandAndInsert <PatternEntryDeclScope>(
710
- insertionPoint, patternBinding, i, isLocalBinding)
711
- .getPtrOr (insertionPoint);
712
-
713
- ASTScopeAssert (isLocalBinding || insertionPoint == parentScope,
714
- " Bindings at the top-level or members of types should "
715
- " not change the insertion point" );
716
- }
717
-
718
- return insertionPoint;
721
+ return scopeCreator.addPatternBindingToScopeTree (
722
+ patternBinding, parentScope, endLoc);
719
723
}
720
724
721
725
NullablePtr<ASTScopeImpl> visitEnumElementDecl (EnumElementDecl *eed,
@@ -769,15 +773,18 @@ class NodeAdder
769
773
// NodeAdder
770
774
NullablePtr<ASTScopeImpl>
771
775
ScopeCreator::addToScopeTreeAndReturnInsertionPoint (ASTNode n,
772
- ASTScopeImpl *parent) {
776
+ ASTScopeImpl *parent,
777
+ Optional<SourceLoc> endLoc) {
773
778
if (!isWorthTryingToCreateScopeFor (n))
774
779
return parent;
780
+
781
+ NodeAdder adder (endLoc);
775
782
if (auto *p = n.dyn_cast <Decl *>())
776
- return NodeAdder () .visit (p, parent, *this );
783
+ return adder .visit (p, parent, *this );
777
784
if (auto *p = n.dyn_cast <Expr *>())
778
- return NodeAdder () .visit (p, parent, *this );
785
+ return adder .visit (p, parent, *this );
779
786
auto *p = n.get <Stmt *>();
780
- return NodeAdder () .visit (p, parent, *this );
787
+ return adder .visit (p, parent, *this );
781
788
}
782
789
783
790
void ScopeCreator::addChildrenForAllLocalizableAccessorsInSourceOrder (
@@ -827,6 +834,41 @@ void ScopeCreator::addChildrenForKnownAttributes(ValueDecl *decl,
827
834
}
828
835
}
829
836
837
+ NullablePtr<ASTScopeImpl>
838
+ ScopeCreator::addPatternBindingToScopeTree (PatternBindingDecl *patternBinding,
839
+ ASTScopeImpl *parentScope,
840
+ Optional<SourceLoc> endLoc) {
841
+ if (auto *var = patternBinding->getSingleVar ())
842
+ addChildrenForKnownAttributes (var, parentScope);
843
+
844
+ auto *insertionPoint = parentScope;
845
+ for (auto i : range (patternBinding->getNumPatternEntries ())) {
846
+ bool isLocalBinding = false ;
847
+ if (auto *varDecl = patternBinding->getAnchoringVarDecl (i)) {
848
+ isLocalBinding = varDecl->getDeclContext ()->isLocalContext ();
849
+ }
850
+
851
+ Optional<SourceLoc> endLocForBinding = None;
852
+ if (isLocalBinding) {
853
+ endLocForBinding = endLoc;
854
+ ASTScopeAssert (endLoc.hasValue () && endLoc->isValid (),
855
+ " PatternBindingDecl in local context outside of BraceStmt?" );
856
+ }
857
+
858
+ insertionPoint =
859
+ ifUniqueConstructExpandAndInsert<PatternEntryDeclScope>(
860
+ insertionPoint, patternBinding, i,
861
+ isLocalBinding, endLocForBinding)
862
+ .getPtrOr (insertionPoint);
863
+
864
+ ASTScopeAssert (isLocalBinding || insertionPoint == parentScope,
865
+ " Bindings at the top-level or members of types should "
866
+ " not change the insertion point" );
867
+ }
868
+
869
+ return insertionPoint;
870
+ }
871
+
830
872
#pragma mark creation helpers
831
873
832
874
void ASTScopeImpl::addChild (ASTScopeImpl *child, ASTContext &ctx) {
@@ -946,9 +988,10 @@ ASTSourceFileScope::expandAScopeThatCreatesANewInsertionPoint(
946
988
// Assume that decls are only added at the end, in source order
947
989
std::vector<ASTNode> newNodes (decls.begin (), decls.end ());
948
990
insertionPoint =
949
- scopeCreator.addSiblingsToScopeTree (insertionPoint, this ,
991
+ scopeCreator.addSiblingsToScopeTree (insertionPoint,
950
992
scopeCreator.sortBySourceRange (
951
- scopeCreator.cull (newNodes)));
993
+ scopeCreator.cull (newNodes)),
994
+ None);
952
995
// Too slow to perform all the time:
953
996
// ASTScopeAssert(scopeCreator->containsAllDeclContextsFromAST(),
954
997
// "ASTScope tree missed some DeclContexts or made some up");
@@ -1048,7 +1091,7 @@ GuardStmtScope::expandAScopeThatCreatesANewInsertionPoint(ScopeCreator &
1048
1091
auto *const lookupParentDiversionScope =
1049
1092
scopeCreator
1050
1093
.constructExpandAndInsertUncheckable <LookupParentDiversionScope>(
1051
- this , conditionLookupParent, stmt->getEndLoc ());
1094
+ this , conditionLookupParent, stmt->getEndLoc (), endLoc );
1052
1095
return {lookupParentDiversionScope,
1053
1096
" Succeeding code must be in scope of guard variables" };
1054
1097
}
@@ -1066,10 +1109,11 @@ BraceStmtScope::expandAScopeThatCreatesANewInsertionPoint(
1066
1109
// TODO: remove the sort after fixing parser to create brace statement
1067
1110
// elements in source order
1068
1111
auto *insertionPoint =
1069
- scopeCreator.addSiblingsToScopeTree (this , this ,
1112
+ scopeCreator.addSiblingsToScopeTree (this ,
1070
1113
scopeCreator.sortBySourceRange (
1071
1114
scopeCreator.cull (
1072
- stmt->getElements ())));
1115
+ stmt->getElements ())),
1116
+ stmt->getEndLoc ());
1073
1117
if (auto *s = scopeCreator.getASTContext ().Stats )
1074
1118
++s->getFrontendCounters ().NumBraceStmtASTScopeExpansions ;
1075
1119
return {
@@ -1083,7 +1127,7 @@ TopLevelCodeScope::expandAScopeThatCreatesANewInsertionPoint(ScopeCreator &
1083
1127
1084
1128
if (auto *body =
1085
1129
scopeCreator
1086
- .addToScopeTreeAndReturnInsertionPoint (decl->getBody (), this )
1130
+ .addToScopeTreeAndReturnInsertionPoint (decl->getBody (), this , None )
1087
1131
.getPtrOrNull ())
1088
1132
return {body, " So next top level code scope and put its decls in its body "
1089
1133
" under a guard statement scope (etc) from the last top level "
@@ -1414,7 +1458,7 @@ void GenericTypeOrExtensionScope::expandBody(ScopeCreator &) {}
1414
1458
void IterableTypeScope::expandBody (ScopeCreator &scopeCreator) {
1415
1459
auto nodes = asNodeVector (getIterableDeclContext ().get ()->getMembers ());
1416
1460
nodes = scopeCreator.sortBySourceRange (scopeCreator.cull (nodes));
1417
- scopeCreator.addSiblingsToScopeTree (this , this , nodes );
1461
+ scopeCreator.addSiblingsToScopeTree (this , nodes, None );
1418
1462
if (auto *s = scopeCreator.getASTContext ().Stats )
1419
1463
++s->getFrontendCounters ().NumIterableTypeBodyASTScopeExpansions ;
1420
1464
}
0 commit comments