https://github.com/jansvoboda11 updated 
https://github.com/llvm/llvm-project/pull/182063

>From a4bd1e4234e3c2ef81d1fe01ac78ba7163ec4e8b Mon Sep 17 00:00:00 2001
From: Jan Svoboda <[email protected]>
Date: Tue, 17 Feb 2026 21:21:35 -0800
Subject: [PATCH 1/2] [clang][deps] Don't treat the 'make' output format
 specially

---
 .../DependencyScannerImpl.h                   | 12 ----
 .../DependencyScanning/ModuleDepCollector.h   |  3 +
 .../clang/Tooling/DependencyScanningTool.h    |  1 +
 .../DependencyScannerImpl.cpp                 | 66 ++++---------------
 .../DependencyScanning/ModuleDepCollector.cpp | 12 ++--
 clang/lib/Tooling/DependencyScanningTool.cpp  | 26 +++++---
 clang/test/ClangScanDeps/modules-cc1.cpp      |  2 +-
 .../modules-has-include-umbrella-header.c     |  3 +-
 clang/tools/clang-scan-deps/ClangScanDeps.cpp |  4 +-
 .../Tooling/DependencyScannerTest.cpp         | 10 +--
 10 files changed, 54 insertions(+), 85 deletions(-)

diff --git a/clang/include/clang/DependencyScanning/DependencyScannerImpl.h 
b/clang/include/clang/DependencyScanning/DependencyScannerImpl.h
index d50371512667d..3d55759d60d83 100644
--- a/clang/include/clang/DependencyScanning/DependencyScannerImpl.h
+++ b/clang/include/clang/DependencyScanning/DependencyScannerImpl.h
@@ -106,18 +106,6 @@ std::optional<PrebuiltModulesAttrsMap>
 computePrebuiltModulesASTMap(CompilerInstance &ScanInstance,
                              SmallVector<StringRef> &StableDirs);
 
