Skip to content

Commit db75b58

Browse files
committed
[clang][deps] Remove dependency on tooling::ToolAction (llvm#149904)
The dependency scanner was initially using a fair amount of infrastructure provided by the `clangTooling` library. Over time, the needs for bespoke handling of command lines grew and the overlap with the tooling library kept shrinking. I don't think the library provides any value anymore. I decided to remove the dependency and only reimplement the small bits required by the scanner. This allowed for a nice simplification, where we no longer need to create temporary dummy `FileManager` instances (mis-named as `DriverFileMgr` in some parts) and `SourceManager` instances to attach to the `DiagnosticsEngine`. That code was copied from the tooling library to support `DiagnosticConsumers` that expect these to exist. The scanner uses a closed set of consumers and none need these objects to exist. The motivation for this (hopefully NFC) patch are some new restrictions to how VFS's can be propagated in Clang that I'm working on.
1 parent 0f62bb2 commit db75b58

File tree

1 file changed

+35
-51
lines changed

1 file changed

+35
-51
lines changed

clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp

Lines changed: 35 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
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 {
510509
public:
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

924917
static 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

964957
static 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

Comments
 (0)