2424#include " clang/Tooling/DependencyScanning/DependencyScanningService.h"
2525#include " clang/Tooling/DependencyScanning/InProcessModuleCache.h"
2626#include " clang/Tooling/DependencyScanning/ModuleDepCollector.h"
27- #include " clang/Tooling/Tooling.h"
2827#include " llvm/ADT/IntrusiveRefCntPtr.h"
2928#include " llvm/Support/Allocator.h"
3029#include " llvm/Support/Error.h"
@@ -376,25 +375,23 @@ class ScanningDependencyDirectivesGetter : public DependencyDirectivesGetter {
376375
377376// / A clang tool that runs the preprocessor in a mode that's optimized for
378377// / dependency scanning for the given compiler invocation.
379- class DependencyScanningAction : public tooling ::ToolAction {
378+ class DependencyScanningAction {
380379public:
381380 DependencyScanningAction (
382381 DependencyScanningService &Service, StringRef WorkingDirectory,
383382 DependencyConsumer &Consumer, DependencyActionController &Controller,
384383 llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS,
385- bool DisableFree, std::optional<StringRef> ModuleName = std::nullopt )
384+ std::optional<StringRef> ModuleName = std::nullopt )
386385 : Service(Service), WorkingDirectory(WorkingDirectory),
387386 Consumer (Consumer), Controller(Controller), DepFS(std::move(DepFS)),
388- DisableFree(DisableFree), ModuleName(ModuleName) {}
387+ ModuleName(ModuleName) {}
389388
390389 bool runInvocation (std::shared_ptr<CompilerInvocation> Invocation,
391- FileManager *DriverFileMgr ,
390+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS ,
392391 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
393- DiagnosticConsumer *DiagConsumer) override {
392+ DiagnosticConsumer *DiagConsumer) {
394393 // Make a deep copy of the original Clang invocation.
395394 CompilerInvocation OriginalInvocation (*Invocation);
396- // Restore the value of DisableFree, which may be modified by Tooling.
397- OriginalInvocation.getFrontendOpts ().DisableFree = DisableFree;
398395 if (any (Service.getOptimizeArgs () & ScanningOptimizations::Macros))
399396 canonicalizeDefines (OriginalInvocation.getPreprocessorOpts ());
400397
@@ -419,8 +416,8 @@ class DependencyScanningAction : public tooling::ToolAction {
419416 // Create the compiler's actual diagnostics engine.
420417 sanitizeDiagOpts (ScanInstance.getDiagnosticOpts ());
421418 assert (!DiagConsumerFinished && " attempt to reuse finished consumer" );
422- ScanInstance.createDiagnostics (DriverFileMgr-> getVirtualFileSystem () ,
423- DiagConsumer, /* ShouldOwnClient=*/ false );
419+ ScanInstance.createDiagnostics (*FS, DiagConsumer ,
420+ /* ShouldOwnClient=*/ false );
424421 if (!ScanInstance.hasDiagnostics ())
425422 return false ;
426423
@@ -431,6 +428,7 @@ class DependencyScanningAction : public tooling::ToolAction {
431428 ScanInstance.getHeaderSearchOpts ().BuildSessionTimestamp =
432429 Service.getBuildSessionTimestamp ();
433430
431+ ScanInstance.getFrontendOpts ().DisableFree = false ;
434432 ScanInstance.getFrontendOpts ().GenerateGlobalModuleIndex = false ;
435433 ScanInstance.getFrontendOpts ().UseGlobalModuleIndex = false ;
436434 // This will prevent us compiling individual modules asynchronously since
@@ -441,9 +439,9 @@ class DependencyScanningAction : public tooling::ToolAction {
441439 any (Service.getOptimizeArgs () & ScanningOptimizations::VFS);
442440
443441 // Support for virtual file system overlays.
444- auto FS = createVFSFromCompilerInvocation (
445- ScanInstance. getInvocation (), ScanInstance.getDiagnostics (),
446- DriverFileMgr-> getVirtualFileSystemPtr ( ));
442+ FS = createVFSFromCompilerInvocation (ScanInstance. getInvocation (),
443+ ScanInstance.getDiagnostics (),
444+ std::move (FS ));
447445
448446 // Create a new FileManager to match the invocation's FileSystemOptions.
449447 auto *FileMgr = ScanInstance.createFileManager (FS);
@@ -554,9 +552,6 @@ class DependencyScanningAction : public tooling::ToolAction {
554552 if (Result)
555553 setLastCC1Arguments (std::move (OriginalInvocation));
556554
557- // Propagate the statistics to the parent FileManager.
558- DriverFileMgr->AddStats (ScanInstance.getFileManager ());
559-
560555 return Result;
561556 }
562557
@@ -584,7 +579,6 @@ class DependencyScanningAction : public tooling::ToolAction {
584579 DependencyConsumer &Consumer;
585580 DependencyActionController &Controller;
586581 llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS;
587- bool DisableFree;
588582 std::optional<StringRef> ModuleName;
589583 std::optional<CompilerInstance> ScanInstanceStorage;
590584 std::shared_ptr<ModuleDepCollector> MDC;
@@ -669,15 +663,14 @@ llvm::Error DependencyScanningWorker::computeDependencies(
669663}
670664
671665static bool forEachDriverJob (
672- ArrayRef<std::string> ArgStrs, DiagnosticsEngine &Diags, FileManager &FM,
666+ ArrayRef<std::string> ArgStrs, DiagnosticsEngine &Diags,
667+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
673668 llvm::function_ref<bool (const driver::Command &Cmd)> Callback) {
674669 SmallVector<const char *, 256 > Argv;
675670 Argv.reserve (ArgStrs.size ());
676671 for (const std::string &Arg : ArgStrs)
677672 Argv.push_back (Arg.c_str ());
678673
679- llvm::vfs::FileSystem *FS = &FM.getVirtualFileSystem ();
680-
681674 std::unique_ptr<driver::Driver> Driver = std::make_unique<driver::Driver>(
682675 Argv[0 ], llvm::sys::getDefaultTargetTriple (), Diags,
683676 " clang LLVM compiler" , FS);
@@ -687,7 +680,8 @@ static bool forEachDriverJob(
687680 bool CLMode = driver::IsClangCL (
688681 driver::getDriverMode (Argv[0 ], ArrayRef (Argv).slice (1 )));
689682
690- if (llvm::Error E = driver::expandResponseFiles (Argv, CLMode, Alloc, FS)) {
683+ if (llvm::Error E =
684+ driver::expandResponseFiles (Argv, CLMode, Alloc, FS.get ())) {
691685 Diags.Report (diag::err_drv_expand_response_file)
692686 << llvm::toString (std::move (E));
693687 return false ;
@@ -710,17 +704,25 @@ static bool forEachDriverJob(
710704
711705static bool createAndRunToolInvocation (
712706 std::vector<std::string> CommandLine, DependencyScanningAction &Action,
713- FileManager &FM ,
707+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS ,
714708 std::shared_ptr<clang::PCHContainerOperations> &PCHContainerOps,
715709 DiagnosticsEngine &Diags, DependencyConsumer &Consumer) {
716710
717711 // Save executable path before providing CommandLine to ToolInvocation
718712 std::string Executable = CommandLine[0 ];
719- ToolInvocation Invocation (std::move (CommandLine), &Action, &FM,
720- PCHContainerOps);
721- Invocation.setDiagnosticConsumer (Diags.getClient ());
722- Invocation.setDiagnosticOptions (&Diags.getDiagnosticOptions ());
723- if (!Invocation.run ())
713+
714+ llvm::opt::ArgStringList Argv;
715+ for (const std::string &Str : ArrayRef (CommandLine).drop_front ())
716+ Argv.push_back (Str.c_str ());
717+
718+ auto Invocation = std::make_shared<CompilerInvocation>();
719+ if (!CompilerInvocation::CreateFromArgs (*Invocation, Argv, Diags)) {
720+ // FIXME: Should we just go on like cc1_main does?
721+ return false ;
722+ }
723+
724+ if (!Action.runInvocation (std::move (Invocation), std::move (FS),
725+ PCHContainerOps, Diags.getClient ()))
724726 return false ;
725727
726728 std::vector<std::string> Args = Action.takeLastCC1Arguments ();
@@ -733,37 +735,24 @@ bool DependencyScanningWorker::scanDependencies(
733735 DependencyConsumer &Consumer, DependencyActionController &Controller,
734736 DiagnosticConsumer &DC, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
735737 std::optional<StringRef> ModuleName) {
736- auto FileMgr =
737- llvm::makeIntrusiveRefCnt<FileManager>(FileSystemOptions{}, FS);
738-
739738 std::vector<const char *> CCommandLine (CommandLine.size (), nullptr );
740739 llvm::transform (CommandLine, CCommandLine.begin (),
741740 [](const std::string &Str) { return Str.c_str (); });
742741 auto DiagOpts = CreateAndPopulateDiagOpts (CCommandLine);
743742 sanitizeDiagOpts (*DiagOpts);
744- IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
745- CompilerInstance::createDiagnostics (FileMgr->getVirtualFileSystem (),
746- *DiagOpts, &DC,
747- /* ShouldOwnClient=*/ false );
748-
749- // Although `Diagnostics` are used only for command-line parsing, the
750- // custom `DiagConsumer` might expect a `SourceManager` to be present.
751- SourceManager SrcMgr (*Diags, *FileMgr);
752- Diags->setSourceManager (&SrcMgr);
753- // DisableFree is modified by Tooling for running
754- // in-process; preserve the original value, which is
755- // always true for a driver invocation.
756- bool DisableFree = true ;
743+ auto Diags = CompilerInstance::createDiagnostics (*FS, *DiagOpts, &DC,
744+ /* ShouldOwnClient=*/ false );
745+
757746 DependencyScanningAction Action (Service, WorkingDirectory, Consumer,
758- Controller, DepFS, DisableFree, ModuleName);
747+ Controller, DepFS, ModuleName);
759748
760749 bool Success = false ;
761750 if (CommandLine[1 ] == " -cc1" ) {
762- Success = createAndRunToolInvocation (CommandLine, Action, *FileMgr ,
751+ Success = createAndRunToolInvocation (CommandLine, Action, FS ,
763752 PCHContainerOps, *Diags, Consumer);
764753 } else {
765754 Success = forEachDriverJob (
766- CommandLine, *Diags, *FileMgr , [&](const driver::Command &Cmd) {
755+ CommandLine, *Diags, FS , [&](const driver::Command &Cmd) {
767756 if (StringRef (Cmd.getCreator ().getName ()) != " clang" ) {
768757 // Non-clang command. Just pass through to the dependency
769758 // consumer.
@@ -782,7 +771,7 @@ bool DependencyScanningWorker::scanDependencies(
782771 // system to ensure that any file system requests that
783772 // are made by the driver do not go through the
784773 // dependency scanning filesystem.
785- return createAndRunToolInvocation (std::move (Argv), Action, *FileMgr ,
774+ return createAndRunToolInvocation (std::move (Argv), Action, FS ,
786775 PCHContainerOps, *Diags, Consumer);
787776 });
788777 }
0 commit comments