[clang] [clang][deps] Simplify by-module-name scan API (PR #184376)
Jan Svoboda via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 5 08:12:28 PST 2026
https://github.com/jansvoboda11 updated https://github.com/llvm/llvm-project/pull/184376
>From 2dae7abb05404e19af480ace773b5b6c694484f5 Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Mon, 2 Mar 2026 08:26:15 -0800
Subject: [PATCH 1/4] Lift by-name Worker APIs to Tool
---
.../DependencyScanningWorker.h | 40 -------------------
.../clang/Tooling/DependencyScanningTool.h | 7 ++--
.../DependencyScanningWorker.cpp | 28 -------------
clang/lib/Tooling/DependencyScanningTool.cpp | 33 +++++++++------
4 files changed, 24 insertions(+), 84 deletions(-)
diff --git a/clang/include/clang/DependencyScanning/DependencyScanningWorker.h b/clang/include/clang/DependencyScanning/DependencyScanningWorker.h
index 9267c25c93ee9..5506d9f78d9fc 100644
--- a/clang/include/clang/DependencyScanning/DependencyScanningWorker.h
+++ b/clang/include/clang/DependencyScanning/DependencyScanningWorker.h
@@ -125,45 +125,6 @@ class DependencyScanningWorker {
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS =
nullptr);
- /// The two method below implements a new interface for by name
- /// dependency scanning. They together enable the dependency scanning worker
- /// to more effectively perform scanning for a sequence of modules
- /// by name when the CWD and CommandLine do not change across the queries.
- /// The initialization function asks the client for a DiagnosticsConsumer
- /// that it direct the diagnostics to.
-
- /// @brief Initializing the context and the compiler instance.
- /// @param CWD The current working directory used during the scan.
- /// @param CommandLine The commandline used for the scan.
- /// @return False if the initializaiton fails.
- bool initializeCompilerInstanceWithContext(StringRef CWD,
- ArrayRef<std::string> CommandLine,
- DiagnosticConsumer &DC);
-
- /// @brief Initializing the context and the compiler instance.
- /// @param CWD The current working directory used during the scan.
- /// @param CommandLine The commandline used for the scan.
- /// @param DiagEngineWithCmdAndOpts Preconfigured diagnostics engine and
- /// options associated with the cc1 command line.
- /// @param FS The overlay file system to use for this compiler instance.
- /// @return False if the initializaiton fails.
- bool initializeCompilerInstanceWithContext(
- StringRef CWD, ArrayRef<std::string> CommandLine,
- std::unique_ptr<DiagnosticsEngineWithDiagOpts> DiagEngineWithCmdAndOpts,
- IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS);
-
- /// @brief Performaces dependency scanning for the module whose name is
- /// specified.
- /// @param ModuleName The name of the module whose dependency will be
- /// scanned.
- /// @param Consumer The dependency consumer that stores the results.
- /// @param Controller The controller for the dependency scanning action.
- /// @return False if the scanner incurs errors.
- bool
- computeDependenciesByNameWithContext(StringRef ModuleName,
- DependencyConsumer &Consumer,
- DependencyActionController &Controller);
-
llvm::vfs::FileSystem &getVFS() const { return *DepFS; }
private:
@@ -175,7 +136,6 @@ class DependencyScanningWorker {
IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS;
friend CompilerInstanceWithContext;
- std::unique_ptr<CompilerInstanceWithContext> CIWithContext;
};
std::pair<IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem>,
diff --git a/clang/include/clang/Tooling/DependencyScanningTool.h b/clang/include/clang/Tooling/DependencyScanningTool.h
index cd7bab37bd917..694c1cb2a1f72 100644
--- a/clang/include/clang/Tooling/DependencyScanningTool.h
+++ b/clang/include/clang/Tooling/DependencyScanningTool.h
@@ -147,10 +147,10 @@ class DependencyScanningTool {
llvm::vfs::FileSystem &getWorkerVFS() const { return Worker.getVFS(); }
- /// @brief Initialize the worker's compiler instance from the commandline.
+ /// @brief Initialize the tool's compiler instance from the commandline.
/// The compiler instance only takes a `-cc1` job, so this method
/// builds the `-cc1` job from the CommandLine input.
- /// @param Worker The dependency scanning worker whose compiler instance
+ /// @param Tool The dependency scanning tool whose compiler instance
/// with context is initialized.
/// @param CWD The current working directory.
/// @param CommandLine This command line may be a driver command or a cc1
@@ -158,13 +158,14 @@ class DependencyScanningTool {
/// @param DC A diagnostics consumer to report error if the initialization
/// fails.
static bool initializeWorkerCIWithContextFromCommandline(
- clang::dependencies::DependencyScanningWorker &Worker, StringRef CWD,
+ DependencyScanningTool &Tool, StringRef CWD,
ArrayRef<std::string> CommandLine, DiagnosticConsumer &DC);
private:
dependencies::DependencyScanningWorker Worker;
std::unique_ptr<dependencies::TextDiagnosticsPrinterWithOutput>
DiagPrinterWithOS;
+ std::unique_ptr<dependencies::CompilerInstanceWithContext> CIWithContext;
};
/// Run the dependency scanning worker for the given driver or frontend
diff --git a/clang/lib/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/DependencyScanning/DependencyScanningWorker.cpp
index 4c24642c437c3..7a7f34a43b338 100644
--- a/clang/lib/DependencyScanning/DependencyScanningWorker.cpp
+++ b/clang/lib/DependencyScanning/DependencyScanningWorker.cpp
@@ -109,34 +109,6 @@ bool DependencyScanningWorker::computeDependencies(
return Success && Action.hasScanned();
}
-bool DependencyScanningWorker::initializeCompilerInstanceWithContext(
- StringRef CWD, ArrayRef<std::string> CommandLine, DiagnosticConsumer &DC) {
- auto [OverlayFS, ModifiedCommandLine] =
- initVFSForByNameScanning(DepFS, CommandLine, CWD, "ScanningByName");
- auto DiagEngineWithCmdAndOpts =
- std::make_unique<DiagnosticsEngineWithDiagOpts>(ModifiedCommandLine,
- OverlayFS, DC);
- return initializeCompilerInstanceWithContext(
- CWD, ModifiedCommandLine, std::move(DiagEngineWithCmdAndOpts), OverlayFS);
-}
-
-bool DependencyScanningWorker::initializeCompilerInstanceWithContext(
- StringRef CWD, ArrayRef<std::string> CommandLine,
- std::unique_ptr<DiagnosticsEngineWithDiagOpts> DiagEngineWithDiagOpts,
- IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS) {
- CIWithContext =
- std::make_unique<CompilerInstanceWithContext>(*this, CWD, CommandLine);
- return CIWithContext->initialize(std::move(DiagEngineWithDiagOpts),
- OverlayFS);
-}
-
-bool DependencyScanningWorker::computeDependenciesByNameWithContext(
- StringRef ModuleName, DependencyConsumer &Consumer,
- DependencyActionController &Controller) {
- assert(CIWithContext && "CompilerInstance with context required!");
- return CIWithContext->computeDependencies(ModuleName, Consumer, Controller);
-}
-
std::pair<IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem>,
std::vector<std::string>>
dependencies::initVFSForTUBufferScanning(
diff --git a/clang/lib/Tooling/DependencyScanningTool.cpp b/clang/lib/Tooling/DependencyScanningTool.cpp
index 26f07286f18c4..79a84f0148fcf 100644
--- a/clang/lib/Tooling/DependencyScanningTool.cpp
+++ b/clang/lib/Tooling/DependencyScanningTool.cpp
@@ -313,30 +313,37 @@ static std::optional<SmallVector<std::string, 0>> getFirstCC1CommandLine(
}
bool DependencyScanningTool::initializeWorkerCIWithContextFromCommandline(
- DependencyScanningWorker &Worker, StringRef CWD,
+ DependencyScanningTool &Tool, StringRef CWD,
ArrayRef<std::string> CommandLine, DiagnosticConsumer &DC) {
+ auto [OverlayFS, ModifiedCommandLine] = initVFSForByNameScanning(
+ &Tool.Worker.getVFS(), CommandLine, CWD, "ScanningByName");
+ auto DiagEngineWithCmdAndOpts =
+ std::make_unique<DiagnosticsEngineWithDiagOpts>(ModifiedCommandLine,
+ OverlayFS, DC);
+
if (CommandLine.size() >= 2 && CommandLine[1] == "-cc1") {
// The input command line is already a -cc1 invocation; initialize the
// compiler instance directly from it.
- return Worker.initializeCompilerInstanceWithContext(CWD, CommandLine, DC);
+ Tool.CIWithContext = std::make_unique<CompilerInstanceWithContext>(
+ Tool.Worker, CWD, CommandLine);
+ return Tool.CIWithContext->initialize(std::move(DiagEngineWithCmdAndOpts),
+ OverlayFS);
}
// The input command line is either a driver-style command line, or
// ill-formed. In this case, we will first call the Driver to build a -cc1
// command line for this compilation or diagnose any ill-formed input.
- auto [OverlayFS, ModifiedCommandLine] = initVFSForByNameScanning(
- &Worker.getVFS(), CommandLine, CWD, "ScanningByName");
- auto DiagEngineWithCmdAndOpts =
- std::make_unique<DiagnosticsEngineWithDiagOpts>(ModifiedCommandLine,
- OverlayFS, DC);
-
const auto MaybeFirstCC1 = getFirstCC1CommandLine(
ModifiedCommandLine, *DiagEngineWithCmdAndOpts->DiagEngine, OverlayFS);
if (!MaybeFirstCC1)
return false;
- return Worker.initializeCompilerInstanceWithContext(
- CWD, *MaybeFirstCC1, std::move(DiagEngineWithCmdAndOpts), OverlayFS);
+ std::vector<std::string> CC1CommandLine(MaybeFirstCC1->begin(),
+ MaybeFirstCC1->end());
+ Tool.CIWithContext = std::make_unique<CompilerInstanceWithContext>(
+ Tool.Worker, CWD, std::move(CC1CommandLine));
+ return Tool.CIWithContext->initialize(std::move(DiagEngineWithCmdAndOpts),
+ OverlayFS);
}
llvm::Error
@@ -346,7 +353,7 @@ DependencyScanningTool::initializeCompilerInstanceWithContextOrError(
std::make_unique<TextDiagnosticsPrinterWithOutput>(CommandLine);
bool Result = initializeWorkerCIWithContextFromCommandline(
- Worker, CWD, CommandLine, DiagPrinterWithOS->DiagPrinter);
+ *this, CWD, CommandLine, DiagPrinterWithOS->DiagPrinter);
if (Result)
return llvm::Error::success();
@@ -362,8 +369,8 @@ DependencyScanningTool::computeDependenciesByNameWithContextOrError(
// We need to clear the DiagnosticOutput so that each by-name lookup
// has a clean diagnostics buffer.
DiagPrinterWithOS->DiagnosticOutput.clear();
- if (Worker.computeDependenciesByNameWithContext(ModuleName, Consumer,
- Controller))
+ assert(CIWithContext && "CompilerInstance with context required!");
+ if (CIWithContext->computeDependencies(ModuleName, Consumer, Controller))
return Consumer.takeTranslationUnitDeps();
return makeErrorFromDiagnosticsOS(*DiagPrinterWithOS);
}
>From 4d37c3fa15d5da4d7c34ce5f82da0803d0d3454f Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Mon, 2 Mar 2026 09:30:55 -0800
Subject: [PATCH 2/4] Expose implementation functions in the header
---
.../DependencyScanning/DependencyScannerImpl.h | 13 +++++++++++++
.../DependencyScannerImpl.cpp | 18 +++++++++---------
2 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/clang/include/clang/DependencyScanning/DependencyScannerImpl.h b/clang/include/clang/DependencyScanning/DependencyScannerImpl.h
index 4210c20942a32..716d69f19347c 100644
--- a/clang/include/clang/DependencyScanning/DependencyScannerImpl.h
+++ b/clang/include/clang/DependencyScanning/DependencyScannerImpl.h
@@ -91,6 +91,19 @@ std::unique_ptr<CompilerInvocation>
createCompilerInvocation(ArrayRef<std::string> CommandLine,
DiagnosticsEngine &Diags);
+/// Canonicalizes command-line macro defines (e.g. removing "-DX -UX").
+void canonicalizeDefines(PreprocessorOptions &PPOpts);
+
+/// Creates a CompilerInvocation suitable for the dependency scanner.
+std::shared_ptr<CompilerInvocation>
+createScanCompilerInvocation(const CompilerInvocation &Invocation,
+ const DependencyScanningService &Service);
+
+/// Creates dependency output options to be reported to the dependency consumer,
+/// deducing missing information if necessary.
+std::unique_ptr<DependencyOutputOptions>
+createDependencyOutputOptions(const CompilerInvocation &Invocation);
+
void initializeScanCompilerInstance(
CompilerInstance &ScanInstance,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
diff --git a/clang/lib/DependencyScanning/DependencyScannerImpl.cpp b/clang/lib/DependencyScanning/DependencyScannerImpl.cpp
index 3e680f4b4b363..9aeae580711f7 100644
--- a/clang/lib/DependencyScanning/DependencyScannerImpl.cpp
+++ b/clang/lib/DependencyScanning/DependencyScannerImpl.cpp
@@ -285,8 +285,9 @@ static std::optional<StringRef> getSimpleMacroName(StringRef Macro) {
}
return FinishName();
}
+} // namespace
-static void canonicalizeDefines(PreprocessorOptions &PPOpts) {
+void dependencies::canonicalizeDefines(PreprocessorOptions &PPOpts) {
using MacroOpt = std::pair<StringRef, std::size_t>;
std::vector<MacroOpt> SimpleNames;
SimpleNames.reserve(PPOpts.Macros.size());
@@ -318,6 +319,7 @@ static void canonicalizeDefines(PreprocessorOptions &PPOpts) {
std::swap(PPOpts.Macros, NewMacros);
}
+namespace {
class ScanningDependencyDirectivesGetter : public DependencyDirectivesGetter {
DependencyScanningWorkerFilesystem *DepFS;
@@ -430,10 +432,9 @@ void dependencies::initializeScanCompilerInstance(
}
}
-/// Creates a CompilerInvocation suitable for the dependency scanner.
-static std::shared_ptr<CompilerInvocation>
-createScanCompilerInvocation(const CompilerInvocation &Invocation,
- const DependencyScanningService &Service) {
+std::shared_ptr<CompilerInvocation> dependencies::createScanCompilerInvocation(
+ const CompilerInvocation &Invocation,
+ const DependencyScanningService &Service) {
auto ScanInvocation = std::make_shared<CompilerInvocation>(Invocation);
sanitizeDiagOpts(ScanInvocation->getDiagnosticOpts());
@@ -508,10 +509,9 @@ dependencies::computePrebuiltModulesASTMap(
return PrebuiltModulesASTMap;
}
-/// Creates dependency output options to be reported to the dependency consumer,
-/// deducing missing information if necessary.
-static std::unique_ptr<DependencyOutputOptions>
-createDependencyOutputOptions(const CompilerInvocation &Invocation) {
+std::unique_ptr<DependencyOutputOptions>
+dependencies::createDependencyOutputOptions(
+ const CompilerInvocation &Invocation) {
auto Opts = std::make_unique<DependencyOutputOptions>(
Invocation.getDependencyOutputOpts());
// We need at least one -MT equivalent for the generator of make dependency
>From 50e6fa6b7c6ba6e62a5544fdfd77157d16e5cbdc Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Tue, 3 Mar 2026 08:16:51 -0800
Subject: [PATCH 3/4] Lift by-name Tool APIs to new type
---
.../DependencyScannerImpl.h | 40 ----
.../DependencyScanningWorker.h | 7 +-
.../clang/Tooling/DependencyScanningTool.h | 141 ++++++++----
.../DependencyScannerImpl.cpp | 153 -------------
clang/lib/Tooling/DependencyScanningTool.cpp | 213 +++++++++++++++---
clang/tools/clang-scan-deps/ClangScanDeps.cpp | 8 +-
6 files changed, 289 insertions(+), 273 deletions(-)
diff --git a/clang/include/clang/DependencyScanning/DependencyScannerImpl.h b/clang/include/clang/DependencyScanning/DependencyScannerImpl.h
index 716d69f19347c..24cf1afaaa450 100644
--- a/clang/include/clang/DependencyScanning/DependencyScannerImpl.h
+++ b/clang/include/clang/DependencyScanning/DependencyScannerImpl.h
@@ -128,46 +128,6 @@ std::shared_ptr<ModuleDepCollector> initializeScanInstanceDependencyCollector(
DependencyActionController &Controller,
PrebuiltModulesAttrsMap PrebuiltModulesASTMap,
llvm::SmallVector<StringRef> &StableDirs);
-
-class CompilerInstanceWithContext {
- // Context
- DependencyScanningWorker &Worker;
- llvm::StringRef CWD;
- std::vector<std::string> CommandLine;
-
- // Context - Diagnostics engine.
- DiagnosticConsumer *DiagConsumer = nullptr;
- std::unique_ptr<DiagnosticsEngineWithDiagOpts> DiagEngineWithCmdAndOpts;
-
- // Context - compiler invocation
- std::unique_ptr<CompilerInvocation> OriginalInvocation;
-
- // Context - output options
- std::unique_ptr<DependencyOutputOptions> OutputOpts;
-
- // Context - stable directory handling
- llvm::SmallVector<StringRef> StableDirs;
- PrebuiltModulesAttrsMap PrebuiltModuleASTMap;
-
- // Compiler Instance
- std::unique_ptr<CompilerInstance> CIPtr;
-
- // Source location offset.
- int32_t SrcLocOffset = 0;
-
-public:
- CompilerInstanceWithContext(DependencyScanningWorker &Worker, StringRef CWD,
- const std::vector<std::string> &CMD)
- : Worker(Worker), CWD(CWD), CommandLine(CMD) {};
-
- // The two methods below returns false when they fail, with the detail
- // accumulated in \c DiagEngineWithDiagOpts's diagnostic consumer.
- bool initialize(
- std::unique_ptr<DiagnosticsEngineWithDiagOpts> DiagEngineWithDiagOpts,
- IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS);
- bool computeDependencies(StringRef ModuleName, DependencyConsumer &Consumer,
- DependencyActionController &Controller);
-};
} // namespace dependencies
} // namespace clang
diff --git a/clang/include/clang/DependencyScanning/DependencyScanningWorker.h b/clang/include/clang/DependencyScanning/DependencyScanningWorker.h
index 5506d9f78d9fc..0a5c4936f7fe7 100644
--- a/clang/include/clang/DependencyScanning/DependencyScanningWorker.h
+++ b/clang/include/clang/DependencyScanning/DependencyScanningWorker.h
@@ -27,10 +27,13 @@ namespace clang {
class DependencyOutputOptions;
+namespace tooling {
+class CompilerInstanceWithContext;
+}
+
namespace dependencies {
class DependencyScanningWorkerFilesystem;
-class CompilerInstanceWithContext;
/// A command-line tool invocation that is part of building a TU.
///
@@ -135,7 +138,7 @@ class DependencyScanningWorker {
/// overlaid on top of the base VFS passed in the constructor.
IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS;
- friend CompilerInstanceWithContext;
+ friend tooling::CompilerInstanceWithContext;
};
std::pair<IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem>,
diff --git a/clang/include/clang/Tooling/DependencyScanningTool.h b/clang/include/clang/Tooling/DependencyScanningTool.h
index 694c1cb2a1f72..f0aa7615f0844 100644
--- a/clang/include/clang/Tooling/DependencyScanningTool.h
+++ b/clang/include/clang/Tooling/DependencyScanningTool.h
@@ -111,10 +111,90 @@ class DependencyScanningTool {
const llvm::DenseSet<dependencies::ModuleID> &AlreadySeen,
dependencies::LookupModuleOutputCallback LookupModuleOutput);
- /// The following two methods provide a new interface to perform
- /// by name dependency scan. The new interface's intention is to improve
- /// dependency scanning performance when a sequence of name is looked up
- /// with the same current working directory and the command line.
+ llvm::vfs::FileSystem &getWorkerVFS() const { return Worker.getVFS(); }
+
+private:
+ dependencies::DependencyScanningWorker Worker;
+
+ friend class CompilerInstanceWithContext;
+};
+
+/// Run the dependency scanning worker for the given driver or frontend
+/// command-line, and report the discovered dependencies to the provided
+/// consumer.
+///
+/// OverlayFS should be based on the Worker's dependency scanning file-system
+/// and can be used to provide any input specified on the command-line as
+/// in-memory file. If no overlay file-system is provided, the Worker's
+/// dependency scanning file-system is used instead.
+///
+/// \returns false if any errors occurred (with diagnostics reported to
+/// \c DiagConsumer), true otherwise.
+bool computeDependencies(
+ dependencies::DependencyScanningWorker &Worker, StringRef WorkingDirectory,
+ ArrayRef<std::string> CommandLine,
+ dependencies::DependencyConsumer &Consumer,
+ dependencies::DependencyActionController &Controller,
+ DiagnosticConsumer &DiagConsumer,
+ llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS = nullptr);
+
+class CompilerInstanceWithContext {
+ // Context
+ dependencies::DependencyScanningWorker &Worker;
+ llvm::StringRef CWD;
+ std::vector<std::string> CommandLine;
+
+ // Context - Diagnostics engine.
+ DiagnosticConsumer *DiagConsumer = nullptr;
+ std::unique_ptr<dependencies::DiagnosticsEngineWithDiagOpts>
+ DiagEngineWithCmdAndOpts;
+ std::unique_ptr<dependencies::TextDiagnosticsPrinterWithOutput>
+ DiagPrinterWithOS;
+
+ // Context - compiler invocation
+ std::unique_ptr<CompilerInvocation> OriginalInvocation;
+
+ // Context - output options
+ std::unique_ptr<DependencyOutputOptions> OutputOpts;
+
+ // Context - stable directory handling
+ llvm::SmallVector<StringRef> StableDirs;
+ dependencies::PrebuiltModulesAttrsMap PrebuiltModuleASTMap;
+
+ // Compiler Instance
+ std::unique_ptr<CompilerInstance> CIPtr;
+
+ // Source location offset.
+ int32_t SrcLocOffset = 0;
+
+ CompilerInstanceWithContext(dependencies::DependencyScanningWorker &Worker,
+ StringRef CWD, ArrayRef<std::string> CommandLine)
+ : Worker(Worker), CWD(CWD), CommandLine(std::move(CommandLine)) {};
+
+ CompilerInstanceWithContext(dependencies::DependencyScanningWorker &Worker)
+ : Worker(Worker) {};
+
+ // The two methods below returns false when they fail, with the detail
+ // accumulated in \c DiagEngineWithDiagOpts's diagnostic consumer.
+ bool initialize(std::unique_ptr<dependencies::DiagnosticsEngineWithDiagOpts>
+ DiagEngineWithDiagOpts,
+ IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS);
+
+public:
+ /// @brief Initialize the tool's compiler instance from the commandline.
+ /// The compiler instance only takes a `-cc1` job, so this method
+ /// builds the `-cc1` job from the CommandLine input.
+ /// @param Tool The dependency scanning tool whose compiler instance
+ /// with context is initialized.
+ /// @param CWD The current working directory.
+ /// @param CommandLine This command line may be a driver command or a cc1
+ /// command.
+ /// @param DC A diagnostics consumer to report error if the initialization
+ /// fails.
+ static std::optional<CompilerInstanceWithContext>
+ initializeFromCommandline(DependencyScanningTool &Tool, StringRef CWD,
+ ArrayRef<std::string> CommandLine,
+ DiagnosticConsumer &DC);
/// @brief Initializing the context and the compiler instance.
/// This method must be called before calling
@@ -122,8 +202,14 @@ class DependencyScanningTool {
/// @param CWD The current working directory used during the scan.
/// @param CommandLine The commandline used for the scan.
/// @return Error if the initializaiton fails.
- llvm::Error initializeCompilerInstanceWithContextOrError(
- StringRef CWD, ArrayRef<std::string> CommandLine);
+ static llvm::Expected<CompilerInstanceWithContext>
+ initializeOrError(DependencyScanningTool &Tool, StringRef CWD,
+ ArrayRef<std::string> CommandLine);
+
+ bool
+ computeDependencies(StringRef ModuleName,
+ dependencies::DependencyConsumer &Consumer,
+ dependencies::DependencyActionController &Controller);
/// @brief Computes the dependeny for the module named ModuleName.
/// @param ModuleName The name of the module for which this method computes
@@ -140,53 +226,12 @@ class DependencyScanningTool {
/// @return An instance of \c TranslationUnitDeps if the scan is successful.
/// Otherwise it returns an error.
llvm::Expected<dependencies::TranslationUnitDeps>
- computeDependenciesByNameWithContextOrError(
+ computeDependenciesByNameOrError(
StringRef ModuleName,
const llvm::DenseSet<dependencies::ModuleID> &AlreadySeen,
dependencies::LookupModuleOutputCallback LookupModuleOutput);
-
- llvm::vfs::FileSystem &getWorkerVFS() const { return Worker.getVFS(); }
-
- /// @brief Initialize the tool's compiler instance from the commandline.
- /// The compiler instance only takes a `-cc1` job, so this method
- /// builds the `-cc1` job from the CommandLine input.
- /// @param Tool The dependency scanning tool whose compiler instance
- /// with context is initialized.
- /// @param CWD The current working directory.
- /// @param CommandLine This command line may be a driver command or a cc1
- /// command.
- /// @param DC A diagnostics consumer to report error if the initialization
- /// fails.
- static bool initializeWorkerCIWithContextFromCommandline(
- DependencyScanningTool &Tool, StringRef CWD,
- ArrayRef<std::string> CommandLine, DiagnosticConsumer &DC);
-
-private:
- dependencies::DependencyScanningWorker Worker;
- std::unique_ptr<dependencies::TextDiagnosticsPrinterWithOutput>
- DiagPrinterWithOS;
- std::unique_ptr<dependencies::CompilerInstanceWithContext> CIWithContext;
};
-/// Run the dependency scanning worker for the given driver or frontend
-/// command-line, and report the discovered dependencies to the provided
-/// consumer.
-///
-/// OverlayFS should be based on the Worker's dependency scanning file-system
-/// and can be used to provide any input specified on the command-line as
-/// in-memory file. If no overlay file-system is provided, the Worker's
-/// dependency scanning file-system is used instead.
-///
-/// \returns false if any errors occurred (with diagnostics reported to
-/// \c DiagConsumer), true otherwise.
-bool computeDependencies(
- dependencies::DependencyScanningWorker &Worker, StringRef WorkingDirectory,
- ArrayRef<std::string> CommandLine,
- dependencies::DependencyConsumer &Consumer,
- dependencies::DependencyActionController &Controller,
- DiagnosticConsumer &DiagConsumer,
- llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS = nullptr);
-
} // end namespace tooling
} // end namespace clang
diff --git a/clang/lib/DependencyScanning/DependencyScannerImpl.cpp b/clang/lib/DependencyScanning/DependencyScannerImpl.cpp
index 9aeae580711f7..0e345af8817ae 100644
--- a/clang/lib/DependencyScanning/DependencyScannerImpl.cpp
+++ b/clang/lib/DependencyScanning/DependencyScannerImpl.cpp
@@ -805,156 +805,3 @@ bool DependencyScanningAction::runInvocation(
return Result;
}
-
-bool CompilerInstanceWithContext::initialize(
- std::unique_ptr<DiagnosticsEngineWithDiagOpts> DiagEngineWithDiagOpts,
- IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS) {
- assert(DiagEngineWithDiagOpts && "Valid diagnostics engine required!");
- DiagEngineWithCmdAndOpts = std::move(DiagEngineWithDiagOpts);
- DiagConsumer = DiagEngineWithCmdAndOpts->DiagEngine->getClient();
-
-#ifndef NDEBUG
- assert(OverlayFS && "OverlayFS required!");
- bool SawDepFS = false;
- OverlayFS->visit([&](llvm::vfs::FileSystem &VFS) {
- SawDepFS |= &VFS == Worker.DepFS.get();
- });
- assert(SawDepFS && "OverlayFS not based on DepFS");
-#endif
-
- OriginalInvocation = createCompilerInvocation(
- CommandLine, *DiagEngineWithCmdAndOpts->DiagEngine);
- if (!OriginalInvocation) {
- DiagEngineWithCmdAndOpts->DiagEngine->Report(
- diag::err_fe_expected_compiler_job)
- << llvm::join(CommandLine, " ");
- return false;
- }
-
- if (any(Worker.Service.getOpts().OptimizeArgs &
- ScanningOptimizations::Macros))
- canonicalizeDefines(OriginalInvocation->getPreprocessorOpts());
-
- // Create the CompilerInstance.
- std::shared_ptr<ModuleCache> ModCache =
- makeInProcessModuleCache(Worker.Service.getModuleCacheEntries());
- CIPtr = std::make_unique<CompilerInstance>(
- createScanCompilerInvocation(*OriginalInvocation, Worker.Service),
- Worker.PCHContainerOps, std::move(ModCache));
- auto &CI = *CIPtr;
-
- initializeScanCompilerInstance(
- CI, OverlayFS, DiagEngineWithCmdAndOpts->DiagEngine->getClient(),
- Worker.Service, Worker.DepFS);
-
- StableDirs = getInitialStableDirs(CI);
- auto MaybePrebuiltModulesASTMap =
- computePrebuiltModulesASTMap(CI, StableDirs);
- if (!MaybePrebuiltModulesASTMap)
- return false;
-
- PrebuiltModuleASTMap = std::move(*MaybePrebuiltModulesASTMap);
- OutputOpts = createDependencyOutputOptions(*OriginalInvocation);
-
- // We do not create the target in initializeScanCompilerInstance because
- // setting it here is unique for by-name lookups. We create the target only
- // once here, and the information is reused for all computeDependencies calls.
- // We do not need to call createTarget explicitly if we go through
- // CompilerInstance::ExecuteAction to perform scanning.
- CI.createTarget();
-
- return true;
-}
-
-bool CompilerInstanceWithContext::computeDependencies(
- StringRef ModuleName, DependencyConsumer &Consumer,
- DependencyActionController &Controller) {
- assert(CIPtr && "CIPtr must be initialized before calling this method");
- auto &CI = *CIPtr;
-
- // We need to reset the diagnostics, so that the diagnostics issued
- // during a previous computeDependencies call do not affect the current call.
- // If we do not reset, we may inherit fatal errors from a previous call.
- CI.getDiagnostics().Reset();
-
- // We create this cleanup object because computeDependencies may exit
- // early with errors.
- llvm::scope_exit CleanUp([&]() {
- CI.clearDependencyCollectors();
- // The preprocessor may not be created at the entry of this method,
- // but it must have been created when this method returns, whether
- // there are errors during scanning or not.
- CI.getPreprocessor().removePPCallbacks();
- });
-
- auto MDC = initializeScanInstanceDependencyCollector(
- CI, std::make_unique<DependencyOutputOptions>(*OutputOpts), CWD, Consumer,
- Worker.Service,
- /* The MDC's constructor makes a copy of the OriginalInvocation, so
- we can pass it in without worrying that it might be changed across
- invocations of computeDependencies. */
- *OriginalInvocation, Controller, PrebuiltModuleASTMap, StableDirs);
-
- if (!SrcLocOffset) {
- // When SrcLocOffset is zero, we are at the beginning of the fake source
- // file. In this case, we call BeginSourceFile to initialize.
- std::unique_ptr<FrontendAction> Action =
- std::make_unique<PreprocessOnlyAction>();
- auto *InputFile = CI.getFrontendOpts().Inputs.begin();
- bool ActionBeginSucceeded = Action->BeginSourceFile(CI, *InputFile);
- assert(ActionBeginSucceeded && "Action BeginSourceFile must succeed");
- (void)ActionBeginSucceeded;
- }
-
- Preprocessor &PP = CI.getPreprocessor();
- SourceManager &SM = PP.getSourceManager();
- FileID MainFileID = SM.getMainFileID();
- SourceLocation FileStart = SM.getLocForStartOfFile(MainFileID);
- SourceLocation IDLocation = FileStart.getLocWithOffset(SrcLocOffset);
- PPCallbacks *CB = nullptr;
- if (!SrcLocOffset) {
- // We need to call EnterSourceFile when SrcLocOffset is zero to initialize
- // the preprocessor.
- bool PPFailed = PP.EnterSourceFile(MainFileID, nullptr, SourceLocation());
- assert(!PPFailed && "Preprocess must be able to enter the main file.");
- (void)PPFailed;
- CB = MDC->getPPCallbacks();
- } else {
- // When SrcLocOffset is non-zero, the preprocessor has already been
- // initialized through a previous call of computeDependencies. We want to
- // preserve the PP's state, hence we do not call EnterSourceFile again.
- MDC->attachToPreprocessor(PP);
- CB = MDC->getPPCallbacks();
-
- FileID PrevFID;
- SrcMgr::CharacteristicKind FileType = SM.getFileCharacteristic(IDLocation);
- CB->LexedFileChanged(MainFileID,
- PPChainedCallbacks::LexedFileChangeReason::EnterFile,
- FileType, PrevFID, IDLocation);
- }
-
- // FIXME: Scan modules asynchronously here as well.
-
- SrcLocOffset++;
- SmallVector<IdentifierLoc, 2> Path;
- IdentifierInfo *ModuleID = PP.getIdentifierInfo(ModuleName);
- Path.emplace_back(IDLocation, ModuleID);
- auto ModResult = CI.loadModule(IDLocation, Path, Module::Hidden, false);
-
- assert(CB && "Must have PPCallbacks after module loading");
- CB->moduleImport(SourceLocation(), Path, ModResult);
- // Note that we are calling the CB's EndOfMainFile function, which
- // forwards the results to the dependency consumer.
- // It does not indicate the end of processing the fake file.
- CB->EndOfMainFile();
-
- if (!ModResult)
- return false;
-
- CompilerInvocation ModuleInvocation(*OriginalInvocation);
- MDC->applyDiscoveredDependencies(ModuleInvocation);
- Consumer.handleBuildCommand(
- {CommandLine[0], ModuleInvocation.getCC1CommandLine()});
-
- return true;
-}
diff --git a/clang/lib/Tooling/DependencyScanningTool.cpp b/clang/lib/Tooling/DependencyScanningTool.cpp
index 79a84f0148fcf..5caa1fcef9d1a 100644
--- a/clang/lib/Tooling/DependencyScanningTool.cpp
+++ b/clang/lib/Tooling/DependencyScanningTool.cpp
@@ -11,7 +11,10 @@
#include "clang/Basic/DiagnosticFrontend.h"
#include "clang/DependencyScanning/DependencyScannerImpl.h"
#include "clang/Driver/Tool.h"
+#include "clang/Frontend/FrontendActions.h"
#include "clang/Frontend/Utils.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallVectorExtras.h"
#include "llvm/ADT/iterator.h"
#include "llvm/TargetParser/Host.h"
@@ -282,12 +285,13 @@ DependencyScanningTool::getModuleDependencies(
StringRef ModuleName, ArrayRef<std::string> CommandLine, StringRef CWD,
const llvm::DenseSet<ModuleID> &AlreadySeen,
LookupModuleOutputCallback LookupModuleOutput) {
- if (auto Error =
- initializeCompilerInstanceWithContextOrError(CWD, CommandLine))
+ auto MaybeCIWithContext =
+ CompilerInstanceWithContext::initializeOrError(*this, CWD, CommandLine);
+ if (auto Error = MaybeCIWithContext.takeError())
return Error;
- return computeDependenciesByNameWithContextOrError(ModuleName, AlreadySeen,
- LookupModuleOutput);
+ return MaybeCIWithContext->computeDependenciesByNameOrError(
+ ModuleName, AlreadySeen, LookupModuleOutput);
}
static std::optional<SmallVector<std::string, 0>> getFirstCC1CommandLine(
@@ -312,7 +316,8 @@ static std::optional<SmallVector<std::string, 0>> getFirstCC1CommandLine(
return std::nullopt;
}
-bool DependencyScanningTool::initializeWorkerCIWithContextFromCommandline(
+std::optional<CompilerInstanceWithContext>
+CompilerInstanceWithContext::initializeFromCommandline(
DependencyScanningTool &Tool, StringRef CWD,
ArrayRef<std::string> CommandLine, DiagnosticConsumer &DC) {
auto [OverlayFS, ModifiedCommandLine] = initVFSForByNameScanning(
@@ -324,10 +329,11 @@ bool DependencyScanningTool::initializeWorkerCIWithContextFromCommandline(
if (CommandLine.size() >= 2 && CommandLine[1] == "-cc1") {
// The input command line is already a -cc1 invocation; initialize the
// compiler instance directly from it.
- Tool.CIWithContext = std::make_unique<CompilerInstanceWithContext>(
- Tool.Worker, CWD, CommandLine);
- return Tool.CIWithContext->initialize(std::move(DiagEngineWithCmdAndOpts),
- OverlayFS);
+ CompilerInstanceWithContext CIWithContext(Tool.Worker, CWD, CommandLine);
+ if (!CIWithContext.initialize(std::move(DiagEngineWithCmdAndOpts),
+ OverlayFS))
+ return std::nullopt;
+ return CIWithContext;
}
// The input command line is either a driver-style command line, or
@@ -336,32 +342,35 @@ bool DependencyScanningTool::initializeWorkerCIWithContextFromCommandline(
const auto MaybeFirstCC1 = getFirstCC1CommandLine(
ModifiedCommandLine, *DiagEngineWithCmdAndOpts->DiagEngine, OverlayFS);
if (!MaybeFirstCC1)
- return false;
+ return std::nullopt;
std::vector<std::string> CC1CommandLine(MaybeFirstCC1->begin(),
MaybeFirstCC1->end());
- Tool.CIWithContext = std::make_unique<CompilerInstanceWithContext>(
- Tool.Worker, CWD, std::move(CC1CommandLine));
- return Tool.CIWithContext->initialize(std::move(DiagEngineWithCmdAndOpts),
- OverlayFS);
+ CompilerInstanceWithContext CIWithContext(Tool.Worker, CWD,
+ std::move(CC1CommandLine));
+ if (!CIWithContext.initialize(std::move(DiagEngineWithCmdAndOpts), OverlayFS))
+ return std::nullopt;
+ return CIWithContext;
}
-llvm::Error
-DependencyScanningTool::initializeCompilerInstanceWithContextOrError(
- StringRef CWD, ArrayRef<std::string> CommandLine) {
- DiagPrinterWithOS =
+llvm::Expected<CompilerInstanceWithContext>
+CompilerInstanceWithContext::initializeOrError(
+ DependencyScanningTool &Tool, StringRef CWD,
+ ArrayRef<std::string> CommandLine) {
+ auto DiagPrinterWithOS =
std::make_unique<TextDiagnosticsPrinterWithOutput>(CommandLine);
- bool Result = initializeWorkerCIWithContextFromCommandline(
- *this, CWD, CommandLine, DiagPrinterWithOS->DiagPrinter);
-
- if (Result)
- return llvm::Error::success();
+ auto Result = initializeFromCommandline(Tool, CWD, CommandLine,
+ DiagPrinterWithOS->DiagPrinter);
+ if (Result) {
+ Result->DiagPrinterWithOS = std::move(DiagPrinterWithOS);
+ return std::move(*Result);
+ }
return makeErrorFromDiagnosticsOS(*DiagPrinterWithOS);
}
llvm::Expected<TranslationUnitDeps>
-DependencyScanningTool::computeDependenciesByNameWithContextOrError(
+CompilerInstanceWithContext::computeDependenciesByNameOrError(
StringRef ModuleName, const llvm::DenseSet<ModuleID> &AlreadySeen,
LookupModuleOutputCallback LookupModuleOutput) {
FullDependencyConsumer Consumer(AlreadySeen);
@@ -369,8 +378,160 @@ DependencyScanningTool::computeDependenciesByNameWithContextOrError(
// We need to clear the DiagnosticOutput so that each by-name lookup
// has a clean diagnostics buffer.
DiagPrinterWithOS->DiagnosticOutput.clear();
- assert(CIWithContext && "CompilerInstance with context required!");
- if (CIWithContext->computeDependencies(ModuleName, Consumer, Controller))
+ if (computeDependencies(ModuleName, Consumer, Controller))
return Consumer.takeTranslationUnitDeps();
return makeErrorFromDiagnosticsOS(*DiagPrinterWithOS);
}
+
+bool CompilerInstanceWithContext::initialize(
+ std::unique_ptr<DiagnosticsEngineWithDiagOpts> DiagEngineWithDiagOpts,
+ IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS) {
+ assert(DiagEngineWithDiagOpts && "Valid diagnostics engine required!");
+ DiagEngineWithCmdAndOpts = std::move(DiagEngineWithDiagOpts);
+ DiagConsumer = DiagEngineWithCmdAndOpts->DiagEngine->getClient();
+
+#ifndef NDEBUG
+ assert(OverlayFS && "OverlayFS required!");
+ bool SawDepFS = false;
+ OverlayFS->visit([&](llvm::vfs::FileSystem &VFS) {
+ SawDepFS |= &VFS == Worker.DepFS.get();
+ });
+ assert(SawDepFS && "OverlayFS not based on DepFS");
+#endif
+
+ OriginalInvocation = createCompilerInvocation(
+ CommandLine, *DiagEngineWithCmdAndOpts->DiagEngine);
+ if (!OriginalInvocation) {
+ DiagEngineWithCmdAndOpts->DiagEngine->Report(
+ diag::err_fe_expected_compiler_job)
+ << llvm::join(CommandLine, " ");
+ return false;
+ }
+
+ if (any(Worker.Service.getOpts().OptimizeArgs &
+ ScanningOptimizations::Macros))
+ canonicalizeDefines(OriginalInvocation->getPreprocessorOpts());
+
+ // Create the CompilerInstance.
+ std::shared_ptr<ModuleCache> ModCache =
+ makeInProcessModuleCache(Worker.Service.getModuleCacheEntries());
+ CIPtr = std::make_unique<CompilerInstance>(
+ createScanCompilerInvocation(*OriginalInvocation, Worker.Service),
+ Worker.PCHContainerOps, std::move(ModCache));
+ auto &CI = *CIPtr;
+
+ initializeScanCompilerInstance(
+ CI, OverlayFS, DiagEngineWithCmdAndOpts->DiagEngine->getClient(),
+ Worker.Service, Worker.DepFS);
+
+ StableDirs = getInitialStableDirs(CI);
+ auto MaybePrebuiltModulesASTMap =
+ computePrebuiltModulesASTMap(CI, StableDirs);
+ if (!MaybePrebuiltModulesASTMap)
+ return false;
+
+ PrebuiltModuleASTMap = std::move(*MaybePrebuiltModulesASTMap);
+ OutputOpts = createDependencyOutputOptions(*OriginalInvocation);
+
+ // We do not create the target in initializeScanCompilerInstance because
+ // setting it here is unique for by-name lookups. We create the target only
+ // once here, and the information is reused for all computeDependencies calls.
+ // We do not need to call createTarget explicitly if we go through
+ // CompilerInstance::ExecuteAction to perform scanning.
+ CI.createTarget();
+
+ return true;
+}
+
+bool CompilerInstanceWithContext::computeDependencies(
+ StringRef ModuleName, DependencyConsumer &Consumer,
+ DependencyActionController &Controller) {
+ assert(CIPtr && "CIPtr must be initialized before calling this method");
+ auto &CI = *CIPtr;
+
+ // We need to reset the diagnostics, so that the diagnostics issued
+ // during a previous computeDependencies call do not affect the current call.
+ // If we do not reset, we may inherit fatal errors from a previous call.
+ CI.getDiagnostics().Reset();
+
+ // We create this cleanup object because computeDependencies may exit
+ // early with errors.
+ llvm::scope_exit CleanUp([&]() {
+ CI.clearDependencyCollectors();
+ // The preprocessor may not be created at the entry of this method,
+ // but it must have been created when this method returns, whether
+ // there are errors during scanning or not.
+ CI.getPreprocessor().removePPCallbacks();
+ });
+
+ auto MDC = initializeScanInstanceDependencyCollector(
+ CI, std::make_unique<DependencyOutputOptions>(*OutputOpts), CWD, Consumer,
+ Worker.Service,
+ /* The MDC's constructor makes a copy of the OriginalInvocation, so
+ we can pass it in without worrying that it might be changed across
+ invocations of computeDependencies. */
+ *OriginalInvocation, Controller, PrebuiltModuleASTMap, StableDirs);
+
+ if (!SrcLocOffset) {
+ // When SrcLocOffset is zero, we are at the beginning of the fake source
+ // file. In this case, we call BeginSourceFile to initialize.
+ std::unique_ptr<FrontendAction> Action =
+ std::make_unique<PreprocessOnlyAction>();
+ auto *InputFile = CI.getFrontendOpts().Inputs.begin();
+ bool ActionBeginSucceeded = Action->BeginSourceFile(CI, *InputFile);
+ assert(ActionBeginSucceeded && "Action BeginSourceFile must succeed");
+ (void)ActionBeginSucceeded;
+ }
+
+ Preprocessor &PP = CI.getPreprocessor();
+ SourceManager &SM = PP.getSourceManager();
+ FileID MainFileID = SM.getMainFileID();
+ SourceLocation FileStart = SM.getLocForStartOfFile(MainFileID);
+ SourceLocation IDLocation = FileStart.getLocWithOffset(SrcLocOffset);
+ PPCallbacks *CB = nullptr;
+ if (!SrcLocOffset) {
+ // We need to call EnterSourceFile when SrcLocOffset is zero to initialize
+ // the preprocessor.
+ bool PPFailed = PP.EnterSourceFile(MainFileID, nullptr, SourceLocation());
+ assert(!PPFailed && "Preprocess must be able to enter the main file.");
+ (void)PPFailed;
+ CB = MDC->getPPCallbacks();
+ } else {
+ // When SrcLocOffset is non-zero, the preprocessor has already been
+ // initialized through a previous call of computeDependencies. We want to
+ // preserve the PP's state, hence we do not call EnterSourceFile again.
+ MDC->attachToPreprocessor(PP);
+ CB = MDC->getPPCallbacks();
+
+ FileID PrevFID;
+ SrcMgr::CharacteristicKind FileType = SM.getFileCharacteristic(IDLocation);
+ CB->LexedFileChanged(MainFileID,
+ PPChainedCallbacks::LexedFileChangeReason::EnterFile,
+ FileType, PrevFID, IDLocation);
+ }
+
+ // FIXME: Scan modules asynchronously here as well.
+
+ SrcLocOffset++;
+ SmallVector<IdentifierLoc, 2> Path;
+ IdentifierInfo *ModuleID = PP.getIdentifierInfo(ModuleName);
+ Path.emplace_back(IDLocation, ModuleID);
+ auto ModResult = CI.loadModule(IDLocation, Path, Module::Hidden, false);
+
+ assert(CB && "Must have PPCallbacks after module loading");
+ CB->moduleImport(SourceLocation(), Path, ModResult);
+ // Note that we are calling the CB's EndOfMainFile function, which
+ // forwards the results to the dependency consumer.
+ // It does not indicate the end of processing the fake file.
+ CB->EndOfMainFile();
+
+ if (!ModResult)
+ return false;
+
+ CompilerInvocation ModuleInvocation(*OriginalInvocation);
+ MDC->applyDiscoveredDependencies(ModuleInvocation);
+ Consumer.handleBuildCommand(
+ {CommandLine[0], ModuleInvocation.getCC1CommandLine()});
+
+ return true;
+}
diff --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
index eb3de3319bc00..737360f9266e6 100644
--- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp
+++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
@@ -1071,9 +1071,9 @@ int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) {
LocalIndex, DependencyOS, Errs))
HadErrors = true;
} else {
- if (llvm::Error Err =
- WorkerTool.initializeCompilerInstanceWithContextOrError(
- CWD, Input->CommandLine)) {
+ auto CIWithCtx = CompilerInstanceWithContext::initializeOrError(
+ WorkerTool, CWD, Input->CommandLine);
+ if (llvm::Error Err = CIWithCtx.takeError()) {
handleErrorWithInfoString(
"Compiler instance with context setup error", std::move(Err),
DependencyOS, Errs);
@@ -1083,7 +1083,7 @@ int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) {
for (auto N : Names) {
auto MaybeModuleDepsGraph =
- WorkerTool.computeDependenciesByNameWithContextOrError(
+ CIWithCtx->computeDependenciesByNameOrError(
N, AlreadySeenModules, LookupOutput);
if (handleModuleResult(N, MaybeModuleDepsGraph, *FD, LocalIndex,
DependencyOS, Errs)) {
>From 2fc0c460d5bf111550932dc98dc700b4a746e0c1 Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Thu, 5 Mar 2026 08:12:13 -0800
Subject: [PATCH 4/4] Remove extra constructor, revert extra change
---
clang/include/clang/Tooling/DependencyScanningTool.h | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/clang/include/clang/Tooling/DependencyScanningTool.h b/clang/include/clang/Tooling/DependencyScanningTool.h
index f0aa7615f0844..40e791fd5bff5 100644
--- a/clang/include/clang/Tooling/DependencyScanningTool.h
+++ b/clang/include/clang/Tooling/DependencyScanningTool.h
@@ -168,14 +168,10 @@ class CompilerInstanceWithContext {
int32_t SrcLocOffset = 0;
CompilerInstanceWithContext(dependencies::DependencyScanningWorker &Worker,
- StringRef CWD, ArrayRef<std::string> CommandLine)
- : Worker(Worker), CWD(CWD), CommandLine(std::move(CommandLine)) {};
+ StringRef CWD,
+ const std::vector<std::string> &CMD)
+ : Worker(Worker), CWD(CWD), CommandLine(CMD) {};
- CompilerInstanceWithContext(dependencies::DependencyScanningWorker &Worker)
- : Worker(Worker) {};
-
- // The two methods below returns false when they fail, with the detail
- // accumulated in \c DiagEngineWithDiagOpts's diagnostic consumer.
bool initialize(std::unique_ptr<dependencies::DiagnosticsEngineWithDiagOpts>
DiagEngineWithDiagOpts,
IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS);
More information about the cfe-commits
mailing list