Lots of cleanups, renamings, etc.

This commit is contained in:
David Ungar
2019-08-07 19:59:08 -07:00
parent 3fe9333052
commit 7992e1c6c4
12 changed files with 604 additions and 959 deletions

View File

@@ -27,6 +27,7 @@
#include "swift/AST/Stmt.h"
#include "swift/AST/TypeRepr.h"
#include "swift/Basic/STLExtras.h"
#include "swift/Parse/Lexer.h"
#include "llvm/Support/Compiler.h"
#include <algorithm>
@@ -34,6 +35,8 @@ using namespace swift;
using namespace ast_scope;
static SourceLoc getStartOfFirstParam(ClosureExpr *closure);
static SourceLoc getLocEncompassingPotentialLookups(const SourceManager &,
SourceLoc endLoc);
SourceRange ASTScopeImpl::widenSourceRangeForIgnoredASTNodes(
const SourceRange range) const {
@@ -53,9 +56,9 @@ ASTScopeImpl::widenSourceRangeForChildren(const SourceRange range,
return range;
}
const auto childStart =
getChildren().front()->getSourceRange(omitAssertions).Start;
getChildren().front()->getSourceRangeOfScope(omitAssertions).Start;
const auto childEnd =
getChildren().back()->getSourceRange(omitAssertions).End;
getChildren().back()->getSourceRangeOfScope(omitAssertions).End;
auto childRange = SourceRange(childStart, childEnd);
assert(omitAssertions || childRange.isValid());
@@ -66,10 +69,21 @@ ASTScopeImpl::widenSourceRangeForChildren(const SourceRange range,
return r;
}
bool ASTScopeImpl::checkSourceRangeAfterExpansion() const {
assert((getSourceRangeOfThisASTNode().isValid() || !getChildren().empty()) &&
"need to be able to find source range");
assert(verifyThatChildrenAreContainedWithin(getSourceRangeOfScope()) &&
"Search will fail");
assert(checkLazySourceRange() &&
"Lazy scopes must have compatible ranges before and after expansion");
return true;
}
#pragma mark validation
bool ASTScopeImpl::hasValidSourceRange() const {
const auto sourceRange = getSourceRange();
const auto sourceRange = getSourceRangeOfScope();
return sourceRange.Start.isValid() && sourceRange.End.isValid() &&
!getSourceManager().isBeforeInBuffer(sourceRange.End,
sourceRange.Start);
@@ -82,8 +96,8 @@ bool ASTScopeImpl::hasValidSourceRangeOfIgnoredASTNodes() const {
bool ASTScopeImpl::precedesInSource(const ASTScopeImpl *next) const {
if (!hasValidSourceRange() || !next->hasValidSourceRange())
return false;
return !getSourceManager().isBeforeInBuffer(next->getSourceRange().Start,
getSourceRange().End);
return !getSourceManager().isBeforeInBuffer(
next->getSourceRangeOfScope().Start, getSourceRangeOfScope().End);
}
bool ASTScopeImpl::verifyThatChildrenAreContainedWithin(
@@ -92,8 +106,8 @@ bool ASTScopeImpl::verifyThatChildrenAreContainedWithin(
if (getChildren().empty())
return true;
const SourceRange rangeOfChildren =
SourceRange(getChildren().front()->getSourceRange().Start,
getChildren().back()->getSourceRange().End);
SourceRange(getChildren().front()->getSourceRangeOfScope().Start,
getChildren().back()->getSourceRangeOfScope().End);
if (getSourceManager().rangeContains(range, rangeOfChildren))
return true;
auto &out = verificationError() << "children not contained in its parent\n";
@@ -152,51 +166,51 @@ NullablePtr<ASTScopeImpl> ASTScopeImpl::getPriorSibling() const {
return siblingsAndMe[myIndex - 1];
}
#pragma mark getChildlessSourceRange
#pragma mark getSourceRangeOfThisASTNode
SourceRange SpecializeAttributeScope::getChildlessSourceRange(
SourceRange SpecializeAttributeScope::getSourceRangeOfThisASTNode(
const bool omitAssertions) const {
return specializeAttr->getRange();
}
SourceRange AbstractFunctionBodyScope::getChildlessSourceRange(
SourceRange AbstractFunctionBodyScope::getSourceRangeOfThisASTNode(
const bool omitAssertions) const {
return decl->getBodySourceRange();
}
SourceRange
TopLevelCodeScope::getChildlessSourceRange(const bool omitAssertions) const {
SourceRange TopLevelCodeScope::getSourceRangeOfThisASTNode(
const bool omitAssertions) const {
return decl->getSourceRange();
}
SourceRange SubscriptDeclScope::getSourceRangeOfThisASTNode(
const bool omitAssertions) const {
return decl->getSourceRange();
}
SourceRange
SubscriptDeclScope::getChildlessSourceRange(const bool omitAssertions) const {
EnumElementScope::getSourceRangeOfThisASTNode(const bool omitAssertions) const {
return decl->getSourceRange();
}
SourceRange
EnumElementScope::getChildlessSourceRange(const bool omitAssertions) const {
return decl->getSourceRange();
}
SourceRange
WholeClosureScope::getChildlessSourceRange(const bool omitAssertions) const {
SourceRange WholeClosureScope::getSourceRangeOfThisASTNode(
const bool omitAssertions) const {
return closureExpr->getSourceRange();
}
SourceRange
AbstractStmtScope::getChildlessSourceRange(const bool omitAssertions) const {
SourceRange AbstractStmtScope::getSourceRangeOfThisASTNode(
const bool omitAssertions) const {
return getStmt()->getSourceRange();
}
SourceRange DefaultArgumentInitializerScope::getChildlessSourceRange(
SourceRange DefaultArgumentInitializerScope::getSourceRangeOfThisASTNode(
const bool omitAssertions) const {
if (auto *dv = decl->getDefaultValue())
return dv->getSourceRange();
return SourceRange();
}
SourceRange PatternEntryDeclScope::getChildlessSourceRange(
SourceRange PatternEntryDeclScope::getSourceRangeOfThisASTNode(
const bool omitAssertions) const {
// TODO: Once rdar://53627317 is accomplished, the following may be able to be
// simplified.
@@ -211,7 +225,7 @@ SourceRange PatternEntryDeclScope::getChildlessSourceRange(
return getPatternEntry().getSourceRange();
}
SourceRange PatternEntryInitializerScope::getChildlessSourceRange(
SourceRange PatternEntryInitializerScope::getSourceRangeOfThisASTNode(
const bool omitAssertions) const {
// See rdar://53921703
// Note: grep for "When the initializer is removed we don't actually clear the
@@ -220,13 +234,13 @@ SourceRange PatternEntryInitializerScope::getChildlessSourceRange(
}
SourceRange
VarDeclScope::getChildlessSourceRange(const bool omitAssertions) const {
VarDeclScope::getSourceRangeOfThisASTNode(const bool omitAssertions) const {
const auto br = decl->getBracesRange();
return br.isValid() ? br : decl->getSourceRange();
}
SourceRange
GenericParamScope::getChildlessSourceRange(const bool omitAssertions) const {
SourceRange GenericParamScope::getSourceRangeOfThisASTNode(
const bool omitAssertions) const {
auto nOrE = holder;
// A protocol's generic parameter list is not written in source, and
// is visible from the start of the body.
@@ -238,8 +252,8 @@ GenericParamScope::getChildlessSourceRange(const bool omitAssertions) const {
return SourceRange(startLoc, holder->getEndLoc());
}
SourceRange
ASTSourceFileScope::getChildlessSourceRange(const bool omitAssertions) const {
SourceRange ASTSourceFileScope::getSourceRangeOfThisASTNode(
const bool omitAssertions) const {
if (auto bufferID = SF->getBufferID()) {
auto charRange = getSourceManager().getRangeForBuffer(*bufferID);
return SourceRange(charRange.getStart(), charRange.getEnd());
@@ -253,7 +267,7 @@ ASTSourceFileScope::getChildlessSourceRange(const bool omitAssertions) const {
SF->Decls.back()->getEndLoc());
}
SourceRange GenericTypeOrExtensionScope::getChildlessSourceRange(
SourceRange GenericTypeOrExtensionScope::getSourceRangeOfThisASTNode(
const bool omitAssertions) const {
return portion->getChildlessSourceRangeOf(this, omitAssertions);
}
@@ -286,7 +300,7 @@ SourceRange IterableTypeBodyPortion::getChildlessSourceRangeOf(
llvm_unreachable("No body!");
}
SourceRange AbstractFunctionDeclScope::getChildlessSourceRange(
SourceRange AbstractFunctionDeclScope::getSourceRangeOfThisASTNode(
const bool omitAssertions) const {
// For a get/put accessor all of the parameters are implicit, so start
// them at the start location of the accessor.
@@ -298,13 +312,14 @@ SourceRange AbstractFunctionDeclScope::getChildlessSourceRange(
return decl->getBodySourceRange();
}
SourceRange
ParameterListScope::getChildlessSourceRange(const bool omitAssertions) const {
const auto rangeForGoodInput = getSourceRangeOfEnclosedParams(omitAssertions);
SourceRange ParameterListScope::getSourceRangeOfThisASTNode(
const bool omitAssertions) const {
const auto rangeForGoodInput =
getSourceRangeOfEnclosedParamsOfASTNode(omitAssertions);
auto r = SourceRange(rangeForGoodInput.Start,
fixupEndForBadInput(rangeForGoodInput));
assert(getSourceManager().rangeContains(
getParent().get()->getChildlessSourceRange(true), r) &&
getParent().get()->getSourceRangeOfThisASTNode(true), r) &&
"Parameters not within function?!");
return r;
}
@@ -316,8 +331,8 @@ SourceLoc ParameterListScope::fixupEndForBadInput(
return getSourceManager().isBeforeInBuffer(s, e) ? e : s;
}
SourceRange
ForEachPatternScope::getChildlessSourceRange(const bool omitAssertions) const {
SourceRange ForEachPatternScope::getSourceRangeOfThisASTNode(
const bool omitAssertions) const {
// The scope of the pattern extends from the 'where' expression (if present)
// until the end of the body.
if (stmt->getWhere())
@@ -329,7 +344,7 @@ ForEachPatternScope::getChildlessSourceRange(const bool omitAssertions) const {
}
SourceRange
CatchStmtScope::getChildlessSourceRange(const bool omitAssertions) const {
CatchStmtScope::getSourceRangeOfThisASTNode(const bool omitAssertions) const {
// The scope of the pattern extends from the 'where' (if present)
// to the end of the body.
if (stmt->getGuardExpr())
@@ -339,7 +354,7 @@ CatchStmtScope::getChildlessSourceRange(const bool omitAssertions) const {
return stmt->getBody()->getSourceRange();
}
SourceRange
CaseStmtScope::getChildlessSourceRange(const bool omitAssertions) const {
CaseStmtScope::getSourceRangeOfThisASTNode(const bool omitAssertions) const {
// The scope of the case statement begins at the first guard expression,
// if there is one, and extends to the end of the body.
// FIXME: Figure out what to do about multiple pattern bindings. We might
@@ -356,7 +371,7 @@ CaseStmtScope::getChildlessSourceRange(const bool omitAssertions) const {
}
SourceRange
BraceStmtScope::getChildlessSourceRange(const bool omitAssertions) const {
BraceStmtScope::getSourceRangeOfThisASTNode(const bool omitAssertions) const {
// The brace statements that represent closures start their scope at the
// 'in' keyword, when present.
if (auto closure = parentClosureIfAny()) {
@@ -366,7 +381,7 @@ BraceStmtScope::getChildlessSourceRange(const bool omitAssertions) const {
return stmt->getSourceRange();
}
SourceRange ConditionalClauseScope::getChildlessSourceRange(
SourceRange ConditionalClauseScope::getSourceRangeOfThisASTNode(
const bool omitAssertions) const {
// From the start of this particular condition to the start of the
// then/body part.
@@ -376,7 +391,7 @@ SourceRange ConditionalClauseScope::getChildlessSourceRange(
: SourceRange(endLoc);
}
SourceRange ConditionalClausePatternUseScope::getChildlessSourceRange(
SourceRange ConditionalClausePatternUseScope::getSourceRangeOfThisASTNode(
const bool omitAssertions) const {
// For a guard continuation, the scope extends from the end of the 'else'
// to the end of the continuation.
@@ -384,12 +399,12 @@ SourceRange ConditionalClausePatternUseScope::getChildlessSourceRange(
}
SourceRange
CaptureListScope::getChildlessSourceRange(const bool omitAssertions) const {
CaptureListScope::getSourceRangeOfThisASTNode(const bool omitAssertions) const {
auto *const closure = expr->getClosureBody();
return SourceRange(expr->getStartLoc(), getStartOfFirstParam(closure));
}
SourceRange ClosureParametersScope::getChildlessSourceRange(
SourceRange ClosureParametersScope::getSourceRangeOfThisASTNode(
const bool omitAssertions) const {
if (!omitAssertions)
assert(closureExpr->getInLoc().isValid() &&
@@ -399,28 +414,29 @@ SourceRange ClosureParametersScope::getChildlessSourceRange(
}
SourceRange
ClosureBodyScope::getChildlessSourceRange(const bool omitAssertions) const {
ClosureBodyScope::getSourceRangeOfThisASTNode(const bool omitAssertions) const {
if (closureExpr->getInLoc().isValid())
return SourceRange(closureExpr->getInLoc(), closureExpr->getEndLoc());
return closureExpr->getSourceRange();
}
SourceRange AttachedPropertyWrapperScope::getChildlessSourceRange(
SourceRange AttachedPropertyWrapperScope::getSourceRangeOfThisASTNode(
const bool omitAssertions) const {
return sourceRangeWhenCreated;
}
SourceRange LookupParentDiversionScope::getChildlessSourceRange(
SourceRange LookupParentDiversionScope::getSourceRangeOfThisASTNode(
const bool omitAssertions) const {
return SourceRange(startLoc);
}
#pragma mark source range caching
SourceRange ASTScopeImpl::getSourceRange(const bool omitAssertions) const {
SourceRange
ASTScopeImpl::getSourceRangeOfScope(const bool omitAssertions) const {
if (!isSourceRangeCached(omitAssertions))
cacheSourceRangeOfMeAndDescendants(omitAssertions);
computeAndCacheSourceRangeOfScope(omitAssertions);
return *cachedSourceRange;
}
@@ -441,33 +457,57 @@ bool ASTScopeImpl::ensureNoAncestorsSourceRangeIsCached() const {
return true;
}
void ASTScopeImpl::cacheSourceRangeOfMeAndDescendants(
void ASTScopeImpl::computeAndCacheSourceRangeOfScope(
const bool omitAssertions) const {
// In order to satisfy the invariant that, if my range is uncached,
// my parent's range is uncached, (which is needed to optimize invalidation
// by obviating the need to uncache all the way to the root every time),
// when caching a range, must ensure all children's ranges are cached.
for (auto *c : getChildren())
c->cacheSourceRangeOfMeAndDescendants(omitAssertions);
c->computeAndCacheSourceRangeOfScope(omitAssertions);
cachedSourceRange = getUncachedSourceRange(omitAssertions);
cachedSourceRange = computeSourceRangeOfScope(omitAssertions);
}
bool ASTScopeImpl::checkLazySourceRange() const {
if (!getASTContext().LangOpts.LazyASTScopes)
return true;
const auto unexpandedRange = sourceRangeForDeferredExpansion();
const auto expandedRange = computeSourceRangeOfScopeWithChildASTNodes();
if (unexpandedRange.isInvalid() || expandedRange.isInvalid())
return true;
if (unexpandedRange == expandedRange)
return true;
auto b = getChildren().back()->computeSourceRangeOfScope();
llvm::errs() << "*** Lazy range problem. Parent: ***\n";
unexpandedRange.print(llvm::errs(), getSourceManager(), false);
llvm::errs() << "\n*** vs last child: ***\n";
b.print(llvm::errs(), getSourceManager(), false);
llvm::errs() << "\n";
print(llvm::errs(), 0, false);
llvm::errs() << "\n";
return false;
}
SourceRange
ASTScopeImpl::getUncachedSourceRange(const bool omitAssertions) const {
const SourceRange rangeForLazyCheck = getASTContext().LangOpts.LazyASTScopes
? sourceRangeForDeferredExpansion()
: SourceRange();
(void)rangeForLazyCheck;
const auto childlessRange = getChildlessSourceRange(omitAssertions);
ASTScopeImpl::computeSourceRangeOfScope(const bool omitAssertions) const {
// If we don't need to consider children, it's cheaper
const auto deferredRange = sourceRangeForDeferredExpansion();
return deferredRange.isValid()
? deferredRange
: computeSourceRangeOfScopeWithChildASTNodes(omitAssertions);
}
SourceRange ASTScopeImpl::computeSourceRangeOfScopeWithChildASTNodes(
const bool omitAssertions) const {
const auto rangeOfJustThisASTNode =
getSourceRangeOfThisASTNode(omitAssertions);
const auto rangeIncludingIgnoredNodes =
widenSourceRangeForIgnoredASTNodes(childlessRange);
assert(rangeForLazyCheck.isInvalid() ||
rangeForLazyCheck == rangeIncludingIgnoredNodes);
auto uncachedSourceRange =
widenSourceRangeForIgnoredASTNodes(rangeOfJustThisASTNode);
const auto uncachedSourceRange =
widenSourceRangeForChildren(rangeIncludingIgnoredNodes, omitAssertions);
assert(rangeForLazyCheck.isInvalid() ||
rangeForLazyCheck == uncachedSourceRange);
return uncachedSourceRange;
}
@@ -480,58 +520,74 @@ void ASTScopeImpl::clearCachedSourceRangesOfMeAndAncestors() {
p.get()->clearCachedSourceRangesOfMeAndAncestors();
}
#pragma mark ignored nodes and compensating for InterpolatedStringLiteralExprs and EditorPlaceHolders
#pragma mark compensating for InterpolatedStringLiteralExprs and EditorPlaceHolders
namespace {
class EffectiveEndFinder : public ASTWalker {
SourceLoc end;
const SourceManager &SM;
public:
EffectiveEndFinder(const SourceManager &SM) : SM(SM) {}
std::pair<bool, Expr *> walkToExprPre(Expr *E) {
if (!E)
return {true, E};
if (auto *isl = dyn_cast<InterpolatedStringLiteralExpr>(E)) {
if (end.isInvalid() ||
SM.isBeforeInBuffer(end, isl->getTrailingQuoteLoc()))
end = isl->getTrailingQuoteLoc();
} else if (auto *epl = dyn_cast<EditorPlaceholderExpr>(E)) {
if (end.isInvalid() ||
SM.isBeforeInBuffer(end, epl->getTrailingAngleBracketLoc()))
end = epl->getTrailingAngleBracketLoc();
}
return ASTWalker::walkToExprPre(E);
// If right brace is missing, the source range of the body will end
// at the last token, which may be a one of the special cases below.
static SourceLoc getLocEncompassingPotentialLookups(const SourceManager &SM,
const SourceLoc endLoc) {
const auto tok = Lexer::getTokenAtLocation(SM, endLoc);
switch (tok.getKind()) {
default:
return endLoc;
case tok::string_literal:
break;
case tok::identifier:
// subtract one to get a closed-range endpoint from a half-open
if (!Identifier::isEditorPlaceholder(tok.getText()))
return endLoc;
break;
}
SourceLoc getTrailingQuoteLoc() const { return end; }
};
} // namespace
return tok.getRange().getEnd().getAdvancedLoc(-1);
}
SourceRange ASTScopeImpl::sourceRangeForDeferredExpansion() const {
return SourceRange();
}
SourceRange IterableTypeScope::sourceRangeForDeferredExpansion() const {
return portion->sourceRangeForDeferredExpansion(this);
}
SourceRange
Portion::sourceRangeForDeferredExpansion(const IterableTypeScope *) const {
return SourceRange();
}
// FIXME: Alter how EditorPlaceHolder and InterpolgatedStringLiteralExpr are
// parsed so getSourceRange is enough.
SourceRange ASTScopeImpl::getEffectiveSourceRange(const ASTNode n) const {
if (const auto *d = n.dyn_cast<Decl *>())
return d->getSourceRange();
if (const auto *s = n.dyn_cast<Stmt *>())
return s->getSourceRange();
auto *e = n.dyn_cast<Expr *>();
assert(e);
EffectiveEndFinder finder(getSourceManager());
e->walk(finder);
return SourceRange(e->getLoc(), finder.getTrailingQuoteLoc().isValid()
? finder.getTrailingQuoteLoc()
: e->getEndLoc());
return getLocEncompassingPotentialLookups(getSourceManager(), e->getEndLoc());
}
/// Some nodes (e.g. the error expression) cannot possibly contain anything to
/// be looked up and if included in a parent scope's source range would expand
/// it beyond an ancestor's source range. But if the ancestor is expanded
/// lazily, we check that its source range does not change when expanding it,
/// and this check would fail.
static bool sourceRangeWouldInterfereWithLaziness(const ASTNode n) {
return n.isExpr(ExprKind::Error);
}
static bool
shouldIgnoredASTNodeSourceRangeWidenEnclosingScope(const ASTNode n) {
if (n.isDecl(DeclKind::Var)) {
// The pattern scopes will include the source ranges for VarDecls.
// Using its range here would cause a pattern initializer scope's range
// to overlap the pattern use scope's range.
return false;
}
if (sourceRangeWouldInterfereWithLaziness(n))
return false;
return true;
}
void ASTScopeImpl::widenSourceRangeForIgnoredASTNode(const ASTNode n) {
// The pattern scopes will include the source ranges for VarDecls.
// Doing the default here would cause a pattern initializer scope's range
// to overlap the pattern use scope's range.
if (n.isDecl(DeclKind::Var))
if (!shouldIgnoredASTNodeSourceRangeWidenEnclosingScope(n))
return;
// FIXME: why only do effectiveness bit for *ignored* nodes?
SourceRange r = getEffectiveSourceRange(n);
if (r.isInvalid())
return;
@@ -553,20 +609,21 @@ static SourceLoc getStartOfFirstParam(ClosureExpr *closure) {
return closure->getStartLoc();
}
#pragma mark getSourceRangeOfEnclosedParams
#pragma mark getSourceRangeOfEnclosedParamsOfASTNode
SourceRange
ASTScopeImpl::getSourceRangeOfEnclosedParams(const bool omitAssertions) const {
return getParent().get()->getSourceRangeOfEnclosedParams(omitAssertions);
SourceRange ASTScopeImpl::getSourceRangeOfEnclosedParamsOfASTNode(
const bool omitAssertions) const {
return getParent().get()->getSourceRangeOfEnclosedParamsOfASTNode(
omitAssertions);
}
SourceRange
EnumElementScope::getSourceRangeOfEnclosedParams(bool omitAssertions) const {
SourceRange EnumElementScope::getSourceRangeOfEnclosedParamsOfASTNode(
bool omitAssertions) const {
auto *pl = decl->getParameterList();
return pl ? pl->getSourceRange() : SourceRange();
}
SourceRange SubscriptDeclScope::getSourceRangeOfEnclosedParams(
SourceRange SubscriptDeclScope::getSourceRangeOfEnclosedParamsOfASTNode(
const bool omitAssertions) const {
auto r = SourceRange(decl->getIndices()->getLParenLoc(), decl->getEndLoc());
// Because of "subscript(x: MyStruct#^PARAM_1^#) -> Int { return 0 }"
@@ -575,15 +632,15 @@ SourceRange SubscriptDeclScope::getSourceRangeOfEnclosedParams(
return r;
}
SourceRange AbstractFunctionDeclScope::getSourceRangeOfEnclosedParams(
SourceRange AbstractFunctionDeclScope::getSourceRangeOfEnclosedParamsOfASTNode(
const bool omitAssertions) const {
const auto s = getParamsSourceLoc(decl);
const auto e = getChildlessSourceRange(omitAssertions).End;
const auto s = getParmsSourceLocOfAFD(decl);
const auto e = getSourceRangeOfThisASTNode(omitAssertions).End;
return s.isInvalid() || e.isInvalid() ? SourceRange() : SourceRange(s, e);
}
SourceLoc
AbstractFunctionDeclScope::getParamsSourceLoc(AbstractFunctionDecl *decl) {
AbstractFunctionDeclScope::getParmsSourceLocOfAFD(AbstractFunctionDecl *decl) {
if (auto *c = dyn_cast<ConstructorDecl>(decl))
return c->getParameters()->getLParenLoc();
@@ -597,3 +654,13 @@ AbstractFunctionDeclScope::getParamsSourceLoc(AbstractFunctionDecl *decl) {
: fd->getParameters()->getLParenLoc();
// clang-format on
}
#pragma mark deferred scope source ranges
SourceRange IterableTypeBodyPortion::sourceRangeForDeferredExpansion(
const IterableTypeScope *s) const {
const auto bracesRange = getChildlessSourceRangeOf(s, false);
const auto &SM = s->getSourceManager();
return SourceRange(bracesRange.Start,
getLocEncompassingPotentialLookups(SM, bracesRange.End));
}