From aa7a06b019660e39925cc9c31d9262232ec06992 Mon Sep 17 00:00:00 2001 From: Michael Spencer Date: Wed, 31 Jan 2024 12:28:27 -0800 Subject: [PATCH] [clang][DependencyScanner] Remove unused -fmodule-map-file arguments (#80090) Since we already add a `-fmodule-map-file=` argument for every used modulemap, we can remove all `ModuleMapFiles` entries before adding them. This reduces the number of module variants when `-fmodule-map-file=` appears on the original command line. --- .../DependencyScanning/ModuleDepCollector.cpp | 4 ++ .../test/ClangScanDeps/optimize-fmodulemap.m | 66 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 clang/test/ClangScanDeps/optimize-fmodulemap.m diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp index b807dc84321852..995d8b2899c8d0 100644 --- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp @@ -211,6 +211,10 @@ ModuleDepCollector::getInvocationAdjustedForModuleBuildWithoutOutputs( ScanInstance.getFileManager().getFile(Deps.ClangModuleMapFile); assert(CurrentModuleMapEntry && "module map file entry not found"); + // Remove directly passed modulemap files. They will get added back if they + // were actually used. + CI.getMutFrontendOpts().ModuleMapFiles.clear(); + auto DepModuleMapFiles = collectModuleMapFiles(Deps.ClangModuleDeps); for (StringRef ModuleMapFile : Deps.ModuleMapFileDeps) { // TODO: Track these as `FileEntryRef` to simplify the equality check below. diff --git a/clang/test/ClangScanDeps/optimize-fmodulemap.m b/clang/test/ClangScanDeps/optimize-fmodulemap.m new file mode 100644 index 00000000000000..5e9affb30b9c1a --- /dev/null +++ b/clang/test/ClangScanDeps/optimize-fmodulemap.m @@ -0,0 +1,66 @@ +// Check that unused directly passed -fmodule-map-file options get dropped. + +// RUN: rm -rf %t && split-file %s %t +// RUN: sed -e "s|DIR|%/t|g" %t/build/cdb.json.in > %t/build/cdb.json +// RUN: clang-scan-deps -compilation-database %t/build/cdb.json \ +// RUN: -format experimental-full > %t/deps.json +// RUN: cat %t/deps.json | sed 's:\\\\\?:/:g' | FileCheck %s -DPREFIX=%/t + +// CHECK: { +// CHECK-NEXT: "modules": [ +// CHECK-NEXT: { +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "{{.*}}", +// CHECK-NEXT: "module-name": "B" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/modules/A/module.modulemap", +// CHECK-NEXT: "command-line": [ +// CHECK-NOT: "-fmodule-map-file=[[PREFIX]]/modules/A/module.modulemap" +// CHECK: "-fmodule-map-file=[[PREFIX]]/modules/B/module.modulemap" +// CHECK-NOT: "-fmodule-map-file=[[PREFIX]]/modules/A/module.modulemap" +// CHECK: ], +// CHECK-NEXT: "context-hash": "{{.*}}", +// CHECK-NEXT: "file-deps": [ +// CHECK: ], +// CHECK-NEXT: "name": "A" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "clang-module-deps": [], +// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/modules/B/module.modulemap", +// CHECK-NEXT: "command-line": [ +// CHECK-NOT: "-fmodule-map-file= +// CHECK: ], +// CHECK-NEXT: "context-hash": "{{.*}}", +// CHECK-NEXT: "file-deps": [ +// CHECK: ], +// CHECK-NEXT: "name": "B" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "translation-units": [ +// CHECK: ] +// CHECK: } + +//--- build/cdb.json.in +[{ + "directory": "DIR", + "command": "clang -c DIR/tu.m -I DIR/modules/B -fmodule-map-file=DIR/modules/A/module.modulemap -fmodules -fmodules-cache-path=DIR/cache -fimplicit-module-maps", + "file": "DIR/tu.m" +}] + +//--- build/vfs.yaml.in + +//--- tu.m +@import A; + +//--- modules/A/module.modulemap +module A { header "A.h" } + +//--- modules/A/A.h +#include + +//--- modules/B/module.modulemap +module B { header "B.h" } + +//--- modules/B/B.h