diff --git a/clang-tools-extra/clangd/indexer/IndexerMain.cpp b/clang-tools-extra/clangd/indexer/IndexerMain.cpp --- a/clang-tools-extra/clangd/indexer/IndexerMain.cpp +++ b/clang-tools-extra/clangd/indexer/IndexerMain.cpp @@ -17,11 +17,15 @@ #include "index/Symbol.h" #include "index/SymbolCollector.h" #include "support/Logger.h" +#include "clang/Basic/SourceManager.h" #include "clang/Tooling/ArgumentsAdjusters.h" #include "clang/Tooling/CommonOptionsParser.h" #include "clang/Tooling/Execution.h" #include "clang/Tooling/Tooling.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Path.h" #include "llvm/Support/Signals.h" namespace clang { @@ -36,12 +40,34 @@ "binary RIFF format")), llvm::cl::init(IndexFileFormat::RIFF)); +static llvm::cl::opt + ProjectRoot("project-root", + llvm::cl::desc("Filter out all symbols outside of this " + "directory. This is useful for remote index."), + llvm::cl::Hidden); + class IndexActionFactory : public tooling::FrontendActionFactory { public: - IndexActionFactory(IndexFileIn &Result) : Result(Result) {} + IndexActionFactory(IndexFileIn &Result, llvm::StringRef IndexRoot) + : Result(Result) { + if (!IndexRoot.empty()) { + // Returns true if file should be indexed. + FileFilter = [&](const SourceManager &SM, FileID ID) { + const FileEntry *Entry = SM.getFileEntryForID(ID); + if (!Entry) + return false; + llvm::SmallString<256> FilePath = Entry->tryGetRealPathName(); + // When replacing prefix it checks whether Path starts with OldPrefix. + // NewPrefix doesn't matter in this case. + return llvm::sys::path::replace_path_prefix( + /*Path=*/FilePath, /*OldPrefix=*/IndexRoot, /*NewPrefix=*/""); + }; + } + } std::unique_ptr create() override { SymbolCollector::Options Opts; + Opts.FileFilter = FileFilter; Opts.CountReferences = true; return createStaticIndexingAction( Opts, @@ -57,10 +83,10 @@ }, [&](RefSlab S) { std::lock_guard 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) { @@ -86,6 +112,7 @@ SymbolSlab::Builder Symbols; RefSlab::Builder Refs; RelationSlab::Builder Relations; + std::function FileFilter = nullptr; }; } // namespace @@ -120,7 +147,9 @@ // Collect symbols found in each translation unit, merging as we go. clang::clangd::IndexFileIn Data; auto Err = Executor->get()->execute( - std::make_unique(Data), + std::make_unique( + Data, llvm::sys::path::convert_to_slash( + clang::clangd::ProjectRoot, llvm::sys::path::Style::posix)), clang::tooling::getStripPluginsAdjuster()); if (Err) { clang::clangd::elog("{0}", std::move(Err));