Skip to content

Commit ab55c19

Browse files
committed
[IDE] Propagate the Stmt visit failure while walking TopLevelCodeDecls
`visitTopLevelCodeDecl` ignored the `Stmt` visit returning a nullptr. This caused the `walkToDeclPost` to run for the `TopLevelCodeDecl` and thus an imbalance in the `RangeResolver` pre and posts (since none of the children would have their `walkTo*Post` called). This was originally incorrectly fixed while assuming that the `walkTo*Post` are called regardless of whether the children were visited or not. Those changes have been reverted - fixing an imbalance in `ExtDecls` in `SemaAnnotator`. Added a test case for the `ExtDecls` imbalance which can occur while an extension is being added. Resolves rdar://74820040
1 parent 0f7f060 commit ab55c19

File tree

4 files changed

+25
-18
lines changed

4 files changed

+25
-18
lines changed

lib/AST/ASTWalker.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,11 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
217217
}
218218

219219
bool visitTopLevelCodeDecl(TopLevelCodeDecl *TLCD) {
220-
if (BraceStmt *S = cast_or_null<BraceStmt>(doIt(TLCD->getBody())))
220+
if (BraceStmt *S = cast_or_null<BraceStmt>(doIt(TLCD->getBody()))) {
221221
TLCD->setBody(S);
222-
return false;
222+
return false;
223+
}
224+
return true;
223225
}
224226

225227
bool visitIfConfigDecl(IfConfigDecl *ICD) {

lib/IDE/IDERequests.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -995,24 +995,16 @@ bool RangeResolver::walkToDeclPre(Decl *D, CharSourceRange Range) {
995995
}
996996

997997
bool RangeResolver::walkToExprPost(Expr *E) {
998-
if (!Impl->shouldEnter(E))
999-
return true;
1000998
Impl->leave(E);
1001999
return !Impl->hasResult();
10021000
}
10031001

10041002
bool RangeResolver::walkToStmtPost(Stmt *S) {
1005-
if (!Impl->shouldEnter(S))
1006-
return true;
10071003
Impl->leave(S);
10081004
return !Impl->hasResult();
10091005
};
10101006

10111007
bool RangeResolver::walkToDeclPost(Decl *D) {
1012-
if (D->isImplicit())
1013-
return true;
1014-
if (!Impl->shouldEnter(D))
1015-
return true;
10161008
Impl->leave(D);
10171009
return !Impl->hasResult();
10181010
}

lib/IDE/SourceEntityWalker.cpp

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,9 @@ bool SemaAnnotator::walkToDeclPre(Decl *D) {
181181
CharSourceRange Range = (Loc.isValid()) ? CharSourceRange(Loc, NameLen)
182182
: CharSourceRange();
183183
bool ShouldVisitChildren = SEWalker.walkToDeclPre(D, Range);
184-
if (IsExtension) {
184+
// walkToDeclPost is only called when visiting children, so make sure to only
185+
// push the extension decl in that case (otherwise it won't be popped)
186+
if (IsExtension && ShouldVisitChildren) {
185187
ExtDecls.push_back(static_cast<ExtensionDecl*>(D));
186188
}
187189
return ShouldVisitChildren;
@@ -194,13 +196,6 @@ bool SemaAnnotator::walkToDeclPost(Decl *D) {
194196
if (shouldIgnore(D))
195197
return true;
196198

197-
// Note: This should match any early (non-cancelling) returns in
198-
// `walkToDeclPre` above
199-
if (auto *ICD = dyn_cast<IfConfigDecl>(D)) {
200-
if (SEWalker.shouldWalkInactiveConfigRegion())
201-
return true;
202-
}
203-
204199
if (isa<ExtensionDecl>(D)) {
205200
assert(ExtDecls.back() == D);
206201
ExtDecls.pop_back();
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
struct Foo {}
2+
struct Bar {}
3+
4+
extension Foo {
5+
6+
extension Bar {
7+
}
8+
9+
func someFunc() {}
10+
11+
// Closing brace for extension Foo intentionally left off, user is in the
12+
// process of adding the extension
13+
14+
// This check is mostly to make sure we don't crash with an assertion -
15+
// extensions are pushed and popped in an AST walk pre/post and they need to
16+
// match up.
17+
// RUN: %sourcekitd-test -req=cursor -pos=9:6 %s -- %s | %FileCheck %s
18+
// CHECK: source.lang.swift.decl.function.method.instance

0 commit comments

Comments
 (0)