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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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);

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to