-/// Create the dependency collector that will collect the produced
-/// dependencies. May return the created ModuleDepCollector depending
-/// on the scanning format.
-std::shared_ptr<ModuleDepCollector> initializeScanInstanceDependencyCollector(
-    CompilerInstance &ScanInstance,
-    std::unique_ptr<DependencyOutputOptions> DepOutputOpts,
-    StringRef WorkingDirectory, DependencyConsumer &Consumer,
-    DependencyScanningService &Service, CompilerInvocation &Inv,
-    DependencyActionController &Controller,
-    PrebuiltModulesAttrsMap PrebuiltModulesASTMap,
-    llvm::SmallVector<StringRef> &StableDirs);
-
 class CompilerInstanceWithContext {
   // Context
   DependencyScanningWorker &Worker;
diff --git a/clang/include/clang/DependencyScanning/ModuleDepCollector.h 
b/clang/include/clang/DependencyScanning/ModuleDepCollector.h
index 8f665daf03c69..2a581d72274f1 100644
--- a/clang/include/clang/DependencyScanning/ModuleDepCollector.h
+++ b/clang/include/clang/DependencyScanning/ModuleDepCollector.h
@@ -225,6 +225,9 @@ class ModuleDepCollectorPP final : public PPCallbacks {
   void LexedFileChanged(FileID FID, LexedFileChangeReason Reason,
                         SrcMgr::CharacteristicKind FileType, FileID PrevFID,
                         SourceLocation Loc) override;
+  void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled,
+                  OptionalFileEntryRef File,
+                  SrcMgr::CharacteristicKind FileType) override;
   void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
                           StringRef FileName, bool IsAngled,
                           CharSourceRange FilenameRange,
diff --git a/clang/include/clang/Tooling/DependencyScanningTool.h 
b/clang/include/clang/Tooling/DependencyScanningTool.h
index 96d21866dd7f9..5a94025191513 100644
--- a/clang/include/clang/Tooling/DependencyScanningTool.h
+++ b/clang/include/clang/Tooling/DependencyScanningTool.h
@@ -47,6 +47,7 @@ class DependencyScanningTool {
   /// dependency file contents otherwise.
   std::optional<std::string>
   getDependencyFile(ArrayRef<std::string> CommandLine, StringRef CWD,
+                    dependencies::LookupModuleOutputCallback 
LookupModuleOutput,
                     DiagnosticConsumer &DiagConsumer);
 
   /// Collect the module dependency in P1689 format for C++20 named modules.
diff --git a/clang/lib/DependencyScanning/DependencyScannerImpl.cpp 
b/clang/lib/DependencyScanning/DependencyScannerImpl.cpp
index 861e6e0042265..8d580012aae78 100644
--- a/clang/lib/DependencyScanning/DependencyScannerImpl.cpp
+++ b/clang/lib/DependencyScanning/DependencyScannerImpl.cpp
@@ -27,32 +27,6 @@
 using namespace clang;
 using namespace dependencies;
 
-namespace {
-/// Forwards the gatherered dependencies to the consumer.
-class DependencyConsumerForwarder : public DependencyFileGenerator {
-public:
-  DependencyConsumerForwarder(std::unique_ptr<DependencyOutputOptions> Opts,
-                              StringRef WorkingDirectory, DependencyConsumer 
&C)
-      : DependencyFileGenerator(*Opts), WorkingDirectory(WorkingDirectory),
-        Opts(std::move(Opts)), C(C) {}
-
-  void finishedMainFile(DiagnosticsEngine &Diags) override {
-    C.handleDependencyOutputOpts(*Opts);
-    llvm::SmallString<256> CanonPath;
-    for (const auto &File : getDependencies()) {
-      CanonPath = File;
-      llvm::sys::path::remove_dots(CanonPath, /*remove_dot_dot=*/true);
-      llvm::sys::path::make_absolute(WorkingDirectory, CanonPath);
-      C.handleFileDependency(CanonPath);
-    }
-  }
-
-private:
-  StringRef WorkingDirectory;
-  std::unique_ptr<DependencyOutputOptions> Opts;
-  DependencyConsumer &C;
-};
-
 static bool checkHeaderSearchPaths(const HeaderSearchOptions &HSOpts,
                                    const HeaderSearchOptions &ExistingHSOpts,
                                    DiagnosticsEngine *Diags,
@@ -77,6 +51,8 @@ static bool checkHeaderSearchPaths(const HeaderSearchOptions 
&HSOpts,
   return false;
 }
 
+namespace {
+
 using PrebuiltModuleFilesT = 
decltype(HeaderSearchOptions::PrebuiltModuleFiles);
 
 /// A listener that collects the imported modules and the input
@@ -527,31 +503,18 @@ createDependencyOutputOptions(const CompilerInvocation 
&Invocation) {
   return Opts;
 }
 
-std::shared_ptr<ModuleDepCollector>
-dependencies::initializeScanInstanceDependencyCollector(
+static std::shared_ptr<ModuleDepCollector>
+initializeScanInstanceDependencyCollector(
     CompilerInstance &ScanInstance,
     std::unique_ptr<DependencyOutputOptions> DepOutputOpts,
-    StringRef WorkingDirectory, DependencyConsumer &Consumer,
-    DependencyScanningService &Service, CompilerInvocation &Inv,
-    DependencyActionController &Controller,
+    DependencyConsumer &Consumer, DependencyScanningService &Service,
+    CompilerInvocation &Inv, DependencyActionController &Controller,
     PrebuiltModulesAttrsMap PrebuiltModulesASTMap,
-    llvm::SmallVector<StringRef> &StableDirs) {
-  std::shared_ptr<ModuleDepCollector> MDC;
-  switch (Service.getOpts().Format) {
-  case ScanningOutputFormat::Make:
-    ScanInstance.addDependencyCollector(
-        std::make_shared<DependencyConsumerForwarder>(
-            std::move(DepOutputOpts), WorkingDirectory, Consumer));
-    break;
-  case ScanningOutputFormat::P1689:
-  case ScanningOutputFormat::Full:
-    MDC = std::make_shared<ModuleDepCollector>(
-        Service, std::move(DepOutputOpts), ScanInstance, Consumer, Controller,
-        Inv, std::move(PrebuiltModulesASTMap), StableDirs);
-    ScanInstance.addDependencyCollector(MDC);
-    break;
-  }
-
+    SmallVector<StringRef> &StableDirs) {
+  auto MDC = std::make_shared<ModuleDepCollector>(
+      Service, std::move(DepOutputOpts), ScanInstance, Consumer, Controller,
+      Inv, std::move(PrebuiltModulesASTMap), StableDirs);
+  ScanInstance.addDependencyCollector(MDC);
   return MDC;
 }
 
@@ -790,9 +753,8 @@ bool DependencyScanningAction::runInvocation(
   auto DepOutputOpts = createDependencyOutputOptions(*OriginalInvocation);
 
   MDC = initializeScanInstanceDependencyCollector(
-      ScanInstance, std::move(DepOutputOpts), WorkingDirectory, Consumer,
-      Service, *OriginalInvocation, Controller, *MaybePrebuiltModulesASTMap,
-      StableDirs);
+      ScanInstance, std::move(DepOutputOpts), Consumer, Service,
+      *OriginalInvocation, Controller, *MaybePrebuiltModulesASTMap, 
StableDirs);
 
   std::unique_ptr<FrontendAction> Action;
 
@@ -901,7 +863,7 @@ bool CompilerInstanceWithContext::computeDependencies(
   });
 
   auto MDC = initializeScanInstanceDependencyCollector(
-      CI, std::make_unique<DependencyOutputOptions>(*OutputOpts), CWD, 
Consumer,
+      CI, std::make_unique<DependencyOutputOptions>(*OutputOpts), 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
diff --git a/clang/lib/DependencyScanning/ModuleDepCollector.cpp 
b/clang/lib/DependencyScanning/ModuleDepCollector.cpp
index 46a0f79bfd38e..ef56c894657e6 100644
--- a/clang/lib/DependencyScanning/ModuleDepCollector.cpp
+++ b/clang/lib/DependencyScanning/ModuleDepCollector.cpp
@@ -549,6 +549,13 @@ void ModuleDepCollectorPP::LexedFileChanged(FileID FID,
     MDC.addFileDep(llvm::sys::path::remove_leading_dotslash(*Filename));
 }
 
+void ModuleDepCollectorPP::HasInclude(SourceLocation Loc, StringRef FileName,
+                                      bool IsAngled, OptionalFileEntryRef File,
+                                      SrcMgr::CharacteristicKind FileType) {
+  if (File)
+    MDC.addFileDep(File->getName());
+}
+
 void ModuleDepCollectorPP::InclusionDirective(
     SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName,
     bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File,
@@ -950,12 +957,9 @@ void ModuleDepCollector::addVisibleModules() {
 
 static StringRef makeAbsoluteAndPreferred(CompilerInstance &CI, StringRef Path,
                                           SmallVectorImpl<char> &Storage) {
-  if (llvm::sys::path::is_absolute(Path) &&
-      !llvm::sys::path::is_style_windows(llvm::sys::path::Style::native))
-    return Path;
   Storage.assign(Path.begin(), Path.end());
   CI.getFileManager().makeAbsolutePath(Storage);
-  llvm::sys::path::make_preferred(Storage);
+  llvm::sys::path::remove_dots(Storage, /*remove_dot_dot=*/true);
   return StringRef(Storage.data(), Storage.size());
 }
 
diff --git a/clang/lib/Tooling/DependencyScanningTool.cpp 
b/clang/lib/Tooling/DependencyScanningTool.cpp
index 2ae149e8fb2cf..56f4e56fd13a1 100644
--- a/clang/lib/Tooling/DependencyScanningTool.cpp
+++ b/clang/lib/Tooling/DependencyScanningTool.cpp
@@ -40,7 +40,11 @@ class MakeDependencyPrinterConsumer : public 
DependencyConsumer {
   // set of deps, and handleFileDependency handles enough for implicitly
   // built modules to work.
   void handlePrebuiltModuleDependency(PrebuiltModuleDep PMD) override {}
-  void handleModuleDependency(ModuleDeps MD) override {}
+  void handleModuleDependency(ModuleDeps MD) override {
+    MD.forEachFileDep([this](StringRef File) {
+      ModuleDependencies.push_back(std::string(File));
+    });
+  }
   void handleDirectModuleDependency(ModuleID ID) override {}
   void handleVisibleModule(std::string ModuleName) override {}
   void handleContextHash(std::string Hash) override {}
@@ -51,10 +55,13 @@ class MakeDependencyPrinterConsumer : public 
DependencyConsumer {
     class DependencyPrinter : public DependencyFileGenerator {
     public:
       DependencyPrinter(DependencyOutputOptions &Opts,
-                        ArrayRef<std::string> Dependencies)
-          : DependencyFileGenerator(Opts) {
+                        ArrayRef<std::string> Dependencies,
+                        ArrayRef<std::string> ModuleDependencies)
+      : DependencyFileGenerator(Opts) {
         for (const auto &Dep : Dependencies)
           addDependency(Dep);
+        for (const auto &Dep : ModuleDependencies)
+          addDependency(Dep);
       }
 
       void printDependencies(std::string &S) {
@@ -63,13 +70,14 @@ class MakeDependencyPrinterConsumer : public 
DependencyConsumer {
       }
     };
 
-    DependencyPrinter Generator(*Opts, Dependencies);
+    DependencyPrinter Generator(*Opts, Dependencies, ModuleDependencies);
     Generator.printDependencies(S);
   }
 
 protected:
   std::unique_ptr<DependencyOutputOptions> Opts;
   std::vector<std::string> Dependencies;
+  std::vector<std::string> ModuleDependencies;
 };
 } // anonymous namespace
 
@@ -182,12 +190,12 @@ bool tooling::computeDependencies(
                           Controller, DiagConsumer, OverlayFS);
 }
 
-std::optional<std::string>
-DependencyScanningTool::getDependencyFile(ArrayRef<std::string> CommandLine,
-                                          StringRef CWD,
-                                          DiagnosticConsumer &DiagConsumer) {
+std::optional<std::string> DependencyScanningTool::getDependencyFile(
+    ArrayRef<std::string> CommandLine, StringRef CWD,
+    LookupModuleOutputCallback LookupModuleOutput,
+    DiagnosticConsumer &DiagConsumer) {
   MakeDependencyPrinterConsumer DepConsumer;
-  CallbackActionController Controller(nullptr);
+  CallbackActionController Controller(LookupModuleOutput);
   if (!computeDependencies(Worker, CWD, CommandLine, DepConsumer, Controller,
                            DiagConsumer))
     return std::nullopt;
diff --git a/clang/test/ClangScanDeps/modules-cc1.cpp 
b/clang/test/ClangScanDeps/modules-cc1.cpp
index 04a365249f379..28fc020847d56 100644
--- a/clang/test/ClangScanDeps/modules-cc1.cpp
+++ b/clang/test/ClangScanDeps/modules-cc1.cpp
@@ -16,7 +16,7 @@ module header1 { header "header.h" }
 [{
   "file": "DIR/modules_cc1.cpp",
   "directory": "DIR",
-  "command": "clang -cc1 DIR/modules_cc1.cpp -fimplicit-module-maps -o 
modules_cc1.o"
+  "command": "clang -cc1 DIR/modules_cc1.cpp -fmodules 
-fmodules-cache-path=DIR/cache -fimplicit-module-maps -o modules_cc1.o"
 }]
 
 // RUN: sed "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
diff --git a/clang/test/ClangScanDeps/modules-has-include-umbrella-header.c 
b/clang/test/ClangScanDeps/modules-has-include-umbrella-header.c
index 022c59ca65db2..f7f804794ab41 100644
--- a/clang/test/ClangScanDeps/modules-has-include-umbrella-header.c
+++ b/clang/test/ClangScanDeps/modules-has-include-umbrella-header.c
@@ -65,7 +65,8 @@ module Dependency { header "dependency.h" }
 // CHECK-NEXT:           "command-line": [
 // CHECK:                ],
 // CHECK:                "file-deps": [
-// CHECK-NEXT:             "[[PREFIX]]/tu.c"
+// CHECK-NEXT:             "[[PREFIX]]/tu.c",
+// CHECK-NEXT:             
"[[PREFIX]]/frameworks/FW.framework/PrivateHeaders/B.h"
 // CHECK-NEXT:           ],
 // CHECK-NEXT:           "input-file": "[[PREFIX]]/tu.c"
 // CHECK-NEXT:         }
diff --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp 
b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
index 30fb8d47f8d5d..7f909ae34e595 100644
--- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp
+++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
@@ -1009,8 +1009,8 @@ int clang_scan_deps_main(int argc, char **argv, const 
llvm::ToolContext &) {
 
       // Run the tool on it.
       if (Format == ScanningOutputFormat::Make) {
-        auto MaybeFile =
-            WorkerTool.getDependencyFile(Input->CommandLine, CWD, 
DiagConsumer);
+        auto MaybeFile = WorkerTool.getDependencyFile(
+            Input->CommandLine, CWD, LookupOutput, DiagConsumer);
         handleDiagnostics(Filename, S, Errs);
         if (MaybeFile)
           DependencyOS.applyLocked([&](raw_ostream &OS) { OS << *MaybeFile; });
diff --git a/clang/unittests/Tooling/DependencyScannerTest.cpp 
b/clang/unittests/Tooling/DependencyScannerTest.cpp
index 79fd5a312d2b9..86d4e0ee1b8c5 100644
--- a/clang/unittests/Tooling/DependencyScannerTest.cpp
+++ b/clang/unittests/Tooling/DependencyScannerTest.cpp
@@ -235,8 +235,9 @@ TEST(DependencyScanner, ScanDepsWithFS) {
   DependencyScanningTool ScanTool(Service);
 
   TextDiagnosticBuffer DiagConsumer;
-  std::optional<std::string> DepFile =
-      ScanTool.getDependencyFile(CommandLine, CWD, DiagConsumer);
+  std::optional<std::string> DepFile = ScanTool.getDependencyFile(
+      CommandLine, CWD, 
CallbackActionController::lookupUnreachableModuleOutput,
+      DiagConsumer);
   ASSERT_TRUE(DepFile.has_value());
   EXPECT_EQ(llvm::sys::path::convert_to_slash(*DepFile),
             "test.cpp.o: /root/test.cpp /root/header.h\n");
@@ -297,8 +298,9 @@ TEST(DependencyScanner, ScanDepsWithModuleLookup) {
   // matter, the point of the test is to check that files are not read
   // unnecessarily.
   TextDiagnosticBuffer DiagConsumer;
-  std::optional<std::string> DepFile =
-      ScanTool.getDependencyFile(CommandLine, CWD, DiagConsumer);
+  std::optional<std::string> DepFile = ScanTool.getDependencyFile(
+      CommandLine, CWD, 
CallbackActionController::lookupUnreachableModuleOutput,
+      DiagConsumer);
   ASSERT_FALSE(DepFile.has_value());
 
   EXPECT_TRUE(!llvm::is_contained(InterceptFS->StatPaths, OtherPath));

>From de42f7769b6208108493ff7cfdbeff5d55ae0e35 Mon Sep 17 00:00:00 2001
From: Jan Svoboda <[email protected]>
Date: Wed, 18 Feb 2026 09:04:11 -0800
Subject: [PATCH 2/2] clang-format

---
 clang/lib/Tooling/DependencyScanningTool.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Tooling/DependencyScanningTool.cpp 
b/clang/lib/Tooling/DependencyScanningTool.cpp
index 56f4e56fd13a1..082417eba3b20 100644
--- a/clang/lib/Tooling/DependencyScanningTool.cpp
+++ b/clang/lib/Tooling/DependencyScanningTool.cpp
@@ -57,7 +57,7 @@ class MakeDependencyPrinterConsumer : public 
DependencyConsumer {
       DependencyPrinter(DependencyOutputOptions &Opts,
                         ArrayRef<std::string> Dependencies,
                         ArrayRef<std::string> ModuleDependencies)
-      : DependencyFileGenerator(Opts) {
+          : DependencyFileGenerator(Opts) {
         for (const auto &Dep : Dependencies)
           addDependency(Dep);
         for (const auto &Dep : ModuleDependencies)

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

Reply via email to