@@ -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
- for (auto nd : sortBySourceRange ( cull ( nodesOrDeclsToAdd)) ) {
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,9 +426,18 @@ class ScopeCreator final {
419
426
void addChildrenForKnownAttributes (ValueDecl *decl,
420
427
ASTScopeImpl *parent);
421
428
422
- public:
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);
423
440
424
- private:
425
441
// / Remove VarDecls because we'll find them when we expand the
426
442
// / PatternBindingDecls. Remove EnunCases
427
443
// / because they overlap EnumElements and AST includes the elements in the
@@ -463,7 +479,6 @@ class ScopeCreator final {
463
479
return -1 == signum;
464
480
}
465
481
466
- public:
467
482
SWIFT_DEBUG_DUMP { print (llvm::errs ()); }
468
483
469
484
void print (raw_ostream &out) const {
@@ -545,7 +560,10 @@ class NodeAdder
545
560
: public ASTVisitor<NodeAdder, NullablePtr<ASTScopeImpl>,
546
561
NullablePtr<ASTScopeImpl>, NullablePtr<ASTScopeImpl>,
547
562
void , void , void , ASTScopeImpl *, ScopeCreator &> {
563
+ Optional<SourceLoc> endLoc;
564
+
548
565
public:
566
+ explicit NodeAdder (Optional<SourceLoc> endLoc) : endLoc(endLoc) {}
549
567
550
568
#pragma mark ASTNodes that do not create scopes
551
569
@@ -637,7 +655,9 @@ class NodeAdder
637
655
// the deferred nodes.
638
656
NullablePtr<ASTScopeImpl> visitGuardStmt (GuardStmt *e, ASTScopeImpl *p,
639
657
ScopeCreator &scopeCreator) {
640
- return scopeCreator.ifUniqueConstructExpandAndInsert <GuardStmtScope>(p, e);
658
+ ASTScopeAssert (endLoc.hasValue (), " GuardStmt outside of a BraceStmt?" );
659
+ return scopeCreator.ifUniqueConstructExpandAndInsert <GuardStmtScope>(
660
+ p, e, *endLoc);
641
661
}
642
662
NullablePtr<ASTScopeImpl> visitTopLevelCodeDecl (TopLevelCodeDecl *d,
643
663
ASTScopeImpl *p,
@@ -698,28 +718,8 @@ class NodeAdder
698
718
visitPatternBindingDecl (PatternBindingDecl *patternBinding,
699
719
ASTScopeImpl *parentScope,
700
720
ScopeCreator &scopeCreator) {
701
- if (auto *var = patternBinding->getSingleVar ())
702
- scopeCreator.addChildrenForKnownAttributes (var, parentScope);
703
-
704
- auto *insertionPoint = parentScope;
705
- for (auto i : range (patternBinding->getNumPatternEntries ())) {
706
- bool isLocalBinding = false ;
707
- if (auto *varDecl = patternBinding->getAnchoringVarDecl (i)) {
708
- isLocalBinding = varDecl->getDeclContext ()->isLocalContext ();
709
- }
710
-
711
- insertionPoint =
712
- scopeCreator
713
- .ifUniqueConstructExpandAndInsert <PatternEntryDeclScope>(
714
- insertionPoint, patternBinding, i, isLocalBinding)
715
- .getPtrOr (insertionPoint);
716
-
717
- ASTScopeAssert (isLocalBinding || insertionPoint == parentScope,
718
- " Bindings at the top-level or members of types should "
719
- " not change the insertion point" );
720
- }
721
-
722
- return insertionPoint;
721
+ return scopeCreator.addPatternBindingToScopeTree (
722
+ patternBinding, parentScope, endLoc);
723
723
}
724
724
725
725
NullablePtr<ASTScopeImpl> visitEnumElementDecl (EnumElementDecl *eed,
@@ -773,15 +773,18 @@ class NodeAdder
773
773
// NodeAdder
774
774
NullablePtr<ASTScopeImpl>
775
775
ScopeCreator::addToScopeTreeAndReturnInsertionPoint (ASTNode n,
776
- ASTScopeImpl *parent) {
776
+ ASTScopeImpl *parent,
777
+ Optional<SourceLoc> endLoc) {
777
778
if (!isWorthTryingToCreateScopeFor (n))
778
779
return parent;
780
+
781
+ NodeAdder adder (endLoc);
779
782
if (auto *p = n.dyn_cast <Decl *>())
780
- return NodeAdder () .visit (p, parent, *this );
783
+ return adder .visit (p, parent, *this );
781
784
if (auto *p = n.dyn_cast <Expr *>())
782
- return NodeAdder () .visit (p, parent, *this );
785
+ return adder .visit (p, parent, *this );
783
786
auto *p = n.get <Stmt *>();
784
- return NodeAdder () .visit (p, parent, *this );
787
+ return adder .visit (p, parent, *this );
785
788
}
786
789
787
790
void ScopeCreator::addChildrenForAllLocalizableAccessorsInSourceOrder (
@@ -831,6 +834,41 @@ void ScopeCreator::addChildrenForKnownAttributes(ValueDecl *decl,
831
834
}
832
835
}
833
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
+
834
872
#pragma mark creation helpers
835
873
836
874
void ASTScopeImpl::addChild (ASTScopeImpl *child, ASTContext &ctx) {
@@ -950,7 +988,10 @@ ASTSourceFileScope::expandAScopeThatCreatesANewInsertionPoint(
950
988
// Assume that decls are only added at the end, in source order
951
989
std::vector<ASTNode> newNodes (decls.begin (), decls.end ());
952
990
insertionPoint =
953
- scopeCreator.addSiblingsToScopeTree (insertionPoint, this , newNodes);
991
+ scopeCreator.addSiblingsToScopeTree (insertionPoint,
992
+ scopeCreator.sortBySourceRange (
993
+ scopeCreator.cull (newNodes)),
994
+ None);
954
995
// Too slow to perform all the time:
955
996
// ASTScopeAssert(scopeCreator->containsAllDeclContextsFromAST(),
956
997
// "ASTScope tree missed some DeclContexts or made some up");
@@ -991,7 +1032,7 @@ PatternEntryDeclScope::expandAScopeThatCreatesANewInsertionPoint(
991
1032
" Original inits are always after the '='" );
992
1033
scopeCreator
993
1034
.constructExpandAndInsertUncheckable <PatternEntryInitializerScope>(
994
- this , decl, patternEntryIndex, isLocalBinding );
1035
+ this , decl, patternEntryIndex);
995
1036
}
996
1037
997
1038
// Add accessors for the variables in this pattern.
@@ -1050,7 +1091,7 @@ GuardStmtScope::expandAScopeThatCreatesANewInsertionPoint(ScopeCreator &
1050
1091
auto *const lookupParentDiversionScope =
1051
1092
scopeCreator
1052
1093
.constructExpandAndInsertUncheckable <LookupParentDiversionScope>(
1053
- this , conditionLookupParent, stmt->getEndLoc ());
1094
+ this , conditionLookupParent, stmt->getEndLoc (), endLoc );
1054
1095
return {lookupParentDiversionScope,
1055
1096
" Succeeding code must be in scope of guard variables" };
1056
1097
}
@@ -1068,7 +1109,11 @@ BraceStmtScope::expandAScopeThatCreatesANewInsertionPoint(
1068
1109
// TODO: remove the sort after fixing parser to create brace statement
1069
1110
// elements in source order
1070
1111
auto *insertionPoint =
1071
- scopeCreator.addSiblingsToScopeTree (this , this , stmt->getElements ());
1112
+ scopeCreator.addSiblingsToScopeTree (this ,
1113
+ scopeCreator.sortBySourceRange (
1114
+ scopeCreator.cull (
1115
+ stmt->getElements ())),
1116
+ stmt->getEndLoc ());
1072
1117
if (auto *s = scopeCreator.getASTContext ().Stats )
1073
1118
++s->getFrontendCounters ().NumBraceStmtASTScopeExpansions ;
1074
1119
return {
@@ -1082,7 +1127,7 @@ TopLevelCodeScope::expandAScopeThatCreatesANewInsertionPoint(ScopeCreator &
1082
1127
1083
1128
if (auto *body =
1084
1129
scopeCreator
1085
- .addToScopeTreeAndReturnInsertionPoint (decl->getBody (), this )
1130
+ .addToScopeTreeAndReturnInsertionPoint (decl->getBody (), this , None )
1086
1131
.getPtrOrNull ())
1087
1132
return {body, " So next top level code scope and put its decls in its body "
1088
1133
" under a guard statement scope (etc) from the last top level "
@@ -1377,10 +1422,8 @@ ASTScopeImpl *LabeledConditionalStmtScope::createNestedConditionalClauseScopes(
1377
1422
}
1378
1423
1379
1424
AbstractPatternEntryScope::AbstractPatternEntryScope (
1380
- PatternBindingDecl *declBeingScoped, unsigned entryIndex,
1381
- bool isLocalBinding)
1382
- : decl(declBeingScoped), patternEntryIndex(entryIndex),
1383
- isLocalBinding(isLocalBinding) {
1425
+ PatternBindingDecl *declBeingScoped, unsigned entryIndex)
1426
+ : decl(declBeingScoped), patternEntryIndex(entryIndex) {
1384
1427
ASTScopeAssert (entryIndex < declBeingScoped->getPatternList ().size (),
1385
1428
" out of bounds" );
1386
1429
}
@@ -1414,7 +1457,8 @@ void GenericTypeOrExtensionScope::expandBody(ScopeCreator &) {}
1414
1457
1415
1458
void IterableTypeScope::expandBody (ScopeCreator &scopeCreator) {
1416
1459
auto nodes = asNodeVector (getIterableDeclContext ().get ()->getMembers ());
1417
- scopeCreator.addSiblingsToScopeTree (this , this , nodes);
1460
+ nodes = scopeCreator.sortBySourceRange (scopeCreator.cull (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