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
