24
24
#include " clang/Tooling/DependencyScanning/DependencyScanningService.h"
25
25
#include " clang/Tooling/DependencyScanning/InProcessModuleCache.h"
26
26
#include " clang/Tooling/DependencyScanning/ModuleDepCollector.h"
27
- #include " clang/Tooling/Tooling.h"
28
27
#include " llvm/ADT/IntrusiveRefCntPtr.h"
29
28
#include " llvm/Support/Allocator.h"
30
29
#include " llvm/Support/Error.h"
@@ -376,25 +375,23 @@ class ScanningDependencyDirectivesGetter : public DependencyDirectivesGetter {
376
375
377
376
// / A clang tool that runs the preprocessor in a mode that's optimized for
378
377
// / dependency scanning for the given compiler invocation.
379
- class DependencyScanningAction : public tooling ::ToolAction {
378
+ class DependencyScanningAction {
380
379
public:
381
380
DependencyScanningAction (
382
381
DependencyScanningService &Service, StringRef WorkingDirectory,
383
382
DependencyConsumer &Consumer, DependencyActionController &Controller,
384
383
llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS,
385
- bool DisableFree, std::optional<StringRef> ModuleName = std::nullopt)
384
+ std::optional<StringRef> ModuleName = std::nullopt)
386
385
: Service(Service), WorkingDirectory(WorkingDirectory),
387
386
Consumer (Consumer), Controller(Controller), DepFS(std::move(DepFS)),
388
- DisableFree(DisableFree), ModuleName(ModuleName) {}
387
+ ModuleName(ModuleName) {}
389
388
390
389
bool runInvocation (std::shared_ptr<CompilerInvocation> Invocation,
391
- FileManager *DriverFileMgr ,
390
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS ,
392
391
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
393
- DiagnosticConsumer *DiagConsumer) override {
392
+ DiagnosticConsumer *DiagConsumer) {
394
393
// Make a deep copy of the original Clang invocation.
395
394
CompilerInvocation OriginalInvocation (*Invocation);
396
- // Restore the value of DisableFree, which may be modified by Tooling.
397
- OriginalInvocation.getFrontendOpts ().DisableFree = DisableFree;
398
395
if (any (Service.getOptimizeArgs () & ScanningOptimizations::Macros))
399
396
canonicalizeDefines (OriginalInvocation.getPreprocessorOpts ());
400
397
@@ -419,8 +416,8 @@ class DependencyScanningAction : public tooling::ToolAction {
419
416
// Create the compiler's actual diagnostics engine.
420
417
sanitizeDiagOpts (ScanInstance.getDiagnosticOpts ());
421
418
assert (!DiagConsumerFinished && " attempt to reuse finished consumer" );
422
- ScanInstance.createDiagnostics (DriverFileMgr-> getVirtualFileSystem () ,
423
- DiagConsumer, /* ShouldOwnClient=*/ false );
419
+ ScanInstance.createDiagnostics (*FS, DiagConsumer ,
420
+ /* ShouldOwnClient=*/ false );
424
421
if (!ScanInstance.hasDiagnostics ())
425
422
return false ;
426
423
@@ -431,6 +428,7 @@ class DependencyScanningAction : public tooling::ToolAction {
431
428
ScanInstance.getHeaderSearchOpts ().BuildSessionTimestamp =
432
429
Service.getBuildSessionTimestamp ();
433
430
431
+ ScanInstance.getFrontendOpts ().DisableFree = false ;
434
432
ScanInstance.getFrontendOpts ().GenerateGlobalModuleIndex = false ;
435
433
ScanInstance.getFrontendOpts ().UseGlobalModuleIndex = false ;
436
434
// This will prevent us compiling individual modules asynchronously since
@@ -441,9 +439,9 @@ class DependencyScanningAction : public tooling::ToolAction {
441
439
any (Service.getOptimizeArgs () & ScanningOptimizations::VFS);
442
440
443
441
// 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 ));
447
445
448
446
// Create a new FileManager to match the invocation's FileSystemOptions.
449
447
auto *FileMgr = ScanInstance.createFileManager (FS);
@@ -554,9 +552,6 @@ class DependencyScanningAction : public tooling::ToolAction {
554
552
if (Result)
555
553
setLastCC1Arguments (std::move (OriginalInvocation));
556
554
557
- // Propagate the statistics to the parent FileManager.
558
- DriverFileMgr->AddStats (ScanInstance.getFileManager ());
559
-
560
555
return Result;
561
556
}
562
557
@@ -584,7 +579,6 @@ class DependencyScanningAction : public tooling::ToolAction {
584
579
DependencyConsumer &Consumer;
585
580
DependencyActionController &Controller;
586
581
llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS;
587
- bool DisableFree;
588
582
std::optional<StringRef> ModuleName;
589
583
std::optional<CompilerInstance> ScanInstanceStorage;
590
584
std::shared_ptr<ModuleDepCollector> MDC;
@@ -669,15 +663,14 @@ llvm::Error DependencyScanningWorker::computeDependencies(
669
663
}
670
664
671
665
static bool forEachDriverJob (
672
- ArrayRef<std::string> ArgStrs, DiagnosticsEngine &Diags, FileManager &FM,
666
+ ArrayRef<std::string> ArgStrs, DiagnosticsEngine &Diags,
667
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
673
668
llvm::function_ref<bool (const driver::Command &Cmd)> Callback) {
674
669
SmallVector<const char *, 256 > Argv;
675
670
Argv.reserve (ArgStrs.size ());
676
671
for (const std::string &Arg : ArgStrs)
677
672
Argv.push_back (Arg.c_str ());
678
673
679
- llvm::vfs::FileSystem *FS = &FM.getVirtualFileSystem ();
680
-
681
674
std::unique_ptr<driver::Driver> Driver = std::make_unique<driver::Driver>(
682
675
Argv[0 ], llvm::sys::getDefaultTargetTriple (), Diags,
683
676
" clang LLVM compiler" , FS);
@@ -687,7 +680,8 @@ static bool forEachDriverJob(
687
680
bool CLMode = driver::IsClangCL (
688
681
driver::getDriverMode (Argv[0 ], ArrayRef (Argv).slice (1 )));
689
682
690
- if (llvm::Error E = driver::expandResponseFiles (Argv, CLMode, Alloc, FS)) {
683
+ if (llvm::Error E =
684
+ driver::expandResponseFiles (Argv, CLMode, Alloc, FS.get ())) {
691
685
Diags.Report (diag::err_drv_expand_response_file)
692
686
<< llvm::toString (std::move (E));
693
687
return false ;
@@ -710,17 +704,25 @@ static bool forEachDriverJob(
710
704
711
705
static bool createAndRunToolInvocation (
712
706
std::vector<std::string> CommandLine, DependencyScanningAction &Action,
713
- FileManager &FM ,
707
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS ,
714
708
std::shared_ptr<clang::PCHContainerOperations> &PCHContainerOps,
715
709
DiagnosticsEngine &Diags, DependencyConsumer &Consumer) {
716
710
717
711
// Save executable path before providing CommandLine to ToolInvocation
718
712
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 ()))
724
726
return false ;
725
727
726
728
std::vector<std::string> Args = Action.takeLastCC1Arguments ();
@@ -733,37 +735,24 @@ bool DependencyScanningWorker::scanDependencies(
733
735
DependencyConsumer &Consumer, DependencyActionController &Controller,
734
736
DiagnosticConsumer &DC, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
735
737
std::optional<StringRef> ModuleName) {
736
- auto FileMgr =
737
- llvm::makeIntrusiveRefCnt<FileManager>(FileSystemOptions{}, FS);
738
-
739
738
std::vector<const char *> CCommandLine (CommandLine.size (), nullptr );
740
739
llvm::transform (CommandLine, CCommandLine.begin (),
741
740
[](const std::string &Str) { return Str.c_str (); });
742
741
auto DiagOpts = CreateAndPopulateDiagOpts (CCommandLine);
743
742
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
+
757
746
DependencyScanningAction Action (Service, WorkingDirectory, Consumer,
758
- Controller, DepFS, DisableFree, ModuleName);
747
+ Controller, DepFS, ModuleName);
759
748
760
749
bool Success = false ;
761
750
if (CommandLine[1 ] == " -cc1" ) {
762
- Success = createAndRunToolInvocation (CommandLine, Action, *FileMgr ,
751
+ Success = createAndRunToolInvocation (CommandLine, Action, FS ,
763
752
PCHContainerOps, *Diags, Consumer);
764
753
} else {
765
754
Success = forEachDriverJob (
766
- CommandLine, *Diags, *FileMgr , [&](const driver::Command &Cmd) {
755
+ CommandLine, *Diags, FS , [&](const driver::Command &Cmd) {
767
756
if (StringRef (Cmd.getCreator ().getName ()) != " clang" ) {
768
757
// Non-clang command. Just pass through to the dependency
769
758
// consumer.
@@ -782,7 +771,7 @@ bool DependencyScanningWorker::scanDependencies(
782
771
// system to ensure that any file system requests that
783
772
// are made by the driver do not go through the
784
773
// dependency scanning filesystem.
785
- return createAndRunToolInvocation (std::move (Argv), Action, *FileMgr ,
774
+ return createAndRunToolInvocation (std::move (Argv), Action, FS ,
786
775
PCHContainerOps, *Diags, Consumer);
787
776
});
788
777
}
0 commit comments