2828#include " clang/Tooling/DependencyScanning/InProcessModuleCache.h"
2929#include " clang/Tooling/DependencyScanning/ModuleDepCollector.h"
3030#include " clang/Tooling/DependencyScanning/ScanAndUpdateArgs.h"
31- #include " clang/Tooling/Tooling.h"
3231#include " llvm/ADT/IntrusiveRefCntPtr.h"
3332#include " llvm/CAS/CASProvidingFileSystem.h"
3433#include " llvm/CAS/CachingOnDiskFileSystem.h"
@@ -506,34 +505,31 @@ class CASDependencyDirectivesGetter : public DependencyDirectivesGetter {
506505
507506// / A clang tool that runs the preprocessor in a mode that's optimized for
508507// / dependency scanning for the given compiler invocation.
509- class DependencyScanningAction : public tooling ::ToolAction {
508+ class DependencyScanningAction {
510509public:
511510 DependencyScanningAction (
512511 DependencyScanningService &Service, StringRef WorkingDirectory,
513512 DependencyConsumer &Consumer, DependencyActionController &Controller,
514513 llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS,
515514 llvm::IntrusiveRefCntPtr<DependencyScanningCASFilesystem> DepCASFS,
516515 llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
517- bool DisableFree, bool EmitDependencyFile,
516+ bool EmitDependencyFile,
518517 bool DiagGenerationAsCompilation, const CASOptions &CASOpts,
519518 std::optional<StringRef> ModuleName = std::nullopt ,
520519 raw_ostream *VerboseOS = nullptr )
521520 : Service(Service), WorkingDirectory(WorkingDirectory), Consumer(Consumer),
522521 Controller (Controller), DepFS(std::move(DepFS)),
523522 DepCASFS(std::move(DepCASFS)), CacheFS(std::move(CacheFS)),
524- DisableFree(DisableFree),
525523 CASOpts(CASOpts), EmitDependencyFile(EmitDependencyFile),
526524 DiagGenerationAsCompilation(DiagGenerationAsCompilation),
527525 ModuleName(ModuleName), VerboseOS(VerboseOS) {}
528526
529527 bool runInvocation (std::shared_ptr<CompilerInvocation> Invocation,
530- FileManager *DriverFileMgr ,
528+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS ,
531529 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
532- DiagnosticConsumer *DiagConsumer) override {
530+ DiagnosticConsumer *DiagConsumer) {
533531 // Make a deep copy of the original Clang invocation.
534532 CompilerInvocation OriginalInvocation (*Invocation);
535- // Restore the value of DisableFree, which may be modified by Tooling.
536- OriginalInvocation.getFrontendOpts ().DisableFree = DisableFree;
537533 if (any (Service.getOptimizeArgs () & ScanningOptimizations::Macros))
538534 canonicalizeDefines (OriginalInvocation.getPreprocessorOpts ());
539535
@@ -574,8 +570,8 @@ class DependencyScanningAction : public tooling::ToolAction {
574570 if (!DiagGenerationAsCompilation)
575571 sanitizeDiagOpts (ScanInstance.getDiagnosticOpts ());
576572 assert (!DiagConsumerFinished && " attempt to reuse finished consumer" );
577- ScanInstance.createDiagnostics (DriverFileMgr-> getVirtualFileSystem () ,
578- DiagConsumer, /* ShouldOwnClient=*/ false );
573+ ScanInstance.createDiagnostics (*FS, DiagConsumer ,
574+ /* ShouldOwnClient=*/ false );
579575 if (!ScanInstance.hasDiagnostics ())
580576 return false ;
581577 if (VerboseOS)
@@ -588,6 +584,7 @@ class DependencyScanningAction : public tooling::ToolAction {
588584 ScanInstance.getHeaderSearchOpts ().BuildSessionTimestamp =
589585 Service.getBuildSessionTimestamp ();
590586
587+ ScanInstance.getFrontendOpts ().DisableFree = false ;
591588 ScanInstance.getFrontendOpts ().GenerateGlobalModuleIndex = false ;
592589 ScanInstance.getFrontendOpts ().UseGlobalModuleIndex = false ;
593590 // This will prevent us compiling individual modules asynchronously since
@@ -600,9 +597,9 @@ class DependencyScanningAction : public tooling::ToolAction {
600597 any (Service.getOptimizeArgs () & ScanningOptimizations::VFS);
601598
602599 // Support for virtual file system overlays.
603- auto FS = createVFSFromCompilerInvocation (
604- ScanInstance. getInvocation (), ScanInstance.getDiagnostics (),
605- DriverFileMgr-> getVirtualFileSystemPtr ( ));
600+ FS = createVFSFromCompilerInvocation (ScanInstance. getInvocation (),
601+ ScanInstance.getDiagnostics (),
602+ std::move (FS ));
606603
607604 // Create a new FileManager to match the invocation's FileSystemOptions.
608605 auto *FileMgr = ScanInstance.createFileManager (FS);
@@ -776,9 +773,6 @@ class DependencyScanningAction : public tooling::ToolAction {
776773 LastCC1Arguments = OriginalInvocation.getCC1CommandLine ();
777774 LastCC1CacheKey = Controller.getCacheKey (OriginalInvocation);
778775
779- // Propagate the statistics to the parent FileManager.
780- DriverFileMgr->AddStats (ScanInstance.getFileManager ());
781-
782776 return true ;
783777 }
784778
@@ -819,7 +813,6 @@ class DependencyScanningAction : public tooling::ToolAction {
819813 llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS;
820814 llvm::IntrusiveRefCntPtr<DependencyScanningCASFilesystem> DepCASFS;
821815 llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS;
822- bool DisableFree;
823816 const CASOptions &CASOpts;
824817 bool EmitDependencyFile = false ;
825818 bool DiagGenerationAsCompilation;
@@ -922,15 +915,14 @@ llvm::Error DependencyScanningWorker::computeDependencies(
922915}
923916
924917static bool forEachDriverJob (
925- ArrayRef<std::string> ArgStrs, DiagnosticsEngine &Diags, FileManager &FM,
918+ ArrayRef<std::string> ArgStrs, DiagnosticsEngine &Diags,
919+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
926920 llvm::function_ref<bool (const driver::Command &Cmd)> Callback) {
927921 SmallVector<const char *, 256 > Argv;
928922 Argv.reserve (ArgStrs.size ());
929923 for (const std::string &Arg : ArgStrs)
930924 Argv.push_back (Arg.c_str ());
931925
932- llvm::vfs::FileSystem *FS = &FM.getVirtualFileSystem ();
933-
934926 std::unique_ptr<driver::Driver> Driver = std::make_unique<driver::Driver>(
935927 Argv[0 ], llvm::sys::getDefaultTargetTriple (), Diags,
936928 " clang LLVM compiler" , FS);
@@ -940,7 +932,8 @@ static bool forEachDriverJob(
940932 bool CLMode = driver::IsClangCL (
941933 driver::getDriverMode (Argv[0 ], ArrayRef (Argv).slice (1 )));
942934
943- if (llvm::Error E = driver::expandResponseFiles (Argv, CLMode, Alloc, FS)) {
935+ if (llvm::Error E =
936+ driver::expandResponseFiles (Argv, CLMode, Alloc, FS.get ())) {
944937 Diags.Report (diag::err_drv_expand_response_file)
945938 << llvm::toString (std::move (E));
946939 return false ;
@@ -963,17 +956,25 @@ static bool forEachDriverJob(
963956
964957static bool createAndRunToolInvocation (
965958 std::vector<std::string> CommandLine, DependencyScanningAction &Action,
966- FileManager &FM ,
959+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS ,
967960 std::shared_ptr<clang::PCHContainerOperations> &PCHContainerOps,
968961 DiagnosticsEngine &Diags, DependencyConsumer &Consumer) {
969962
970963 // Save executable path before providing CommandLine to ToolInvocation
971964 std::string Executable = CommandLine[0 ];
972- ToolInvocation Invocation (std::move (CommandLine), &Action, &FM,
973- PCHContainerOps);
974- Invocation.setDiagnosticConsumer (Diags.getClient ());
975- Invocation.setDiagnosticOptions (&Diags.getDiagnosticOptions ());
976- if (!Invocation.run ())
965+
966+ llvm::opt::ArgStringList Argv;
967+ for (const std::string &Str : ArrayRef (CommandLine).drop_front ())
968+ Argv.push_back (Str.c_str ());
969+
970+ auto Invocation = std::make_shared<CompilerInvocation>();
971+ if (!CompilerInvocation::CreateFromArgs (*Invocation, Argv, Diags)) {
972+ // FIXME: Should we just go on like cc1_main does?
973+ return false ;
974+ }
975+
976+ if (!Action.runInvocation (std::move (Invocation), std::move (FS),
977+ PCHContainerOps, Diags.getClient ()))
977978 return false ;
978979
979980 std::vector<std::string> Args = Action.takeLastCC1Arguments ();
@@ -988,40 +989,26 @@ bool DependencyScanningWorker::scanDependencies(
988989 DependencyConsumer &Consumer, DependencyActionController &Controller,
989990 DiagnosticConsumer &DC, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
990991 std::optional<StringRef> ModuleName) {
991- auto FileMgr =
992- llvm::makeIntrusiveRefCnt<FileManager>(FileSystemOptions{}, FS);
993-
994992 std::vector<const char *> CCommandLine (CommandLine.size (), nullptr );
995993 llvm::transform (CommandLine, CCommandLine.begin (),
996994 [](const std::string &Str) { return Str.c_str (); });
997995 auto DiagOpts = CreateAndPopulateDiagOpts (CCommandLine);
998996 sanitizeDiagOpts (*DiagOpts);
999- IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
1000- CompilerInstance::createDiagnostics (FileMgr->getVirtualFileSystem (),
1001- *DiagOpts, &DC,
1002- /* ShouldOwnClient=*/ false );
1003-
1004- // Although `Diagnostics` are used only for command-line parsing, the
1005- // custom `DiagConsumer` might expect a `SourceManager` to be present.
1006- SourceManager SrcMgr (*Diags, *FileMgr);
1007- Diags->setSourceManager (&SrcMgr);
1008- // DisableFree is modified by Tooling for running
1009- // in-process; preserve the original value, which is
1010- // always true for a driver invocation.
1011- bool DisableFree = true ;
997+ auto Diags = CompilerInstance::createDiagnostics (*FS, *DiagOpts, &DC,
998+ /* ShouldOwnClient=*/ false );
999+
10121000 DependencyScanningAction Action (Service, WorkingDirectory, Consumer, Controller, DepFS,
10131001 DepCASFS, CacheFS,
1014- DisableFree,
10151002 /* EmitDependencyFile=*/ false ,
10161003 /* DiagGenerationAsCompilation=*/ false , getCASOpts (),
10171004 ModuleName);
10181005 bool Success = false ;
10191006 if (CommandLine[1 ] == " -cc1" ) {
1020- Success = createAndRunToolInvocation (CommandLine, Action, *FileMgr ,
1007+ Success = createAndRunToolInvocation (CommandLine, Action, FS ,
10211008 PCHContainerOps, *Diags, Consumer);
10221009 } else {
10231010 Success = forEachDriverJob (
1024- CommandLine, *Diags, *FileMgr , [&](const driver::Command &Cmd) {
1011+ CommandLine, *Diags, FS , [&](const driver::Command &Cmd) {
10251012 if (StringRef (Cmd.getCreator ().getName ()) != " clang" ) {
10261013 // Non-clang command. Just pass through to the dependency
10271014 // consumer.
@@ -1041,7 +1028,7 @@ bool DependencyScanningWorker::scanDependencies(
10411028 // system to ensure that any file system requests that
10421029 // are made by the driver do not go through the
10431030 // dependency scanning filesystem.
1044- return createAndRunToolInvocation (std::move (Argv), Action, *FileMgr ,
1031+ return createAndRunToolInvocation (std::move (Argv), Action, FS ,
10451032 PCHContainerOps, *Diags, Consumer);
10461033 });
10471034 }
@@ -1171,16 +1158,13 @@ void DependencyScanningWorker::computeDependenciesFromCompilerInvocation(
11711158 // compilation.
11721159 DependencyScanningAction Action (Service, WorkingDirectory, DepsConsumer,
11731160 Controller, DepFS, DepCASFS, CacheFS,
1174- /* DisableFree=*/ false ,
11751161 /* EmitDependencyFile=*/ !DepFile.empty (),
11761162 DiagGenerationAsCompilation, getCASOpts (),
11771163 /* ModuleName=*/ std::nullopt , VerboseOS);
11781164
11791165 // Ignore result; we're just collecting dependencies.
11801166 //
11811167 // FIXME: will clients other than -cc1scand care?
1182- IntrusiveRefCntPtr<FileManager> ActiveFiles =
1183- new FileManager (Invocation->getFileSystemOpts (), BaseFS);
1184- (void )Action.runInvocation (std::move (Invocation), ActiveFiles.get (),
1168+ (void )Action.runInvocation (std::move (Invocation), BaseFS,
11851169 PCHContainerOps, &DiagsConsumer);
11861170}
0 commit comments