Skip to content

Commit 9e64628

Browse files
jansvoboda11qiongsiwu
authored andcommitted
[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. (cherry picked from commit aa1b416)
1 parent 5fa0165 commit 9e64628

File tree

1 file changed

+43
-58
lines changed

1 file changed

+43
-58
lines changed

clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp

Lines changed: 43 additions & 58 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,
518-
bool DiagGenerationAsCompilation, const CASOptions &CASOpts,
516+
bool EmitDependencyFile, bool DiagGenerationAsCompilation,
517+
const CASOptions &CASOpts,
519518
std::optional<StringRef> ModuleName = std::nullopt,
520519
raw_ostream *VerboseOS = nullptr)
521-
: Service(Service), WorkingDirectory(WorkingDirectory), Consumer(Consumer),
522-
Controller(Controller), DepFS(std::move(DepFS)),
520+
: Service(Service), WorkingDirectory(WorkingDirectory),
521+
Consumer(Consumer), 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,25 @@ 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;
1012-
DependencyScanningAction Action(Service, WorkingDirectory, Consumer, Controller, DepFS,
1013-
DepCASFS, CacheFS,
1014-
DisableFree,
1015-
/*EmitDependencyFile=*/false,
1016-
/*DiagGenerationAsCompilation=*/false, getCASOpts(),
1017-
ModuleName);
997+
auto Diags = CompilerInstance::createDiagnostics(*FS, *DiagOpts, &DC,
998+
/*ShouldOwnClient=*/false);
999+
1000+
DependencyScanningAction Action(
1001+
Service, WorkingDirectory, Consumer, Controller, DepFS, DepCASFS, CacheFS,
1002+
/*EmitDependencyFile=*/false,
1003+
/*DiagGenerationAsCompilation=*/false, getCASOpts(), ModuleName);
10181004
bool Success = false;
10191005
if (CommandLine[1] == "-cc1") {
1020-
Success = createAndRunToolInvocation(CommandLine, Action, *FileMgr,
1006+
Success = createAndRunToolInvocation(CommandLine, Action, FS,
10211007
PCHContainerOps, *Diags, Consumer);
10221008
} else {
10231009
Success = forEachDriverJob(
1024-
CommandLine, *Diags, *FileMgr, [&](const driver::Command &Cmd) {
1010+
CommandLine, *Diags, FS, [&](const driver::Command &Cmd) {
10251011
if (StringRef(Cmd.getCreator().getName()) != "clang") {
10261012
// Non-clang command. Just pass through to the dependency
10271013
// consumer.
@@ -1041,7 +1027,7 @@ bool DependencyScanningWorker::scanDependencies(
10411027
// system to ensure that any file system requests that
10421028
// are made by the driver do not go through the
10431029
// dependency scanning filesystem.
1044-
return createAndRunToolInvocation(std::move(Argv), Action, *FileMgr,
1030+
return createAndRunToolInvocation(std::move(Argv), Action, FS,
10451031
PCHContainerOps, *Diags, Consumer);
10461032
});
10471033
}
@@ -1171,7 +1157,6 @@ void DependencyScanningWorker::computeDependenciesFromCompilerInvocation(
11711157
// compilation.
11721158
DependencyScanningAction Action(Service, WorkingDirectory, DepsConsumer,
11731159
Controller, DepFS, DepCASFS, CacheFS,
1174-
/*DisableFree=*/false,
11751160
/*EmitDependencyFile=*/!DepFile.empty(),
11761161
DiagGenerationAsCompilation, getCASOpts(),
11771162
/*ModuleName=*/std::nullopt, VerboseOS);
@@ -1181,6 +1166,6 @@ void DependencyScanningWorker::computeDependenciesFromCompilerInvocation(
11811166
// FIXME: will clients other than -cc1scand care?
11821167
IntrusiveRefCntPtr<FileManager> ActiveFiles =
11831168
new FileManager(Invocation->getFileSystemOpts(), BaseFS);
1184-
(void)Action.runInvocation(std::move(Invocation), ActiveFiles.get(),
1185-
PCHContainerOps, &DiagsConsumer);
1169+
(void)Action.runInvocation(std::move(Invocation), BaseFS, PCHContainerOps,
1170+
&DiagsConsumer);
11861171
}

0 commit comments

Comments
 (0)