llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-modules Author: Jan Svoboda (jansvoboda11) <details> <summary>Changes</summary> This introduces the search-path counterpart to `-fmodules-ignore-macro=<macro>`. The named header search `<path>` is dropped from the context hash of every module and physically removed from every module-build invocation, and kept only for the translation unit itself. The motivating case is a build system that hands every compile a per-target header search directory (e.g. Xcode's `DerivedSources`) even though no modules include anything from it. Under `-fmodules-strict-context-hash` those directories feed every module's context hash, so an SDK module like Foundation is rebuilt once per target rather than just once. Ignoring the directories for modules lets those builds share a single module cache while the TUs that really do need them keep working. This only works right when no module needs the path: a lookup that would have resolved through an ignored path simply fails, exactly as ignoring a macro a module needs silently changes what that module sees. The dependency scanner prunes in `makeCommonInvocationForModuleBuild()`, on the common invocation every module descends from, so the pruning is uniform and the search-path bit indices that `optimizeHeaderSearchOpts()` works with still line up with what the real implicit builds used. --- Patch is 23.97 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/217061.diff 11 Files Affected: - (modified) clang/docs/ReleaseNotes.md (+7) - (modified) clang/include/clang/Lex/HeaderSearchOptions.h (+5-2) - (modified) clang/include/clang/Options/Options.td (+3) - (modified) clang/lib/DependencyScanning/ModuleDepCollector.cpp (+12) - (modified) clang/lib/Driver/ToolChains/Clang.cpp (+1-1) - (modified) clang/lib/Frontend/CompilerInstance.cpp (+11) - (modified) clang/lib/Frontend/CompilerInvocation.cpp (+20-1) - (added) clang/test/ClangScanDeps/modules-context-hash-ignore-search-path.c (+112) - (added) clang/test/ClangScanDeps/modules-ignore-search-path-optimize-args.c (+194) - (added) clang/test/Driver/modules-ignore-search-path.c (+7) - (added) clang/test/Modules/modules-ignore-search-path.c (+91) ``````````diff diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index f5f9958543e34..fec61e74edb74 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -209,6 +209,13 @@ features cannot lower the translation-unit ABI level; `-fsanitize=shadow-call-stack`. The selected register must also be reserved with the matching `-ffixed-<reg>`. +- Added `-fmodules-ignore-search-path=<path>`, the search-path counterpart to + `-fmodules-ignore-macro=<macro>`: the path is dropped from the context hash of + every module and physically removed from every module build, and kept only for + the translation unit itself. This lets builds that differ only in a search + path share one module cache, and is only sound when no module needs the path + -- a lookup that would have resolved through an ignored path simply fails. + ### Deprecated Compiler Flags ### Modified Compiler Flags diff --git a/clang/include/clang/Lex/HeaderSearchOptions.h b/clang/include/clang/Lex/HeaderSearchOptions.h index fd46ea223bae1..a521f38e28233 100644 --- a/clang/include/clang/Lex/HeaderSearchOptions.h +++ b/clang/include/clang/Lex/HeaderSearchOptions.h @@ -180,10 +180,13 @@ class HeaderSearchOptions { /// loading. uint64_t BuildSessionTimestamp = 0; - /// The set of macro names that should be ignored for the purposes - /// of computing the module hash. + /// The set of macro names that should be ignored by implicitly-built modules. llvm::SmallSetVector<llvm::CachedHashString, 16> ModulesIgnoreMacros; + /// The set of header search paths that should be ignored by implicitly-built + /// modules. + llvm::SmallSetVector<llvm::CachedHashString, 16> ModulesIgnoreSearchPaths; + /// The set of user-provided virtual filesystem overlay files. std::vector<std::string> VFSOverlayFiles; diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index adc4224dd561c..ff085e374e3f9 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -3883,6 +3883,9 @@ def fmodule_file : Joined<["-"], "fmodule-file=">, def fmodules_ignore_macro : Joined<["-"], "fmodules-ignore-macro=">, Group<f_Group>, Visibility<[ClangOption, CC1Option, CLOption]>, HelpText<"Ignore the definition of the given macro when building and loading modules">; +def fmodules_ignore_search_path : Joined<["-"], "fmodules-ignore-search-path=">, Group<f_Group>, + Visibility<[ClangOption, CC1Option, CLOption]>, + HelpText<"Ignore the given header search path when building and loading modules">; def fmodules_strict_decluse : Flag <["-"], "fmodules-strict-decluse">, Group<f_Group>, Visibility<[ClangOption, CC1Option, CLOption]>, HelpText<"Like -fmodules-decluse but requires all headers to be in modules">, diff --git a/clang/lib/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/DependencyScanning/ModuleDepCollector.cpp index c7b7fcc8750c3..d48ac6b45cf46 100644 --- a/clang/lib/DependencyScanning/ModuleDepCollector.cpp +++ b/clang/lib/DependencyScanning/ModuleDepCollector.cpp @@ -294,6 +294,18 @@ makeCommonInvocationForModuleBuild(CompilerInvocation CI) { CI.getHeaderSearchOpts().ModulesIgnoreMacros.clear(); } + // Remove any header search paths that are explicitly ignored. + if (!CI.getHeaderSearchOpts().ModulesIgnoreSearchPaths.empty()) { + llvm::erase_if( + CI.getHeaderSearchOpts().UserEntries, + [&CI](const HeaderSearchOptions::Entry &E) { + return CI.getHeaderSearchOpts().ModulesIgnoreSearchPaths.contains( + llvm::CachedHashString(E.Path)); + }); + // Remove the now unused option. + CI.getHeaderSearchOpts().ModulesIgnoreSearchPaths.clear(); + } + return CI; } diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 54583fe3abbd8..8731188dab706 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4214,8 +4214,8 @@ static bool RenderModulesOptions(Compilation &C, const Driver &D, if (HaveClangModules) Args.AddLastArg(CmdArgs, options::OPT_fmodules_user_build_path); - // Pass through all -fmodules-ignore-macro arguments. Args.AddAllArgs(CmdArgs, options::OPT_fmodules_ignore_macro); + Args.AddAllArgs(CmdArgs, options::OPT_fmodules_ignore_search_path); Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_interval); Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_after); diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 66662a786e6fc..83bbdd96d89eb 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -1164,6 +1164,17 @@ std::unique_ptr<CompilerInstance> CompilerInstance::cloneForModuleCompileImpl( return HSOpts.ModulesIgnoreMacros.contains( llvm::CachedHashString(MacroDef.split('=').first)); }); + HSOpts.ModulesIgnoreMacros.clear(); + + // Remove any search paths that are explicitly ignored by the module. + // They aren't supposed to affect how the module is built anyway. + if (!HSOpts.ModulesIgnoreSearchPaths.empty()) + llvm::erase_if(HSOpts.UserEntries, + [&HSOpts](const HeaderSearchOptions::Entry &E) { + return HSOpts.ModulesIgnoreSearchPaths.contains( + llvm::CachedHashString(E.Path)); + }); + HSOpts.ModulesIgnoreSearchPaths.clear(); // If the original compiler invocation had -fmodule-name, pass it through. Invocation->getLangOpts().ModuleName = diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 9359848d3a29b..2f5e882d59084 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3352,6 +3352,9 @@ static void GenerateHeaderSearchArgs(const HeaderSearchOptions &Opts, for (const auto &Macro : Opts.ModulesIgnoreMacros) GenerateArg(Consumer, OPT_fmodules_ignore_macro, Macro.val()); + for (const auto &Path : Opts.ModulesIgnoreSearchPaths) + GenerateArg(Consumer, OPT_fmodules_ignore_search_path, Path.val()); + auto Matches = [](const HeaderSearchOptions::Entry &Entry, llvm::ArrayRef<frontend::IncludeDirGroup> Groups, std::optional<bool> IsFramework, @@ -3476,6 +3479,9 @@ static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, llvm::CachedHashString(MacroDef.split('=').first)); } + for (const auto *A : Args.filtered(OPT_fmodules_ignore_search_path)) + Opts.ModulesIgnoreSearchPaths.insert(llvm::CachedHashString(A->getValue())); + // Add -I... and -F... options in order. bool IsSysrootSpecified = Args.hasArg(OPT__sysroot_EQ) || Args.hasArg(OPT_isysroot); @@ -5324,7 +5330,20 @@ std::string CompilerInvocation::computeContextHash() const { if (hsOpts.ModulesStrictContextHash) { HBuilder.addRange(hsOpts.SystemHeaderPrefixes); - HBuilder.addRange(hsOpts.UserEntries); + + for (const auto &UserEntry : hsOpts.UserEntries) { + // If we're supposed to ignore this search path for the purposes of + // modules, don't put it into the hash. + if (!hsOpts.ModulesIgnoreSearchPaths.empty()) { + // Check whether we're ignoring this search path. + StringRef Path = UserEntry.Path; + if (hsOpts.ModulesIgnoreSearchPaths.count(llvm::CachedHashString(Path))) + continue; + } + + HBuilder.add(UserEntry); + } + HBuilder.addRange(hsOpts.VFSOverlayFiles); const DiagnosticOptions &diagOpts = getDiagnosticOpts(); diff --git a/clang/test/ClangScanDeps/modules-context-hash-ignore-search-path.c b/clang/test/ClangScanDeps/modules-context-hash-ignore-search-path.c new file mode 100644 index 0000000000000..da5b3e4b027be --- /dev/null +++ b/clang/test/ClangScanDeps/modules-context-hash-ignore-search-path.c @@ -0,0 +1,112 @@ +// Ensure -fmodules-ignore-search-path drops the path from the module build and +// from its context hash, so a TU that passes such a path shares one module with +// a TU that never mentioned it, while the path itself is still available to the +// TU that did. + +// RUN: rm -rf %t +// RUN: split-file %s %t + +// RUN: sed "s|DIR|%/t|g" %t/cdb.json.in > %t/cdb.json + +// RUN: clang-scan-deps -compilation-database %t/cdb.json -j 1 \ +// RUN: -optimize-args=none -format experimental-full -o %t/deps.json + +// RUN: ls %t/cache/*/Common-*.pcm | count 1 + +// RUN: cat %t/deps.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s + +// CHECK: { +// CHECK-NEXT: "modules": [ +// CHECK-NEXT: { +// CHECK-NEXT: "clang-module-deps": [], +// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/common/module.modulemap", +// CHECK-NEXT: "command-line": [ +// CHECK-NOT: "-fmodules-ignore-search-path +// CHECK-NOT: "[[PREFIX]]/extra" +// CHECK: "-I" +// CHECK-NEXT: "[[PREFIX]]/common" +// CHECK-NOT: "-I" +// CHECK: ], +// CHECK-NEXT: "context-hash": "[[HASH:.*]]", +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/common/module.modulemap", +// CHECK-NEXT: "[[PREFIX]]/common/common.h" +// CHECK-NEXT: ], +// CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "name": "Common" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "translation-units": [ +// CHECK-NEXT: { +// CHECK-NEXT: "commands": [ +// CHECK-NEXT: { +// CHECK-NEXT: "clang-context-hash": "{{.*}}", +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH]]", +// CHECK-NEXT: "module-name": "Common" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "command-line": [ +// CHECK: "-I", +// CHECK-NEXT: "[[PREFIX]]/common", +// CHECK: ], +// CHECK-NEXT: "executable": "{{.*}}", +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/tu.c" +// CHECK-NEXT: ], +// CHECK-NEXT: "input-file": "[[PREFIX]]/tu.c" +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "commands": [ +// CHECK-NEXT: { +// CHECK-NEXT: "clang-context-hash": "{{.*}}", +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH]]", +// CHECK-NEXT: "module-name": "Common" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "command-line": [ +// CHECK: "-fmodules-ignore-search-path=[[PREFIX]]/extra", +// CHECK-NEXT: "-I", +// CHECK-NEXT: "[[PREFIX]]/common", +// CHECK-NEXT: "-I", +// CHECK-NEXT: "[[PREFIX]]/extra", +// CHECK: ], +// CHECK-NEXT: "executable": "{{.*}}", +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/tu.c" +// CHECK-NEXT: ], +// CHECK-NEXT: "input-file": "[[PREFIX]]/tu.c" +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } + +//--- cdb.json.in +[ + { + "directory": "DIR", + "command": "clang -c DIR/tu.c -o DIR/tu1.o -fmodules -fimplicit-module-maps -fmodules-cache-path=DIR/cache -I DIR/common", + "file": "DIR/tu.c" + }, + { + "directory": "DIR", + "command": "clang -c DIR/tu.c -o DIR/tu1.o -fmodules -fimplicit-module-maps -fmodules-cache-path=DIR/cache -I DIR/common -I DIR/extra -fmodules-ignore-search-path=DIR/extra", + "file": "DIR/tu.c" + } +] + +//--- common/module.modulemap +module Common { header "common.h" } +//--- common/common.h + +//--- extra/module.modulemap +//--- extra/extra.h + +//--- tu.c +#include "common.h" diff --git a/clang/test/ClangScanDeps/modules-ignore-search-path-optimize-args.c b/clang/test/ClangScanDeps/modules-ignore-search-path-optimize-args.c new file mode 100644 index 0000000000000..586087a391f28 --- /dev/null +++ b/clang/test/ClangScanDeps/modules-ignore-search-path-optimize-args.c @@ -0,0 +1,194 @@ +// Check that -fmodules-ignore-search-path composes with the scanner's own +// usage-based pruning of header search paths (-optimize-args=header-search). + +// RUN: rm -rf %t +// RUN: split-file %s %t + +// RUN: sed "s|DIR|%/t|g" %t/cdb.json.in > %t/cdb.json + +// The ignored path is the *first* -I, so dropping it shifts the index of every +// path the modules do use. +// +// RUN: clang-scan-deps -compilation-database %t/cdb.json -j 1 \ +// RUN: -optimize-args=header-search -format experimental-full -o %t/deps.json + +// RUN: cat %t/deps.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s + +// CHECK: { +// CHECK-NEXT: "modules": [ +// CHECK-NEXT: { +// CHECK-NEXT: "clang-module-deps": [], +// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/leaf/module.modulemap", +// CHECK-NEXT: "command-line": [ +// CHECK-NOT: "-fmodules-ignore-search-path +// CHECK-NOT: "-I" +// CHECK: ], +// CHECK-NEXT: "context-hash": "[[HASH_LEAF:.*]]", +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/leaf/module.modulemap", +// CHECK-NEXT: "[[PREFIX]]/leaf/leaf.h" +// CHECK-NEXT: ], +// CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "name": "Leaf" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH_LEAF]]", +// CHECK-NEXT: "module-name": "Leaf" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/middle/module.modulemap", +// CHECK-NEXT: "command-line": [ +// CHECK-NOT: "-fmodules-ignore-search-path +// CHECK: "-I" +// CHECK-NEXT: "[[PREFIX]]/leaf" +// CHECK-NOT: "-I" +// CHECK: ], +// CHECK-NEXT: "context-hash": "[[HASH_MIDDLE:.*]]", +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/middle/module.modulemap", +// CHECK-NEXT: "[[PREFIX]]/middle/middle.h", +// CHECK-NEXT: "[[PREFIX]]/leaf/module.modulemap" +// CHECK-NEXT: ], +// CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "name": "Middle" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH_MIDDLE]]", +// CHECK-NEXT: "module-name": "Middle" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/top/module.modulemap", +// CHECK-NEXT: "command-line": [ +// CHECK-NOT: "-fmodules-ignore-search-path +// CHECK: "-I" +// CHECK-NEXT: "[[PREFIX]]/middle" +// CHECK-NEXT: "-I" +// CHECK-NEXT: "[[PREFIX]]/leaf" +// CHECK-NOT: "-I" +// CHECK: ], +// CHECK-NEXT: "context-hash": "[[HASH_TOP:.*]]", +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/top/module.modulemap", +// CHECK-NEXT: "[[PREFIX]]/top/top.h", +// CHECK-NEXT: "[[PREFIX]]/middle/module.modulemap" +// CHECK-NEXT: ], +// CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "name": "Top" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "translation-units": [ +// CHECK-NEXT: { +// CHECK-NEXT: "commands": [ +// CHECK-NEXT: { +// CHECK-NEXT: "clang-context-hash": "[[HASH_TU:.*]]", +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH_TOP]]", +// CHECK-NEXT: "module-name": "Top" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "command-line": [ +// CHECK: "-fmodules-ignore-search-path=[[PREFIX]]/ignored1" +// CHECK-NEXT: "-I" +// CHECK-NEXT: "[[PREFIX]]/ignored1" +// CHECK-NEXT: "-I" +// CHECK-NEXT: "[[PREFIX]]/top" +// CHECK-NEXT: "-I" +// CHECK-NEXT: "[[PREFIX]]/middle" +// CHECK-NEXT: "-I" +// CHECK-NEXT: "[[PREFIX]]/leaf" +// CHECK-NEXT: "-I" +// CHECK-NEXT: "[[PREFIX]]/unused" +// CHECK: ], +// CHECK-NEXT: "executable": "{{.*}}", +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/tu.c", +// CHECK-NEXT: "[[PREFIX]]/ignored1/ignored.h" +// CHECK-NEXT: ], +// CHECK-NEXT: "input-file": "[[PREFIX]]/tu.c" +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "commands": [ +// CHECK-NEXT: { +// CHECK-NEXT: "clang-context-hash": "[[HASH_TU]]", +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH_TOP]]", +// CHECK-NEXT: "module-name": "Top" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "command-line": [ +// CHECK: "-fmodules-ignore-search-path=[[PREFIX]]/ignored2" +// CHECK-NEXT: "-I" +// CHECK-NEXT: "[[PREFIX]]/ignored2" +// CHECK-NEXT: "-I" +// CHECK-NEXT: "[[PREFIX]]/top" +// CHECK-NEXT: "-I" +// CHECK-NEXT: "[[PREFIX]]/middle" +// CHECK-NEXT: "-I" +// CHECK-NEXT: "[[PREFIX]]/leaf" +// CHECK-NEXT: "-I" +// CHECK-NEXT: "[[PREFIX]]/unused" +// CHECK: ], +// CHECK-NEXT: "executable": "{{.*}}", +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/tu.c", +// CHECK-NEXT: "[[PREFIX]]/ignored2/ignored.h" +// CHECK-NEXT: ], +// CHECK-NEXT: "input-file": "[[PREFIX]]/tu.c" +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } + +//--- cdb.json.in +[ + { + "directory": "DIR", + "command": "clang -c DIR/tu.c -o DIR/tu1.o -fmodules -fimplicit-module-maps -fmodules-cache-path=DIR/cache -I DIR/ignored1 -I DIR/top -I DIR/middle -I DIR/leaf -I DIR/unused -fmodules-ignore-search-path=DIR/ignored1", + "file": "DIR/tu.c" + }, + { + "directory": "DIR", + "command": "clang -c DIR/tu.c -o DIR/tu2.o -fmodules -fimplicit-module-maps -fmodules-cache-path=DIR/cache -I DIR/ignored2 -I DIR/top -I DIR/middle -I DIR/leaf -I DIR/unused -fmodules-ignore-search-path=DIR/ignored2", + "file": "DIR/tu.c" + } +] + +//--- top/module.modulemap +module Top { header "top.h" } + +//--- top/top.h +#include "middle.h" + +//--- middle/module.modulemap +module Middle { header "middle.h" } + +//--- middle/middle.h +#include "leaf.h" + +//--- leaf/module.modulemap +module Leaf { header "leaf.h" } + +//--- leaf/leaf.h +int leaf(void); + +//--- unused/unused.h +int unused(void); + +//--- ignored1/ignored.h +int ignored(void); + +//--- ignored2/ignored.h +int ignored(void); + +//--- tu.c +#include "top.h" +#include "ignored.h" diff --git a/clang/test/Driver/modules-ignore-search-path.c b/clang/test/Driver/modules-ignore-search-path.c new file mode 100644 index 0000000000000..c032af9ab32cf --- /dev/null +++ b/clang/test/Driver/modules-ignore-search-path.c @@ -0,0 +1,7 @@ +// Check that -fmodules-ignore-search-path reaches cc1 through the driver. + +// RUN: %clang -### -c -fmodules -fmodules-ignore-search-path=/tmp/gen1 \ +// RUN: -fmodules-ignore-search-path=/tmp/gen2 %s 2>&1 | FileCheck %s +// +// CHECK: "-fmodules-ignore-search-path=/tmp/gen1" +// CHECK-SAME: "-fmodules-ignore-search-path=/tmp/gen2" diff --git a/clang/test/Modules/modules-ignore-search-path.c b/clang/test/Modules/modules-ignore-search-path.c new file mode 100644 index 0000000000000..6610c6201db73 --- /dev/null +++ b/clang/test/Modules/modules-ignore-search-path.c @@ -0,0 +1,91 @@ +// Tests -fmodules-ignore-search-path=P for implicitly-built modules: the path is +// dropped from the context hash of every module and physically removed from +// every module build, and kept only for the tran... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/217061 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
