diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h --- a/clang-tools-extra/clangd/ClangdLSPServer.h +++ b/clang-tools-extra/clangd/ClangdLSPServer.h @@ -41,7 +41,7 @@ /// for compile_commands.json in all parent directories of each file. /// If UseDirBasedCDB is false, compile commands are not read from disk. // FIXME: Clean up signature around CDBs. - ClangdLSPServer(Transport &Transp, const FileSystemProvider &FSProvider, + ClangdLSPServer(Transport &Transp, const ThreadsafeFS &FSProvider, const clangd::CodeCompleteOptions &CCOpts, const clangd::RenameOptions &RenameOpts, llvm::Optional CompileCommandsDir, bool UseDirBasedCDB, @@ -207,7 +207,7 @@ notify("$/progress", Params); } - const FileSystemProvider &FSProvider; + const ThreadsafeFS &FSProvider; /// Options used for code completion clangd::CodeCompleteOptions CCOpts; /// Options used for rename. diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -1340,7 +1340,7 @@ } ClangdLSPServer::ClangdLSPServer( - class Transport &Transp, const FileSystemProvider &FSProvider, + class Transport &Transp, const ThreadsafeFS &FSProvider, const clangd::CodeCompleteOptions &CCOpts, const clangd::RenameOptions &RenameOpts, llvm::Optional CompileCommandsDir, bool UseDirBasedCDB, 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 @@ -23,8 +23,8 @@ #include "refactor/Rename.h" #include "refactor/Tweak.h" #include "support/Cancellation.h" -#include "support/FSProvider.h" #include "support/Function.h" +#include "support/ThreadsafeFS.h" #include "clang/Tooling/CompilationDatabase.h" #include "clang/Tooling/Core/Replacement.h" #include "llvm/ADT/FunctionExtras.h" @@ -172,7 +172,7 @@ /// those arguments for subsequent reparses. However, ClangdServer will check /// if compilation arguments changed on calls to forceReparse(). ClangdServer(const GlobalCompilationDatabase &CDB, - const FileSystemProvider &FSProvider, const Options &Opts, + const ThreadsafeFS &FSProvider, const Options &Opts, Callbacks *Callbacks = nullptr); /// Add a \p File to the list of tracked C++ files or update the contents if @@ -330,7 +330,7 @@ formatCode(llvm::StringRef Code, PathRef File, ArrayRef Ranges); - const FileSystemProvider &FSProvider; + const ThreadsafeFS &FSProvider; Path ResourceDir; // The index used to look up symbols. This could be: 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 @@ -27,6 +27,7 @@ #include "refactor/Tweak.h" #include "support/Logger.h" #include "support/Markup.h" +#include "support/ThreadsafeFS.h" #include "support/Trace.h" #include "clang/Format/Format.h" #include "clang/Frontend/CompilerInstance.h" @@ -129,8 +130,8 @@ } ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB, - const FileSystemProvider &FSProvider, - const Options &Opts, Callbacks *Callbacks) + const ThreadsafeFS &FSProvider, const Options &Opts, + Callbacks *Callbacks) : FSProvider(FSProvider), DynamicIdx(Opts.BuildDynamicSymbolIndex ? new FileIndex(Opts.HeavyweightDynamicSymbolIndex) @@ -183,8 +184,8 @@ Opts.ClangTidyOpts = tidy::ClangTidyOptions::getDefaults(); // FIXME: call tidy options builder on the worker thread, it can do IO. if (GetClangTidyOptions) - Opts.ClangTidyOpts = GetClangTidyOptions( - *FSProvider.getFileSystem(/*CWD=*/llvm::None), File); + Opts.ClangTidyOpts = + GetClangTidyOptions(*FSProvider.view(/*CWD=*/llvm::None), File); Opts.SuggestMissingIncludes = SuggestMissingIncludes; // Compile command is set asynchronously during update, as it can be slow. @@ -318,9 +319,9 @@ llvm::Expected CursorPos = positionToOffset(Code, Pos); if (!CursorPos) return CursorPos.takeError(); - auto Style = format::getStyle( - format::DefaultFormatStyle, File, format::DefaultFallbackStyle, Code, - FSProvider.getFileSystem(/*CWD=*/llvm::None).get()); + auto Style = format::getStyle(format::DefaultFormatStyle, File, + format::DefaultFallbackStyle, Code, + FSProvider.view(/*CWD=*/llvm::None).get()); if (!Style) return Style.takeError(); @@ -549,7 +550,7 @@ // 2) if 1) fails, we use the AST&Index approach, it is slower but supports // different code layout. if (auto CorrespondingFile = getCorrespondingHeaderOrSource( - std::string(Path), FSProvider.getFileSystem(llvm::None))) + std::string(Path), FSProvider.view(llvm::None))) return CB(std::move(CorrespondingFile)); auto Action = [Path = Path.str(), CB = std::move(CB), this](llvm::Expected InpAST) mutable { diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp --- a/clang-tools-extra/clangd/CodeComplete.cpp +++ b/clang-tools-extra/clangd/CodeComplete.cpp @@ -36,9 +36,9 @@ #include "index/Index.h" #include "index/Symbol.h" #include "index/SymbolOrigin.h" -#include "support/FSProvider.h" #include "support/Logger.h" #include "support/Threading.h" +#include "support/ThreadsafeFS.h" #include "support/Trace.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" @@ -1113,7 +1113,7 @@ // NOTE: we must call BeginSourceFile after prepareCompilerInstance. Otherwise // the remapped buffers do not get freed. llvm::IntrusiveRefCntPtr VFS = - Input.ParseInput.FSProvider->getFileSystem( + Input.ParseInput.FSProvider->view( Input.ParseInput.CompileCommand.Directory); if (Input.Preamble.StatCache) VFS = Input.Preamble.StatCache->getConsumingFS(std::move(VFS)); @@ -1364,7 +1364,7 @@ } CodeCompleteResult runWithoutSema(llvm::StringRef Content, size_t Offset, - const FileSystemProvider &FSProvider) && { + const ThreadsafeFS &FSProvider) && { trace::Span Tracer("CodeCompleteWithoutSema"); // Fill in fields normally set by runWithSema() HeuristicPrefix = guessCompletionPrefix(Content, Offset); diff --git a/clang-tools-extra/clangd/Compiler.h b/clang-tools-extra/clangd/Compiler.h --- a/clang-tools-extra/clangd/Compiler.h +++ b/clang-tools-extra/clangd/Compiler.h @@ -18,7 +18,7 @@ #include "../clang-tidy/ClangTidyOptions.h" #include "GlobalCompilationDatabase.h" #include "index/Index.h" -#include "support/FSProvider.h" +#include "support/ThreadsafeFS.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/PrecompiledPreamble.h" #include "clang/Tooling/CompilationDatabase.h" @@ -46,7 +46,7 @@ /// Information required to run clang, e.g. to parse AST or do code completion. struct ParseInputs { tooling::CompileCommand CompileCommand; - const FileSystemProvider *FSProvider; + const ThreadsafeFS *FSProvider; std::string Contents; // Version identifier for Contents, provided by the client and opaque to us. std::string Version = "null"; diff --git a/clang-tools-extra/clangd/Compiler.cpp b/clang-tools-extra/clangd/Compiler.cpp --- a/clang-tools-extra/clangd/Compiler.cpp +++ b/clang-tools-extra/clangd/Compiler.cpp @@ -48,7 +48,7 @@ for (const auto &S : Inputs.CompileCommand.CommandLine) ArgStrs.push_back(S.c_str()); - auto VFS = Inputs.FSProvider->getFileSystem(Inputs.CompileCommand.Directory); + auto VFS = Inputs.FSProvider->view(Inputs.CompileCommand.Directory); llvm::IntrusiveRefCntPtr CommandLineDiagsEngine = CompilerInstance::createDiagnostics(new DiagnosticOptions, &D, false); std::unique_ptr CI = createInvocationFromCommandLine( diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp --- a/clang-tools-extra/clangd/ParsedAST.cpp +++ b/clang-tools-extra/clangd/ParsedAST.cpp @@ -249,7 +249,7 @@ trace::Span Tracer("BuildAST"); SPAN_ATTACH(Tracer, "File", Filename); - auto VFS = Inputs.FSProvider->getFileSystem(Inputs.CompileCommand.Directory); + auto VFS = Inputs.FSProvider->view(Inputs.CompileCommand.Directory); if (Preamble && Preamble->StatCache) VFS = Preamble->StatCache->getConsumingFS(std::move(VFS)); diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp --- a/clang-tools-extra/clangd/Preamble.cpp +++ b/clang-tools-extra/clangd/Preamble.cpp @@ -10,8 +10,8 @@ #include "Compiler.h" #include "Headers.h" #include "SourceCode.h" -#include "support/FSProvider.h" #include "support/Logger.h" +#include "support/ThreadsafeFS.h" #include "support/Trace.h" #include "clang/AST/DeclTemplate.h" #include "clang/Basic/Diagnostic.h" @@ -234,12 +234,12 @@ // than vfs::FileSystem, that way we can just use ParseInputs without this // hack. auto GetFSProvider = [](llvm::IntrusiveRefCntPtr FS) { - class VFSProvider : public FileSystemProvider { + class VFSProvider : public ThreadsafeFS { public: VFSProvider(llvm::IntrusiveRefCntPtr FS) : VFS(std::move(FS)) {} llvm::IntrusiveRefCntPtr - getFileSystem(llvm::NoneType) const override { + view(llvm::NoneType) const override { return VFS; } @@ -358,7 +358,7 @@ CI.getPreprocessorOpts().WriteCommentListToPCH = false; CppFilePreambleCallbacks SerializedDeclsCollector(FileName, PreambleCallback); - auto VFS = Inputs.FSProvider->getFileSystem(Inputs.CompileCommand.Directory); + auto VFS = Inputs.FSProvider->view(Inputs.CompileCommand.Directory); llvm::SmallString<32> AbsFileName(FileName); VFS->makeAbsolute(AbsFileName); auto StatCache = std::make_unique(AbsFileName); @@ -395,7 +395,7 @@ llvm::MemoryBuffer::getMemBuffer(Inputs.Contents, FileName); auto Bounds = ComputePreambleBounds(*CI.getLangOpts(), ContentsBuffer.get(), 0); - auto VFS = Inputs.FSProvider->getFileSystem(Inputs.CompileCommand.Directory); + auto VFS = Inputs.FSProvider->view(Inputs.CompileCommand.Directory); return compileCommandsAreEqual(Inputs.CompileCommand, Preamble.CompileCommand) && Preamble.Preamble.CanReuse(CI, ContentsBuffer.get(), Bounds, @@ -423,7 +423,7 @@ SPAN_ATTACH(Tracer, "File", FileName); assert(llvm::sys::path::is_absolute(FileName) && "relative FileName!"); auto VFS = Baseline.StatCache->getConsumingFS( - Modified.FSProvider->getFileSystem(/*CWD=*/llvm::None)); + Modified.FSProvider->view(/*CWD=*/llvm::None)); // First scan preprocessor directives in Baseline and Modified. These will be // used to figure out newly added directives in Modified. Scanning can fail, // the code just bails out and creates an empty patch in such cases, as: diff --git a/clang-tools-extra/clangd/SourceCode.h b/clang-tools-extra/clangd/SourceCode.h --- a/clang-tools-extra/clangd/SourceCode.h +++ b/clang-tools-extra/clangd/SourceCode.h @@ -15,7 +15,7 @@ #include "Protocol.h" #include "support/Context.h" -#include "support/FSProvider.h" +#include "support/ThreadsafeFS.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceLocation.h" @@ -168,7 +168,7 @@ /// though the latter may have been overridden in main()! format::FormatStyle getFormatStyleForFile(llvm::StringRef File, llvm::StringRef Content, - const FileSystemProvider &FSProvider); + const ThreadsafeFS &FSProvider); /// Cleanup and format the given replacements. llvm::Expected diff --git a/clang-tools-extra/clangd/SourceCode.cpp b/clang-tools-extra/clangd/SourceCode.cpp --- a/clang-tools-extra/clangd/SourceCode.cpp +++ b/clang-tools-extra/clangd/SourceCode.cpp @@ -12,8 +12,8 @@ #include "Protocol.h" #include "refactor/Tweak.h" #include "support/Context.h" -#include "support/FSProvider.h" #include "support/Logger.h" +#include "support/Threading.h" #include "clang/AST/ASTContext.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceLocation.h" @@ -575,12 +575,12 @@ return digest(Content); } -format::FormatStyle -getFormatStyleForFile(llvm::StringRef File, llvm::StringRef Content, - const FileSystemProvider &FSProvider) { - auto Style = format::getStyle( - format::DefaultFormatStyle, File, format::DefaultFallbackStyle, Content, - FSProvider.getFileSystem(/*CWD=*/llvm::None).get()); +format::FormatStyle getFormatStyleForFile(llvm::StringRef File, + llvm::StringRef Content, + const ThreadsafeFS &FSProvider) { + auto Style = format::getStyle(format::DefaultFormatStyle, File, + format::DefaultFallbackStyle, Content, + FSProvider.view(/*CWD=*/llvm::None).get()); if (!Style) { log("getStyle() failed for file {0}: {1}. Fallback is LLVM style.", File, Style.takeError()); diff --git a/clang-tools-extra/clangd/fuzzer/clangd-fuzzer.cpp b/clang-tools-extra/clangd/fuzzer/clangd-fuzzer.cpp --- a/clang-tools-extra/clangd/fuzzer/clangd-fuzzer.cpp +++ b/clang-tools-extra/clangd/fuzzer/clangd-fuzzer.cpp @@ -16,7 +16,7 @@ #include "ClangdServer.h" #include "CodeComplete.h" #include "refactor/Rename.h" -#include "support/FSProvider.h" +#include "support/ThreadsafeFS.h" #include #include @@ -31,7 +31,7 @@ auto Transport = newJSONTransport(In, llvm::nulls(), /*InMirror=*/nullptr, /*Pretty=*/false, /*Style=*/JSONStreamStyle::Delimited); - RealFileSystemProvider FS; + RealThreadsafeFS FS; CodeCompleteOptions CCOpts; CCOpts.EnableSnippets = false; ClangdServer::Options Opts; 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 @@ -16,9 +16,9 @@ #include "index/Index.h" #include "index/Serialization.h" #include "support/Context.h" -#include "support/FSProvider.h" #include "support/Path.h" #include "support/Threading.h" +#include "support/ThreadsafeFS.h" #include "clang/Tooling/CompilationDatabase.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/Threading.h" @@ -132,7 +132,7 @@ /// rebuilt periodically (one per \p BuildIndexPeriodMs); otherwise, index is /// rebuilt for each indexed file. BackgroundIndex( - Context BackgroundContext, const FileSystemProvider &, + Context BackgroundContext, const ThreadsafeFS &, const GlobalCompilationDatabase &CDB, BackgroundIndexStorage::Factory IndexStorageFactory, size_t ThreadPoolSize = 0, // 0 = use all hardware threads @@ -178,7 +178,7 @@ bool HadErrors); // configuration - const FileSystemProvider &FSProvider; + const ThreadsafeFS &FSProvider; const GlobalCompilationDatabase &CDB; Context BackgroundContext; diff --git a/clang-tools-extra/clangd/index/Background.cpp b/clang-tools-extra/clangd/index/Background.cpp --- a/clang-tools-extra/clangd/index/Background.cpp +++ b/clang-tools-extra/clangd/index/Background.cpp @@ -22,10 +22,10 @@ #include "index/Serialization.h" #include "index/SymbolCollector.h" #include "support/Context.h" -#include "support/FSProvider.h" #include "support/Logger.h" #include "support/Path.h" #include "support/Threading.h" +#include "support/ThreadsafeFS.h" #include "support/Trace.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" @@ -90,7 +90,7 @@ } // namespace BackgroundIndex::BackgroundIndex( - Context BackgroundContext, const FileSystemProvider &FSProvider, + Context BackgroundContext, const ThreadsafeFS &FSProvider, const GlobalCompilationDatabase &CDB, BackgroundIndexStorage::Factory IndexStorageFactory, size_t ThreadPoolSize, std::function OnProgress) @@ -244,7 +244,7 @@ SPAN_ATTACH(Tracer, "file", Cmd.Filename); auto AbsolutePath = getAbsolutePath(Cmd); - auto FS = FSProvider.getFileSystem(Cmd.Directory); + auto FS = FSProvider.view(Cmd.Directory); auto Buf = FS->getBufferForFile(AbsolutePath); if (!Buf) return llvm::errorCodeToError(Buf.getError()); @@ -381,7 +381,7 @@ Rebuilder.loadedShard(LoadedShards); Rebuilder.doneLoading(); - auto FS = FSProvider.getFileSystem(/*CWD=*/llvm::None); + auto FS = FSProvider.view(/*CWD=*/llvm::None); llvm::DenseSet TUsToIndex; // We'll accept data from stale shards, but ensure the files get reindexed // soon. diff --git a/clang-tools-extra/clangd/support/CMakeLists.txt b/clang-tools-extra/clangd/support/CMakeLists.txt --- a/clang-tools-extra/clangd/support/CMakeLists.txt +++ b/clang-tools-extra/clangd/support/CMakeLists.txt @@ -19,11 +19,11 @@ add_clang_library(clangdSupport Cancellation.cpp Context.cpp - FSProvider.cpp Logger.cpp Markup.cpp Shutdown.cpp Threading.cpp + ThreadsafeFS.cpp Trace.cpp LINK_LIBS diff --git a/clang-tools-extra/clangd/support/FSProvider.h b/clang-tools-extra/clangd/support/FSProvider.h deleted file mode 100644 --- a/clang-tools-extra/clangd/support/FSProvider.h +++ /dev/null @@ -1,51 +0,0 @@ -//===--- FSProvider.h - VFS provider for ClangdServer ------------*- C++-*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_FSPROVIDER_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_FSPROVIDER_H - -#include "Path.h" -#include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/None.h" -#include "llvm/ADT/Optional.h" -#include "llvm/Support/VirtualFileSystem.h" -#include - -namespace clang { -namespace clangd { - -// Wrapper for vfs::FileSystem for use in multithreaded programs like clangd. -// As FileSystem is not threadsafe, concurrent threads must each obtain one. -class FileSystemProvider { -public: - virtual ~FileSystemProvider() = default; - /// Called by ClangdServer to obtain a vfs::FileSystem to be used for parsing. - /// Context::current() will be the context passed to the clang entrypoint, - /// such as addDocument(), and will also be propagated to result callbacks. - /// Embedders may use this to isolate filesystem accesses. - /// Initial working directory is arbitrary. - virtual llvm::IntrusiveRefCntPtr - getFileSystem(llvm::NoneType CWD) const = 0; - - /// As above, except it will try to set current working directory to \p CWD. - /// This is an overload instead of an optional to make implicit string -> - /// StringRef conversion possible. - virtual llvm::IntrusiveRefCntPtr - getFileSystem(PathRef CWD) const; -}; - -class RealFileSystemProvider : public FileSystemProvider { -public: - llvm::IntrusiveRefCntPtr - getFileSystem(llvm::NoneType) const override; -}; - -} // namespace clangd -} // namespace clang - -#endif diff --git a/clang-tools-extra/clangd/support/ThreadsafeFS.h b/clang-tools-extra/clangd/support/ThreadsafeFS.h new file mode 100644 --- /dev/null +++ b/clang-tools-extra/clangd/support/ThreadsafeFS.h @@ -0,0 +1,52 @@ +//===--- ThreadsafeFS.h ------------------------------------------*- C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_THREADSAFEFS_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_THREADSAFEFS_H + +#include "Path.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" +#include "llvm/Support/VirtualFileSystem.h" +#include + +namespace clang { +namespace clangd { + +/// Wrapper for vfs::FileSystem for use in multithreaded programs like clangd. +/// As FileSystem is not threadsafe, concurrent threads must each obtain one. +/// Implementations may choose to depend on Context::current() e.g. to implement +/// snapshot semantics. clangd will not create vfs::FileSystems for use in +/// different contexts, so either ThreadsafeFS::view or the returned FS may +/// contain this logic. +class ThreadsafeFS { +public: + virtual ~ThreadsafeFS() = default; + + /// Obtain a vfs::FileSystem with an arbitrary initial working directory. + virtual llvm::IntrusiveRefCntPtr + view(llvm::NoneType CWD) const = 0; + + /// Obtain a vfs::FileSystem with a specified working directory. + /// If the working directory can't be set (e.g. doesn't exist), logs and + /// returns the FS anyway. + virtual llvm::IntrusiveRefCntPtr + view(PathRef CWD) const; +}; + +class RealThreadsafeFS : public ThreadsafeFS { +public: + llvm::IntrusiveRefCntPtr + view(llvm::NoneType) const override; +}; + +} // namespace clangd +} // namespace clang + +#endif diff --git a/clang-tools-extra/clangd/support/FSProvider.cpp b/clang-tools-extra/clangd/support/ThreadsafeFS.cpp rename from clang-tools-extra/clangd/support/FSProvider.cpp rename to clang-tools-extra/clangd/support/ThreadsafeFS.cpp --- a/clang-tools-extra/clangd/support/FSProvider.cpp +++ b/clang-tools-extra/clangd/support/ThreadsafeFS.cpp @@ -1,4 +1,4 @@ -//===--- FSProvider.cpp - VFS provider for ClangdServer -------------------===// +//===--- ThreadsafeFS.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "support/FSProvider.h" +#include "support/ThreadsafeFS.h" #include "Logger.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" @@ -75,15 +75,15 @@ } // namespace llvm::IntrusiveRefCntPtr -FileSystemProvider::getFileSystem(PathRef CWD) const { - auto FS = getFileSystem(/*CWD=*/llvm::None); +ThreadsafeFS::view(PathRef CWD) const { + auto FS = view(llvm::None); if (auto EC = FS->setCurrentWorkingDirectory(CWD)) elog("VFS: failed to set CWD to {0}: {1}", CWD, EC.message()); return FS; } llvm::IntrusiveRefCntPtr -clang::clangd::RealFileSystemProvider::getFileSystem(llvm::NoneType) const { +RealThreadsafeFS::view(llvm::NoneType) const { // Avoid using memory-mapped files. // FIXME: Try to use a similar approach in Sema instead of relying on // propagation of the 'isVolatile' flag through all layers. 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 @@ -17,6 +17,7 @@ #include "refactor/Rename.h" #include "support/Path.h" #include "support/Shutdown.h" +#include "support/ThreadsafeFS.h" #include "support/Trace.h" #include "clang/Basic/Version.h" #include "clang/Format/Format.h" @@ -675,7 +676,7 @@ CCOpts.AllScopes = AllScopesCompletion; CCOpts.RunParser = CodeCompletionParse; - RealFileSystemProvider FSProvider; + RealThreadsafeFS FSProvider; // Initialize and run ClangdLSPServer. // Change stdin to binary to not lose \r\n on windows. llvm::sys::ChangeStdinToBinary(); @@ -719,7 +720,7 @@ tidy::ClangTidyGlobalOptions(), /* Default */ EmptyDefaults, /* Override */ OverrideClangTidyOptions, - FSProvider.getFileSystem(/*CWD=*/llvm::None)); + FSProvider.view(/*CWD=*/llvm::None)); Opts.GetClangTidyOptions = [&](llvm::vfs::FileSystem &, llvm::StringRef File) { // This function must be thread-safe and tidy option providers are not. 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 @@ -86,7 +86,7 @@ }; TEST_F(BackgroundIndexTest, NoCrashOnErrorFile) { - MockFSProvider FS; + MockFS FS; FS.Files[testPath("root/A.cc")] = "error file"; llvm::StringMap Storage; size_t CacheHits = 0; @@ -105,7 +105,7 @@ } TEST_F(BackgroundIndexTest, IndexTwoFiles) { - MockFSProvider FS; + MockFS FS; // a.h yields different symbols when included by A.cc vs B.cc. FS.Files[testPath("root/A.h")] = R"cpp( void common(); @@ -175,7 +175,7 @@ } TEST_F(BackgroundIndexTest, ShardStorageTest) { - MockFSProvider FS; + MockFS FS; FS.Files[testPath("root/A.h")] = R"cpp( void common(); void f_b(); @@ -246,7 +246,7 @@ } TEST_F(BackgroundIndexTest, DirectIncludesTest) { - MockFSProvider FS; + MockFS FS; FS.Files[testPath("root/B.h")] = ""; FS.Files[testPath("root/A.h")] = R"cpp( #include "B.h" @@ -297,7 +297,7 @@ } TEST_F(BackgroundIndexTest, ShardStorageLoad) { - MockFSProvider FS; + MockFS FS; FS.Files[testPath("root/A.h")] = R"cpp( void common(); void f_b(); @@ -368,7 +368,7 @@ } TEST_F(BackgroundIndexTest, ShardStorageEmptyFile) { - MockFSProvider FS; + MockFS FS; FS.Files[testPath("root/A.h")] = R"cpp( void common(); void f_b(); @@ -436,7 +436,7 @@ } TEST_F(BackgroundIndexTest, NoDotsInAbsPath) { - MockFSProvider FS; + MockFS FS; llvm::StringMap Storage; size_t CacheHits = 0; MemoryShardStorage MSS(Storage, CacheHits); @@ -467,7 +467,7 @@ } TEST_F(BackgroundIndexTest, UncompilableFiles) { - MockFSProvider FS; + MockFS FS; llvm::StringMap Storage; size_t CacheHits = 0; MemoryShardStorage MSS(Storage, CacheHits); @@ -530,7 +530,7 @@ } TEST_F(BackgroundIndexTest, CmdLineHash) { - MockFSProvider FS; + MockFS FS; llvm::StringMap Storage; size_t CacheHits = 0; MemoryShardStorage MSS(Storage, CacheHits); diff --git a/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp b/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp --- a/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp +++ b/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp @@ -63,7 +63,7 @@ stop(); } - MockFSProvider FS; + MockFS FS; CodeCompleteOptions CCOpts; RenameOptions RenameOpts; ClangdServer::Options Opts = ClangdServer::optsForTest(); diff --git a/clang-tools-extra/clangd/unittests/ClangdTests.cpp b/clang-tools-extra/clangd/unittests/ClangdTests.cpp --- a/clang-tools-extra/clangd/unittests/ClangdTests.cpp +++ b/clang-tools-extra/clangd/unittests/ClangdTests.cpp @@ -145,7 +145,7 @@ PathRef SourceFileRelPath, llvm::StringRef SourceContents, std::vector> ExtraFiles = {}, bool ExpectErrors = false) { - MockFSProvider FS; + MockFS FS; ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); @@ -198,7 +198,7 @@ } TEST_F(ClangdVFSTest, Reparse) { - MockFSProvider FS; + MockFS FS; ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); @@ -233,7 +233,7 @@ } TEST_F(ClangdVFSTest, ReparseOnHeaderChange) { - MockFSProvider FS; + MockFS FS; ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); @@ -272,9 +272,9 @@ TEST_F(ClangdVFSTest, PropagatesContexts) { static Key Secret; - struct FSProvider : public FileSystemProvider { + struct FSProvider : public ThreadsafeFS { IntrusiveRefCntPtr - getFileSystem(llvm::NoneType) const override { + view(llvm::NoneType) const override { Got = Context::current().getExisting(Secret); return buildTestFS({}); } @@ -302,7 +302,7 @@ TEST_F(ClangdVFSTest, PropagatesVersion) { MockCompilationDatabase CDB; - MockFSProvider FS; + MockFS FS; struct Callbacks : public ClangdServer::Callbacks { void onDiagnosticsReady(PathRef File, llvm::StringRef Version, std::vector Diagnostics) override { @@ -321,7 +321,7 @@ #ifdef LLVM_ON_UNIX TEST_F(ClangdVFSTest, SearchLibDir) { // Checks that searches for GCC installation is done through vfs. - MockFSProvider FS; + MockFS FS; ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; CDB.ExtraClangFlags.insert(CDB.ExtraClangFlags.end(), @@ -370,7 +370,7 @@ #endif // LLVM_ON_UNIX TEST_F(ClangdVFSTest, ForceReparseCompileCommand) { - MockFSProvider FS; + MockFS FS; ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); @@ -406,7 +406,7 @@ } TEST_F(ClangdVFSTest, ForceReparseCompileCommandDefines) { - MockFSProvider FS; + MockFS FS; ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); @@ -458,7 +458,7 @@ int hello; )cpp"); - MockFSProvider FS; + MockFS FS; MockCompilationDatabase CDB; MultipleErrorCheckingCallbacks DiagConsumer; ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); @@ -508,7 +508,7 @@ } TEST_F(ClangdVFSTest, FileStats) { - MockFSProvider FS; + MockFS FS; ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); @@ -544,7 +544,7 @@ } TEST_F(ClangdVFSTest, InvalidCompileCommand) { - MockFSProvider FS; + MockFS FS; ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; @@ -605,7 +605,7 @@ unsigned MaxColumnForFileRequests = 10; std::vector FilePaths; - MockFSProvider FS; + MockFS FS; for (unsigned I = 0; I < FilesCount; ++I) { std::string Name = std::string("Foo") + std::to_string(I) + ".cpp"; FS.Files[Name] = ""; @@ -839,7 +839,7 @@ )cpp"; auto FooCpp = testPath("foo.cpp"); - MockFSProvider FS; + MockFS FS; FS.Files[FooCpp] = ""; std::promise StartSecondPromise; @@ -856,7 +856,7 @@ } TEST_F(ClangdVFSTest, FormatCode) { - MockFSProvider FS; + MockFS FS; ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); @@ -885,7 +885,7 @@ } TEST_F(ClangdVFSTest, ChangedHeaderFromISystem) { - MockFSProvider FS; + MockFS FS; ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); @@ -924,13 +924,13 @@ // Check that running code completion doesn't stat() a bunch of files from the // preamble again. (They should be using the preamble's stat-cache) TEST(ClangdTests, PreambleVFSStatCache) { - class ListenStatsFSProvider : public FileSystemProvider { + class ListenStatsFSProvider : public ThreadsafeFS { public: ListenStatsFSProvider(llvm::StringMap &CountStats) : CountStats(CountStats) {} IntrusiveRefCntPtr - getFileSystem(llvm::NoneType) const override { + view(llvm::NoneType) const override { class ListenStatVFS : public llvm::vfs::ProxyFileSystem { public: ListenStatVFS(IntrusiveRefCntPtr FS, @@ -990,7 +990,7 @@ #endif TEST_F(ClangdVFSTest, FallbackWhenPreambleIsNotReady) { - MockFSProvider FS; + MockFS FS; ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); @@ -1036,7 +1036,7 @@ } TEST_F(ClangdVFSTest, FallbackWhenWaitingForCompileCommand) { - MockFSProvider FS; + MockFS FS; ErrorCheckingCallbacks DiagConsumer; // Returns compile command only when notified. class DelayedCompilationDatabase : public GlobalCompilationDatabase { @@ -1098,7 +1098,7 @@ // test as a workaround. #if !defined(__has_feature) || !__has_feature(address_sanitizer) TEST_F(ClangdVFSTest, TestStackOverflow) { - MockFSProvider FS; + MockFS FS; ErrorCheckingCallbacks DiagConsumer; MockCompilationDatabase CDB; ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer); diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp --- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -108,7 +108,7 @@ Opts.Index = OverrideIndex.get(); } - MockFSProvider FS; + MockFS FS; auto Inputs = TU.inputs(FS); Inputs.Opts.BuildRecoveryAST = true; Inputs.Opts.PreserveRecoveryASTType = true; @@ -149,7 +149,7 @@ Opts.Index = OverrideIndex.get(); } - MockFSProvider FS; + MockFS FS; Annotations Test(Text); ParseInputs ParseInput{tooling::CompileCommand(), &FS, Test.code().str()}; return codeComplete(FilePath, Test.point(), /*Preamble=*/nullptr, ParseInput, @@ -770,7 +770,7 @@ } TEST(CompletionTest, DynamicIndexIncludeInsertion) { - MockFSProvider FS; + MockFS FS; MockCompilationDatabase CDB; ClangdServer::Options Opts = ClangdServer::optsForTest(); Opts.BuildDynamicSymbolIndex = true; @@ -805,7 +805,7 @@ } TEST(CompletionTest, DynamicIndexMultiFile) { - MockFSProvider FS; + MockFS FS; MockCompilationDatabase CDB; auto Opts = ClangdServer::optsForTest(); Opts.BuildDynamicSymbolIndex = true; @@ -865,7 +865,7 @@ } TEST(CompletionTest, CommentsFromSystemHeaders) { - MockFSProvider FS; + MockFS FS; MockCompilationDatabase CDB; auto Opts = ClangdServer::optsForTest(); @@ -1057,7 +1057,7 @@ Index = memIndex(IndexSymbols); auto TU = TestTU::withCode(Text); - MockFSProvider FS; + MockFS FS; auto Inputs = TU.inputs(FS); Inputs.Index = Index.get(); Inputs.Opts.BuildRecoveryAST = true; @@ -1214,7 +1214,7 @@ TestTU TU; TU.Code = ""; IgnoreDiagnostics Diags; - MockFSProvider FS; + MockFS FS; auto Inputs = TU.inputs(FS); auto CI = buildCompilerInvocation(Inputs, Diags); ASSERT_TRUE(CI); @@ -1537,7 +1537,7 @@ } TEST(CompletionTest, DocumentationFromChangedFileCrash) { - MockFSProvider FS; + MockFS FS; auto FooH = testPath("foo.h"); auto FooCpp = testPath("foo.cpp"); FS.Files[FooH] = R"cpp( @@ -1632,7 +1632,7 @@ auto FooCpp = testPath("foo.cpp"); MockCompilationDatabase CDB; - MockFSProvider FS; + MockFS FS; FS.Files[FooCpp] = "// empty file"; ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); @@ -1761,7 +1761,7 @@ } TEST(CompletionTest, FixItForArrowToDot) { - MockFSProvider FS; + MockFS FS; MockCompilationDatabase CDB; CodeCompleteOptions Opts; @@ -1872,7 +1872,7 @@ } TEST(CompletionTest, CompletionTokenRange) { - MockFSProvider FS; + MockFS FS; MockCompilationDatabase CDB; TestTU TU; TU.AdditionalFiles["foo/abc/foo.h"] = ""; @@ -2037,7 +2037,7 @@ } TEST(SignatureHelpTest, DynamicIndexDocumentation) { - MockFSProvider FS; + MockFS FS; MockCompilationDatabase CDB; ClangdServer::Options Opts = ClangdServer::optsForTest(); Opts.BuildDynamicSymbolIndex = true; @@ -2209,7 +2209,7 @@ } TEST(CompletionTest, EnableSpeculativeIndexRequest) { - MockFSProvider FS; + MockFS FS; MockCompilationDatabase CDB; ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); diff --git a/clang-tools-extra/clangd/unittests/CompilerTests.cpp b/clang-tools-extra/clangd/unittests/CompilerTests.cpp --- a/clang-tools-extra/clangd/unittests/CompilerTests.cpp +++ b/clang-tools-extra/clangd/unittests/CompilerTests.cpp @@ -19,7 +19,7 @@ using testing::IsEmpty; TEST(BuildCompilerInvocation, DropsPCH) { - MockFSProvider FS; + MockFS FS; IgnoreDiagnostics Diags; TestTU TU; TU.AdditionalFiles["test.h.pch"] = ""; diff --git a/clang-tools-extra/clangd/unittests/FileIndexTests.cpp b/clang-tools-extra/clangd/unittests/FileIndexTests.cpp --- a/clang-tools-extra/clangd/unittests/FileIndexTests.cpp +++ b/clang-tools-extra/clangd/unittests/FileIndexTests.cpp @@ -272,7 +272,7 @@ PI.CompileCommand.Filename = FooCpp; PI.CompileCommand.CommandLine = {"clang", "-xc++", FooCpp}; - MockFSProvider FSProvider; + MockFS FSProvider; FSProvider.Files[FooCpp] = ""; FSProvider.Files[FooH] = R"cpp( namespace ns_in_header { diff --git a/clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp b/clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp --- a/clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp @@ -58,7 +58,7 @@ } protected: - MockFSProvider FSProvider; + MockFS FSProvider; MockCompilationDatabase CDB; ClangdServer Server; int Limit = 0; @@ -310,7 +310,7 @@ DocumentSymbolsTest() : Server(CDB, FSProvider, optsForTests()) {} protected: - MockFSProvider FSProvider; + MockFS FSProvider; MockCompilationDatabase CDB; ClangdServer Server; diff --git a/clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp b/clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp --- a/clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp +++ b/clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp @@ -12,6 +12,7 @@ #include "TestFS.h" #include "TestTU.h" #include "index/MemIndex.h" +#include "llvm/ADT/None.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -20,7 +21,7 @@ namespace { TEST(HeaderSourceSwitchTest, FileHeuristic) { - MockFSProvider FS; + MockFS FS; auto FooCpp = testPath("foo.cpp"); auto FooH = testPath("foo.h"); auto Invalid = testPath("main.cpp"); @@ -29,11 +30,11 @@ FS.Files[FooH]; FS.Files[Invalid]; Optional PathResult = - getCorrespondingHeaderOrSource(FooCpp, FS.getFileSystem()); + getCorrespondingHeaderOrSource(FooCpp, FS.view(llvm::None)); EXPECT_TRUE(PathResult.hasValue()); ASSERT_EQ(PathResult.getValue(), FooH); - PathResult = getCorrespondingHeaderOrSource(FooH, FS.getFileSystem()); + PathResult = getCorrespondingHeaderOrSource(FooH, FS.view(llvm::None)); EXPECT_TRUE(PathResult.hasValue()); ASSERT_EQ(PathResult.getValue(), FooCpp); @@ -44,7 +45,7 @@ FS.Files[FooC]; FS.Files[FooHH]; - PathResult = getCorrespondingHeaderOrSource(FooC, FS.getFileSystem()); + PathResult = getCorrespondingHeaderOrSource(FooC, FS.view(llvm::None)); EXPECT_TRUE(PathResult.hasValue()); ASSERT_EQ(PathResult.getValue(), FooHH); @@ -53,7 +54,7 @@ auto Foo2HH = testPath("foo2.HH"); FS.Files[Foo2C]; FS.Files[Foo2HH]; - PathResult = getCorrespondingHeaderOrSource(Foo2C, FS.getFileSystem()); + PathResult = getCorrespondingHeaderOrSource(Foo2C, FS.view(llvm::None)); EXPECT_TRUE(PathResult.hasValue()); ASSERT_EQ(PathResult.getValue(), Foo2HH); @@ -63,13 +64,13 @@ FS.Files[Foo3C]; FS.Files[Foo3HXX]; - PathResult = getCorrespondingHeaderOrSource(Foo3C, FS.getFileSystem()); + PathResult = getCorrespondingHeaderOrSource(Foo3C, FS.view(llvm::None)); EXPECT_TRUE(PathResult.hasValue()); ASSERT_EQ(PathResult.getValue(), Foo3HXX); // Test if asking for a corresponding file that doesn't exist returns an empty // string. - PathResult = getCorrespondingHeaderOrSource(Invalid, FS.getFileSystem()); + PathResult = getCorrespondingHeaderOrSource(Invalid, FS.view(llvm::None)); EXPECT_FALSE(PathResult.hasValue()); } @@ -252,7 +253,7 @@ MockCompilationDatabase CDB; CDB.ExtraClangFlags = {"-I" + testPath("src/include")}; // add search directory. - MockFSProvider FS; + MockFS FS; // File heuristic fails here, we rely on the index to find the .h file. std::string CppPath = testPath("src/lib/test.cpp"); std::string HeaderPath = testPath("src/include/test.h"); diff --git a/clang-tools-extra/clangd/unittests/HeadersTests.cpp b/clang-tools-extra/clangd/unittests/HeadersTests.cpp --- a/clang-tools-extra/clangd/unittests/HeadersTests.cpp +++ b/clang-tools-extra/clangd/unittests/HeadersTests.cpp @@ -53,7 +53,7 @@ EXPECT_TRUE(static_cast(CI)); // The diagnostic options must be set before creating a CompilerInstance. CI->getDiagnosticOpts().IgnoreWarnings = true; - auto VFS = PI.FSProvider->getFileSystem(Cmd->Directory); + auto VFS = PI.FSProvider->view(Cmd->Directory); auto Clang = prepareCompilerInstance( std::move(CI), /*Preamble=*/nullptr, llvm::MemoryBuffer::getMemBuffer(FS.Files[MainFile], MainFile), @@ -120,7 +120,7 @@ return Edit; } - MockFSProvider FS; + MockFS FS; MockCompilationDatabase CDB; std::string MainFile = testPath("main.cpp"); std::string Subdir = testPath("sub"); diff --git a/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp b/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp --- a/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp +++ b/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp @@ -249,7 +249,7 @@ } TEST(ParsedASTTest, CanBuildInvocationWithUnknownArgs) { - MockFSProvider FSProvider; + MockFS FSProvider; FSProvider.Files = {{testPath("foo.cpp"), "void test() {}"}}; // Unknown flags should not prevent a build of compiler invocation. ParseInputs Inputs; @@ -451,7 +451,7 @@ llvm::StringLiteral Baseline = R"cpp( #include "a.h" #include "c.h")cpp"; - MockFSProvider FS; + MockFS FS; TU.Code = Baseline.str(); auto Inputs = TU.inputs(FS); auto BaselinePreamble = TU.preamble(); @@ -539,7 +539,7 @@ // Build preamble with no includes. TU.Code = ""; StoreDiags Diags; - MockFSProvider FS; + MockFS FS; auto Inputs = TU.inputs(FS); auto CI = buildCompilerInvocation(Inputs, Diags); auto EmptyPreamble = @@ -582,7 +582,7 @@ // Build preamble with no includes. TU.Code = R"cpp(#include )cpp"; StoreDiags Diags; - MockFSProvider FS; + MockFS FS; auto Inputs = TU.inputs(FS); auto CI = buildCompilerInvocation(Inputs, Diags); auto BaselinePreamble = diff --git a/clang-tools-extra/clangd/unittests/PreambleTests.cpp b/clang-tools-extra/clangd/unittests/PreambleTests.cpp --- a/clang-tools-extra/clangd/unittests/PreambleTests.cpp +++ b/clang-tools-extra/clangd/unittests/PreambleTests.cpp @@ -50,7 +50,7 @@ collectPatchedIncludes(llvm::StringRef ModifiedContents, llvm::StringRef BaselineContents, llvm::StringRef MainFileName = "main.cpp") { - MockFSProvider FS; + MockFS FS; auto TU = TestTU::withCode(BaselineContents); TU.Filename = MainFileName.str(); // ms-compatibility changes meaning of #import, make sure it is turned off. @@ -74,7 +74,7 @@ std::move(CI), &BaselinePreamble->Preamble, llvm::MemoryBuffer::getMemBufferCopy( ModifiedContents.slice(0, Bounds.Size).str()), - PI.FSProvider->getFileSystem(PI.CompileCommand.Directory), Diags); + PI.FSProvider->view(PI.CompileCommand.Directory), Diags); PreprocessOnlyAction Action; if (!Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) { ADD_FAILURE() << "failed begin source file"; @@ -165,7 +165,7 @@ } TEST(PreamblePatchTest, PatchesPreambleIncludes) { - MockFSProvider FS; + MockFS FS; IgnoreDiagnostics Diags; auto TU = TestTU::withCode(R"cpp( #include "a.h" @@ -201,7 +201,7 @@ } IgnoreDiagnostics Diags; - MockFSProvider FS; + MockFS FS; auto TU = TestTU::withCode(Modified); auto CI = buildCompilerInvocation(TU.inputs(FS), Diags); if (!CI) { @@ -219,7 +219,7 @@ ADD_FAILURE() << "Failed to build baseline preamble"; return ""; } - MockFSProvider FS; + MockFS FS; auto TU = TestTU::withCode(Modified); return PreamblePatch::create(testPath("main.cpp"), TU.inputs(FS), *BaselinePreamble) @@ -518,7 +518,7 @@ Annotations Modified(Case.Modified); TU.Code = Modified.code().str(); - MockFSProvider FSProvider; + MockFS FSProvider; auto PP = PreamblePatch::create(testPath(TU.Filename), TU.inputs(FSProvider), *BaselinePreamble); diff --git a/clang-tools-extra/clangd/unittests/RenameTests.cpp b/clang-tools-extra/clangd/unittests/RenameTests.cpp --- a/clang-tools-extra/clangd/unittests/RenameTests.cpp +++ b/clang-tools-extra/clangd/unittests/RenameTests.cpp @@ -1027,7 +1027,7 @@ std::string FooHPath = testPath("foo.h"); std::string FooCCPath = testPath("foo.cc"); - MockFSProvider FS; + MockFS FS; FS.Files[FooHPath] = std::string(FooH.code()); FS.Files[FooCCPath] = std::string(FooCC.code()); diff --git a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp --- a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp +++ b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp @@ -728,7 +728,7 @@ }; auto FooCpp = testPath("foo.cpp"); - MockFSProvider FS; + MockFS FS; FS.Files[FooCpp] = ""; MockCompilationDatabase MCD; diff --git a/clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp b/clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp --- a/clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp +++ b/clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp @@ -149,7 +149,7 @@ } TEST(SemanticSelection, RunViaClangdServer) { - MockFSProvider FS; + MockFS FS; MockCompilationDatabase CDB; ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); diff --git a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp --- a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp +++ b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp @@ -16,10 +16,10 @@ #include "TestFS.h" #include "support/Cancellation.h" #include "support/Context.h" -#include "support/FSProvider.h" #include "support/Path.h" #include "support/TestTracer.h" #include "support/Threading.h" +#include "support/ThreadsafeFS.h" #include "clang/Basic/DiagnosticDriver.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/FunctionExtras.h" @@ -150,7 +150,7 @@ std::move(CB)); } - MockFSProvider FSProvider; + MockFS FSProvider; MockCompilationDatabase CDB; }; @@ -775,12 +775,11 @@ FSProvider.Timestamps[HeaderB] = time_t(1); // The addition of the missing header file triggers a rebuild, no errors. - updateWithDiags( - S, Source, Inputs, WantDiagnostics::Yes, - [&DiagCount](std::vector Diags) { - ++DiagCount; - EXPECT_THAT(Diags, IsEmpty()); - }); + updateWithDiags(S, Source, Inputs, WantDiagnostics::Yes, + [&DiagCount](std::vector Diags) { + ++DiagCount; + EXPECT_THAT(Diags, IsEmpty()); + }); // Ensure previous assertions are done before we touch the FS again. ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10))); @@ -798,12 +797,12 @@ // Forcing the reload should should cause a rebuild. Inputs.ForceRebuild = true; - updateWithDiags(S, Source, Inputs, WantDiagnostics::Yes, - [&DiagCount](std::vector Diags) { - ++DiagCount; - ElementsAre(Field(&Diag::Message, - "use of undeclared identifier 'b'")); - }); + updateWithDiags( + S, Source, Inputs, WantDiagnostics::Yes, + [&DiagCount](std::vector Diags) { + ++DiagCount; + ElementsAre(Field(&Diag::Message, "use of undeclared identifier 'b'")); + }); ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10))); EXPECT_EQ(DiagCount, 3U); @@ -901,7 +900,7 @@ std::vector ASTActions; std::vector PreambleActions; } CaptureTUStatus; - MockFSProvider FS; + MockFS FS; MockCompilationDatabase CDB; ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &CaptureTUStatus); Annotations Code("int m^ain () {}"); diff --git a/clang-tools-extra/clangd/unittests/TestFS.h b/clang-tools-extra/clangd/unittests/TestFS.h --- a/clang-tools-extra/clangd/unittests/TestFS.h +++ b/clang-tools-extra/clangd/unittests/TestFS.h @@ -13,8 +13,8 @@ #define LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_TESTFS_H #include "ClangdServer.h" #include "GlobalCompilationDatabase.h" -#include "support/FSProvider.h" #include "support/Path.h" +#include "support/ThreadsafeFS.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" @@ -31,18 +31,11 @@ llvm::StringMap const &Timestamps = {}); // A VFS provider that returns TestFSes containing a provided set of files. -class MockFSProvider : public FileSystemProvider { +class MockFS : public ThreadsafeFS { public: - // Prevent name hiding caused by the overload below. - using FileSystemProvider::getFileSystem; - - IntrusiveRefCntPtr getFileSystem() const { - return buildTestFS(Files, Timestamps); - } - IntrusiveRefCntPtr - getFileSystem(llvm::NoneType) const override { - return getFileSystem(); + view(llvm::NoneType) const override { + return buildTestFS(Files, Timestamps); } // If relative paths are used, they are resolved with testPath(). diff --git a/clang-tools-extra/clangd/unittests/TestTU.h b/clang-tools-extra/clangd/unittests/TestTU.h --- a/clang-tools-extra/clangd/unittests/TestTU.h +++ b/clang-tools-extra/clangd/unittests/TestTU.h @@ -70,7 +70,7 @@ // Suppress this behavior by adding an 'error-ok' comment to the code. ParsedAST build() const; std::shared_ptr preamble() const; - ParseInputs inputs(MockFSProvider &FSProvider) const; + ParseInputs inputs(MockFS &FSProvider) const; SymbolSlab headerSymbols() const; RefSlab headerRefs() const; std::unique_ptr index() const; diff --git a/clang-tools-extra/clangd/unittests/TestTU.cpp b/clang-tools-extra/clangd/unittests/TestTU.cpp --- a/clang-tools-extra/clangd/unittests/TestTU.cpp +++ b/clang-tools-extra/clangd/unittests/TestTU.cpp @@ -20,7 +20,7 @@ namespace clang { namespace clangd { -ParseInputs TestTU::inputs(MockFSProvider &FSProvider) const { +ParseInputs TestTU::inputs(MockFS &FSProvider) const { std::string FullFilename = testPath(Filename), FullHeaderName = testPath(HeaderFilename), ImportThunk = testPath("import_thunk.h"); @@ -67,7 +67,7 @@ } std::shared_ptr TestTU::preamble() const { - MockFSProvider FSProvider; + MockFS FSProvider; auto Inputs = inputs(FSProvider); IgnoreDiagnostics Diags; auto CI = buildCompilerInvocation(Inputs, Diags); @@ -78,7 +78,7 @@ } ParsedAST TestTU::build() const { - MockFSProvider FSProvider; + MockFS FSProvider; auto Inputs = inputs(FSProvider); StoreDiags Diags; auto CI = buildCompilerInvocation(Inputs, Diags); diff --git a/clang-tools-extra/clangd/unittests/XRefsTests.cpp b/clang-tools-extra/clangd/unittests/XRefsTests.cpp --- a/clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ b/clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -974,7 +974,7 @@ std::string BuildDir = testPath("build"); MockCompilationDatabase CDB(BuildDir, RelPathPrefix); - MockFSProvider FS; + MockFS FS; ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); // Fill the filesystem. @@ -1010,7 +1010,7 @@ } TEST(GoToInclude, All) { - MockFSProvider FS; + MockFS FS; MockCompilationDatabase CDB; ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); @@ -1084,7 +1084,7 @@ TEST(LocateSymbol, WithPreamble) { // Test stragety: AST should always use the latest preamble instead of last // good preamble. - MockFSProvider FS; + MockFS FS; MockCompilationDatabase CDB; ClangdServer Server(CDB, FS, ClangdServer::optsForTest());