class FullDependencyConsumer : public DependencyConsumer {
public:
- FullDependencyConsumer(const llvm::StringSet<> &AlreadySeen,
- LookupModuleOutputCallback LookupModuleOutput)
- : AlreadySeen(AlreadySeen), LookupModuleOutput(LookupModuleOutput) {}
+ FullDependencyConsumer(const llvm::StringSet<> &AlreadySeen)
+ : AlreadySeen(AlreadySeen) {}
void handleBuildCommand(Command Cmd) override {
Commands.push_back(std::move(Cmd));
ContextHash = std::move(Hash);
}
- std::string lookupModuleOutput(const ModuleID &ID,
- ModuleOutputKind Kind) override {
- return LookupModuleOutput(ID, Kind);
- }
-
TranslationUnitDeps takeTranslationUnitDeps();
ModuleDepsGraph takeModuleGraphDeps();
std::string ContextHash;
std::vector<std::string> OutputPaths;
const llvm::StringSet<> &AlreadySeen;
+};
+
+/// A simple dependency action controller that uses a callback. If no callback
+/// is provided, it is assumed that looking up module outputs is unreachable.
+class CallbackActionController : public DependencyActionController {
+public:
+ virtual ~CallbackActionController();
+
+ CallbackActionController(LookupModuleOutputCallback LMO)
+ : LookupModuleOutput(std::move(LMO)) {
+ if (!LookupModuleOutput) {
+ LookupModuleOutput = [](const ModuleID &,
+ ModuleOutputKind) -> std::string {
+ llvm::report_fatal_error("unexpected call to lookupModuleOutput");
+ };
+ }
+ }
+
+ std::string lookupModuleOutput(const ModuleID &ID,
+ ModuleOutputKind Kind) override {
+ return LookupModuleOutput(ID, Kind);
+ }
+
+private:
LookupModuleOutputCallback LookupModuleOutput;
};
virtual void handleModuleDependency(ModuleDeps MD) = 0;
virtual void handleContextHash(std::string Hash) = 0;
+};
+
+/// Dependency scanner callbacks that are used during scanning to influence the
+/// behaviour of the scan - for example, to customize the scanned invocations.
+class DependencyActionController {
+public:
+ virtual ~DependencyActionController();
virtual std::string lookupModuleOutput(const ModuleID &ID,
ModuleOutputKind Kind) = 0;
bool computeDependencies(StringRef WorkingDirectory,
const std::vector<std::string> &CommandLine,
DependencyConsumer &DepConsumer,
+ DependencyActionController &Controller,
DiagnosticConsumer &DiagConsumer,
std::optional<StringRef> ModuleName = std::nullopt);
/// \returns A \c StringError with the diagnostic output if clang errors
/// occurred, success otherwise.
- llvm::Error
- computeDependencies(StringRef WorkingDirectory,
- const std::vector<std::string> &CommandLine,
- DependencyConsumer &Consumer,
- std::optional<StringRef> ModuleName = std::nullopt);
+ llvm::Error computeDependencies(
+ StringRef WorkingDirectory, const std::vector<std::string> &CommandLine,
+ DependencyConsumer &Consumer, DependencyActionController &Controller,
+ std::optional<StringRef> ModuleName = std::nullopt);
bool shouldEagerLoadModules() const { return EagerLoadModules; }
namespace tooling {
namespace dependencies {
+class DependencyActionController;
class DependencyConsumer;
/// Modular dependency that has already been built prior to the dependency scan.
public:
ModuleDepCollector(std::unique_ptr<DependencyOutputOptions> Opts,
CompilerInstance &ScanInstance, DependencyConsumer &C,
+ DependencyActionController &Controller,
CompilerInvocation OriginalCI, bool OptimizeArgs,
bool EagerLoadModules, bool IsStdModuleP1689Format);
CompilerInstance &ScanInstance;
/// The consumer of collected dependency information.
DependencyConsumer &Consumer;
+ /// Callbacks for computing dependency information.
+ DependencyActionController &Controller;
/// Path to the main source file.
std::string MainFile;
/// Hash identifying the compilation conditions of the current TU.
void handleContextHash(std::string Hash) override {}
- std::string lookupModuleOutput(const ModuleID &ID,
- ModuleOutputKind Kind) override {
- llvm::report_fatal_error("unexpected call to lookupModuleOutput");
- }
-
void printDependencies(std::string &S) {
assert(Opts && "Handled dependency output options.");
llvm::Expected<std::string> DependencyScanningTool::getDependencyFile(
const std::vector<std::string> &CommandLine, StringRef CWD) {
MakeDependencyPrinterConsumer Consumer;
- auto Result = Worker.computeDependencies(CWD, CommandLine, Consumer);
+ CallbackActionController Controller(nullptr);
+ auto Result =
+ Worker.computeDependencies(CWD, CommandLine, Consumer, Controller);
if (Result)
return std::move(Result);
std::string Output;
return Opts->OutputFile;
}
- // The lookupModuleOutput is for clang modules. P1689 format don't need it.
- std::string lookupModuleOutput(const ModuleID &ID,
- ModuleOutputKind Kind) override {
- return "";
- }
-
private:
StringRef Filename;
P1689Rule &Rule;
};
+ class P1689ActionController : public DependencyActionController {
+ public:
+ // The lookupModuleOutput is for clang modules. P1689 format don't need it.
+ std::string lookupModuleOutput(const ModuleID &,
+ ModuleOutputKind Kind) override {
+ return "";
+ }
+ };
+
P1689Rule Rule;
P1689ModuleDependencyPrinterConsumer Consumer(Rule, Command);
- auto Result = Worker.computeDependencies(CWD, Command.CommandLine, Consumer);
+ P1689ActionController Controller;
+ auto Result = Worker.computeDependencies(CWD, Command.CommandLine, Consumer,
+ Controller);
if (Result)
return std::move(Result);
const std::vector<std::string> &CommandLine, StringRef CWD,
const llvm::StringSet<> &AlreadySeen,
LookupModuleOutputCallback LookupModuleOutput) {
- FullDependencyConsumer Consumer(AlreadySeen, LookupModuleOutput);
- llvm::Error Result = Worker.computeDependencies(CWD, CommandLine, Consumer);
+ FullDependencyConsumer Consumer(AlreadySeen);
+ CallbackActionController Controller(LookupModuleOutput);
+ llvm::Error Result =
+ Worker.computeDependencies(CWD, CommandLine, Consumer, Controller);
if (Result)
return std::move(Result);
return Consumer.takeTranslationUnitDeps();
StringRef ModuleName, const std::vector<std::string> &CommandLine,
StringRef CWD, const llvm::StringSet<> &AlreadySeen,
LookupModuleOutputCallback LookupModuleOutput) {
- FullDependencyConsumer Consumer(AlreadySeen, LookupModuleOutput);
- llvm::Error Result =
- Worker.computeDependencies(CWD, CommandLine, Consumer, ModuleName);
+ FullDependencyConsumer Consumer(AlreadySeen);
+ CallbackActionController Controller(LookupModuleOutput);
+ llvm::Error Result = Worker.computeDependencies(CWD, CommandLine, Consumer,
+ Controller, ModuleName);
if (Result)
return std::move(Result);
return Consumer.takeModuleGraphDeps();
return ModuleGraph;
}
+
+CallbackActionController::~CallbackActionController() {}
public:
DependencyScanningAction(
StringRef WorkingDirectory, DependencyConsumer &Consumer,
+ DependencyActionController &Controller,
llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS,
ScanningOutputFormat Format, bool OptimizeArgs, bool EagerLoadModules,
bool DisableFree, std::optional<StringRef> ModuleName = std::nullopt)
: WorkingDirectory(WorkingDirectory), Consumer(Consumer),
- DepFS(std::move(DepFS)), Format(Format), OptimizeArgs(OptimizeArgs),
- EagerLoadModules(EagerLoadModules), DisableFree(DisableFree),
- ModuleName(ModuleName) {}
+ Controller(Controller), DepFS(std::move(DepFS)), Format(Format),
+ OptimizeArgs(OptimizeArgs), EagerLoadModules(EagerLoadModules),
+ DisableFree(DisableFree), ModuleName(ModuleName) {}
bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
FileManager *FileMgr,
case ScanningOutputFormat::P1689:
case ScanningOutputFormat::Full:
MDC = std::make_shared<ModuleDepCollector>(
- std::move(Opts), ScanInstance, Consumer, OriginalInvocation,
- OptimizeArgs, EagerLoadModules,
+ std::move(Opts), ScanInstance, Consumer, Controller,
+ OriginalInvocation, OptimizeArgs, EagerLoadModules,
Format == ScanningOutputFormat::P1689);
ScanInstance.addDependencyCollector(MDC);
break;
private:
StringRef WorkingDirectory;
DependencyConsumer &Consumer;
+ DependencyActionController &Controller;
llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS;
ScanningOutputFormat Format;
bool OptimizeArgs;
llvm::Error DependencyScanningWorker::computeDependencies(
StringRef WorkingDirectory, const std::vector<std::string> &CommandLine,
- DependencyConsumer &Consumer, std::optional<StringRef> ModuleName) {
+ DependencyConsumer &Consumer, DependencyActionController &Controller,
+ std::optional<StringRef> ModuleName) {
std::vector<const char *> CLI;
for (const std::string &Arg : CommandLine)
CLI.push_back(Arg.c_str());
llvm::raw_string_ostream DiagnosticsOS(DiagnosticOutput);
TextDiagnosticPrinter DiagPrinter(DiagnosticsOS, DiagOpts.release());
- if (computeDependencies(WorkingDirectory, CommandLine, Consumer, DiagPrinter,
- ModuleName))
+ if (computeDependencies(WorkingDirectory, CommandLine, Consumer, Controller,
+ DiagPrinter, ModuleName))
return llvm::Error::success();
return llvm::make_error<llvm::StringError>(DiagnosticsOS.str(),
llvm::inconvertibleErrorCode());
bool DependencyScanningWorker::computeDependencies(
StringRef WorkingDirectory, const std::vector<std::string> &CommandLine,
- DependencyConsumer &Consumer, DiagnosticConsumer &DC,
- std::optional<StringRef> ModuleName) {
+ DependencyConsumer &Consumer, DependencyActionController &Controller,
+ DiagnosticConsumer &DC, std::optional<StringRef> ModuleName) {
// Reset what might have been modified in the previous worker invocation.
BaseFS->setCurrentWorkingDirectory(WorkingDirectory);
// in-process; preserve the original value, which is
// always true for a driver invocation.
bool DisableFree = true;
- DependencyScanningAction Action(WorkingDirectory, Consumer, DepFS, Format,
- OptimizeArgs, EagerLoadModules, DisableFree,
- ModuleName);
+ DependencyScanningAction Action(WorkingDirectory, Consumer, Controller, DepFS,
+ Format, OptimizeArgs, EagerLoadModules,
+ DisableFree, ModuleName);
bool Success = forEachDriverJob(
FinalCommandLine, *Diags, *FileMgr, [&](const driver::Command &Cmd) {
if (StringRef(Cmd.getCreator().getName()) != "clang") {
<< llvm::join(FinalCommandLine, " ");
return Success && Action.hasScanned();
}
+
+DependencyActionController::~DependencyActionController() {}
void ModuleDepCollector::addOutputPaths(CompilerInvocation &CI,
ModuleDeps &Deps) {
CI.getFrontendOpts().OutputFile =
- Consumer.lookupModuleOutput(Deps.ID, ModuleOutputKind::ModuleFile);
+ Controller.lookupModuleOutput(Deps.ID, ModuleOutputKind::ModuleFile);
if (!CI.getDiagnosticOpts().DiagnosticSerializationFile.empty())
CI.getDiagnosticOpts().DiagnosticSerializationFile =
- Consumer.lookupModuleOutput(
+ Controller.lookupModuleOutput(
Deps.ID, ModuleOutputKind::DiagnosticSerializationFile);
if (!CI.getDependencyOutputOpts().OutputFile.empty()) {
- CI.getDependencyOutputOpts().OutputFile =
- Consumer.lookupModuleOutput(Deps.ID, ModuleOutputKind::DependencyFile);
+ CI.getDependencyOutputOpts().OutputFile = Controller.lookupModuleOutput(
+ Deps.ID, ModuleOutputKind::DependencyFile);
CI.getDependencyOutputOpts().Targets =
- splitString(Consumer.lookupModuleOutput(
+ splitString(Controller.lookupModuleOutput(
Deps.ID, ModuleOutputKind::DependencyTargets),
'\0');
if (!CI.getDependencyOutputOpts().OutputFile.empty() &&
CompilerInvocation &CI, ArrayRef<ModuleID> ClangModuleDeps) const {
for (const ModuleID &MID : ClangModuleDeps) {
std::string PCMPath =
- Consumer.lookupModuleOutput(MID, ModuleOutputKind::ModuleFile);
+ Controller.lookupModuleOutput(MID, ModuleOutputKind::ModuleFile);
if (EagerLoadModules)
CI.getFrontendOpts().ModuleFiles.push_back(std::move(PCMPath));
else
ModuleDepCollector::ModuleDepCollector(
std::unique_ptr<DependencyOutputOptions> Opts,
CompilerInstance &ScanInstance, DependencyConsumer &C,
- CompilerInvocation OriginalCI, bool OptimizeArgs, bool EagerLoadModules,
- bool IsStdModuleP1689Format)
- : ScanInstance(ScanInstance), Consumer(C), Opts(std::move(Opts)),
- OriginalInvocation(std::move(OriginalCI)), OptimizeArgs(OptimizeArgs),
- EagerLoadModules(EagerLoadModules),
+ DependencyActionController &Controller, CompilerInvocation OriginalCI,
+ bool OptimizeArgs, bool EagerLoadModules, bool IsStdModuleP1689Format)
+ : ScanInstance(ScanInstance), Consumer(C), Controller(Controller),
+ Opts(std::move(Opts)), OriginalInvocation(std::move(OriginalCI)),
+ OptimizeArgs(OptimizeArgs), EagerLoadModules(EagerLoadModules),
IsStdModuleP1689Format(IsStdModuleP1689Format) {}
void ModuleDepCollector::attachToPreprocessor(Preprocessor &PP) {