Author: Qiongsi Wu
Date: 2026-01-30T08:41:11-08:00
New Revision: 5d01a0ad3d599df56d902b418e1a7eaf3f84db42

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

LOG: [clang][Modules] Fixing Incorrect Diagnostics Issued during By-name 
Dependency Scanning (#178542)

The by-name lookup API uses the same diagnostics engine and consumer for
multiple lookups. When multiple lookups fail, the diagnostics could be
incorrect for all but the first failing lookup. All the subsequent
failing lookups inherit the diagnostics from the first failing lookup.

This PR resets the diagnostics consumer's buffer and the
CompilerInstance's diagnostics engine for each by-name lookup, so each
lookup can produce the correct diagnostics.

Part of work for rdar://136303612.

Added: 
    clang/test/ClangScanDeps/modules-full-by-mult-mod-names-diagnostics.c

Modified: 
    clang/lib/DependencyScanning/DependencyScannerImpl.cpp
    clang/lib/Tooling/DependencyScanningTool.cpp
    clang/tools/clang-scan-deps/ClangScanDeps.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/DependencyScanning/DependencyScannerImpl.cpp 
b/clang/lib/DependencyScanning/DependencyScannerImpl.cpp
index 7df2b5a18ea1d..ec157cdd8f464 100644
--- a/clang/lib/DependencyScanning/DependencyScannerImpl.cpp
+++ b/clang/lib/DependencyScanning/DependencyScannerImpl.cpp
@@ -686,6 +686,11 @@ bool CompilerInstanceWithContext::computeDependencies(
   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([&]() {

diff  --git a/clang/lib/Tooling/DependencyScanningTool.cpp 
b/clang/lib/Tooling/DependencyScanningTool.cpp
index 1559ae0a8ec9b..9f27cb59b9cc8 100644
--- a/clang/lib/Tooling/DependencyScanningTool.cpp
+++ b/clang/lib/Tooling/DependencyScanningTool.cpp
@@ -370,6 +370,9 @@ 
DependencyScanningTool::computeDependenciesByNameWithContextOrError(
     LookupModuleOutputCallback LookupModuleOutput) {
   FullDependencyConsumer Consumer(AlreadySeen);
   CallbackActionController Controller(LookupModuleOutput);
+  // 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))
     return Consumer.takeTranslationUnitDeps();

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
new file mode 100644
index 0000000000000..9889982354e90
--- /dev/null
+++ b/clang/test/ClangScanDeps/modules-full-by-mult-mod-names-diagnostics.c
@@ -0,0 +1,52 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+
+// This test interleaves valid by-name lookups with invalid by-name lookups
+// to check that the valid lookups return correct results, and the invalid
+// ones generate correct diagnostics.
+
+//--- module.modulemap
+module root { header "root.h" }
+module root2 { header "root2.h" }
+//--- root.h
+
+//--- root2.h
+
+//--- cdb.json.template
+[{
+  "file": "",
+  "directory": "DIR",
+  "command": "clang -fmodules -fmodules-cache-path=DIR/cache -I DIR -x c"
+}]
+
+// RUN: sed "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
+// RUN: not clang-scan-deps -compilation-database %t/cdb.json -format \
+// RUN:   experimental-full -module-names=modA,root,modB,modC,root2 2> \
+// RUN:   %t/error.txt > %t/result.json
+// RUN: cat %t/error.txt | FileCheck %s --check-prefixes=ERROR
+// RUN: cat %t/result.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s
+
+// ERROR: Error while scanning dependencies for modA:
+// ERROR-NEXT: {{.*}}: fatal error: module 'modA' not found
+// ERROR-NEXT: Error while scanning dependencies for modB:
+// ERROR-NEXT: {{.*}}: fatal error: module 'modB' not found
+// ERROR-NEXT: Error while scanning dependencies for modC:
+// ERROR-NEXT: {{.*}}: fatal error: module 'modC' not found
+// CHECK:      {
+// CHECK-NEXT:   "modules": [
+// CHECK-NEXT:     {
+// CHECK:            "file-deps": [
+// CHECK-NEXT:         "[[PREFIX]]/module.modulemap",
+// CHECK-NEXT:         "[[PREFIX]]/root.h"
+// CHECK-NEXT:       ],
+// CHECK-NEXT:       "link-libraries": [],
+// CHECK-NEXT:       "name": "root"
+// CHECK-NEXT:     },
+// CHECK-NEXT:    {
+// CHECK:            "file-deps": [
+// CHECK-NEXT:         "[[PREFIX]]/module.modulemap",
+// CHECK-NEXT:         "[[PREFIX]]/root2.h"
+// CHECK-NEXT:       ],
+// CHECK-NEXT:       "link-libraries": [],
+// CHECK-NEXT:       "name": "root2"
+// CHECK-NEXT:     }

diff  --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp 
b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
index 256a70568a3bf..bfca051c68299 100644
--- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp
+++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
@@ -1085,7 +1085,6 @@ int clang_scan_deps_main(int argc, char **argv, const 
llvm::ToolContext &) {
             if (handleModuleResult(N, MaybeModuleDepsGraph, *FD, LocalIndex,
                                    DependencyOS, Errs)) {
               HadErrors = true;
-              break;
             }
           }
 


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

Reply via email to