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 @@ -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 @@ -129,8 +129,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) @@ -184,7 +184,7 @@ // FIXME: call tidy options builder on the worker thread, it can do IO. if (GetClangTidyOptions) Opts.ClangTidyOpts = - GetClangTidyOptions(*FSProvider.getFileSystem(llvm::None), File); + GetClangTidyOptions(*FSProvider.view(llvm::None), File); Opts.SuggestMissingIncludes = SuggestMissingIncludes; // Compile command is set asynchronously during update, as it can be slow. @@ -320,7 +320,7 @@ return CursorPos.takeError(); auto Style = format::getStyle(format::DefaultFormatStyle, File, format::DefaultFallbackStyle, Code, - FSProvider.getFileSystem(llvm::None).get()); + FSProvider.view(llvm::None).get()); if (!Style) return Style.takeError(); @@ -399,8 +399,7 @@ auto Style = getFormatStyleForFile( File, InpAST->Inputs.Contents, InpAST->Inputs.FSProvider - ->getFileSystem( - llvm::StringRef(InpAST->Inputs.CompileCommand.Directory)) + ->view(llvm::StringRef(InpAST->Inputs.CompileCommand.Directory)) .get()); llvm::Error Err = llvm::Error::success(); for (auto &E : *Edits) @@ -497,7 +496,7 @@ Effect = T.takeError(); } assert(Effect.hasValue() && "Expected at least one selection"); - auto FS = FSProvider.getFileSystem( + auto FS = FSProvider.view( llvm::StringRef(InpAST->Inputs.CompileCommand.Directory)); if (*Effect) { // Tweaks don't apply clang-format, do that centrally here. @@ -555,7 +554,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 { @@ -570,8 +569,8 @@ ClangdServer::formatCode(llvm::StringRef Code, PathRef File, llvm::ArrayRef Ranges) { // Call clang-format. - format::FormatStyle Style = getFormatStyleForFile( - File, Code, FSProvider.getFileSystem(llvm::None).get()); + format::FormatStyle Style = + getFormatStyleForFile(File, Code, FSProvider.view(llvm::None).get()); tooling::Replacements IncludeReplaces = format::sortIncludes(Style, Code, Ranges, File); auto Changed = tooling::applyAllReplacements(Code, IncludeReplaces); @@ -603,12 +602,11 @@ this](llvm::Expected InpAST) mutable { if (!InpAST) return CB(InpAST.takeError()); - format::FormatStyle Style = - getFormatStyleForFile(File, InpAST->Inputs.Contents, - InpAST->Inputs.FSProvider - ->getFileSystem(llvm::StringRef( - InpAST->Inputs.CompileCommand.Directory)) - .get()); + format::FormatStyle Style = getFormatStyleForFile( + File, InpAST->Inputs.Contents, + InpAST->Inputs.FSProvider + ->view(llvm::StringRef(InpAST->Inputs.CompileCommand.Directory)) + .get()); CB(clangd::getHover(InpAST->AST, Pos, std::move(Style), Index)); }; 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 @@ -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( llvm::StringRef(Input.ParseInput.CompileCommand.Directory)); if (Input.Preamble.StatCache) VFS = Input.Preamble.StatCache->getConsumingFS(std::move(VFS)); @@ -1293,7 +1293,7 @@ auto Style = getFormatStyleForFile( SemaCCInput.FileName, SemaCCInput.ParseInput.Contents, SemaCCInput.ParseInput.FSProvider - ->getFileSystem(llvm::StringRef( + ->view(llvm::StringRef( SemaCCInput.ParseInput.CompileCommand.Directory)) .get()); const auto NextToken = Lexer::findNextToken( @@ -1786,7 +1786,7 @@ return (!Preamble || Opts.RunParser == CodeCompleteOptions::NeverParse) ? std::move(Flow).runWithoutSema( ParseInput.Contents, *Offset, - ParseInput.FSProvider->getFileSystem( + ParseInput.FSProvider->view( llvm::StringRef(ParseInput.CompileCommand.Directory))) : std::move(Flow).run({FileName, *Offset, *Preamble, // We want to serve code completions with 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 @@ -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,8 +48,8 @@ for (const auto &S : Inputs.CompileCommand.CommandLine) ArgStrs.push_back(S.c_str()); - auto VFS = Inputs.FSProvider->getFileSystem( - llvm::StringRef(Inputs.CompileCommand.Directory)); + auto VFS = + Inputs.FSProvider->view(llvm::StringRef(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,8 +249,8 @@ trace::Span Tracer("BuildAST"); SPAN_ATTACH(Tracer, "File", Filename); - auto VFS = Inputs.FSProvider->getFileSystem( - llvm::StringRef(Inputs.CompileCommand.Directory)); + auto VFS = + Inputs.FSProvider->view(llvm::StringRef(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 @@ -232,12 +232,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::Optional) const override { + view(llvm::Optional) const override { return VFS; } @@ -355,8 +355,8 @@ CI.getPreprocessorOpts().WriteCommentListToPCH = false; CppFilePreambleCallbacks SerializedDeclsCollector(FileName, PreambleCallback); - auto VFS = Inputs.FSProvider->getFileSystem( - llvm::StringRef(Inputs.CompileCommand.Directory)); + auto VFS = + Inputs.FSProvider->view(llvm::StringRef(Inputs.CompileCommand.Directory)); llvm::SmallString<32> AbsFileName(FileName); VFS->makeAbsolute(AbsFileName); auto StatCache = std::make_unique(AbsFileName); @@ -393,8 +393,8 @@ llvm::MemoryBuffer::getMemBuffer(Inputs.Contents, FileName); auto Bounds = ComputePreambleBounds(*CI.getLangOpts(), ContentsBuffer.get(), 0); - auto VFS = Inputs.FSProvider->getFileSystem( - llvm::StringRef(Inputs.CompileCommand.Directory)); + auto VFS = + Inputs.FSProvider->view(llvm::StringRef(Inputs.CompileCommand.Directory)); return compileCommandsAreEqual(Inputs.CompileCommand, Preamble.CompileCommand) && Preamble.Preamble.CanReuse(CI, ContentsBuffer.get(), Bounds, @@ -421,9 +421,8 @@ trace::Span Tracer("CreatePreamblePatch"); SPAN_ATTACH(Tracer, "File", FileName); assert(llvm::sys::path::is_absolute(FileName) && "relative FileName!"); - auto VFS = - Baseline.StatCache->getConsumingFS(Modified.FSProvider->getFileSystem( - llvm::StringRef(Modified.CompileCommand.Directory))); + auto VFS = Baseline.StatCache->getConsumingFS(Modified.FSProvider->view( + llvm::StringRef(Modified.CompileCommand.Directory))); // 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/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 @@ -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 @@ -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(llvm::StringRef(Cmd.Directory)); + auto FS = FSProvider.view(llvm::StringRef(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(llvm::None); + auto FS = FSProvider.view(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/FSProvider.h b/clang-tools-extra/clangd/support/FSProvider.h --- a/clang-tools-extra/clangd/support/FSProvider.h +++ b/clang-tools-extra/clangd/support/FSProvider.h @@ -20,22 +20,22 @@ // Wrapper for vfs::FileSystem for use in multithreaded programs like clangd. // As FileSystem is not threadsafe, concurrent threads must each obtain one. -class FileSystemProvider { +class ThreadSafeFS { public: - virtual ~FileSystemProvider() = default; + virtual ~ThreadSafeFS() = 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. /// Will try to set curret working directory to \p CWD. virtual llvm::IntrusiveRefCntPtr - getFileSystem(llvm::Optional CWD) const = 0; + view(llvm::Optional CWD) const = 0; }; -class RealFileSystemProvider : public FileSystemProvider { +class RealFileSystemProvider : public ThreadSafeFS { public: llvm::IntrusiveRefCntPtr - getFileSystem(llvm::Optional CWD) const override; + view(llvm::Optional CWD) const override; }; } // namespace clangd diff --git a/clang-tools-extra/clangd/support/FSProvider.cpp b/clang-tools-extra/clangd/support/FSProvider.cpp --- a/clang-tools-extra/clangd/support/FSProvider.cpp +++ b/clang-tools-extra/clangd/support/FSProvider.cpp @@ -74,8 +74,7 @@ } // namespace llvm::IntrusiveRefCntPtr -clang::clangd::RealFileSystemProvider::getFileSystem( - llvm::Optional CWD) const { +clang::clangd::RealFileSystemProvider::view(llvm::Optional CWD) const { auto FS = llvm::vfs::createPhysicalFileSystem(); if (CWD && FS->setCurrentWorkingDirectory(*CWD)) elog("Failed to set CWD in RealFileSystemProvider"); 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 @@ -718,8 +718,7 @@ ClangTidyOptProvider = std::make_unique( tidy::ClangTidyGlobalOptions(), /* Default */ EmptyDefaults, - /* Override */ OverrideClangTidyOptions, - FSProvider.getFileSystem(llvm::None)); + /* Override */ OverrideClangTidyOptions, FSProvider.view(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/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 @@ -271,9 +271,9 @@ TEST_F(ClangdVFSTest, PropagatesContexts) { static Key Secret; - struct FSProvider : public FileSystemProvider { + struct FSProvider : public ThreadSafeFS { IntrusiveRefCntPtr - getFileSystem(llvm::Optional) const override { + view(llvm::Optional) const override { Got = Context::current().getExisting(Secret); return buildTestFS({}); } @@ -923,13 +923,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::Optional) const override { + view(llvm::Optional) const override { class ListenStatVFS : public llvm::vfs::ProxyFileSystem { public: ListenStatVFS(IntrusiveRefCntPtr FS, 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 = FS.getFileSystem(llvm::StringRef(Cmd->Directory)); + auto VFS = FS.view(llvm::StringRef(Cmd->Directory)); auto Clang = prepareCompilerInstance( std::move(CI), /*Preamble=*/nullptr, llvm::MemoryBuffer::getMemBuffer(FS.Files[MainFile], MainFile), 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 @@ -70,13 +70,11 @@ // We don't run PP directly over the patch cotents to test production // behaviour. auto Bounds = Lexer::ComputePreamble(ModifiedContents, *CI->getLangOpts()); - auto Clang = - prepareCompilerInstance(std::move(CI), &BaselinePreamble->Preamble, - llvm::MemoryBuffer::getMemBufferCopy( - ModifiedContents.slice(0, Bounds.Size).str()), - PI.FSProvider->getFileSystem( - llvm::StringRef(PI.CompileCommand.Directory)), - Diags); + auto Clang = prepareCompilerInstance( + std::move(CI), &BaselinePreamble->Preamble, + llvm::MemoryBuffer::getMemBufferCopy( + ModifiedContents.slice(0, Bounds.Size).str()), + PI.FSProvider->view(llvm::StringRef(PI.CompileCommand.Directory)), Diags); PreprocessOnlyAction Action; if (!Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) { ADD_FAILURE() << "failed begin source file"; 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 @@ -29,14 +29,14 @@ llvm::StringMap const &Timestamps = {}); // A VFS provider that returns TestFSes containing a provided set of files. -class MockFSProvider : public FileSystemProvider { +class MockFSProvider : public ThreadSafeFS { public: IntrusiveRefCntPtr getFileSystem() const { return buildTestFS(Files, Timestamps); } IntrusiveRefCntPtr - getFileSystem(llvm::Optional CWD) const override { + view(llvm::Optional CWD) const override { auto FS = getFileSystem(); if (CWD) FS->setCurrentWorkingDirectory(*CWD);