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

Previously we did not record local class declarations. Now with features like
findImplementation and typeHierarchy, we have a need to index such local
classes to accurately report subclasses and implementations of methods.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D94785

Files:
  clang-tools-extra/clangd/index/FileIndex.cpp
  clang-tools-extra/clangd/index/IndexAction.cpp
  clang-tools-extra/clangd/index/SymbolCollector.cpp
  clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp
  clang-tools-extra/clangd/unittests/SymbolCollectorTests.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
@@ -1637,14 +1637,28 @@
     template<typename T>
     struct $5^TemplateBase {};
     struct $5[[Child3]] : public TemplateBase<Child3> {};
+
+    // Local classes.
+    void LocationFunction() {
+      struct $0[[LocalClass1]] : Base {
+        void $1[[Foo]]() override;
+      };
+      struct $6^LocalBase {
+        virtual void $7^Bar();
+      };
+      struct $6[[LocalClass2]]: LocalBase {
+        void $7[[Bar]]() override;
+      };
+    }
   )cpp";
 
   Annotations Code(Test);
   auto TU = TestTU::withCode(Code.code());
   auto AST = TU.build();
-  for (StringRef Label : {"0", "1", "2", "3", "4", "5"}) {
+  auto Index = TU.index();
+  for (StringRef Label : {"0", "1", "2", "3", "4", "5", "6", "7"}) {
     for (const auto &Point : Code.points(Label)) {
-      EXPECT_THAT(findImplementations(AST, Point, TU.index().get()),
+      EXPECT_THAT(findImplementations(AST, Point, Index.get()),
                   UnorderedPointwise(DeclRange(), Code.ranges(Label)))
           << Code.code() << " at " << Point << " for Label " << Label;
     }
Index: clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
+++ clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
@@ -138,6 +138,13 @@
     namespace nx {
     class X{};
     auto f() { int Local; } // auto ensures function body is parsed.
+    auto foo() {
+      class LocalBase {
+        virtual void LocalVirtual();
+        void LocalConcrete();
+        int BaseMember;
+      };
+    }
     struct { int x; } var;
     }
   )",
@@ -154,6 +161,11 @@
   EXPECT_TRUE(shouldCollect("InAnonymous", /*Qualified=*/false));
   EXPECT_TRUE(shouldCollect("g"));
 
+  // Locals.
+  EXPECT_TRUE(shouldCollect("LocalBase", /*Qualified=*/false));
+  EXPECT_TRUE(shouldCollect("LocalVirtual", /*Qualified=*/false));
+  EXPECT_FALSE(shouldCollect("LocalConcrete", /*Qualified=*/false));
+  EXPECT_FALSE(shouldCollect("BaseMember", /*Qualified=*/false));
   EXPECT_FALSE(shouldCollect("Local", /*Qualified=*/false));
 }
 
Index: clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp
+++ clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp
@@ -72,7 +72,7 @@
         struct LocalClass {};
         int local_var;
       })cpp";
-  EXPECT_THAT(getSymbols(TU, "l"), IsEmpty());
+  EXPECT_THAT(getSymbols(TU, "l"), ElementsAre(QName("LocalClass")));
   EXPECT_THAT(getSymbols(TU, "p"), IsEmpty());
 }
 
Index: clang-tools-extra/clangd/index/SymbolCollector.cpp
===================================================================
--- clang-tools-extra/clangd/index/SymbolCollector.cpp
+++ clang-tools-extra/clangd/index/SymbolCollector.cpp
@@ -223,6 +223,13 @@
   if (!IsMainFileOnly && ND.isInAnonymousNamespace())
     return false;
 
+  // Index all virtual and overridding methods.
+  if (const auto *CXXMD = llvm::dyn_cast<CXXMethodDecl>(&ND))
+    if (CXXMD->isVirtual() || !CXXMD->overridden_methods().empty())
+      return true;
+  // For function local symbols, index only classes.
+  if (ND.getParentFunctionOrMethod())
+    return isa<RecordDecl>(ND);
   // We want most things but not "local" symbols such as symbols inside
   // FunctionDecl, BlockDecl, ObjCMethodDecl and OMPDeclareReductionDecl.
   // FIXME: Need a matcher for ExportDecl in order to include symbols declared
Index: clang-tools-extra/clangd/index/IndexAction.cpp
===================================================================
--- clang-tools-extra/clangd/index/IndexAction.cpp
+++ clang-tools-extra/clangd/index/IndexAction.cpp
@@ -212,6 +212,7 @@
   index::IndexingOptions IndexOpts;
   IndexOpts.SystemSymbolFilter =
       index::IndexingOptions::SystemSymbolFilterKind::All;
+  IndexOpts.IndexFunctionLocals = true;
   Opts.CollectIncludePath = true;
   if (Opts.Origin == SymbolOrigin::Unknown)
     Opts.Origin = SymbolOrigin::Static;
Index: clang-tools-extra/clangd/index/FileIndex.cpp
===================================================================
--- clang-tools-extra/clangd/index/FileIndex.cpp
+++ clang-tools-extra/clangd/index/FileIndex.cpp
@@ -61,7 +61,7 @@
   // We only need declarations, because we don't count references.
   IndexOpts.SystemSymbolFilter =
       index::IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly;
-  IndexOpts.IndexFunctionLocals = false;
+  IndexOpts.IndexFunctionLocals = true;
   if (IsIndexMainAST) {
     // We only collect refs when indexing main AST.
     CollectorOpts.RefFilter = RefKind::All;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to