[PATCH] D110825: [clangd] Handle members of anon structs in SelectionTree

Kadir Cetinkaya via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 30 06:27:27 PDT 2021


kadircet created this revision.
kadircet added a reviewer: sammccall.
Herald added subscribers: usaxena95, arphaman.
kadircet requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.

References to fields inside anon structs contain an implicit children
for the container, which has the same SourceLocation with the field.
This was resulting in SelectionTree always picking the anon-struct rather than
the field as the selection.

This patch prevents that by claiming the range for the field early.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D110825

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


Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -365,6 +365,25 @@
       ElementsAre(Sym("Forward", SymbolHeader.range("forward"), Test.range())));
 }
 
+TEST(LocateSymbol, AnonymousStructFields) {
+  auto Code = Annotations(R"cpp(
+    class Foo {
+      struct {
+        struct {
+          int $1[[x]];
+        } $0[[y]];
+      };
+      void foo() { $0^y.$1^x = 2; }
+    };
+  )cpp");
+  TestTU TU = TestTU::withCode(Code.code());
+  auto AST = TU.build();
+  EXPECT_THAT(locateSymbolAt(AST, Code.point("0"), TU.index().get()),
+              UnorderedElementsAre(Sym("y", Code.range("0"), Code.range("0"))));
+  EXPECT_THAT(locateSymbolAt(AST, Code.point("1"), TU.index().get()),
+              UnorderedElementsAre(Sym("x", Code.range("1"), Code.range("1"))));
+}
+
 TEST(LocateSymbol, FindOverrides) {
   auto Code = Annotations(R"cpp(
     class Foo {
Index: clang-tools-extra/clangd/Selection.cpp
===================================================================
--- clang-tools-extra/clangd/Selection.cpp
+++ clang-tools-extra/clangd/Selection.cpp
@@ -732,6 +732,19 @@
     } else if (const auto *CCI = N.get<CXXCtorInitializer>()) {
       // : [[b_]](42)
       return CCI->getMemberLocation();
+    } else if (const auto *ME = N.get<MemberExpr>()) {
+      // In member expressions involving anonymous structs, there's an implicit
+      // reference to the container. Make sure all the tokens that belong to the
+      // member are claimed first to prevent this unspelled children from owning
+      // them.
+      // struct Foo {
+      //   struct { int x; }
+      //   void foo() { [[x]] = 2; }
+      // };
+      if (auto *FD = llvm::dyn_cast<FieldDecl>(ME->getMemberDecl())) {
+        if (FD->getParent()->isAnonymousStructOrUnion())
+          return SourceRange(ME->getMemberLoc(), ME->getEndLoc());
+      }
     }
     return SourceRange();
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D110825.376179.patch
Type: text/x-patch
Size: 2068 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210930/4b67d8fc/attachment.bin>


More information about the cfe-commits mailing list