Skip to content

Commit 436c999

Browse files
committed
[clang][DependencyScanning] Move driver-command logic for by-name scanning into DependencyScanningTool
This is the second patch in a series that removes the dependency of clangDependencyScanning on clangDriver, splitting the work from #169964 into smaller changes (see comment linked below). This patch updates the by-name scanning interface in DependencyScanningWorker to accept only -cc1 command lines and moves the logic for handling driver-style command lines into DependencyScanningTool in clangTooling. Support for -cc1 command lines in by-name scanning is introduced in this patch. The next patch will update the remaining parts of DependencyScanningWorker to operate only on -cc1 command lines, allowing its dependency on clangDriver to be removed. #169964 (review)
1 parent bb926c1 commit 436c999

File tree

9 files changed

+205
-137
lines changed

9 files changed

+205
-137
lines changed

clang/include/clang/DependencyScanning/DependencyScannerImpl.h

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "clang/Frontend/CompilerInvocation.h"
1818
#include "clang/Frontend/TextDiagnosticPrinter.h"
1919
#include "clang/Serialization/ObjectFilePCHContainerReader.h"
20+
#include "llvm/Support/VirtualFileSystem.h"
2021

2122
namespace clang {
2223
class DiagnosticConsumer;
@@ -63,15 +64,15 @@ class DependencyScanningAction {
6364
std::unique_ptr<DiagnosticOptions>
6465
createDiagOptions(ArrayRef<std::string> CommandLine);
6566

66-
struct DignosticsEngineWithDiagOpts {
67+
struct DiagnosticsEngineWithDiagOpts {
6768
// We need to bound the lifetime of the DiagOpts used to create the
6869
// DiganosticsEngine with the DiagnosticsEngine itself.
6970
std::unique_ptr<DiagnosticOptions> DiagOpts;
7071
IntrusiveRefCntPtr<DiagnosticsEngine> DiagEngine;
7172

72-
DignosticsEngineWithDiagOpts(ArrayRef<std::string> CommandLine,
73-
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
74-
DiagnosticConsumer &DC);
73+
DiagnosticsEngineWithDiagOpts(ArrayRef<std::string> CommandLine,
74+
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
75+
DiagnosticConsumer &DC);
7576
};
7677

7778
struct TextDiagnosticsPrinterWithOutput {
@@ -143,22 +144,11 @@ class CompilerInstanceWithContext {
143144
llvm::StringRef CWD;
144145
std::vector<std::string> CommandLine;
145146

146-
// Context - file systems
147-
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS;
148-
149147
// Context - Diagnostics engine.
150-
std::unique_ptr<TextDiagnosticsPrinterWithOutput> DiagPrinterWithOS;
151-
// DiagConsumer may points to DiagPrinterWithOS->DiagPrinter, or a custom
152-
// DiagnosticConsumer passed in from initialize.
153148
DiagnosticConsumer *DiagConsumer = nullptr;
154-
std::unique_ptr<DignosticsEngineWithDiagOpts> DiagEngineWithCmdAndOpts;
149+
std::unique_ptr<DiagnosticsEngineWithDiagOpts> DiagEngineWithCmdAndOpts;
155150

156151
// Context - compiler invocation
157-
// Compilation's command's arguments may be owned by Alloc when expanded from
158-
// response files, so we need to keep Alloc alive in the context.
159-
llvm::BumpPtrAllocator Alloc;
160-
std::unique_ptr<clang::driver::Driver> Driver;
161-
std::unique_ptr<clang::driver::Compilation> Compilation;
162152
std::unique_ptr<CompilerInvocation> OriginalInvocation;
163153

164154
// Context - output options
@@ -180,15 +170,13 @@ class CompilerInstanceWithContext {
180170
: Worker(Worker), CWD(CWD), CommandLine(CMD) {};
181171

182172
// The three methods below returns false when they fail, with the detail
183-
// accumulated in DiagConsumer.
184-
bool initialize(DiagnosticConsumer *DC);
173+
// accumulated in \c DiagEngineWithDiagOpts's diagnostic consumer.
174+
bool initialize(
175+
std::unique_ptr<DiagnosticsEngineWithDiagOpts> DiagEngineWithDiagOpts,
176+
IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS);
185177
bool computeDependencies(StringRef ModuleName, DependencyConsumer &Consumer,
186178
DependencyActionController &Controller);
187179
bool finalize();
188-
189-
// The method below turns the return status from the above methods
190-
// into an llvm::Error using a default DiagnosticConsumer.
191-
llvm::Error handleReturnStatus(bool Success);
192180
};
193181
} // namespace dependencies
194182
} // namespace clang

clang/include/clang/DependencyScanning/DependencyScanningWorker.h

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@
1212
#include "clang/Basic/DiagnosticOptions.h"
1313
#include "clang/Basic/FileManager.h"
1414
#include "clang/Basic/LLVM.h"
15+
#include "clang/DependencyScanning/DependencyScannerImpl.h"
1516
#include "clang/DependencyScanning/DependencyScanningService.h"
1617
#include "clang/DependencyScanning/ModuleDepCollector.h"
1718
#include "clang/Frontend/PCHContainerOperations.h"
1819
#include "llvm/Support/Error.h"
1920
#include "llvm/Support/FileSystem.h"
2021
#include "llvm/Support/MemoryBufferRef.h"
22+
#include "llvm/Support/VirtualFileSystem.h"
2123
#include <optional>
2224
#include <string>
2325

@@ -119,42 +121,44 @@ class DependencyScanningWorker {
119121
/// dependency scanning. They together enable the dependency scanning worker
120122
/// to more effectively perform scanning for a sequence of modules
121123
/// by name when the CWD and CommandLine do not change across the queries.
124+
/// The initialization function asks the client for a DiagnosticsConsumer
125+
/// that it direct the diagnostics to.
122126

123127
/// @brief Initializing the context and the compiler instance.
124128
/// @param CWD The current working directory used during the scan.
125129
/// @param CommandLine The commandline used for the scan.
126-
/// @return Error if the initializaiton fails.
127-
llvm::Error initializeCompilerInstanceWithContextOrError(
128-
StringRef CWD, ArrayRef<std::string> CommandLine);
130+
/// @return False if the initializaiton fails.
131+
bool initializeCompilerInstanceWithContext(StringRef CWD,
132+
ArrayRef<std::string> CommandLine,
133+
DiagnosticConsumer &DC);
134+
135+
/// @brief Initializing the context and the compiler instance.
136+
/// @param CWD The current working directory used during the scan.
137+
/// @param CommandLine The commandline used for the scan.
138+
/// @param DiagEngineWithCmdAndOpts Preconfigured diagnostics engine and
139+
/// options associated with the cc1 command line.
140+
/// @param FS The overlay file system to use for this compiler instance.
141+
/// @return False if the initializaiton fails.
142+
bool initializeCompilerInstanceWithContext(
143+
StringRef CWD, ArrayRef<std::string> CommandLine,
144+
std::unique_ptr<DiagnosticsEngineWithDiagOpts> DiagEngineWithCmdAndOpts,
145+
IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS);
129146

130147
/// @brief Performaces dependency scanning for the module whose name is
131148
/// specified.
132149
/// @param ModuleName The name of the module whose dependency will be
133150
/// scanned.
134151
/// @param Consumer The dependency consumer that stores the results.
135152
/// @param Controller The controller for the dependency scanning action.
136-
/// @return Error if the scanner incurs errors.
137-
llvm::Error computeDependenciesByNameWithContextOrError(
138-
StringRef ModuleName, DependencyConsumer &Consumer,
139-
DependencyActionController &Controller);
140-
141-
/// @brief Finalizes the diagnostics engine and deletes the compiler instance.
142-
/// @return Error if errors occur during finalization.
143-
llvm::Error finalizeCompilerInstanceWithContextOrError();
144-
145-
/// The three methods below provides the same functionality as the
146-
/// three methods above. Instead of returning `llvm::Error`s, these
147-
/// three methods return a flag to indicate if the call is successful.
148-
/// The initialization function asks the client for a DiagnosticsConsumer
149-
/// that it direct the diagnostics to.
150-
bool initializeCompilerInstanceWithContext(StringRef CWD,
151-
ArrayRef<std::string> CommandLine,
152-
DiagnosticConsumer *DC = nullptr);
153+
/// @return False if the scanner incurs errors.
153154
bool
154155
computeDependenciesByNameWithContext(StringRef ModuleName,
155156
DependencyConsumer &Consumer,
156157
DependencyActionController &Controller);
157-
bool finalizeCompilerInstance();
158+
159+
/// @brief Finalizes the diagnostics engine and deletes the compiler instance.
160+
/// @return False if errors occur during finalization.
161+
bool finalizeCompilerInstanceWithContext();
158162

159163
llvm::vfs::FileSystem &getVFS() const { return *DepFS; }
160164

clang/include/clang/Tooling/DependencyScanningTool.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNINGTOOL_H
1010
#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNINGTOOL_H
1111

12+
#include "clang/DependencyScanning/DependencyScannerImpl.h"
1213
#include "clang/DependencyScanning/DependencyScanningService.h"
1314
#include "clang/DependencyScanning/DependencyScanningUtils.h"
1415
#include "clang/DependencyScanning/DependencyScanningWorker.h"
@@ -119,9 +120,8 @@ class DependencyScanningTool {
119120
/// @param CWD The current working directory used during the scan.
120121
/// @param CommandLine The commandline used for the scan.
121122
/// @return Error if the initializaiton fails.
122-
llvm::Error
123-
initializeCompilerInstanceWithContext(StringRef CWD,
124-
ArrayRef<std::string> CommandLine);
123+
llvm::Error initializeCompilerInstanceWithContextOrError(
124+
StringRef CWD, ArrayRef<std::string> CommandLine);
125125

126126
/// @brief Computes the dependeny for the module named ModuleName.
127127
/// @param ModuleName The name of the module for which this method computes
@@ -137,8 +137,8 @@ class DependencyScanningTool {
137137
/// arguments for dependencies.
138138
/// @return An instance of \c TranslationUnitDeps if the scan is successful.
139139
/// Otherwise it returns an error.
140-
llvm::Expected<dependencies::TranslationUnitDeps>
141-
computeDependenciesByNameWithContext(
140+
llvm::Expected<clang::dependencies::TranslationUnitDeps>
141+
computeDependenciesByNameWithContextOrError(
142142
StringRef ModuleName,
143143
const llvm::DenseSet<dependencies::ModuleID> &AlreadySeen,
144144
dependencies::LookupModuleOutputCallback LookupModuleOutput);
@@ -147,7 +147,7 @@ class DependencyScanningTool {
147147
/// diagnostics and deletes the compiler instance. Call this method
148148
/// once all names for a same commandline are scanned.
149149
/// @return Error if an error occured during finalization.
150-
llvm::Error finalizeCompilerInstanceWithContext();
150+
llvm::Error finalizeCompilerInstanceWithContextOrError();
151151

152152
llvm::vfs::FileSystem &getWorkerVFS() const { return Worker.getVFS(); }
153153

clang/lib/DependencyScanning/DependencyScannerImpl.cpp

Lines changed: 25 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "clang/Driver/Driver.h"
1414
#include "clang/Frontend/FrontendActions.h"
1515
#include "llvm/ADT/ScopeExit.h"
16+
#include "llvm/Support/VirtualFileSystem.h"
1617
#include "llvm/TargetParser/Host.h"
1718

1819
using namespace clang;
@@ -367,7 +368,7 @@ dependencies::createDiagOptions(ArrayRef<std::string> CommandLine) {
367368
return DiagOpts;
368369
}
369370

370-
DignosticsEngineWithDiagOpts::DignosticsEngineWithDiagOpts(
371+
DiagnosticsEngineWithDiagOpts::DiagnosticsEngineWithDiagOpts(
371372
ArrayRef<std::string> CommandLine,
372373
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, DiagnosticConsumer &DC) {
373374
std::vector<const char *> CCommandLine(CommandLine.size(), nullptr);
@@ -713,38 +714,31 @@ bool DependencyScanningAction::runInvocation(
713714
return Result;
714715
}
715716

716-
bool CompilerInstanceWithContext::initialize(DiagnosticConsumer *DC) {
717-
if (DC) {
718-
DiagConsumer = DC;
719-
} else {
720-
DiagPrinterWithOS =
721-
std::make_unique<TextDiagnosticsPrinterWithOutput>(CommandLine);
722-
DiagConsumer = &DiagPrinterWithOS->DiagPrinter;
717+
bool CompilerInstanceWithContext::initialize(
718+
std::unique_ptr<DiagnosticsEngineWithDiagOpts> DiagEngineWithDiagOpts,
719+
IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS) {
720+
assert(DiagEngineWithDiagOpts && "Valid diagnostics engine required!");
721+
DiagEngineWithCmdAndOpts = std::move(DiagEngineWithDiagOpts);
722+
DiagConsumer = DiagEngineWithCmdAndOpts->DiagEngine->getClient();
723+
724+
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = Worker.DepFS;
725+
if (OverlayFS) {
726+
#ifndef NDEBUG
727+
bool SawDepFS = false;
728+
OverlayFS->visit([&](llvm::vfs::FileSystem &VFS) {
729+
SawDepFS |= &VFS == Worker.DepFS.get();
730+
});
731+
assert(SawDepFS && "OverlayFS not based on DepFS");
732+
#endif
733+
FS = std::move(OverlayFS);
723734
}
724735

725-
std::tie(OverlayFS, CommandLine) = initVFSForByNameScanning(
726-
Worker.DepFS, CommandLine, CWD, "ScanningByName");
727-
728-
DiagEngineWithCmdAndOpts = std::make_unique<DignosticsEngineWithDiagOpts>(
729-
CommandLine, OverlayFS, *DiagConsumer);
730-
731-
std::tie(Driver, Compilation) = buildCompilation(
732-
CommandLine, *DiagEngineWithCmdAndOpts->DiagEngine, OverlayFS, Alloc);
733-
734-
if (!Compilation)
735-
return false;
736+
// Reset what might have been modified in the previous worker invocation.
737+
FS->setCurrentWorkingDirectory(CWD);
736738

737-
assert(Compilation->getJobs().size() &&
738-
"Must have a job list of non-zero size");
739-
const driver::Command &Command = *(Compilation->getJobs().begin());
740-
const auto &CommandArgs = Command.getArguments();
741-
assert(!CommandArgs.empty() && "Cannot have a command with 0 args");
742-
assert(StringRef(CommandArgs[0]) == "-cc1" && "Requires a cc1 job.");
743-
OriginalInvocation = std::make_unique<CompilerInvocation>();
744-
745-
if (!CompilerInvocation::CreateFromArgs(*OriginalInvocation, CommandArgs,
746-
*DiagEngineWithCmdAndOpts->DiagEngine,
747-
Command.getExecutable())) {
739+
OriginalInvocation = createCompilerInvocation(
740+
CommandLine, *DiagEngineWithCmdAndOpts->DiagEngine);
741+
if (!OriginalInvocation) {
748742
DiagEngineWithCmdAndOpts->DiagEngine->Report(
749743
diag::err_fe_expected_compiler_job)
750744
<< llvm::join(CommandLine, " ");
@@ -763,7 +757,7 @@ bool CompilerInstanceWithContext::initialize(DiagnosticConsumer *DC) {
763757
auto &CI = *CIPtr;
764758

765759
if (!initializeScanCompilerInstance(
766-
CI, OverlayFS, DiagEngineWithCmdAndOpts->DiagEngine->getClient(),
760+
CI, FS, DiagEngineWithCmdAndOpts->DiagEngine->getClient(),
767761
Worker.Service, Worker.DepFS))
768762
return false;
769763

@@ -876,11 +870,3 @@ bool CompilerInstanceWithContext::finalize() {
876870
DiagConsumer->finish();
877871
return true;
878872
}
879-
880-
llvm::Error CompilerInstanceWithContext::handleReturnStatus(bool Success) {
881-
assert(DiagPrinterWithOS && "Must use the default DiagnosticConsumer.");
882-
return Success ? llvm::Error::success()
883-
: llvm::make_error<llvm::StringError>(
884-
DiagPrinterWithOS->DiagnosticsOS.str(),
885-
llvm::inconvertibleErrorCode());
886-
}

clang/lib/DependencyScanning/DependencyScanningWorker.cpp

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "clang/DependencyScanning/DependencyScanningWorker.h"
10+
#include "clang/Basic/Diagnostic.h"
1011
#include "clang/Basic/DiagnosticFrontend.h"
1112
#include "clang/DependencyScanning/DependencyScannerImpl.h"
1213
#include "clang/Driver/Driver.h"
1314
#include "clang/Driver/Tool.h"
15+
#include "clang/Serialization/ObjectFilePCHContainerReader.h"
16+
#include "llvm/Support/VirtualFileSystem.h"
1417

1518
using namespace clang;
1619
using namespace dependencies;
@@ -100,7 +103,7 @@ bool DependencyScanningWorker::scanDependencies(
100103
FS = std::move(OverlayFS);
101104
}
102105

103-
DignosticsEngineWithDiagOpts DiagEngineWithCmdAndOpts(CommandLine, FS, DC);
106+
DiagnosticsEngineWithDiagOpts DiagEngineWithCmdAndOpts(CommandLine, FS, DC);
104107
DependencyScanningAction Action(Service, WorkingDirectory, Consumer,
105108
Controller, DepFS);
106109

@@ -165,33 +168,29 @@ bool DependencyScanningWorker::computeDependencies(
165168
DC);
166169
}
167170

168-
llvm::Error
169-
DependencyScanningWorker::initializeCompilerInstanceWithContextOrError(
170-
StringRef CWD, ArrayRef<std::string> CommandLine) {
171-
bool Success = initializeCompilerInstanceWithContext(CWD, CommandLine);
172-
return CIWithContext->handleReturnStatus(Success);
173-
}
174-
175-
llvm::Error
176-
DependencyScanningWorker::computeDependenciesByNameWithContextOrError(
177-
StringRef ModuleName, DependencyConsumer &Consumer,
178-
DependencyActionController &Controller) {
179-
bool Success =
180-
computeDependenciesByNameWithContext(ModuleName, Consumer, Controller);
181-
return CIWithContext->handleReturnStatus(Success);
182-
}
183-
184-
llvm::Error
185-
DependencyScanningWorker::finalizeCompilerInstanceWithContextOrError() {
186-
bool Success = finalizeCompilerInstance();
187-
return CIWithContext->handleReturnStatus(Success);
171+
bool DependencyScanningWorker::initializeCompilerInstanceWithContext(
172+
StringRef CWD, ArrayRef<std::string> CommandLine, DiagnosticConsumer &DC) {
173+
auto OverlayFSAndArgs =
174+
initVFSForByNameScanning(DepFS, CommandLine, CWD, "ScanningByName");
175+
auto &OverlayFS = OverlayFSAndArgs.first;
176+
const auto &ModifiedCommandLine = OverlayFSAndArgs.second;
177+
178+
auto DiagEngineWithCmdAndOpts =
179+
std::make_unique<DiagnosticsEngineWithDiagOpts>(ModifiedCommandLine,
180+
OverlayFS, DC);
181+
182+
return initializeCompilerInstanceWithContext(
183+
CWD, ModifiedCommandLine, std::move(DiagEngineWithCmdAndOpts), OverlayFS);
188184
}
189185

190186
bool DependencyScanningWorker::initializeCompilerInstanceWithContext(
191-
StringRef CWD, ArrayRef<std::string> CommandLine, DiagnosticConsumer *DC) {
187+
StringRef CWD, ArrayRef<std::string> CommandLine,
188+
std::unique_ptr<DiagnosticsEngineWithDiagOpts> DiagEngineWithDiagOpts,
189+
IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS) {
192190
CIWithContext =
193191
std::make_unique<CompilerInstanceWithContext>(*this, CWD, CommandLine);
194-
return CIWithContext->initialize(DC);
192+
return CIWithContext->initialize(std::move(DiagEngineWithDiagOpts),
193+
OverlayFS);
195194
}
196195

197196
bool DependencyScanningWorker::computeDependenciesByNameWithContext(
@@ -201,6 +200,6 @@ bool DependencyScanningWorker::computeDependenciesByNameWithContext(
201200
return CIWithContext->computeDependencies(ModuleName, Consumer, Controller);
202201
}
203202

204-
bool DependencyScanningWorker::finalizeCompilerInstance() {
203+
bool DependencyScanningWorker::finalizeCompilerInstanceWithContext() {
205204
return CIWithContext->finalize();
206205
}

0 commit comments

Comments
 (0)