@@ -2462,12 +2462,29 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
24622462 return MacroWalking::ArgumentsAndExpansion;
24632463 }
24642464
2465+ // / Checks whether the given range, when treated as a character range,
2466+ // / contains the searched location.
2467+ bool charRangeContainsLoc (SourceRange range) {
2468+ if (!range)
2469+ return false ;
2470+
2471+ if (SM.isBefore (Loc, range.Start ))
2472+ return false ;
2473+
2474+ // NOTE: We need to check the character loc here because the target
2475+ // loc can be inside the last token of the node. i.e. interpolated
2476+ // string.
2477+ return SM.isBefore (Loc, Lexer::getLocForEndOfToken (SM, range.End ));
2478+ }
2479+
24652480 PreWalkResult<Stmt *> walkToStmtPre (Stmt *S) override {
24662481 if (auto *brace = dyn_cast<BraceStmt>(S)) {
2467- auto braceCharRange = Lexer::getCharSourceRangeFromSourceRange (
2468- SM, brace->getSourceRange ());
2482+ auto braceRange = brace->getSourceRange ();
2483+ auto braceCharRange = SourceRange (
2484+ braceRange.Start , Lexer::getLocForEndOfToken (SM, braceRange.End ));
2485+
24692486 // Unless this brace contains the loc, there's nothing to do.
2470- if (!braceCharRange. contains ( Loc))
2487+ if (!SM. containsLoc (braceCharRange, Loc))
24712488 return Action::SkipNode (S);
24722489
24732490 // Reset the node found in a parent context if it's not part of this
@@ -2477,22 +2494,22 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
24772494 // syntactically part of the brace stmt's range but won't be walked as
24782495 // a child of the brace stmt.
24792496 if (!brace->isImplicit () && FoundNode) {
2480- auto foundNodeCharRange = Lexer::getCharSourceRangeFromSourceRange (
2481- SM, FoundNode->getSourceRange ());
2482- if (!braceCharRange.contains (foundNodeCharRange)) {
2497+ auto foundRange = FoundNode->getSourceRange ();
2498+ auto foundCharRange = SourceRange (
2499+ foundRange.Start , Lexer::getLocForEndOfToken (SM, foundRange.End ));
2500+ if (!SM.encloses (braceCharRange, foundCharRange))
24832501 FoundNode = nullptr ;
2484- }
24852502 }
24862503
24872504 for (ASTNode &node : brace->getElements ()) {
2488- if (SM.isBeforeInBuffer (Loc, node.getStartLoc ()))
2505+ auto range = node.getSourceRange ();
2506+ if (SM.isBefore (Loc, range.Start ))
24892507 break ;
24902508
24912509 // NOTE: We need to check the character loc here because the target
24922510 // loc can be inside the last token of the node. i.e. interpolated
24932511 // string.
2494- SourceLoc endLoc = Lexer::getLocForEndOfToken (SM, node.getEndLoc ());
2495- if (SM.isBeforeInBuffer (endLoc, Loc) || endLoc == Loc)
2512+ if (!SM.isBefore (Loc, Lexer::getLocForEndOfToken (SM, range.End )))
24962513 continue ;
24972514
24982515 // 'node' may be the target node, except 'CaseStmt' which cannot be
@@ -2509,13 +2526,11 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
25092526 return Action::Stop ();
25102527 } else if (auto Conditional = dyn_cast<LabeledConditionalStmt>(S)) {
25112528 for (StmtConditionElement &Cond : Conditional->getCond ()) {
2512- if (SM.isBeforeInBuffer (Loc, Cond.getStartLoc ())) {
2529+ auto range = Cond.getSourceRange ();
2530+ if (SM.isBefore (Loc, range.Start ))
25132531 break ;
2514- }
2515- SourceLoc endLoc = Lexer::getLocForEndOfToken (SM, Cond.getEndLoc ());
2516- if (SM.isBeforeInBuffer (endLoc, Loc) || endLoc == Loc) {
2532+ if (!SM.isBefore (Loc, Lexer::getLocForEndOfToken (SM, range.End )))
25172533 continue ;
2518- }
25192534
25202535 FoundNodeStorage = ASTNode (&Cond);
25212536 FoundNode = &FoundNodeStorage;
@@ -2527,11 +2542,7 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
25272542 }
25282543
25292544 PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
2530- if (SM.isBeforeInBuffer (Loc, E->getStartLoc ()))
2531- return Action::SkipNode (E);
2532-
2533- SourceLoc endLoc = Lexer::getLocForEndOfToken (SM, E->getEndLoc ());
2534- if (SM.isBeforeInBuffer (endLoc, Loc))
2545+ if (!charRangeContainsLoc (E->getSourceRange ()))
25352546 return Action::SkipNode (E);
25362547
25372548 // Don't walk into 'TapExpr'. They should be type checked with parent
@@ -2546,9 +2557,7 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
25462557 if (auto *SVE = dyn_cast<SingleValueStmtExpr>(E)) {
25472558 SmallVector<Expr *> scratch;
25482559 for (auto *result : SVE->getResultExprs (scratch)) {
2549- auto resultCharRange = Lexer::getCharSourceRangeFromSourceRange (
2550- SM, result->getSourceRange ());
2551- if (resultCharRange.contains (Loc)) {
2560+ if (charRangeContainsLoc (result->getSourceRange ())) {
25522561 if (!result->walk (*this ))
25532562 return Action::Stop ();
25542563
@@ -2570,20 +2579,15 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
25702579 }
25712580
25722581 PreWalkAction walkToDeclPre (Decl *D) override {
2582+ if (!charRangeContainsLoc (D->getSourceRange ()))
2583+ return Action::SkipNode ();
2584+
25732585 if (auto *newDC = dyn_cast<DeclContext>(D))
25742586 DC = newDC;
25752587
2576- if (!SM.isBeforeInBuffer (Loc, D->getStartLoc ())) {
2577- // NOTE: We need to check the character loc here because the target
2578- // loc can be inside the last token of the node. i.e. interpolated
2579- // string.
2580- SourceLoc endLoc = Lexer::getLocForEndOfToken (SM, D->getEndLoc ());
2581- if (!(SM.isBeforeInBuffer (endLoc, Loc) || endLoc == Loc)) {
2582- if (!isa<TopLevelCodeDecl>(D)) {
2583- FoundNodeStorage = ASTNode (D);
2584- FoundNode = &FoundNodeStorage;
2585- }
2586- }
2588+ if (!isa<TopLevelCodeDecl>(D)) {
2589+ FoundNodeStorage = ASTNode (D);
2590+ FoundNode = &FoundNodeStorage;
25872591 }
25882592 return Action::Continue ();
25892593 }
0 commit comments