Skip to content

Commit b89b58c

Browse files
author
David Ungar
authored
Merge pull request #28039 from davidungar/factor-ASTScope-ordering
[NameLookup ASTScope] Factor ASTScope ordering
2 parents 8a45e7d + f162a84 commit b89b58c

File tree

4 files changed

+49
-22
lines changed

4 files changed

+49
-22
lines changed

include/swift/AST/ASTScope.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,10 @@ class ASTScopeImpl {
226226
#pragma mark - source range queries
227227

228228
public:
229+
/// Return signum of ranges. Centralize the invariant that ASTScopes use ends.
230+
static int compare(SourceRange, SourceRange, const SourceManager &,
231+
bool ensureDisjoint);
232+
229233
SourceRange getSourceRangeOfScope(bool omitAssertions = false) const;
230234

231235
/// InterpolatedStringLiteralExprs and EditorPlaceHolders respond to

lib/AST/ASTScopeCreation.cpp

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ static bool rangeableIsIgnored(const Stmt *d) {
5252
return false; // ??
5353
}
5454
static bool rangeableIsIgnored(const ASTNode n) {
55-
return n.is<Decl *>() && n.get<Decl *>()->isImplicit();
55+
return (n.is<Decl *>() && rangeableIsIgnored(n.get<Decl *>())) ||
56+
(n.is<Stmt *>() && rangeableIsIgnored(n.get<Stmt *>())) ||
57+
(n.is<Expr *>() && rangeableIsIgnored(n.get<Expr *>()));
5658
}
5759

5860
template <typename Rangeable>
@@ -600,25 +602,12 @@ class ScopeCreator final {
600602

601603
template <typename Rangeable>
602604
bool isNotAfter(Rangeable n1, Rangeable n2) const {
603-
auto cmpLoc = [&](const SourceLoc l1, const SourceLoc l2) {
604-
return l1 == l2 ? 0 : ctx.SourceMgr.isBeforeInBuffer(l1, l2) ? -1 : 1;
605-
};
606605
const auto r1 = getRangeableSourceRange(n1);
607606
const auto r2 = getRangeableSourceRange(n2);
608-
const int startOrder = cmpLoc(r1.Start, r2.Start);
609-
const int endOrder = cmpLoc(r1.End, r2.End);
610-
611-
#ifndef NDEBUG
612-
if (startOrder * endOrder == -1) {
613-
llvm::errs() << "*** Start order contradicts end order between: ***\n";
614-
dumpRangeable(n1, llvm::errs());
615-
llvm::errs() << "\n*** and: ***\n";
616-
dumpRangeable(n2, llvm::errs());
617-
}
618-
#endif
619-
ASTScopeAssert(startOrder * endOrder != -1,
620-
"Start order contradicts end order");
621-
return startOrder + endOrder < 1;
607+
608+
const int signum = ASTScopeImpl::compare(r1, r2, ctx.SourceMgr,
609+
/*ensureDisjoint=*/true);
610+
return -1 == signum;
622611
}
623612

624613
static bool isVarDeclInPatternBindingDecl(ASTNode n1, ASTNode n2) {

lib/AST/ASTScopeLookup.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,16 @@ ASTScopeImpl::findChildContaining(SourceLoc loc,
152152

153153
bool operator()(const ASTScopeImpl *scope, SourceLoc loc) {
154154
ASTScopeAssert(scope->checkSourceRangeOfThisASTNode(), "Bad range.");
155-
return sourceMgr.isBeforeInBuffer(scope->getSourceRangeOfScope().End,
156-
loc);
155+
return -1 == ASTScopeImpl::compare(scope->getSourceRangeOfScope(), loc,
156+
sourceMgr,
157+
/*ensureDisjoint=*/false);
157158
}
158159
bool operator()(SourceLoc loc, const ASTScopeImpl *scope) {
159160
ASTScopeAssert(scope->checkSourceRangeOfThisASTNode(), "Bad range.");
160-
return !sourceMgr.isBeforeInBuffer(scope->getSourceRangeOfScope().End,
161-
loc);
161+
// Alternatively, we could check that loc < start-of-scope
162+
return 0 >= ASTScopeImpl::compare(loc, scope->getSourceRangeOfScope(),
163+
sourceMgr,
164+
/*ensureDisjoint=*/false);
162165
}
163166
};
164167
auto *const *child = std::lower_bound(

lib/AST/ASTScopeSourceRange.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,3 +764,34 @@ SourceLoc ast_scope::extractNearestSourceLoc(
764764
const ASTScopeImpl *scope = std::get<0>(scopeAndCreator);
765765
return scope->getSourceRangeOfThisASTNode().Start;
766766
}
767+
768+
int ASTScopeImpl::compare(const SourceRange lhs, const SourceRange rhs,
769+
const SourceManager &SM, const bool ensureDisjoint) {
770+
ASTScopeAssert(!SM.isBeforeInBuffer(lhs.End, lhs.Start),
771+
"Range is backwards.");
772+
ASTScopeAssert(!SM.isBeforeInBuffer(rhs.End, rhs.Start),
773+
"Range is backwards.");
774+
775+
auto cmpLoc = [&](const SourceLoc lhs, const SourceLoc rhs) {
776+
return lhs == rhs ? 0 : SM.isBeforeInBuffer(lhs, rhs) ? -1 : 1;
777+
};
778+
// Establish that we use end locations throughout ASTScopes here
779+
const int endOrder = cmpLoc(lhs.End, rhs.End);
780+
781+
#ifndef NDEBUG
782+
if (ensureDisjoint) {
783+
const int startOrder = cmpLoc(lhs.Start, rhs.Start);
784+
785+
if (startOrder * endOrder == -1) {
786+
llvm::errs() << "*** Start order contradicts end order between: ***\n";
787+
lhs.print(llvm::errs(), SM, false);
788+
llvm::errs() << "\n*** and: ***\n";
789+
rhs.print(llvm::errs(), SM, false);
790+
}
791+
ASTScopeAssert(startOrder * endOrder != -1,
792+
"Start order contradicts end order");
793+
}
794+
#endif
795+
796+
return endOrder;
797+
}

0 commit comments

Comments
 (0)