This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG4581bf31bb83: [clangd] Dont index deeply nested symbols 
(authored by kadircet).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D101066

Files:
  clang-tools-extra/clangd/AST.cpp
  clang-tools-extra/clangd/AST.h
  clang-tools-extra/clangd/index/IndexAction.cpp
  clang-tools-extra/clangd/unittests/ASTTests.cpp
  clang-tools-extra/clangd/unittests/IndexActionTests.cpp

Index: clang-tools-extra/clangd/unittests/IndexActionTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/IndexActionTests.cpp
+++ clang-tools-extra/clangd/unittests/IndexActionTests.cpp
@@ -281,6 +281,36 @@
       EXPECT_THAT(Ref.Location.FileURI, EndsWith("good.h"));
 }
 
+TEST_F(IndexActionTest, SkipNestedSymbols) {
+  std::string MainFilePath = testPath("main.cpp");
+  addFile(MainFilePath, R"cpp(
+  namespace ns1 {
+  namespace ns2 {
+  namespace ns3 {
+  namespace ns4 {
+  namespace ns5 {
+  namespace ns6 {
+  namespace ns7 {
+  namespace ns8 {
+  namespace ns9 {
+  class Bar {};
+  void foo() {
+    class Baz {};
+  }
+  }
+  }
+  }
+  }
+  }
+  }
+  }
+  }
+  })cpp");
+  IndexFileIn IndexFile = runIndexingAction(MainFilePath, {"-std=c++14"});
+  EXPECT_THAT(*IndexFile.Symbols, testing::Contains(HasName("foo")));
+  EXPECT_THAT(*IndexFile.Symbols, testing::Contains(HasName("Bar")));
+  EXPECT_THAT(*IndexFile.Symbols, Not(testing::Contains(HasName("Baz"))));
+}
 } // namespace
 } // namespace clangd
 } // namespace clang
Index: clang-tools-extra/clangd/unittests/ASTTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/ASTTests.cpp
+++ clang-tools-extra/clangd/unittests/ASTTests.cpp
@@ -351,6 +351,32 @@
     }
   }
 }
+
+TEST(ClangdAST, IsDeeplyNested) {
+  Annotations Test(
+      R"cpp(
+        namespace ns {
+        class Foo {
+          void bar() {
+            class Bar {};
+          }
+        };
+        })cpp");
+  TestTU TU = TestTU::withCode(Test.code());
+  ParsedAST AST = TU.build();
+
+  EXPECT_TRUE(isDeeplyNested(&findUnqualifiedDecl(AST, "Foo"), /*MaxDepth=*/1));
+  EXPECT_FALSE(
+      isDeeplyNested(&findUnqualifiedDecl(AST, "Foo"), /*MaxDepth=*/2));
+
+  EXPECT_TRUE(isDeeplyNested(&findUnqualifiedDecl(AST, "bar"), /*MaxDepth=*/2));
+  EXPECT_FALSE(
+      isDeeplyNested(&findUnqualifiedDecl(AST, "bar"), /*MaxDepth=*/3));
+
+  EXPECT_TRUE(isDeeplyNested(&findUnqualifiedDecl(AST, "Bar"), /*MaxDepth=*/3));
+  EXPECT_FALSE(
+      isDeeplyNested(&findUnqualifiedDecl(AST, "Bar"), /*MaxDepth=*/4));
+}
 } // namespace
 } // namespace clangd
 } // namespace clang
Index: clang-tools-extra/clangd/index/IndexAction.cpp
===================================================================
--- clang-tools-extra/clangd/index/IndexAction.cpp
+++ clang-tools-extra/clangd/index/IndexAction.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "IndexAction.h"
+#include "AST.h"
 #include "Headers.h"
 #include "index/Relation.h"
 #include "index/SymbolOrigin.h"
@@ -21,6 +22,7 @@
 #include "clang/Index/IndexingOptions.h"
 #include "clang/Tooling/Tooling.h"
 #include "llvm/ADT/STLExtras.h"
+#include <cstddef>
 #include <functional>
 #include <memory>
 #include <utility>
@@ -138,6 +140,12 @@
         Includes(std::move(Includes)), Opts(Opts),
         PragmaHandler(collectIWYUHeaderMaps(this->Includes.get())) {
     this->Opts.ShouldTraverseDecl = [this](const Decl *D) {
+      // Many operations performed during indexing is linear in terms of depth
+      // of the decl (USR generation, name lookups, figuring out role of a
+      // reference are some examples). Since we index all the decls nested
+      // inside, it becomes quadratic. So we give up on nested symbols.
+      if (isDeeplyNested(D))
+        return false;
       auto &SM = D->getASTContext().getSourceManager();
       auto FID = SM.getFileID(SM.getExpansionLoc(D->getLocation()));
       if (!FID.isValid())
Index: clang-tools-extra/clangd/AST.h
===================================================================
--- clang-tools-extra/clangd/AST.h
+++ clang-tools-extra/clangd/AST.h
@@ -171,6 +171,12 @@
 /// the cached value is incorrect. (clang catches this with an assertion).
 bool hasUnstableLinkage(const Decl *D);
 
+/// Checks whether \p D is more than \p MaxDepth away from translation unit
+/// scope.
+/// This is useful for limiting traversals to keep operation latencies
+/// reasonable.
+bool isDeeplyNested(const Decl *D, unsigned MaxDepth = 10);
+
 } // namespace clangd
 } // namespace clang
 
Index: clang-tools-extra/clangd/AST.cpp
===================================================================
--- clang-tools-extra/clangd/AST.cpp
+++ clang-tools-extra/clangd/AST.cpp
@@ -524,5 +524,14 @@
   return VD && !VD->getType().isNull() && VD->getType()->isUndeducedType();
 }
 
+bool isDeeplyNested(const Decl *D, unsigned MaxDepth) {
+  size_t ContextDepth = 0;
+  for (auto *Ctx = D->getDeclContext(); Ctx && !Ctx->isTranslationUnit();
+       Ctx = Ctx->getParent()) {
+    if (++ContextDepth == MaxDepth)
+      return true;
+  }
+  return false;
+}
 } // namespace clangd
 } // namespace clang
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to