llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Jan Svoboda (jansvoboda11) <details> <summary>Changes</summary> The `llvm::vfs::FileSystem` interface makes no promises around thread-safety. To enable making `CompilerInstance` thread-safe, this PR allows passing an explicit VFS to `cloneForModuleCompile()`. This will be used from the dependency scanner. --- Full diff: https://github.com/llvm/llvm-project/pull/135737.diff 2 Files Affected: - (modified) clang/include/clang/Frontend/CompilerInstance.h (+11-4) - (modified) clang/lib/Frontend/CompilerInstance.cpp (+17-11) ``````````diff diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h index 41dc7f1fef461..d70f5c45b3d38 100644 --- a/clang/include/clang/Frontend/CompilerInstance.h +++ b/clang/include/clang/Frontend/CompilerInstance.h @@ -845,18 +845,25 @@ class CompilerInstance : public ModuleLoader { /// Creates a \c CompilerInstance for compiling a module. /// /// This expects a properly initialized \c FrontendInputFile. + /// + /// Explicitly-specified \c VFS takes precedence over the VFS of this instance + /// when creating the clone and also prevents \c FileManager sharing. std::unique_ptr<CompilerInstance> cloneForModuleCompileImpl( SourceLocation ImportLoc, StringRef ModuleName, FrontendInputFile Input, - StringRef OriginalModuleMapFile, StringRef ModuleFileName); + StringRef OriginalModuleMapFile, StringRef ModuleFileName, + IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr); public: /// Creates a new \c CompilerInstance for compiling a module. /// /// This takes care of creating appropriate \c FrontendInputFile for /// public/private frameworks, inferred modules and such. - std::unique_ptr<CompilerInstance> - cloneForModuleCompile(SourceLocation ImportLoc, Module *Module, - StringRef ModuleFileName); + /// + /// Explicitly-specified \c VFS takes precedence over the VFS of this instance + /// when creating the clone and also prevents \c FileManager sharing. + std::unique_ptr<CompilerInstance> cloneForModuleCompile( + SourceLocation ImportLoc, Module *Module, StringRef ModuleFileName, + IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr); /// Compile a module file for the given module, using the options /// provided by the importing compiler instance. Returns true if the module diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 243e0a3c15b05..fa6b137338f26 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -1152,7 +1152,8 @@ static Language getLanguageFromOptions(const LangOptions &LangOpts) { std::unique_ptr<CompilerInstance> CompilerInstance::cloneForModuleCompileImpl( SourceLocation ImportLoc, StringRef ModuleName, FrontendInputFile Input, - StringRef OriginalModuleMapFile, StringRef ModuleFileName) { + StringRef OriginalModuleMapFile, StringRef ModuleFileName, + IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) { // Construct a compiler invocation for creating this module. auto Invocation = std::make_shared<CompilerInvocation>(getInvocation()); @@ -1212,19 +1213,21 @@ std::unique_ptr<CompilerInstance> CompilerInstance::cloneForModuleCompileImpl( auto &Inv = *Invocation; Instance.setInvocation(std::move(Invocation)); + if (VFS) { + Instance.createFileManager(std::move(VFS)); + } else if (FrontendOpts.ModulesShareFileManager) { + Instance.setFileManager(&getFileManager()); + } else { + Instance.createFileManager(&getVirtualFileSystem()); + } + Instance.createDiagnostics( - getVirtualFileSystem(), + Instance.getVirtualFileSystem(), new ForwardingDiagnosticConsumer(getDiagnosticClient()), /*ShouldOwnClient=*/true); - if (llvm::is_contained(DiagOpts.SystemHeaderWarningsModules, ModuleName)) Instance.getDiagnostics().setSuppressSystemWarnings(false); - if (FrontendOpts.ModulesShareFileManager) { - Instance.setFileManager(&getFileManager()); - } else { - Instance.createFileManager(&getVirtualFileSystem()); - } Instance.createSourceManager(Instance.getFileManager()); SourceManager &SourceMgr = Instance.getSourceManager(); @@ -1318,7 +1321,8 @@ static OptionalFileEntryRef getPublicModuleMap(FileEntryRef File, } std::unique_ptr<CompilerInstance> CompilerInstance::cloneForModuleCompile( - SourceLocation ImportLoc, Module *Module, StringRef ModuleFileName) { + SourceLocation ImportLoc, Module *Module, StringRef ModuleFileName, + IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) { StringRef ModuleName = Module->getTopLevelModuleName(); InputKind IK(getLanguageFromOptions(getLangOpts()), InputKind::ModuleMap); @@ -1363,7 +1367,8 @@ std::unique_ptr<CompilerInstance> CompilerInstance::cloneForModuleCompile( return cloneForModuleCompileImpl( ImportLoc, ModuleName, FrontendInputFile(ModuleMapFilePath, IK, IsSystem), - ModMap.getModuleMapFileForUniquing(Module)->getName(), ModuleFileName); + ModMap.getModuleMapFileForUniquing(Module)->getName(), ModuleFileName, + std::move(VFS)); } // FIXME: We only need to fake up an input file here as a way of @@ -1380,7 +1385,8 @@ std::unique_ptr<CompilerInstance> CompilerInstance::cloneForModuleCompile( auto Instance = cloneForModuleCompileImpl( ImportLoc, ModuleName, FrontendInputFile(FakeModuleMapFile, IK, +Module->IsSystem), - ModMap.getModuleMapFileForUniquing(Module)->getName(), ModuleFileName); + ModMap.getModuleMapFileForUniquing(Module)->getName(), ModuleFileName, + std::move(VFS)); std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer = llvm::MemoryBuffer::getMemBufferCopy(InferredModuleMapContent); `````````` </details> https://github.com/llvm/llvm-project/pull/135737 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits