diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h --- a/clang-tools-extra/clangd/ClangdServer.h +++ b/clang-tools-extra/clangd/ClangdServer.h @@ -114,6 +114,8 @@ /// If true, ClangdServer automatically indexes files in the current project /// on background threads. The index is stored in the project root. bool BackgroundIndex = false; + /// Path to force the disk storage of the index cache + llvm::Optional BackgroundIndexCachePath; /// If set, use this index to augment code completion results. SymbolIndex *StaticIndex = nullptr; diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -188,7 +188,7 @@ BackgroundIdx = std::make_unique( TFS, CDB, BackgroundIndexStorage::createDiskBackedStorageFactory( - [&CDB](llvm::StringRef File) { return CDB.getProjectInfo(File); }), + [&CDB](llvm::StringRef File) { return CDB.getProjectInfo(File); }, Opts.BackgroundIndexCachePath), std::move(BGOpts)); AddIndex(BackgroundIdx.get()); } diff --git a/clang-tools-extra/clangd/index/Background.h b/clang-tools-extra/clangd/index/Background.h --- a/clang-tools-extra/clangd/index/Background.h +++ b/clang-tools-extra/clangd/index/Background.h @@ -62,7 +62,8 @@ // CDBDirectory is the first directory containing a CDB in parent directories // of a file, or user cache directory if none was found, e.g. stdlib headers. static Factory createDiskBackedStorageFactory( - std::function(PathRef)> GetProjectInfo); + std::function(PathRef)> GetProjectInfo, + llvm::Optional BackgroundIndexCachePath); }; // A priority queue of tasks which can be run on (external) worker threads. diff --git a/clang-tools-extra/clangd/index/BackgroundIndexStorage.cpp b/clang-tools-extra/clangd/index/BackgroundIndexStorage.cpp --- a/clang-tools-extra/clangd/index/BackgroundIndexStorage.cpp +++ b/clang-tools-extra/clangd/index/BackgroundIndexStorage.cpp @@ -100,9 +100,11 @@ class DiskBackedIndexStorageManager { public: DiskBackedIndexStorageManager( - std::function(PathRef)> GetProjectInfo) + std::function(PathRef)> GetProjectInfo, + llvm::Optional BackgroundDiskCachePath) : IndexStorageMapMu(std::make_unique()), - GetProjectInfo(std::move(GetProjectInfo)) { + GetProjectInfo(std::move(GetProjectInfo)), + BackgroundDiskCachePath(BackgroundDiskCachePath) { llvm::SmallString<128> FallbackDir; if (llvm::sys::path::cache_directory(FallbackDir)) llvm::sys::path::append(FallbackDir, "clangd", "index"); @@ -113,7 +115,12 @@ BackgroundIndexStorage *operator()(PathRef File) { std::lock_guard Lock(*IndexStorageMapMu); llvm::SmallString<128> StorageDir(FallbackDir); - if (auto PI = GetProjectInfo(File)) { + if (BackgroundDiskCachePath && + !BackgroundDiskCachePath.getValue().empty()) { + StorageDir = BackgroundDiskCachePath.getValue(); + llvm::sys::path::append(StorageDir, ".cache", "clangd", "index"); + + } else if (auto PI = GetProjectInfo(File)) { StorageDir = PI->SourceRoot; llvm::sys::path::append(StorageDir, ".cache", "clangd", "index"); } @@ -138,14 +145,17 @@ std::unique_ptr IndexStorageMapMu; std::function(PathRef)> GetProjectInfo; + llvm::Optional BackgroundDiskCachePath; }; } // namespace BackgroundIndexStorage::Factory BackgroundIndexStorage::createDiskBackedStorageFactory( - std::function(PathRef)> GetProjectInfo) { - return DiskBackedIndexStorageManager(std::move(GetProjectInfo)); + std::function(PathRef)> GetProjectInfo, + llvm::Optional BackgroundIndexCachePath) { + return DiskBackedIndexStorageManager(std::move(GetProjectInfo), + std::move(BackgroundIndexCachePath)); } } // namespace clangd 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 @@ -339,6 +339,14 @@ Hidden, }; +opt BackgroundIndexCachePath{ + "background-index-storage", + cat(Misc), + desc("The path to store the index files generated by background indexing"), + init(""), + Hidden +}; + opt Test{ "lit-test", cat(Misc), @@ -830,6 +838,7 @@ #endif Opts.BackgroundIndex = EnableBackgroundIndex; Opts.ReferencesLimit = ReferencesLimit; + Opts.BackgroundIndexCachePath = BackgroundIndexCachePath; auto PAI = createProjectAwareIndex(loadExternalIndex, Sync); if (StaticIdx) { IdxStack.emplace_back(std::move(StaticIdx)); diff --git a/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp b/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp --- a/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp +++ b/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp @@ -161,6 +161,30 @@ QName("bar"), QName("bar::one"))); } +TEST_F(BackgroundIndexTest, StoreIndexedFilesInCustomPath){ + + OverlayCDB CDB(/*Base=*/nullptr); + auto DiskStorage = BackgroundIndexStorage::createDiskBackedStorageFactory( + [&CDB](llvm::StringRef File) { + return CDB.getProjectInfo(File); + }, + testing::TempDir() + ); + + auto *Result = DiskStorage("root/A.cc"); + IndexFileIn ShardIn{ + SymbolSlab{}, + RefSlab{}, + RelationSlab{}, + IncludeGraph{}, + tooling::CompileCommand{} + }; + IndexFileOut Shard{ShardIn}; + auto Result2 = Result->storeShard("root/A.cc", Shard); + + ASSERT_TRUE(Result); + ASSERT_FALSE(llvm::errorToBool(std::move(Result2))); +} TEST_F(BackgroundIndexTest, IndexTwoFiles) { MockFS FS; // a.h yields different symbols when included by A.cc vs B.cc.