https://github.com/jansvoboda11 updated https://github.com/llvm/llvm-project/pull/89428
>From baa15bb0f35e3f9845407c6b843b82c3a466369f Mon Sep 17 00:00:00 2001 From: Jan Svoboda <jan_svob...@apple.com> Date: Fri, 19 Apr 2024 10:28:33 -0700 Subject: [PATCH] [clang][modules] Only avoid pruning module maps when asked to --- clang/include/clang/Driver/Options.td | 5 ++ clang/include/clang/Lex/HeaderSearchOptions.h | 7 ++- clang/lib/Serialization/ASTWriter.cpp | 6 +- .../DependencyScanning/ModuleDepCollector.cpp | 5 ++ clang/test/ClangScanDeps/modules-full.cpp | 3 + .../add-remove-irrelevant-module-map.m | 32 ---------- .../prune-non-affecting-module-map-files.m | 62 +++++++++++++++++++ 7 files changed, 84 insertions(+), 36 deletions(-) delete mode 100644 clang/test/Modules/add-remove-irrelevant-module-map.m create mode 100644 clang/test/Modules/prune-non-affecting-module-map-files.m diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d83031b05cebc4..a3d2863bc7507e 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3100,6 +3100,11 @@ defm modules_skip_header_search_paths : BoolFOption<"modules-skip-header-search- HeaderSearchOpts<"ModulesSkipHeaderSearchPaths">, DefaultFalse, PosFlag<SetTrue, [], [], "Disable writing header search paths">, NegFlag<SetFalse>, BothFlags<[], [CC1Option]>>; +def fno_modules_prune_non_affecting_module_map_files : + Flag<["-"], "fno-modules-prune-non-affecting-module-map-files">, + Group<f_Group>, Flags<[]>, Visibility<[CC1Option]>, + MarshallingInfoNegativeFlag<HeaderSearchOpts<"ModulesPruneNonAffectingModuleMaps">>, + HelpText<"Do not prune non-affecting module map files when writing module files">; def fincremental_extensions : Flag<["-"], "fincremental-extensions">, diff --git a/clang/include/clang/Lex/HeaderSearchOptions.h b/clang/include/clang/Lex/HeaderSearchOptions.h index 637dc77e5d957e..e4437ac0e35263 100644 --- a/clang/include/clang/Lex/HeaderSearchOptions.h +++ b/clang/include/clang/Lex/HeaderSearchOptions.h @@ -252,6 +252,10 @@ class HeaderSearchOptions { LLVM_PREFERRED_TYPE(bool) unsigned ModulesSkipPragmaDiagnosticMappings : 1; + /// Whether to prune non-affecting module map files from PCM files. + LLVM_PREFERRED_TYPE(bool) + unsigned ModulesPruneNonAffectingModuleMaps : 1; + LLVM_PREFERRED_TYPE(bool) unsigned ModulesHashContent : 1; @@ -280,7 +284,8 @@ class HeaderSearchOptions { ModulesValidateDiagnosticOptions(true), ModulesSkipDiagnosticOptions(false), ModulesSkipHeaderSearchPaths(false), - ModulesSkipPragmaDiagnosticMappings(false), ModulesHashContent(false), + ModulesSkipPragmaDiagnosticMappings(false), + ModulesPruneNonAffectingModuleMaps(true), ModulesHashContent(false), ModulesStrictContextHash(false), ModulesIncludeVFSUsage(false) {} /// AddPath - Add the \p Path path to the specified \p Group list. diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 6dd87b5d200db6..8a4b36207c4734 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -166,9 +166,9 @@ namespace { std::optional<std::set<const FileEntry *>> GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) { - // Without implicit module map search, there's no good reason to know about - // any module maps that are not affecting. - if (!PP.getHeaderSearchInfo().getHeaderSearchOpts().ImplicitModuleMaps) + if (!PP.getHeaderSearchInfo() + .getHeaderSearchOpts() + .ModulesPruneNonAffectingModuleMaps) return std::nullopt; SmallVector<const Module *> ModulesToProcess{RootModule}; diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp index e19f19b2528c15..f46324ee9989eb 100644 --- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp @@ -179,6 +179,11 @@ makeCommonInvocationForModuleBuild(CompilerInvocation CI) { CI.resetNonModularOptions(); CI.clearImplicitModuleBuildOptions(); + // The scanner takes care to avoid passing non-affecting module maps to the + // explicit compiles. No need to do extra work just to find out there are no + // module map files to prune. + CI.getHeaderSearchOpts().ModulesPruneNonAffectingModuleMaps = false; + // Remove options incompatible with explicit module build or are likely to // differ between identical modules discovered from different translation // units. diff --git a/clang/test/ClangScanDeps/modules-full.cpp b/clang/test/ClangScanDeps/modules-full.cpp index 59efef0ecbaa64..a00a431eb56911 100644 --- a/clang/test/ClangScanDeps/modules-full.cpp +++ b/clang/test/ClangScanDeps/modules-full.cpp @@ -33,6 +33,7 @@ // CHECK-NEXT: "command-line": [ // CHECK-NEXT: "-cc1" // CHECK: "-emit-module" +// CHECK: "-fno-modules-prune-non-affecting-module-map-files" // CHECK: "-fmodule-file={{.*}}[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H2_DINCLUDE]]/header2-{{[A-Z0-9]+}}.pcm" // CHECK-NOT: "-fimplicit-module-maps" // CHECK: "-fmodule-name=header1" @@ -51,6 +52,7 @@ // CHECK-NEXT: "command-line": [ // CHECK-NEXT: "-cc1", // CHECK: "-emit-module", +// CHECK: "-fno-modules-prune-non-affecting-module-map-files" // CHECK-NOT: "-fimplicit-module-maps", // CHECK: "-fmodule-name=header1", // CHECK: "-fno-implicit-modules", @@ -68,6 +70,7 @@ // CHECK-NEXT: "command-line": [ // CHECK-NEXT: "-cc1", // CHECK: "-emit-module", +// CHECK: "-fno-modules-prune-non-affecting-module-map-files" // CHECK: "-fmodule-name=header2", // CHECK-NOT: "-fimplicit-module-maps", // CHECK: "-fno-implicit-modules", diff --git a/clang/test/Modules/add-remove-irrelevant-module-map.m b/clang/test/Modules/add-remove-irrelevant-module-map.m deleted file mode 100644 index 7e3e58037e6f21..00000000000000 --- a/clang/test/Modules/add-remove-irrelevant-module-map.m +++ /dev/null @@ -1,32 +0,0 @@ -// RUN: rm -rf %t && mkdir %t -// RUN: split-file %s %t - -//--- a/module.modulemap -module a {} - -//--- b/module.modulemap -module b {} - -//--- c/module.modulemap -module c {} - -//--- module.modulemap -module m { header "m.h" } -//--- m.h -@import c; - -//--- test-simple.m -// expected-no-diagnostics -@import m; - -// Build modules with the non-affecting "a/module.modulemap". -// RUN: %clang_cc1 -I %t/a -I %t/b -I %t/c -I %t -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -fdisable-module-hash %t/test-simple.m -verify -// RUN: mv %t/cache %t/cache-with - -// Build modules without the non-affecting "a/module.modulemap". -// RUN: rm -rf %t/a/module.modulemap -// RUN: %clang_cc1 -I %t/a -I %t/b -I %t/c -I %t -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -fdisable-module-hash %t/test-simple.m -verify -// RUN: mv %t/cache %t/cache-without - -// Check that the PCM files are bit-for-bit identical. -// RUN: diff %t/cache-with/m.pcm %t/cache-without/m.pcm diff --git a/clang/test/Modules/prune-non-affecting-module-map-files.m b/clang/test/Modules/prune-non-affecting-module-map-files.m new file mode 100644 index 00000000000000..ba2b3a306eaf46 --- /dev/null +++ b/clang/test/Modules/prune-non-affecting-module-map-files.m @@ -0,0 +1,62 @@ +// Check that the presence of non-affecting module map files does not affect the +// contents of PCM files. + +// RUN: rm -rf %t && mkdir %t +// RUN: split-file %s %t + +//--- a/module.modulemap +module a {} + +//--- b/module.modulemap +module b {} + +//--- c/module.modulemap +module c { header "c.h" } +//--- c/c.h +@import b; + +//--- tu.m +@import c; + +//--- explicit-mms-common-args.rsp +-fmodule-map-file=b/module.modulemap -fmodule-map-file=c/module.modulemap -fmodules -fmodules-cache-path=cache -fdisable-module-hash -fsyntax-only tu.m +//--- implicit-search-args.rsp +-I a -I b -I c -fimplicit-module-maps -fmodules -fmodules-cache-path=cache -fdisable-module-hash -fsyntax-only tu.m +//--- implicit-search-args.rsp-end + +// Test with explicit module map files. +// +// RUN: %clang_cc1 -working-directory %t @%t/explicit-mms-common-args.rsp +// RUN: mv %t/cache %t/cache-explicit-no-a-prune +// RUN: %clang_cc1 -working-directory %t @%t/explicit-mms-common-args.rsp -fno-modules-prune-non-affecting-module-map-files +// RUN: mv %t/cache %t/cache-explicit-no-a-keep +// +// RUN: %clang_cc1 -working-directory %t -fmodule-map-file=a/module.modulemap @%t/explicit-mms-common-args.rsp +// RUN: mv %t/cache %t/cache-explicit-a-prune +// RUN: %clang_cc1 -working-directory %t -fmodule-map-file=a/module.modulemap @%t/explicit-mms-common-args.rsp -fno-modules-prune-non-affecting-module-map-files +// RUN: mv %t/cache %t/cache-explicit-a-keep +// +// RUN: diff %t/cache-explicit-no-a-prune/c.pcm %t/cache-explicit-a-prune/c.pcm +// RUN: not diff %t/cache-explicit-no-a-keep/c.pcm %t/cache-explicit-a-keep/c.pcm + +// Test with implicit module map search. +// +// RUN: %clang_cc1 -working-directory %t @%t/implicit-search-args.rsp +// RUN: mv %t/cache %t/cache-implicit-no-a-prune +// RUN: %clang_cc1 -working-directory %t @%t/implicit-search-args.rsp -fno-modules-prune-non-affecting-module-map-files +// RUN: mv %t/cache %t/cache-implicit-no-a-keep +// +// FIXME: Instead of removing "a/module.modulemap" from the file system, we +// could drop the "-I a" search path argument in combination with the +// "-fmodules-skip-header-search-paths" flag. Unfortunately, that flag +// does not prevent serialization of the search path usage bit vector, +// making the files differ anyways. +// RUN: rm %t/a/module.modulemap +// +// RUN: %clang_cc1 -working-directory %t @%t/implicit-search-args.rsp +// RUN: mv %t/cache %t/cache-implicit-a-prune +// RUN: %clang_cc1 -working-directory %t @%t/implicit-search-args.rsp -fno-modules-prune-non-affecting-module-map-files +// RUN: mv %t/cache %t/cache-implicit-a-keep +// +// RUN: diff %t/cache-implicit-no-a-prune/c.pcm %t/cache-implicit-a-prune/c.pcm +// RUN: not diff %t/cache-implicit-no-a-keep/c.pcm %t/cache-implicit-a-keep/c.pcm _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits