diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp index 9bd85479d9810..8ce2706cb1062 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -24,7 +24,6 @@ #include "clang/Tooling/DependencyScanning/DependencyScanningService.h" #include "clang/Tooling/DependencyScanning/InProcessModuleCache.h" #include "clang/Tooling/DependencyScanning/ModuleDepCollector.h" -#include "clang/Tooling/Tooling.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Error.h" @@ -376,25 +375,23 @@ class ScanningDependencyDirectivesGetter : public DependencyDirectivesGetter { /// A clang tool that runs the preprocessor in a mode that's optimized for /// dependency scanning for the given compiler invocation. -class DependencyScanningAction : public tooling::ToolAction { +class DependencyScanningAction { public: DependencyScanningAction( DependencyScanningService &Service, StringRef WorkingDirectory, DependencyConsumer &Consumer, DependencyActionController &Controller, llvm::IntrusiveRefCntPtr DepFS, - bool DisableFree, std::optional ModuleName = std::nullopt) + std::optional ModuleName = std::nullopt) : Service(Service), WorkingDirectory(WorkingDirectory), Consumer(Consumer), Controller(Controller), DepFS(std::move(DepFS)), - DisableFree(DisableFree), ModuleName(ModuleName) {} + ModuleName(ModuleName) {} bool runInvocation(std::shared_ptr Invocation, - FileManager *DriverFileMgr, + IntrusiveRefCntPtr FS, std::shared_ptr PCHContainerOps, - DiagnosticConsumer *DiagConsumer) override { + DiagnosticConsumer *DiagConsumer) { // Make a deep copy of the original Clang invocation. CompilerInvocation OriginalInvocation(*Invocation); - // Restore the value of DisableFree, which may be modified by Tooling. - OriginalInvocation.getFrontendOpts().DisableFree = DisableFree; if (any(Service.getOptimizeArgs() & ScanningOptimizations::Macros)) canonicalizeDefines(OriginalInvocation.getPreprocessorOpts()); @@ -419,8 +416,8 @@ class DependencyScanningAction : public tooling::ToolAction { // Create the compiler's actual diagnostics engine. sanitizeDiagOpts(ScanInstance.getDiagnosticOpts()); assert(!DiagConsumerFinished && "attempt to reuse finished consumer"); - ScanInstance.createDiagnostics(DriverFileMgr->getVirtualFileSystem(), - DiagConsumer, /*ShouldOwnClient=*/false); + ScanInstance.createDiagnostics(*FS, DiagConsumer, + /*ShouldOwnClient=*/false); if (!ScanInstance.hasDiagnostics()) return false; @@ -431,6 +428,7 @@ class DependencyScanningAction : public tooling::ToolAction { ScanInstance.getHeaderSearchOpts().BuildSessionTimestamp = Service.getBuildSessionTimestamp(); + ScanInstance.getFrontendOpts().DisableFree = false; ScanInstance.getFrontendOpts().GenerateGlobalModuleIndex = false; ScanInstance.getFrontendOpts().UseGlobalModuleIndex = false; // This will prevent us compiling individual modules asynchronously since @@ -441,9 +439,9 @@ class DependencyScanningAction : public tooling::ToolAction { any(Service.getOptimizeArgs() & ScanningOptimizations::VFS); // Support for virtual file system overlays. - auto FS = createVFSFromCompilerInvocation( - ScanInstance.getInvocation(), ScanInstance.getDiagnostics(), - DriverFileMgr->getVirtualFileSystemPtr()); + FS = createVFSFromCompilerInvocation(ScanInstance.getInvocation(), + ScanInstance.getDiagnostics(), + std::move(FS)); // Create a new FileManager to match the invocation's FileSystemOptions. auto *FileMgr = ScanInstance.createFileManager(FS); @@ -554,9 +552,6 @@ class DependencyScanningAction : public tooling::ToolAction { if (Result) setLastCC1Arguments(std::move(OriginalInvocation)); - // Propagate the statistics to the parent FileManager. - DriverFileMgr->AddStats(ScanInstance.getFileManager()); - return Result; } @@ -584,7 +579,6 @@ class DependencyScanningAction : public tooling::ToolAction { DependencyConsumer &Consumer; DependencyActionController &Controller; llvm::IntrusiveRefCntPtr DepFS; - bool DisableFree; std::optional ModuleName; std::optional ScanInstanceStorage; std::shared_ptr MDC; @@ -669,15 +663,14 @@ llvm::Error DependencyScanningWorker::computeDependencies( } static bool forEachDriverJob( - ArrayRef ArgStrs, DiagnosticsEngine &Diags, FileManager &FM, + ArrayRef ArgStrs, DiagnosticsEngine &Diags, + IntrusiveRefCntPtr FS, llvm::function_ref Callback) { SmallVector Argv; Argv.reserve(ArgStrs.size()); for (const std::string &Arg : ArgStrs) Argv.push_back(Arg.c_str()); - llvm::vfs::FileSystem *FS = &FM.getVirtualFileSystem(); - std::unique_ptr Driver = std::make_unique( Argv[0], llvm::sys::getDefaultTargetTriple(), Diags, "clang LLVM compiler", FS); @@ -687,7 +680,8 @@ static bool forEachDriverJob( bool CLMode = driver::IsClangCL( driver::getDriverMode(Argv[0], ArrayRef(Argv).slice(1))); - if (llvm::Error E = driver::expandResponseFiles(Argv, CLMode, Alloc, FS)) { + if (llvm::Error E = + driver::expandResponseFiles(Argv, CLMode, Alloc, FS.get())) { Diags.Report(diag::err_drv_expand_response_file) << llvm::toString(std::move(E)); return false; @@ -710,17 +704,25 @@ static bool forEachDriverJob( static bool createAndRunToolInvocation( std::vector CommandLine, DependencyScanningAction &Action, - FileManager &FM, + IntrusiveRefCntPtr FS, std::shared_ptr &PCHContainerOps, DiagnosticsEngine &Diags, DependencyConsumer &Consumer) { // Save executable path before providing CommandLine to ToolInvocation std::string Executable = CommandLine[0]; - ToolInvocation Invocation(std::move(CommandLine), &Action, &FM, - PCHContainerOps); - Invocation.setDiagnosticConsumer(Diags.getClient()); - Invocation.setDiagnosticOptions(&Diags.getDiagnosticOptions()); - if (!Invocation.run()) + + llvm::opt::ArgStringList Argv; + for (const std::string &Str : ArrayRef(CommandLine).drop_front()) + Argv.push_back(Str.c_str()); + + auto Invocation = std::make_shared(); + if (!CompilerInvocation::CreateFromArgs(*Invocation, Argv, Diags)) { + // FIXME: Should we just go on like cc1_main does? + return false; + } + + if (!Action.runInvocation(std::move(Invocation), std::move(FS), + PCHContainerOps, Diags.getClient())) return false; std::vector Args = Action.takeLastCC1Arguments(); @@ -733,37 +735,24 @@ bool DependencyScanningWorker::scanDependencies( DependencyConsumer &Consumer, DependencyActionController &Controller, DiagnosticConsumer &DC, llvm::IntrusiveRefCntPtr FS, std::optional ModuleName) { - auto FileMgr = - llvm::makeIntrusiveRefCnt(FileSystemOptions{}, FS); - std::vector CCommandLine(CommandLine.size(), nullptr); llvm::transform(CommandLine, CCommandLine.begin(), [](const std::string &Str) { return Str.c_str(); }); auto DiagOpts = CreateAndPopulateDiagOpts(CCommandLine); sanitizeDiagOpts(*DiagOpts); - IntrusiveRefCntPtr Diags = - CompilerInstance::createDiagnostics(FileMgr->getVirtualFileSystem(), - *DiagOpts, &DC, - /*ShouldOwnClient=*/false); - - // Although `Diagnostics` are used only for command-line parsing, the - // custom `DiagConsumer` might expect a `SourceManager` to be present. - SourceManager SrcMgr(*Diags, *FileMgr); - Diags->setSourceManager(&SrcMgr); - // DisableFree is modified by Tooling for running - // in-process; preserve the original value, which is - // always true for a driver invocation. - bool DisableFree = true; + auto Diags = CompilerInstance::createDiagnostics(*FS, *DiagOpts, &DC, + /*ShouldOwnClient=*/false); + DependencyScanningAction Action(Service, WorkingDirectory, Consumer, - Controller, DepFS, DisableFree, ModuleName); + Controller, DepFS, ModuleName); bool Success = false; if (CommandLine[1] == "-cc1") { - Success = createAndRunToolInvocation(CommandLine, Action, *FileMgr, + Success = createAndRunToolInvocation(CommandLine, Action, FS, PCHContainerOps, *Diags, Consumer); } else { Success = forEachDriverJob( - CommandLine, *Diags, *FileMgr, [&](const driver::Command &Cmd) { + CommandLine, *Diags, FS, [&](const driver::Command &Cmd) { if (StringRef(Cmd.getCreator().getName()) != "clang") { // Non-clang command. Just pass through to the dependency // consumer. @@ -782,7 +771,7 @@ bool DependencyScanningWorker::scanDependencies( // system to ensure that any file system requests that // are made by the driver do not go through the // dependency scanning filesystem. - return createAndRunToolInvocation(std::move(Argv), Action, *FileMgr, + return createAndRunToolInvocation(std::move(Argv), Action, FS, PCHContainerOps, *Diags, Consumer); }); }