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

This is useful for the remote index: system libraries and external dependencies
would still have a different location on local and remote machine, so they
should be simply excluded.

Unfortunately, it is not possible to filter symbols during indexing because
symbol information is merged throughout the whole process, so the only option
is to do post-processing.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84811

Files:
  clang-tools-extra/clangd/indexer/IndexerMain.cpp

Index: clang-tools-extra/clangd/indexer/IndexerMain.cpp
===================================================================
--- clang-tools-extra/clangd/indexer/IndexerMain.cpp
+++ clang-tools-extra/clangd/indexer/IndexerMain.cpp
@@ -20,7 +20,9 @@
 #include "clang/Tooling/CommonOptionsParser.h"
 #include "clang/Tooling/Execution.h"
 #include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/Signals.h"
 
 namespace clang {
@@ -35,9 +37,36 @@
                                        "binary RIFF format")),
            llvm::cl::init(IndexFileFormat::RIFF));
 
+static llvm::cl::opt<std::string>
+    ProjectRoot("project-root",
+                llvm::cl::desc("Filter out all symbols outside of this "
+                               "directory. This is useful for remote index."),
+                llvm::cl::Hidden);
+
+bool filterURI(llvm::StringRef URI, llvm::StringRef IndexRoot) {
+  auto Parsed = URI::parse(URI);
+  return !Parsed || !Parsed->body().startswith(IndexRoot);
+}
+
+/// Returns true if \p Sym should be excluded from index.
+bool filterSymbol(const Symbol &Sym, llvm::StringRef IndexRoot) {
+  if (*Sym.CanonicalDeclaration.FileURI)
+    if (filterURI(Sym.CanonicalDeclaration.FileURI, IndexRoot))
+      return true;
+  if (*Sym.Definition.FileURI)
+    if (filterURI(Sym.Definition.FileURI, IndexRoot))
+      return true;
+  for (const auto &Header : Sym.IncludeHeaders)
+    if (!isLiteralInclude(Header.IncludeHeader))
+      if (filterURI(Header.IncludeHeader, IndexRoot))
+        return true;
+  return false;
+}
+
 class IndexActionFactory : public tooling::FrontendActionFactory {
 public:
-  IndexActionFactory(IndexFileIn &Result) : Result(Result) {}
+  IndexActionFactory(IndexFileIn &Result, llvm::StringRef IndexRoot)
+      : Result(Result), IndexRoot(IndexRoot) {}
 
   std::unique_ptr<FrontendAction> create() override {
     SymbolCollector::Options Opts;
@@ -56,10 +85,10 @@
         },
         [&](RefSlab S) {
           std::lock_guard<std::mutex> Lock(SymbolsMu);
-          for (const auto &Sym : S) {
+          for (const auto &SymbolAndRefs : S) {
             // Deduplication happens during insertion.
-            for (const auto &Ref : Sym.second)
-              Refs.insert(Sym.first, Ref);
+            for (const auto &Ref : SymbolAndRefs.second)
+              Refs.insert(SymbolAndRefs.first, Ref);
           }
         },
         [&](RelationSlab S) {
@@ -77,6 +106,38 @@
     Result.Symbols = std::move(Symbols).build();
     Result.Refs = std::move(Refs).build();
     Result.Relations = std::move(Relations).build();
+
+    // Post-filtering.
+    if (!IndexRoot.empty()) {
+      llvm::DenseSet<SymbolID> ExcludeIDs;
+      for (const auto &Sym : *Result.Symbols)
+        if (filterSymbol(Sym, IndexRoot))
+          ExcludeIDs.insert(Sym.ID);
+
+      llvm::errs() << "Total symbols collected: " << Result.Symbols->size()
+                   << ". Filtering out " << ExcludeIDs.size() << " of them.\n";
+
+      if (!ExcludeIDs.empty()) {
+        SymbolSlab::Builder FilteredSymbols;
+        RefSlab::Builder FilteredRefs;
+        RelationSlab::Builder FilteredRelations;
+        for (const auto &Sym : *Result.Symbols)
+          if (ExcludeIDs.find(Sym.ID) == ExcludeIDs.end())
+            FilteredSymbols.insert(Sym);
+        for (const auto &SymbolAndRefs : *Result.Refs)
+          if (ExcludeIDs.find(SymbolAndRefs.first) == ExcludeIDs.end())
+            for (const auto &Ref : SymbolAndRefs.second)
+              FilteredRefs.insert(SymbolAndRefs.first, Ref);
+        for (const auto &Rel : *Result.Relations)
+          if ((ExcludeIDs.find(Rel.Object) == ExcludeIDs.end()) &&
+              (ExcludeIDs.find(Rel.Subject) == ExcludeIDs.end()))
+            FilteredRelations.insert(Rel);
+
+        Result.Symbols = std::move(FilteredSymbols).build();
+        Result.Refs = std::move(FilteredRefs).build();
+        Result.Relations = std::move(FilteredRelations).build();
+      }
+    }
   }
 
 private:
@@ -85,6 +146,7 @@
   SymbolSlab::Builder Symbols;
   RefSlab::Builder Refs;
   RelationSlab::Builder Relations;
+  std::string IndexRoot;
 };
 
 } // namespace
@@ -119,7 +181,9 @@
   // Collect symbols found in each translation unit, merging as we go.
   clang::clangd::IndexFileIn Data;
   auto Err = Executor->get()->execute(
-      std::make_unique<clang::clangd::IndexActionFactory>(Data),
+      std::make_unique<clang::clangd::IndexActionFactory>(
+          Data, llvm::sys::path::convert_to_slash(
+                    clang::clangd::ProjectRoot, llvm::sys::path::Style::posix)),
       clang::tooling::getStripPluginsAdjuster());
   if (Err) {
     llvm::errs() << llvm::toString(std::move(Err)) << "\n";
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to