[clang] 5f4d725 - [clang][DependencyScanning] Implement the Streaming Style By-name Scanning API (#211406)

via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 31 08:54:24 PDT 2026


Author: Qiongsi Wu
Date: 2026-07-31T08:54:13-07:00
New Revision: 5f4d725bca798dc9ab56af114865212849eb6bda

URL: https://github.com/llvm/llvm-project/commit/5f4d725bca798dc9ab56af114865212849eb6bda
DIFF: https://github.com/llvm/llvm-project/commit/5f4d725bca798dc9ab56af114865212849eb6bda.diff

LOG: [clang][DependencyScanning] Implement the Streaming Style By-name Scanning API (#211406)

This PR implements a streaming stype by-name scanning API. The new API
takes a `DependencyConsumer`, a `DiagnosticsConsumer` and a
`getNextName` lambda. Any diagnositcs flow to the `DependencyConsumer`,
and the results flows to to `DependencyConsumer`. The `getNextName`
lambda is allows the client to stream names into the API, and the API
keeps scanning dependencies for input names until `getNextName` does not
return more names.

rdar://178088113

---

<sub>Stack created with <a
href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a
href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>

Added: 
    

Modified: 
    clang/include/clang/DependencyScanning/DependencyConsumer.h
    clang/include/clang/DependencyScanning/DependencyScannerImpl.h
    clang/include/clang/Tooling/DependencyScanningTool.h
    clang/lib/Tooling/DependencyScanningTool.cpp
    clang/test/ClangScanDeps/modules-full-by-mult-mod-names-diagnostics.c
    clang/test/ClangScanDeps/modules-invalid-target.c
    clang/tools/clang-scan-deps/ClangScanDeps.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/DependencyScanning/DependencyConsumer.h b/clang/include/clang/DependencyScanning/DependencyConsumer.h
index 85dca17ee2f6f..54152635a3253 100644
--- a/clang/include/clang/DependencyScanning/DependencyConsumer.h
+++ b/clang/include/clang/DependencyScanning/DependencyConsumer.h
@@ -41,6 +41,8 @@ class DependencyConsumer {
   virtual void handleVisibleModule(std::string ModuleName) = 0;
 
   virtual void handleContextHash(std::string Hash) = 0;
+
+  virtual void finishQuery(StringRef ModuleName, bool Success) {}
 };
 } // namespace clang::dependencies
 

diff  --git a/clang/include/clang/DependencyScanning/DependencyScannerImpl.h b/clang/include/clang/DependencyScanning/DependencyScannerImpl.h
index 893017e68233b..f973429a783c3 100644
--- a/clang/include/clang/DependencyScanning/DependencyScannerImpl.h
+++ b/clang/include/clang/DependencyScanning/DependencyScannerImpl.h
@@ -69,20 +69,6 @@ struct DiagnosticsEngineWithDiagOpts {
                                 DiagnosticConsumer &DC);
 };
 
-struct TextDiagnosticsPrinterWithOutput {
-  // We need to bound the lifetime of the data that supports the DiagPrinter
-  // with it together so they have the same lifetime.
-  std::string DiagnosticOutput;
-  llvm::raw_string_ostream DiagnosticsOS;
-  std::unique_ptr<DiagnosticOptions> DiagOpts;
-  TextDiagnosticPrinter DiagPrinter;
-
-  TextDiagnosticsPrinterWithOutput(ArrayRef<std::string> CommandLine)
-      : DiagnosticsOS(DiagnosticOutput),
-        DiagOpts(createDiagOptions(CommandLine)),
-        DiagPrinter(DiagnosticsOS, *DiagOpts) {}
-};
-
 std::unique_ptr<CompilerInvocation>
 createCompilerInvocation(ArrayRef<std::string> CommandLine,
                          DiagnosticsEngine &Diags);

diff  --git a/clang/include/clang/Tooling/DependencyScanningTool.h b/clang/include/clang/Tooling/DependencyScanningTool.h
index 908a70efee89b..b3ed10f7a50d9 100644
--- a/clang/include/clang/Tooling/DependencyScanningTool.h
+++ b/clang/include/clang/Tooling/DependencyScanningTool.h
@@ -101,16 +101,21 @@ class DependencyScanningTool {
       dependencies::LookupModuleOutputCallback LookupModuleOutput,
       std::optional<llvm::MemoryBufferRef> TUBuffer = std::nullopt);
 
