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=&lt;macro&gt;`. The named header search `&lt;path&gt;` 
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

Reply via email to