[PATCH] D117472: [clangd] Bring back early-claim approach to fix a selection-tree regression.

Haojian Wu via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 18 01:22:45 PST 2022


This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
hokein marked an inline comment as done.
Closed by commit rGfd598e185972: [clangd] Bring back early-claim approach to fix a selection-tree regression. (authored by hokein).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117472/new/

https://reviews.llvm.org/D117472

Files:
  clang-tools-extra/clangd/Selection.cpp
  clang-tools-extra/clangd/unittests/SelectionTests.cpp


Index: clang-tools-extra/clangd/unittests/SelectionTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/SelectionTests.cpp
+++ clang-tools-extra/clangd/unittests/SelectionTests.cpp
@@ -516,6 +516,13 @@
         enum Bar : [[Fo^o]];
       )cpp",
        "TypedefTypeLoc"},
+
+      // lambda captured var-decl
+      {R"cpp(
+        void test(int bar) {
+          auto l = [^[[foo = bar]]] { };
+        })cpp",
+       "VarDecl"},
   };
 
   for (const Case &C : Cases) {
Index: clang-tools-extra/clangd/Selection.cpp
===================================================================
--- clang-tools-extra/clangd/Selection.cpp
+++ clang-tools-extra/clangd/Selection.cpp
@@ -794,13 +794,16 @@
   }
 
   // Pushes a node onto the ancestor stack. Pairs with pop().
+  // Performs early hit detection for some nodes (on the earlySourceRange).
   void push(DynTypedNode Node) {
+    SourceRange Early = earlySourceRange(Node);
     dlog("{1}push: {0}", printNodeToString(Node, PrintPolicy), indent());
     Nodes.emplace_back();
     Nodes.back().ASTNode = std::move(Node);
     Nodes.back().Parent = Stack.top();
     Nodes.back().Selected = NoTokens;
     Stack.push(&Nodes.back());
+    claimRange(Early, Nodes.back().Selected);
   }
 
   // Pops a node off the ancestor stack, and finalizes it. Pairs with push().
@@ -822,6 +825,26 @@
     Stack.pop();
   }
 
+  // Returns the range of tokens that this node will claim directly, and
+  // is not available to the node's children.
+  // Usually empty, but sometimes children cover tokens but shouldn't own them.
+  SourceRange earlySourceRange(const DynTypedNode &N) {
+    if (const Decl *D = N.get<Decl>()) {
+      // We want the name in the var-decl to be claimed by the decl itself and
+      // not by any children. Ususally, we don't need this, because source
+      // ranges of children are not overlapped with their parent's.
+      // An exception is lambda captured var decl, where AutoTypeLoc is
+      // overlapped with the name loc.
+      //    auto fun = [bar = foo]() { ... }
+      //                ~~~~~~~~~   VarDecl
+      //                ~~~         |- AutoTypeLoc
+      if (const auto *DD = llvm::dyn_cast<VarDecl>(D))
+        return DD->getLocation();
+    }
+
+    return SourceRange();
+  }
+
   // Claim tokens for N, after processing its children.
   // By default this claims all unclaimed tokens in getSourceRange().
   // We override this if we want to claim fewer tokens (e.g. there are gaps).


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D117472.400766.patch
Type: text/x-patch
Size: 2551 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220118/b553d480/attachment.bin>


More information about the cfe-commits mailing list