diff --git a/clang-tools-extra/clangd/CMakeLists.txt b/clang-tools-extra/clangd/CMakeLists.txt --- a/clang-tools-extra/clangd/CMakeLists.txt +++ b/clang-tools-extra/clangd/CMakeLists.txt @@ -150,7 +150,6 @@ clangTidy ${ALL_CLANG_TIDY_CHECKS} - clangdRemoteIndex clangdSupport ) diff --git a/clang-tools-extra/clangd/index/ProjectAware.h b/clang-tools-extra/clangd/index/ProjectAware.h --- a/clang-tools-extra/clangd/index/ProjectAware.h +++ b/clang-tools-extra/clangd/index/ProjectAware.h @@ -23,11 +23,11 @@ using IndexFactory = std::function( const Config::ExternalIndexSpec &, AsyncTaskRunner &)>; -/// Returns an index that answers queries using external indices. IndexGenerator -/// can be used to customize how to generate an index from an external source. -/// The default implementation loads the index asynchronously on the -/// AsyncTaskRunner. The index will appear empty until loaded. -std::unique_ptr createProjectAwareIndex(IndexFactory = nullptr); +/// Returns an index that answers queries using external indices. IndexFactory +/// specifies how to generate an index from an external source. +/// IndexFactory must be injected because this code cannot depend on the remote +/// index client. +std::unique_ptr createProjectAwareIndex(IndexFactory); } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/index/ProjectAware.cpp b/clang-tools-extra/clangd/index/ProjectAware.cpp --- a/clang-tools-extra/clangd/index/ProjectAware.cpp +++ b/clang-tools-extra/clangd/index/ProjectAware.cpp @@ -15,7 +15,6 @@ #include "index/Serialization.h" #include "index/Symbol.h" #include "index/SymbolID.h" -#include "index/remote/Client.h" #include "support/Logger.h" #include "support/Threading.h" #include "support/Trace.h" @@ -124,33 +123,11 @@ Entry.first->getSecond() = Gen(External, Tasks); return Entry.first->second.get(); } - -std::unique_ptr -defaultFactory(const Config::ExternalIndexSpec &External, - AsyncTaskRunner &Tasks) { - switch (External.Kind) { - case Config::ExternalIndexSpec::Server: - log("Associating {0} with remote index at {1}.", External.MountPoint, - External.Location); - return remote::getClient(External.Location, External.MountPoint); - case Config::ExternalIndexSpec::File: - log("Associating {0} with monolithic index at {1}.", External.MountPoint, - External.Location); - auto NewIndex = std::make_unique(std::make_unique()); - Tasks.runAsync("Load-index:" + External.Location, - [File = External.Location, PlaceHolder = NewIndex.get()] { - if (auto Idx = loadIndex(File, /*UseDex=*/true)) - PlaceHolder->reset(std::move(Idx)); - }); - return std::move(NewIndex); - } - llvm_unreachable("Invalid ExternalIndexKind."); -} } // namespace std::unique_ptr createProjectAwareIndex(IndexFactory Gen) { - return std::make_unique(Gen ? std::move(Gen) - : defaultFactory); + assert(Gen); + return std::make_unique(std::move(Gen)); } } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp --- a/clang-tools-extra/clangd/tool/ClangdMain.cpp +++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -13,6 +13,9 @@ #include "Protocol.h" #include "Transport.h" #include "index/Background.h" +#include "index/Index.h" +#include "index/Merge.h" +#include "index/ProjectAware.h" #include "index/Serialization.h" #include "index/remote/Client.h" #include "refactor/Rename.h" @@ -40,6 +43,7 @@ #include #include #include +#include #ifndef _WIN32 #include @@ -551,6 +555,27 @@ const char TestScheme::TestDir[] = "/clangd-test"; #endif +std::unique_ptr +loadExternalIndex(const Config::ExternalIndexSpec &External, + AsyncTaskRunner &Tasks) { + switch (External.Kind) { + case Config::ExternalIndexSpec::Server: + log("Associating {0} with remote index at {1}.", External.MountPoint, + External.Location); + return remote::getClient(External.Location, External.MountPoint); + case Config::ExternalIndexSpec::File: + log("Associating {0} with monolithic index at {1}.", External.MountPoint, + External.Location); + auto NewIndex = std::make_unique(std::make_unique()); + Tasks.runAsync("Load-index:" + External.Location, + [File = External.Location, PlaceHolder = NewIndex.get()] { + if (auto Idx = loadIndex(File, /*UseDex=*/true)) + PlaceHolder->reset(std::move(Idx)); + }); + return std::move(NewIndex); + } + llvm_unreachable("Invalid ExternalIndexKind."); +} } // namespace } // namespace clangd } // namespace clang @@ -726,6 +751,7 @@ Opts.ResourceDir = ResourceDir; Opts.BuildDynamicSymbolIndex = EnableIndex; Opts.CollectMainFileRefs = CollectMainFileRefs; + std::vector> IdxStack; std::unique_ptr StaticIdx; std::future AsyncIndexLoad; // Block exit while loading the index. if (EnableIndex && !IndexFile.empty()) { @@ -757,7 +783,15 @@ } #endif Opts.BackgroundIndex = EnableBackgroundIndex; - Opts.StaticIndex = StaticIdx.get(); + auto PAI = createProjectAwareIndex(loadExternalIndex); + if (StaticIdx) { + IdxStack.emplace_back(std::move(StaticIdx)); + IdxStack.emplace_back( + std::make_unique(PAI.get(), IdxStack.back().get())); + Opts.StaticIndex = IdxStack.back().get(); + } else { + Opts.StaticIndex = PAI.get(); + } Opts.AsyncThreadsCount = WorkerThreadsCount; Opts.BuildRecoveryAST = RecoveryAST; Opts.PreserveRecoveryASTType = RecoveryASTType;