@@ -2462,12 +2462,26 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
2462
2462
return MacroWalking::ArgumentsAndExpansion;
2463
2463
}
2464
2464
2465
+ // / Checks whether the given range, when treated as a character range,
2466
+ // / contains the searched location.
2467
+ bool charRangeContainsLoc (SourceRange range) {
2468
+ if (SM.isBefore (Loc, range.Start ))
2469
+ return false ;
2470
+
2471
+ // NOTE: We need to check the character loc here because the target
2472
+ // loc can be inside the last token of the node. i.e. interpolated
2473
+ // string.
2474
+ return SM.isBefore (Loc, Lexer::getLocForEndOfToken (SM, range.End ));
2475
+ }
2476
+
2465
2477
PreWalkResult<Stmt *> walkToStmtPre (Stmt *S) override {
2466
2478
if (auto *brace = dyn_cast<BraceStmt>(S)) {
2467
- auto braceCharRange = Lexer::getCharSourceRangeFromSourceRange (
2468
- SM, brace->getSourceRange ());
2479
+ auto braceRange = brace->getSourceRange ();
2480
+ auto braceCharRange = SourceRange (
2481
+ braceRange.Start , Lexer::getLocForEndOfToken (SM, braceRange.End ));
2482
+
2469
2483
// Unless this brace contains the loc, there's nothing to do.
2470
- if (!braceCharRange. contains ( Loc))
2484
+ if (!SM. containsLoc (braceCharRange, Loc))
2471
2485
return Action::SkipNode (S);
2472
2486
2473
2487
// Reset the node found in a parent context if it's not part of this
@@ -2477,22 +2491,22 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
2477
2491
// syntactically part of the brace stmt's range but won't be walked as
2478
2492
// a child of the brace stmt.
2479
2493
if (!brace->isImplicit () && FoundNode) {
2480
- auto foundNodeCharRange = Lexer::getCharSourceRangeFromSourceRange (
2481
- SM, FoundNode->getSourceRange ());
2482
- if (!braceCharRange.contains (foundNodeCharRange)) {
2494
+ auto foundRange = FoundNode->getSourceRange ();
2495
+ auto foundCharRange = SourceRange (
2496
+ foundRange.Start , Lexer::getLocForEndOfToken (SM, foundRange.End ));
2497
+ if (!SM.encloses (braceCharRange, foundCharRange))
2483
2498
FoundNode = nullptr ;
2484
- }
2485
2499
}
2486
2500
2487
2501
for (ASTNode &node : brace->getElements ()) {
2488
- if (SM.isBeforeInBuffer (Loc, node.getStartLoc ()))
2502
+ auto range = node.getSourceRange ();
2503
+ if (SM.isBefore (Loc, range.Start ))
2489
2504
break ;
2490
2505
2491
2506
// NOTE: We need to check the character loc here because the target
2492
2507
// loc can be inside the last token of the node. i.e. interpolated
2493
2508
// string.
2494
- SourceLoc endLoc = Lexer::getLocForEndOfToken (SM, node.getEndLoc ());
2495
- if (SM.isBeforeInBuffer (endLoc, Loc) || endLoc == Loc)
2509
+ if (!SM.isBefore (Loc, Lexer::getLocForEndOfToken (SM, range.End )))
2496
2510
continue ;
2497
2511
2498
2512
// 'node' may be the target node, except 'CaseStmt' which cannot be
@@ -2509,13 +2523,11 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
2509
2523
return Action::Stop ();
2510
2524
} else if (auto Conditional = dyn_cast<LabeledConditionalStmt>(S)) {
2511
2525
for (StmtConditionElement &Cond : Conditional->getCond ()) {
2512
- if (SM.isBeforeInBuffer (Loc, Cond.getStartLoc ())) {
2526
+ auto range = Cond.getSourceRange ();
2527
+ if (SM.isBefore (Loc, range.Start ))
2513
2528
break ;
2514
- }
2515
- SourceLoc endLoc = Lexer::getLocForEndOfToken (SM, Cond.getEndLoc ());
2516
- if (SM.isBeforeInBuffer (endLoc, Loc) || endLoc == Loc) {
2529
+ if (!SM.isBefore (Loc, Lexer::getLocForEndOfToken (SM, range.End )))
2517
2530
continue ;
2518
- }
2519
2531
2520
2532
FoundNodeStorage = ASTNode (&Cond);
2521
2533
FoundNode = &FoundNodeStorage;
@@ -2527,11 +2539,7 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
2527
2539
}
2528
2540
2529
2541
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))
2542
+ if (!charRangeContainsLoc (E->getSourceRange ()))
2535
2543
return Action::SkipNode (E);
2536
2544
2537
2545
// Don't walk into 'TapExpr'. They should be type checked with parent
@@ -2546,9 +2554,7 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
2546
2554
if (auto *SVE = dyn_cast<SingleValueStmtExpr>(E)) {
2547
2555
SmallVector<Expr *> scratch;
2548
2556
for (auto *result : SVE->getResultExprs (scratch)) {
2549
- auto resultCharRange = Lexer::getCharSourceRangeFromSourceRange (
2550
- SM, result->getSourceRange ());
2551
- if (resultCharRange.contains (Loc)) {
2557
+ if (charRangeContainsLoc (result->getSourceRange ())) {
2552
2558
if (!result->walk (*this ))
2553
2559
return Action::Stop ();
2554
2560
@@ -2570,20 +2576,20 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
2570
2576
}
2571
2577
2572
2578
PreWalkAction walkToDeclPre (Decl *D) override {
2579
+ // Ignore implicit decls with no source range.
2580
+ auto range = D->getSourceRange ();
2581
+ if (!range)
2582
+ return Action::Continue ();
2583
+
2584
+ if (!charRangeContainsLoc (range))
2585
+ return Action::SkipNode ();
2586
+
2573
2587
if (auto *newDC = dyn_cast<DeclContext>(D))
2574
2588
DC = newDC;
2575
2589
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
- }
2590
+ if (!isa<TopLevelCodeDecl>(D)) {
2591
+ FoundNodeStorage = ASTNode (D);
2592
+ FoundNode = &FoundNodeStorage;
2587
2593
}
2588
2594
return Action::Continue ();
2589
2595
}
0 commit comments