-  /// Given a compilation context specified via the Clang driver command-line,
-  /// gather modular dependencies of module with the given name, and return the
-  /// information needed for explicit build.
-  /// TODO: this method should be removed as soon as Swift and our C-APIs adopt
-  /// CompilerInstanceWithContext. We are keeping it here so that it is easier
-  /// to coordinate with Swift and C-API changes.
-  llvm::Expected<dependencies::TranslationUnitDeps> getModuleDependencies(
-      StringRef ModuleName, ArrayRef<std::string> CommandLine, StringRef CWD,
-      const llvm::DenseSet<dependencies::ModuleID> &AlreadySeen,
-      dependencies::DependencyActionController &Controller);
+  /// By-name scanning given a Clang command-line. The scanning context is
+  /// initialized once and reused for each name pulled from
+  /// \p getNextName until it returns std::nullopt. Results flow to
+  /// \p DepConsumer (with per-name status via finishQuery); diagnostics flow to
+  /// \p DiagConsumer.
+  ///
+  /// \returns true if the scanning context initialized successfully and all
+  /// scans succeeded. Query the DepConsumer for the state of each individual
+  /// scan.
+  bool getByNameDependencies(
+      StringRef CWD, ArrayRef<std::string> CommandLine,
+      DiagnosticConsumer &DiagConsumer,
+      dependencies::DependencyActionController &Controller,
+      llvm::function_ref<std::optional<std::string>()> getNextName,
+      dependencies::DependencyConsumer &DepConsumer);
 
   /// Returns the worker tracing VFS, if it was requested via the service.
   llvm::vfs::TracingFileSystem *getWorkerTracingVFS() const {
@@ -152,8 +157,6 @@ class CompilerInstanceWithContext {
   DiagnosticConsumer *DiagConsumer = nullptr;
   std::unique_ptr<dependencies::DiagnosticsEngineWithDiagOpts>
       DiagEngineWithCmdAndOpts;
-  std::unique_ptr<dependencies::TextDiagnosticsPrinterWithOutput>
-      DiagPrinterWithOS;
 
   // Context - compiler invocation
   std::unique_ptr<CompilerInvocation> OriginalInvocation;
@@ -181,22 +184,6 @@ class CompilerInstanceWithContext {
                   IntrusiveRefCntPtr<llvm::vfs::FileSystem> 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,
-      dependencies::DependencyActionController &Controller,
-      DiagnosticConsumer &DC);
-
   /// @brief Initialize the compiler instance from an already-lowered cc1
   ///        commandline (driver-free).
   /// @param Worker The dependency scanning worker to initialize the compiler
@@ -216,42 +203,11 @@ class CompilerInstanceWithContext {
       IntrusiveRefCntPtr<llvm::vfs::FileSystem> OverlayFS,
       dependencies::DependencyActionController &Controller);
 
-  /// @brief Initializing the context and the compiler instance.
-  ///        This method must be called before calling
-  ///        computeDependenciesByNameWithContext.
-  /// @param CWD The current working directory used during the scan.
-  /// @param CommandLine The commandline used for the scan.
-  /// @return Error if the initializaiton fails.
-  static llvm::Expected<CompilerInstanceWithContext>
-  initializeOrError(DependencyScanningTool &Tool, StringRef CWD,
-                    ArrayRef<std::string> CommandLine,
-                    dependencies::DependencyActionController &Controller);
-
   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
-  ///.                  dependencies.
-  /// @param AlreadySeen This stores modules which have previously been
-  ///                    reported. Use the same instance for all calls to this
-  ///                    function for a single \c DependencyScanningTool in a
-  ///                    single build. Note that this parameter is not part of
-  ///                    the context because it can be shared across 
diff erent
-  ///                    worker threads and each worker thread may update it.
-  /// @param LookupModuleOutput This function is called to fill in
-  ///                           "-fmodule-file=", "-o" and other output
-  ///                           arguments for dependencies.
-  /// @return An instance of \c TranslationUnitDeps if the scan is successful.
-  ///         Otherwise it returns an error.
-  llvm::Expected<dependencies::TranslationUnitDeps>
-  computeDependenciesByNameOrError(
-      StringRef ModuleName,
-      const llvm::DenseSet<dependencies::ModuleID> &AlreadySeen,
-      dependencies::DependencyActionController &Controller);
-
   // MaxNumOfQueries is the upper limit of the number of names the by-name
   // scanning API (computeDependencies) can support after a
   // CompilerInstanceWithContext is initialized. At the time of this commit, the

diff  --git a/clang/lib/Tooling/DependencyScanningTool.cpp b/clang/lib/Tooling/DependencyScanningTool.cpp
index 6d2c57204b249..5ffd8c0b02115 100644
--- a/clang/lib/Tooling/DependencyScanningTool.cpp
+++ b/clang/lib/Tooling/DependencyScanningTool.cpp
@@ -171,12 +171,6 @@ static bool computeDependenciesForDriverCommandLine(
                                     std::move(OverlayFS));
 }
 
-static llvm::Error makeErrorFromDiagnosticsOS(
-    TextDiagnosticsPrinterWithOutput &DiagPrinterWithOS) {
-  return llvm::make_error<llvm::StringError>(
-      DiagPrinterWithOS.DiagnosticsOS.str(), llvm::inconvertibleErrorCode());
-}
-
 bool tooling::computeDependencies(
     DependencyScanningWorker &Worker, StringRef WorkingDirectory,
     ArrayRef<std::string> CommandLine, DependencyConsumer &Consumer,
@@ -329,20 +323,6 @@ DependencyScanningTool::getTranslationUnitDependencies(
   return Consumer.takeTranslationUnitDeps();
 }
 
-llvm::Expected<TranslationUnitDeps>
-DependencyScanningTool::getModuleDependencies(
-    StringRef ModuleName, ArrayRef<std::string> CommandLine, StringRef CWD,
-    const llvm::DenseSet<ModuleID> &AlreadySeen,
-    DependencyActionController &Controller) {
-  auto MaybeCIWithContext = CompilerInstanceWithContext::initializeOrError(
-      *this, CWD, CommandLine, Controller);
-  if (auto Error = MaybeCIWithContext.takeError())
-    return Error;
-
-  return MaybeCIWithContext->computeDependenciesByNameOrError(
-      ModuleName, AlreadySeen, Controller);
-}
-
 static std::optional<SmallVector<std::string, 0>>
 getFirstCC1CommandLine(ArrayRef<std::string> CommandLine,
                        DiagnosticsEngine &Diags,
@@ -366,39 +346,46 @@ getFirstCC1CommandLine(ArrayRef<std::string> CommandLine,
   return std::nullopt;
 }
 
-std::optional<CompilerInstanceWithContext>
-CompilerInstanceWithContext::initializeFromCommandline(
-    DependencyScanningTool &Tool, StringRef CWD,
-    ArrayRef<std::string> CommandLine, DependencyActionController &Controller,
-    DiagnosticConsumer &DC) {
+bool DependencyScanningTool::getByNameDependencies(
+    StringRef CWD, ArrayRef<std::string> CommandLine,
+    DiagnosticConsumer &DiagConsumer, DependencyActionController &Controller,
+    llvm::function_ref<std::optional<std::string>()> getNextName,
+    DependencyConsumer &DepConsumer) {
   auto [OverlayFS, ModifiedCommandLine] = initVFSForByNameScanning(CommandLine);
-  auto FS = Tool.Worker.makeEffectiveVFS(CWD, OverlayFS);
-
-  auto DiagEngineWithCmdAndOpts =
-      std::make_unique<DiagnosticsEngineWithDiagOpts>(ModifiedCommandLine, FS,
-                                                      DC);
-
+  auto FS = Worker.makeEffectiveVFS(CWD, OverlayFS);
+  std::vector<std::string> CC1CommandLine;
   if (ModifiedCommandLine.size() >= 2 && ModifiedCommandLine[1] == "-cc1") {
-    // The input command line is already a -cc1 invocation; initialize the
-    // compiler instance directly from it.
-    return initializeFromCC1Commandline(Tool.Worker, CWD, ModifiedCommandLine,
-                                        std::move(DiagEngineWithCmdAndOpts),
-                                        std::move(OverlayFS), Controller);
+    CC1CommandLine = std::move(ModifiedCommandLine);
+  } else {
+    // Driver-style (or ill-formed): lower to a cc1 command line, or diagnose.
+    DiagnosticsEngineWithDiagOpts DiagEngineWithOpts(ModifiedCommandLine, FS,
+                                                     DiagConsumer);
+    auto MaybeFirstCC1 = getFirstCC1CommandLine(
+        ModifiedCommandLine, *DiagEngineWithOpts.DiagEngine, FS);
+    if (!MaybeFirstCC1)
+      return false;
+    CC1CommandLine.assign(MaybeFirstCC1->begin(), MaybeFirstCC1->end());
   }
 
-  // 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.
-  const auto MaybeFirstCC1 = getFirstCC1CommandLine(
-      ModifiedCommandLine, *DiagEngineWithCmdAndOpts->DiagEngine, FS);
-  if (!MaybeFirstCC1)
-    return std::nullopt;
+  // Build one scanning session (a CIWC reused across all input names) and pull
+  // names until getNextName is exhausted.
+  auto DiagEngineWithOpts = std::make_unique<DiagnosticsEngineWithDiagOpts>(
+      CC1CommandLine, FS, DiagConsumer);
+  std::optional<CompilerInstanceWithContext> CIWC =
+      CompilerInstanceWithContext::initializeFromCC1Commandline(
+          Worker, CWD, CC1CommandLine, std::move(DiagEngineWithOpts),
+          std::move(OverlayFS), Controller);
+  if (!CIWC)
+    return false;
 
-  std::vector<std::string> CC1CommandLine(MaybeFirstCC1->begin(),
-                                          MaybeFirstCC1->end());
-  return initializeFromCC1Commandline(Tool.Worker, CWD, CC1CommandLine,
-                                      std::move(DiagEngineWithCmdAndOpts),
-                                      std::move(OverlayFS), Controller);
+  bool AllScansSucceeded = true;
+  while (std::optional<std::string> NextName = getNextName()) {
+    bool Success =
+        CIWC->computeDependencies(*NextName, DepConsumer, Controller);
+    DepConsumer.finishQuery(*NextName, Success);
+    AllScansSucceeded = AllScansSucceeded && Success;
+  }
+  return AllScansSucceeded;
 }
 
 std::optional<CompilerInstanceWithContext>
@@ -416,51 +403,14 @@ CompilerInstanceWithContext::initializeFromCC1Commandline(
   return std::move(CIWC);
 }
 
-llvm::Expected<CompilerInstanceWithContext>
-CompilerInstanceWithContext::initializeOrError(
-    DependencyScanningTool &Tool, StringRef CWD,
-    ArrayRef<std::string> CommandLine, DependencyActionController &Controller) {
-  {
-    auto LogLine = Tool.Worker.Service.getLogger().log();
-    LogLine << "init_compiler_instance_with_context:";
-    for (const auto &C : CommandLine) {
-      LogLine << " " << C;
-    }
-  }
-  auto DiagPrinterWithOS =
-      std::make_unique<TextDiagnosticsPrinterWithOutput>(CommandLine);
-
-  auto Result = initializeFromCommandline(Tool, CWD, CommandLine, Controller,
-                                          DiagPrinterWithOS->DiagPrinter);
-  if (Result) {
-    Result->DiagPrinterWithOS = std::move(DiagPrinterWithOS);
-    return std::move(*Result);
-  }
-  return makeErrorFromDiagnosticsOS(*DiagPrinterWithOS);
-}
-
-llvm::Expected<TranslationUnitDeps>
-CompilerInstanceWithContext::computeDependenciesByNameOrError(
-    StringRef ModuleName, const llvm::DenseSet<ModuleID> &AlreadySeen,
-    DependencyActionController &Controller) {
-  Worker.Service.getLogger().log() << "start scan_by_name: " << ModuleName;
-  llvm::scope_exit ExitLogging([&] {
-    Worker.Service.getLogger().log() << "finish scan_by_name: " << ModuleName;
-  });
-
-  FullDependencyConsumer Consumer(AlreadySeen);
-  // We need to clear the DiagnosticOutput so that each by-name lookup
-  // has a clean diagnostics buffer.
-  DiagPrinterWithOS->DiagnosticOutput.clear();
-  if (computeDependencies(ModuleName, Consumer, Controller))
-    return Consumer.takeTranslationUnitDeps();
-  return makeErrorFromDiagnosticsOS(*DiagPrinterWithOS);
-}
-
 bool CompilerInstanceWithContext::initialize(
     DependencyActionController &Controller,
     std::unique_ptr<DiagnosticsEngineWithDiagOpts> DiagEngineWithDiagOpts,
     IntrusiveRefCntPtr<llvm::vfs::FileSystem> OverlayFS) {
+  {
+    auto LogLine = Worker.Service.getLogger().log();
+    LogLine.logArray("init_compiler_instance_with_context:", " ", CommandLine);
+  }
   assert(DiagEngineWithDiagOpts && "Valid diagnostics engine required!");
   DiagEngineWithCmdAndOpts = std::move(DiagEngineWithDiagOpts);
   DiagConsumer = DiagEngineWithCmdAndOpts->DiagEngine->getClient();
@@ -514,6 +464,10 @@ bool CompilerInstanceWithContext::initialize(
 bool CompilerInstanceWithContext::computeDependencies(
     StringRef ModuleName, DependencyConsumer &Consumer,
     DependencyActionController &Controller) {
+  Worker.Service.getLogger().log() << "start scan_by_name: " << ModuleName;
+  llvm::scope_exit ExitLogging([&] {
+    Worker.Service.getLogger().log() << "finish scan_by_name: " << ModuleName;
+  });
   if (SrcLocOffset >= MaxNumOfQueries)
     llvm::report_fatal_error("exceeded maximum by-name scans for worker");
 

diff  --git a/clang/test/ClangScanDeps/modules-full-by-mult-mod-names-diagnostics.c b/clang/test/ClangScanDeps/modules-full-by-mult-mod-names-diagnostics.c
index 0eafb119c6bfe..ae8b116a2a4a6 100644
--- a/clang/test/ClangScanDeps/modules-full-by-mult-mod-names-diagnostics.c
+++ b/clang/test/ClangScanDeps/modules-full-by-mult-mod-names-diagnostics.c
@@ -40,11 +40,9 @@ module root2 { header "root2.h" }
 // RUN: cat %t/error.cc1.txt | FileCheck %s --check-prefixes=ERROR
 // RUN: cat %t/result.cc1.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s
 
-// ERROR: Error while scanning dependencies for modA:
+// ERROR: Diagnostics while scanning dependencies for 'modA,root,modB,modC,root2':
 // ERROR-NEXT: module-include.input:1:1: fatal error: module 'modA' not found
-// ERROR-NEXT: Error while scanning dependencies for modB:
 // ERROR-NEXT: module-include.input:1:3: fatal error: module 'modB' not found
-// ERROR-NEXT: Error while scanning dependencies for modC:
 // ERROR-NEXT: module-include.input:1:4: fatal error: module 'modC' not found
 // CHECK:      {
 // CHECK-NEXT:   "modules": [

diff  --git a/clang/test/ClangScanDeps/modules-invalid-target.c b/clang/test/ClangScanDeps/modules-invalid-target.c
index 333bfdfe48c9e..8432bbbcd0b34 100644
--- a/clang/test/ClangScanDeps/modules-invalid-target.c
+++ b/clang/test/ClangScanDeps/modules-invalid-target.c
@@ -12,7 +12,7 @@
 // Check that CompilerInstanceWithContext::initializeOrError properly errors
 // during target creation, instead of an assert or a segfault later down the
 // line:
-// CHECK: Error while scanning dependencies for M:
+// CHECK: Diagnostics while scanning dependencies for 'M':
 // CHECK-NEXT: error: unknown target triple 'unknown-unknown-unknown'
 
 //--- module.modulemap

diff  --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
index 2b35d54349f3c..83b4860c130c3 100644
--- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp
+++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
@@ -644,35 +644,6 @@ class FullDeps {
   std::vector<InputDeps> Inputs;
 };
 
-static bool handleModuleResult(StringRef ModuleName,
-                               llvm::Expected<TranslationUnitDeps> &MaybeTUDeps,
-                               FullDeps &FD, size_t InputIndex,
-                               SharedStream &OS, SharedStream &Errs) {
-  if (!MaybeTUDeps) {
-    llvm::handleAllErrors(MaybeTUDeps.takeError(),
-                          [&ModuleName, &Errs](llvm::StringError &Err) {
-                            Errs.applyLocked([&](raw_ostream &OS) {
-                              OS << "Error while scanning dependencies for "
-                                 << ModuleName << ":\n";
-                              OS << Err.getMessage();
-                            });
-                          });
-    return true;
-  }
-  FD.mergeDeps(std::move(MaybeTUDeps->ModuleGraph), InputIndex);
-  return false;
-}
-
-static void handleErrorWithInfoString(StringRef Info, llvm::Error E,
-                                      SharedStream &OS, SharedStream &Errs) {
-  llvm::handleAllErrors(std::move(E), [&Info, &Errs](llvm::StringError &Err) {
-    Errs.applyLocked([&](raw_ostream &OS) {
-      OS << "Error: " << Info << ":\n";
-      OS << Err.getMessage();
-    });
-  });
-}
-
 class P1689Deps {
 public:
   void printDependencies(raw_ostream &OS) {
@@ -865,6 +836,32 @@ getCompilationDatabase(int argc, char **argv, std::string &ErrorMessage) {
       FEOpts.Inputs[0].getFile(), OutputFile, CommandLine);
 }
 
+namespace {
+struct ByNameConsumer : DependencyConsumer {
+  FullDeps &FD;
+  size_t InputIndex;
+  ModuleDepsGraph ModuleGraph;
+
+  ByNameConsumer(FullDeps &FD, size_t InputIndex)
+      : FD(FD), InputIndex(InputIndex) {}
+
+  void handleDependencyOutputOpts(const DependencyOutputOptions &) override {}
+  void handleFileDependency(StringRef) override {}
+  void handlePrebuiltModuleDependency(PrebuiltModuleDep) override {}
+  void handleDirectModuleDependency(ModuleID) override {}
+  void handleVisibleModule(std::string) override {}
+  void handleContextHash(std::string) override {}
+  void handleModuleDependency(ModuleDeps MD) override {
+    ModuleGraph.push_back(std::move(MD));
+  }
+  void finishQuery(StringRef, bool Success) override {
+    if (Success)
+      FD.mergeDeps(std::move(ModuleGraph), InputIndex);
+    ModuleGraph.clear();
+  }
+};
+} // namespace
+
 int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) {
   llvm::InitializeAllTargetInfos();
   std::string ErrorMessage;
@@ -1110,35 +1107,21 @@ int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) {
         ModuleNameRef.split(Names, ',');
 
         CallbackActionController Controller(LookupOutput);
-
-        if (Names.size() == 1) {
-          auto MaybeModuleDepsGraph = WorkerTool.getModuleDependencies(
-              Names[0], Input->CommandLine, CWD, AlreadySeenModules,
-              Controller);
-          if (handleModuleResult(Names[0], MaybeModuleDepsGraph, *FD,
-                                 LocalIndex, DependencyOS, Errs))
-            HadErrors = true;
-        } else {
-          auto CIWithCtx = CompilerInstanceWithContext::initializeOrError(
-              WorkerTool, CWD, Input->CommandLine, Controller);
-          if (llvm::Error Err = CIWithCtx.takeError()) {
-            handleErrorWithInfoString(
-                "Compiler instance with context setup error", std::move(Err),
-                DependencyOS, Errs);
-            HadErrors = true;
-            continue;
-          }
-
-          for (auto N : Names) {
-            auto MaybeModuleDepsGraph =
-                CIWithCtx->computeDependenciesByNameOrError(
-                    N, AlreadySeenModules, Controller);
-            if (handleModuleResult(N, MaybeModuleDepsGraph, *FD, LocalIndex,
-                                   DependencyOS, Errs)) {
-              HadErrors = true;
-            }
-          }
-        }
+        ByNameConsumer DepConsumer(*FD, LocalIndex);
+
+        unsigned NameIdx = 0;
+        auto GetNextName = [&]() -> std::optional<std::string> {
+          if (NameIdx >= Names.size())
+            return std::nullopt;
+          return Names[NameIdx++].str();
+        };
+
+        bool Success = WorkerTool.getByNameDependencies(
+            CWD, Input->CommandLine, DiagConsumer, Controller, GetNextName,
+            DepConsumer);
+        handleDiagnostics(ModuleNameRef, S, Errs);
+        if (!Success)
+          HadErrors = true;
       } else {
         std::unique_ptr<llvm::MemoryBuffer> TU;
         std::optional<llvm::MemoryBufferRef> TUBuffer;


        


More information about the cfe-commits mailing list