https://github.com/cyndyishida created https://github.com/llvm/llvm-project/pull/147969
Clients of the dependency scanning service may need to add dependencies based on the visibility of top-level modules, for example, when determining whether a Swift overlay dependency should be brought in based on whether there's a corresponding **visible** clang module for it. This patch introduces a new field `VisibleModules` that contains all the visible top-level modules in a given TU. Because visibility is determined by which headers or (sub)modules were imported, and not top-level module dependencies, the scanner now performs a separate DFS starting from what was directly imported for this computation. In my local performance testing, there was no observable performance impact. resolves: rdar://151416358 >From 7688e348f6da6f71f9c929ca9cfb7e68af8a421a Mon Sep 17 00:00:00 2001 From: Cyndy Ishida <cyndy_ish...@apple.com> Date: Wed, 9 Jul 2025 21:50:44 -0700 Subject: [PATCH 1/2] [clang][scan-deps] Report a scanned TU's visible modules --- .../DependencyScanningTool.h | 9 +++ .../DependencyScanningWorker.h | 2 + .../DependencyScanning/ModuleDepCollector.h | 8 +++ .../DependencyScanningTool.cpp | 2 + .../DependencyScanning/ModuleDepCollector.cpp | 31 +++++++- clang/test/ClangScanDeps/visible-modules.c | 72 +++++++++++++++++++ clang/tools/clang-scan-deps/ClangScanDeps.cpp | 14 ++++ 7 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 clang/test/ClangScanDeps/visible-modules.c diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h index ee24e5d1543d3..14de81a5ff2b6 100644 --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h +++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h @@ -57,6 +57,10 @@ struct TranslationUnitDeps { /// determined that the differences are benign for this compilation. std::vector<ModuleID> ClangModuleDeps; + /// A list of module names that are visible to this translation unit. This + /// includes both direct and transitive module dependencies. + std::vector<std::string> VisibleModules; + /// A list of the C++20 named modules this translation unit depends on. std::vector<std::string> NamedModuleDeps; @@ -188,6 +192,10 @@ class FullDependencyConsumer : public DependencyConsumer { DirectModuleDeps.push_back(ID); } + void handleVisibleModule(std::string ModuleName) override { + VisibleModules.push_back(ModuleName); + } + void handleContextHash(std::string Hash) override { ContextHash = std::move(Hash); } @@ -210,6 +218,7 @@ class FullDependencyConsumer : public DependencyConsumer { std::string ModuleName; std::vector<std::string> NamedModuleDeps; std::vector<ModuleID> DirectModuleDeps; + std::vector<std::string> VisibleModules; std::vector<Command> Commands; std::string ContextHash; std::vector<std::string> OutputPaths; diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h index 3e232c79397ce..6060e4b43312e 100644 --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h +++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h @@ -59,6 +59,8 @@ class DependencyConsumer { virtual void handleDirectModuleDependency(ModuleID MD) = 0; + virtual void handleVisibleModule(std::string ModuleName) = 0; + virtual void handleContextHash(std::string Hash) = 0; }; diff --git a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h b/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h index e96c49883d3c6..4136cb73f7043 100644 --- a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h +++ b/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h @@ -323,6 +323,11 @@ class ModuleDepCollector final : public DependencyCollector { llvm::MapVector<const Module *, PrebuiltModuleDep> DirectPrebuiltModularDeps; /// Working set of direct modular dependencies. llvm::SetVector<const Module *> DirectModularDeps; + /// Working set of direct modular dependencies, as they were imported. + llvm::SmallPtrSet<const Module *, 32> DirectImports; + /// All direct and transitive visible modules. + llvm::StringSet<> VisibleModules; + /// Options that control the dependency output generation. std::unique_ptr<DependencyOutputOptions> Opts; /// A Clang invocation that's based on the original TU invocation and that has @@ -337,6 +342,9 @@ class ModuleDepCollector final : public DependencyCollector { /// Checks whether the module is known as being prebuilt. bool isPrebuiltModule(const Module *M); + /// Computes all visible modules resolved from direct imports. + void addVisibleModules(); + /// Adds \p Path to \c FileDeps, making it absolute if necessary. void addFileDep(StringRef Path); /// Adds \p Path to \c MD.FileDeps, making it absolute if necessary. diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp index 515211d47b348..d3d7641b83d48 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp @@ -40,6 +40,7 @@ class MakeDependencyPrinterConsumer : public DependencyConsumer { void handlePrebuiltModuleDependency(PrebuiltModuleDep PMD) override {} void handleModuleDependency(ModuleDeps MD) override {} void handleDirectModuleDependency(ModuleID ID) override {} + void handleVisibleModule(std::string ModuleName) override {} void handleContextHash(std::string Hash) override {} void printDependencies(std::string &S) { @@ -175,6 +176,7 @@ TranslationUnitDeps FullDependencyConsumer::takeTranslationUnitDeps() { TU.NamedModuleDeps = std::move(NamedModuleDeps); TU.FileDeps = std::move(Dependencies); TU.PrebuiltModuleDeps = std::move(PrebuiltModuleDeps); + TU.VisibleModules = std::move(VisibleModules); TU.Commands = std::move(Commands); for (auto &&M : ClangModuleDeps) { diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp index fa86d714ff69a..1a36171b0d483 100644 --- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp @@ -673,8 +673,10 @@ void ModuleDepCollectorPP::handleImport(const Module *Imported) { if (MDC.isPrebuiltModule(TopLevelModule)) MDC.DirectPrebuiltModularDeps.insert( {TopLevelModule, PrebuiltModuleDep{TopLevelModule}}); - else + else { MDC.DirectModularDeps.insert(TopLevelModule); + MDC.DirectImports.insert(Imported); + } } void ModuleDepCollectorPP::EndOfMainFile() { @@ -706,6 +708,8 @@ void ModuleDepCollectorPP::EndOfMainFile() { if (!MDC.isPrebuiltModule(M)) MDC.DirectModularDeps.insert(M); + MDC.addVisibleModules(); + for (const Module *M : MDC.DirectModularDeps) handleTopLevelModule(M); @@ -727,6 +731,9 @@ void ModuleDepCollectorPP::EndOfMainFile() { MDC.Consumer.handleDirectModuleDependency(It->second->ID); } + for (auto &&I : MDC.VisibleModules) + MDC.Consumer.handleVisibleModule(std::string(I.getKey())); + for (auto &&I : MDC.FileDeps) MDC.Consumer.handleFileDependency(I); @@ -993,6 +1000,28 @@ bool ModuleDepCollector::isPrebuiltModule(const Module *M) { return true; } +void ModuleDepCollector::addVisibleModules() { + llvm::DenseSet<Module *> ImportedModules; + auto InsertVisibleModules = [&](const Module *M) { + if (ImportedModules.contains(M)) + return; + + VisibleModules.insert(M->getTopLevelModuleName()); + SmallVector<Module *> Stack(M->Imports.begin(), M->Imports.end()); + while (!Stack.empty()) { + Module *CurrModule = Stack.pop_back_val(); + if (ImportedModules.contains(CurrModule)) + continue; + ImportedModules.insert(CurrModule); + VisibleModules.insert(CurrModule->getTopLevelModuleName()); + CurrModule->getExportedModules(Stack); + } + }; + + for (const Module *Import : DirectImports) + InsertVisibleModules(Import); +} + static StringRef makeAbsoluteAndPreferred(CompilerInstance &CI, StringRef Path, SmallVectorImpl<char> &Storage) { if (llvm::sys::path::is_absolute(Path) && diff --git a/clang/test/ClangScanDeps/visible-modules.c b/clang/test/ClangScanDeps/visible-modules.c new file mode 100644 index 0000000000000..d2545237d48f7 --- /dev/null +++ b/clang/test/ClangScanDeps/visible-modules.c @@ -0,0 +1,72 @@ +// This test verifies that the modules visible to the translation unit are computed in dependency scanning. +// "client" represents the translation unit that imports an explicit submodule, that only exports one other module. +// Thus, the dependencies of the top level module for the submodule differ from what is visible to the TU. + +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: sed -e "s|DIR|%/t|g" %t/compile-commands.json.in > %t/compile-commands.json +// RUN: clang-scan-deps -compilation-database %t/compile-commands.json \ +// RUN: -j 1 -format experimental-full 2>&1 > %t/result.json +// RUN: cat %t/result.json | sed 's:\\\\\?:/:g' | FileCheck %s -DPREFIX=%/t + +// CHECK: "visible-clang-modules": [ +// CHECK-NEXT: "A", +// CHECK-NEXT: "visible" +// CHECK-NEXT: ] + +//--- compile-commands.json.in +[ +{ + "directory": "DIR", + "command": "clang -c DIR/client.c -isysroot DIR/Sysroot -IDIR/Sysroot/usr/include -fmodules -fmodules-cache-path=DIR/module-cache -fimplicit-module-maps", + "file": "DIR/client.c" +} +] + +//--- Sysroot/usr/include/A/module.modulemap +module A { + explicit module visibleToTU { + header "visibleToTU.h" + } + explicit module invisibleToTU { + header "invisibleToTU.h" + } +} +//--- Sysroot/usr/include/A/visibleToTU.h +#include <visible/visible.h> +typedef int A_visibleToTU; + +//--- Sysroot/usr/include/A/invisibleToTU.h +#include <invisible/invisible.h> +typedef int A_invisibleToTU; + +//--- Sysroot/usr/include/invisible/module.modulemap +module invisible { + umbrella "." +} + +//--- Sysroot/usr/include/invisible/invisible.h +typedef int invisible_t; + +//--- Sysroot/usr/include/visible/module.modulemap +module visible { + umbrella "." +} + +//--- Sysroot/usr/include/visible/visible.h +#include <transitive/transitive.h> +typedef int visible_t; + +//--- Sysroot/usr/include/transitive/module.modulemap +module transitive { + umbrella "." +} + +//--- Sysroot/usr/include/transitive/transitive.h +typedef int transitive_t; + +//--- client.c +#include <A/visibleToTU.h> +// Both decls are not visible, thus should fail to actually compile. +transitive_t foo_t(void); +invisible_t foo(void); diff --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp index 8b590bd57e1a3..cdff8400b322b 100644 --- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp +++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp @@ -380,6 +380,14 @@ static auto toJSONSorted(llvm::json::OStream &JOS, }; } +static auto toJSONSorted(llvm::json::OStream &JOS, std::vector<std::string> V) { + llvm::sort(V); + return [&JOS, V = std::move(V)] { + for (const StringRef Entry : V) + JOS.value(Entry); + }; +} + // Thread safe. class FullDeps { public: @@ -396,6 +404,7 @@ class FullDeps { ID.NamedModule = std::move(TUDeps.ID.ModuleName); ID.NamedModuleDeps = std::move(TUDeps.NamedModuleDeps); ID.ClangModuleDeps = std::move(TUDeps.ClangModuleDeps); + ID.VisibleModules = std::move(TUDeps.VisibleModules); ID.DriverCommandLine = std::move(TUDeps.DriverCommandLine); ID.Commands = std::move(TUDeps.Commands); @@ -519,6 +528,8 @@ class FullDeps { }); JOS.attributeArray("clang-module-deps", toJSONSorted(JOS, I.ClangModuleDeps)); + JOS.attributeArray("visible-clang-modules", + toJSONSorted(JOS, I.VisibleModules)); JOS.attributeArray("command-line", toJSONStrings(JOS, Cmd.Arguments)); JOS.attribute("executable", StringRef(Cmd.Executable)); @@ -539,6 +550,8 @@ class FullDeps { }); JOS.attributeArray("clang-module-deps", toJSONSorted(JOS, I.ClangModuleDeps)); + JOS.attributeArray("visible-clang-modules", + toJSONSorted(JOS, I.VisibleModules)); JOS.attributeArray("command-line", toJSONStrings(JOS, I.DriverCommandLine)); JOS.attribute("executable", "clang"); @@ -596,6 +609,7 @@ class FullDeps { std::string NamedModule; std::vector<std::string> NamedModuleDeps; std::vector<ModuleID> ClangModuleDeps; + std::vector<std::string> VisibleModules; std::vector<std::string> DriverCommandLine; std::vector<Command> Commands; }; >From 52a1a716d59a645b50d054c903b53f2fbc1e8bad Mon Sep 17 00:00:00 2001 From: Cyndy Ishida <cyndy_ish...@apple.com> Date: Wed, 9 Jul 2025 22:04:06 -0700 Subject: [PATCH 2/2] Update tests with visible-clang-module section --- clang/test/ClangScanDeps/diagnostics.c | 3 +++ .../header-search-pruning-transitive.c | 8 ++++++++ .../modules-context-hash-ignore-macros.c | 9 +++++++++ .../ClangScanDeps/modules-context-hash-outputs.c | 6 ++++++ .../ClangScanDeps/modules-context-hash-warnings.c | 6 ++++++ clang/test/ClangScanDeps/modules-context-hash.c | 6 ++++++ clang/test/ClangScanDeps/modules-dep-args.c | 4 ++++ .../test/ClangScanDeps/modules-extern-submodule.c | 4 ++++ .../test/ClangScanDeps/modules-extern-unrelated.m | 5 +++++ .../modules-fmodule-name-no-module-built.m | 4 ++++ .../ClangScanDeps/modules-full-output-tu-order.c | 2 ++ clang/test/ClangScanDeps/modules-full.cpp | 13 +++++++++++++ .../modules-has-include-umbrella-header.c | 6 ++++++ .../ClangScanDeps/modules-implementation-private.m | 4 ++++ .../ClangScanDeps/modules-implicit-dot-private.m | 3 +++ .../ClangScanDeps/modules-incomplete-umbrella.c | 8 ++++++++ clang/test/ClangScanDeps/modules-inferred.m | 3 +++ .../ClangScanDeps/modules-no-undeclared-includes.c | 3 +++ .../test/ClangScanDeps/modules-pch-common-stale.c | 9 +++++++++ .../ClangScanDeps/modules-pch-common-submodule.c | 7 +++++++ .../modules-pch-common-via-submodule.c | 6 ++++++ clang/test/ClangScanDeps/modules-pch.c | 12 ++++++++++++ .../test/ClangScanDeps/modules-priv-fw-from-pub.m | 4 ++++ clang/test/ClangScanDeps/multiple-commands.c | 14 ++++++++++++++ clang/test/ClangScanDeps/removed-args.c | 4 ++++ clang/test/ClangScanDeps/tu-buffer.c | 4 ++++ 26 files changed, 157 insertions(+) diff --git a/clang/test/ClangScanDeps/diagnostics.c b/clang/test/ClangScanDeps/diagnostics.c index 8e3cf4c9f9fa6..4d09740d7b5ae 100644 --- a/clang/test/ClangScanDeps/diagnostics.c +++ b/clang/test/ClangScanDeps/diagnostics.c @@ -50,6 +50,9 @@ module mod { header "mod.h" } // CHECK-NEXT: "module-name": "mod" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "mod" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK-NOT: "-fimplicit-modules" // CHECK-NOT: "-fimplicit-module-maps" diff --git a/clang/test/ClangScanDeps/header-search-pruning-transitive.c b/clang/test/ClangScanDeps/header-search-pruning-transitive.c index 1e829bb02ddc4..680228d51a181 100644 --- a/clang/test/ClangScanDeps/header-search-pruning-transitive.c +++ b/clang/test/ClangScanDeps/header-search-pruning-transitive.c @@ -104,6 +104,10 @@ module X { header "X.h" } // CHECK-NEXT: "module-name": "X" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "X", +// CHECK-NEXT: "Y" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: ], // CHECK: "file-deps": [ @@ -159,6 +163,10 @@ module X { header "X.h" } // CHECK-NEXT: "module-name": "X" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "X", +// CHECK-NEXT: "Y" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: ], // CHECK: "file-deps": [ diff --git a/clang/test/ClangScanDeps/modules-context-hash-ignore-macros.c b/clang/test/ClangScanDeps/modules-context-hash-ignore-macros.c index 9f7a62fb9eb74..065a10dfb4841 100644 --- a/clang/test/ClangScanDeps/modules-context-hash-ignore-macros.c +++ b/clang/test/ClangScanDeps/modules-context-hash-ignore-macros.c @@ -36,6 +36,9 @@ // CHECK-NEXT: "module-name": "Mod" // CHECK-NEXT: } // CHECK-NEXT: ] +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "Mod" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK-NOT: "-DFOO" // CHECK-NOT: "FOO" @@ -49,6 +52,9 @@ // CHECK-NEXT: "module-name": "Mod" // CHECK-NEXT: } // CHECK-NEXT: ] +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "Mod" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: "-D" // CHECK-NEXT: "FOO" @@ -62,6 +68,9 @@ // CHECK-NEXT: "module-name": "Mod" // CHECK-NEXT: } // CHECK-NEXT: ] +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "Mod" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: "-fmodules-ignore-macro=FOO" // CHECK: "-D" diff --git a/clang/test/ClangScanDeps/modules-context-hash-outputs.c b/clang/test/ClangScanDeps/modules-context-hash-outputs.c index 5e63e60a70370..75f8f1c583d92 100644 --- a/clang/test/ClangScanDeps/modules-context-hash-outputs.c +++ b/clang/test/ClangScanDeps/modules-context-hash-outputs.c @@ -34,6 +34,9 @@ // CHECK-NEXT: "module-name": "Mod" // CHECK-NEXT: } // CHECK-NEXT: ] +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "Mod" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: "-dependency-file" // CHECK: ] @@ -46,6 +49,9 @@ // CHECK-NEXT: "module-name": "Mod" // CHECK-NEXT: } // CHECK-NEXT: ] +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "Mod" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK-NOT: "-MF" // CHECK-NOT: "-dependency-file" diff --git a/clang/test/ClangScanDeps/modules-context-hash-warnings.c b/clang/test/ClangScanDeps/modules-context-hash-warnings.c index 09d2f20b329e3..5a3d76e158c98 100644 --- a/clang/test/ClangScanDeps/modules-context-hash-warnings.c +++ b/clang/test/ClangScanDeps/modules-context-hash-warnings.c @@ -34,6 +34,9 @@ // CHECK-NEXT: "module-name": "Mod" // CHECK-NEXT: } // CHECK-NEXT: ] +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "Mod" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: "-Wall" // CHECK: ] @@ -46,6 +49,9 @@ // CHECK-NEXT: "module-name": "Mod" // CHECK-NEXT: } // CHECK-NEXT: ] +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "Mod" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK-NOT: "-Wall" // CHECK: ] diff --git a/clang/test/ClangScanDeps/modules-context-hash.c b/clang/test/ClangScanDeps/modules-context-hash.c index 9489563576d3b..6ea831f7aed08 100644 --- a/clang/test/ClangScanDeps/modules-context-hash.c +++ b/clang/test/ClangScanDeps/modules-context-hash.c @@ -51,6 +51,9 @@ // CHECK-NEXT: "module-name": "mod" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "mod" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: ], // CHECK: "file-deps": [ @@ -89,6 +92,9 @@ // CHECK: "module-name": "mod" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "mod" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: ], // CHECK: "file-deps": [ diff --git a/clang/test/ClangScanDeps/modules-dep-args.c b/clang/test/ClangScanDeps/modules-dep-args.c index 19f915923b84c..310a33e9533cf 100644 --- a/clang/test/ClangScanDeps/modules-dep-args.c +++ b/clang/test/ClangScanDeps/modules-dep-args.c @@ -87,6 +87,10 @@ module Direct { header "direct.h" } // CHECK-NEXT: "module-name": "Direct" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "Direct", +// CHECK-NEXT: "Transitive" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK_CACHE: "-fmodule-file={{.*}}/cache/{{.*}}/Direct-{{.*}}.pcm" // CHECK_BUILD: "-fmodule-file={{.*}}/build/{{.*}}/Direct-{{.*}}.pcm" diff --git a/clang/test/ClangScanDeps/modules-extern-submodule.c b/clang/test/ClangScanDeps/modules-extern-submodule.c index 01d3d6ba5e0d3..7a2b49879b97b 100644 --- a/clang/test/ClangScanDeps/modules-extern-submodule.c +++ b/clang/test/ClangScanDeps/modules-extern-submodule.c @@ -107,6 +107,10 @@ module third {} // CHECK-NEXT: "module-name": "first" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "first", +// CHECK-NEXT: "second" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK-NEXT: "-cc1", // CHECK: "-fmodule-map-file=[[PREFIX]]/first/first/module.modulemap", diff --git a/clang/test/ClangScanDeps/modules-extern-unrelated.m b/clang/test/ClangScanDeps/modules-extern-unrelated.m index c003f0d9a2ee8..50ee7464419f7 100644 --- a/clang/test/ClangScanDeps/modules-extern-unrelated.m +++ b/clang/test/ClangScanDeps/modules-extern-unrelated.m @@ -113,6 +113,11 @@ // CHECK-NEXT: "module-name": "zeroth" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "first", +// CHECK-NEXT: "second", +// CHECK-NEXT: "zeroth" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: ], // CHECK-NEXT: "executable": "{{.*}}", diff --git a/clang/test/ClangScanDeps/modules-fmodule-name-no-module-built.m b/clang/test/ClangScanDeps/modules-fmodule-name-no-module-built.m index cfe29c2bf7cdb..0d91808e2bc04 100644 --- a/clang/test/ClangScanDeps/modules-fmodule-name-no-module-built.m +++ b/clang/test/ClangScanDeps/modules-fmodule-name-no-module-built.m @@ -41,6 +41,10 @@ // CHECK-NEXT: "module-name": "header2" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "header2", +// CHECK-NEXT: "header3" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: ], // CHECK: "file-deps": [ diff --git a/clang/test/ClangScanDeps/modules-full-output-tu-order.c b/clang/test/ClangScanDeps/modules-full-output-tu-order.c index 065b8ac8ae07f..79e2947c5f039 100644 --- a/clang/test/ClangScanDeps/modules-full-output-tu-order.c +++ b/clang/test/ClangScanDeps/modules-full-output-tu-order.c @@ -31,6 +31,7 @@ // CHECK-NEXT: { // CHECK-NEXT: "clang-context-hash": "{{.*}}", // CHECK-NEXT: "clang-module-deps": [], +// CHECK-NEXT: "visible-clang-modules": [], // CHECK-NEXT: "command-line": [ // CHECK: "-D" // CHECK-NEXT: "ONE" @@ -47,6 +48,7 @@ // CHECK-NEXT: { // CHECK-NEXT: "clang-context-hash": "{{.*}}", // CHECK-NEXT: "clang-module-deps": [], +// CHECK-NEXT: "visible-clang-modules": [], // CHECK-NEXT: "command-line": [ // CHECK: "-D" // CHECK-NEXT: "TWO" diff --git a/clang/test/ClangScanDeps/modules-full.cpp b/clang/test/ClangScanDeps/modules-full.cpp index 38db3af4403bb..67da82eb35960 100644 --- a/clang/test/ClangScanDeps/modules-full.cpp +++ b/clang/test/ClangScanDeps/modules-full.cpp @@ -97,6 +97,10 @@ // CHECK-NEXT: "module-name": "header1" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "header1", +// CHECK-NEXT: "header2" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK-NOT: "-fimplicit-modules" // CHECK-NOT: "-fimplicit-module-maps" @@ -120,6 +124,9 @@ // CHECK-NEXT: "module-name": "header1" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "header1" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK-NOT: "-fimplicit-modules" // CHECK-NOT: "-fimplicit-module-maps" @@ -143,6 +150,9 @@ // CHECK-NEXT: "module-name": "header1" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "header1" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK-NOT: "-fimplicit-modules" // CHECK-NOT: "-fimplicit-module-maps" @@ -166,6 +176,9 @@ // CHECK-NEXT: "module-name": "header1" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "header1" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK-NOT: "-fimplicit-modules" // CHECK-NOT: "-fimplicit-module-maps" diff --git a/clang/test/ClangScanDeps/modules-has-include-umbrella-header.c b/clang/test/ClangScanDeps/modules-has-include-umbrella-header.c index 022c59ca65db2..f27ea8e1ed2eb 100644 --- a/clang/test/ClangScanDeps/modules-has-include-umbrella-header.c +++ b/clang/test/ClangScanDeps/modules-has-include-umbrella-header.c @@ -62,6 +62,12 @@ module Dependency { header "dependency.h" } // CHECK-NEXT: "module-name": "FW_Private" // CHECK-NEXT: } // CHECK: ], +// CHECK: "visible-clang-modules": [ +// CHECK-NEXT: "Dependency", +// CHECK-NEXT: "FW_Private", +// CHECK-NEXT: "Import", +// CHECK-NEXT: "Poison" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: ], // CHECK: "file-deps": [ diff --git a/clang/test/ClangScanDeps/modules-implementation-private.m b/clang/test/ClangScanDeps/modules-implementation-private.m index b376073f4b9ee..59e77b85b7967 100644 --- a/clang/test/ClangScanDeps/modules-implementation-private.m +++ b/clang/test/ClangScanDeps/modules-implementation-private.m @@ -60,6 +60,10 @@ // CHECK-NEXT: "module-name": "FW_Private" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "FW", +// CHECK-NEXT: "FW_Private" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: ], // CHECK: "file-deps": [ diff --git a/clang/test/ClangScanDeps/modules-implicit-dot-private.m b/clang/test/ClangScanDeps/modules-implicit-dot-private.m index aa8caf3451dc4..5dfac2b09b316 100644 --- a/clang/test/ClangScanDeps/modules-implicit-dot-private.m +++ b/clang/test/ClangScanDeps/modules-implicit-dot-private.m @@ -75,6 +75,9 @@ // CHECK-NEXT: "module-name": "FW_Private" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "FW_Private" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: "-fmodule-file={{.*}}/FW-{{.*}}.pcm" // CHECK: "-fmodule-file={{.*}}/FW_Private-{{.*}}.pcm" diff --git a/clang/test/ClangScanDeps/modules-incomplete-umbrella.c b/clang/test/ClangScanDeps/modules-incomplete-umbrella.c index 696e621960b6f..bb5ccb31cfd30 100644 --- a/clang/test/ClangScanDeps/modules-incomplete-umbrella.c +++ b/clang/test/ClangScanDeps/modules-incomplete-umbrella.c @@ -88,6 +88,10 @@ framework module FW_Private { // CHECK_TU-NEXT: "module-name": "FW_Private" // CHECK_TU-NEXT: } // CHECK_TU-NEXT: ], +// CHECK_TU-NEXT: "visible-clang-modules": [ +// CHECK_TU-NEXT: "FW", +// CHECK_TU-NEXT: "FW_Private" +// CHECK_TU-NEXT: ], // CHECK_TU-NEXT: "command-line": [ // CHECK_TU: "-fmodule-file={{.*}}/FW-{{.*}}.pcm" // CHECK_TU: "-fmodule-file={{.*}}/FW_Private-{{.*}}.pcm" @@ -201,6 +205,10 @@ module Mod { header "Mod.h" } // CHECK_MODULE-NEXT: "module-name": "Mod" // CHECK_MODULE-NEXT: } // CHECK_MODULE-NEXT: ], +// CHECK_MODULE-NEXT: "visible-clang-modules": [ +// CHECK_MODULE-NEXT: "FW", +// CHECK_MODULE-NEXT: "Mod" +// CHECK_MODULE-NEXT: ], // CHECK_MODULE-NEXT: "command-line": [ // CHECK_MODULE: ], // CHECK_MODULE: "file-deps": [ diff --git a/clang/test/ClangScanDeps/modules-inferred.m b/clang/test/ClangScanDeps/modules-inferred.m index 4c7a4095c9bef..83c523b1de219 100644 --- a/clang/test/ClangScanDeps/modules-inferred.m +++ b/clang/test/ClangScanDeps/modules-inferred.m @@ -61,6 +61,9 @@ // CHECK-NEXT: "module-name": "Inferred" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "Inferred" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: ], // CHECK: "file-deps": [ diff --git a/clang/test/ClangScanDeps/modules-no-undeclared-includes.c b/clang/test/ClangScanDeps/modules-no-undeclared-includes.c index 6110c419949f9..683d96988825f 100644 --- a/clang/test/ClangScanDeps/modules-no-undeclared-includes.c +++ b/clang/test/ClangScanDeps/modules-no-undeclared-includes.c @@ -60,6 +60,9 @@ module User [no_undeclared_includes] { header "user.h" } // CHECK-NEXT: "module-name": "User" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "User" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: ], // CHECK: "file-deps": [ diff --git a/clang/test/ClangScanDeps/modules-pch-common-stale.c b/clang/test/ClangScanDeps/modules-pch-common-stale.c index 72a4dc949b0f5..b3ffd188e66f7 100644 --- a/clang/test/ClangScanDeps/modules-pch-common-stale.c +++ b/clang/test/ClangScanDeps/modules-pch-common-stale.c @@ -68,6 +68,10 @@ module mod_tu_extra { header "mod_tu_extra.h" } // CHECK-TU-CLEAN-NEXT: "module-name": "mod_tu" // CHECK-TU-CLEAN-NEXT: } // CHECK-TU-CLEAN-NEXT: ], +// CHECK-TU-CLEAN-NEXT: "visible-clang-modules": [ +// CHECK-TU-CLEAN-NEXT: "mod_common", +// CHECK-TU-CLEAN-NEXT: "mod_tu" +// CHECK-TU-CLEAN-NEXT: ], // CHECK-TU-CLEAN-NEXT: "command-line": [ // CHECK-TU-CLEAN: ], // CHECK-TU-CLEAN-NEXT: "executable": "{{.*}}", @@ -155,6 +159,11 @@ module mod_tu_extra { header "mod_tu_extra.h" } // CHECK-TU-INCREMENTAL-NEXT: "module-name": "mod_tu" // CHECK-TU-INCREMENTAL-NEXT: } // CHECK-TU-INCREMENTAL-NEXT: ], +// CHECK-TU-INCREMENTAL-NEXT: "visible-clang-modules": [ +// CHECK-TU-INCREMENTAL-NEXT: "mod_common", +// CHECK-TU-INCREMENTAL-NEXT: "mod_tu", +// CHECK-TU-INCREMENTAL-NEXT: "mod_tu_extra" +// CHECK-TU-INCREMENTAL-NEXT: ], // CHECK-TU-INCREMENTAL-NEXT: "command-line": [ // CHECK-TU-INCREMENTAL: ], // CHECK-TU-INCREMENTAL-NEXT: "executable": "{{.*}}", diff --git a/clang/test/ClangScanDeps/modules-pch-common-submodule.c b/clang/test/ClangScanDeps/modules-pch-common-submodule.c index 59dd3f172d8ee..2c8da8b4f4ef8 100644 --- a/clang/test/ClangScanDeps/modules-pch-common-submodule.c +++ b/clang/test/ClangScanDeps/modules-pch-common-submodule.c @@ -44,6 +44,9 @@ // CHECK-PCH-NEXT: "module-name": "ModCommon" // CHECK-PCH-NEXT: } // CHECK-PCH-NEXT: ], +// CHECK-PCH-NEXT: "visible-clang-modules": [ +// CHECK-PCH-NEXT: "ModCommon" +// CHECK-PCH-NEXT: ], // CHECK-PCH-NEXT: "command-line": [ // CHECK-PCH: ], // CHECK-PCH: "file-deps": [ @@ -92,6 +95,10 @@ // CHECK-TU-NEXT: "module-name": "ModTU" // CHECK-TU-NEXT: } // CHECK-TU-NEXT: ], +// CHECK-TU-NEXT: "visible-clang-modules": [ +// CHECK-TU-NEXT: "ModCommon", +// CHECK-TU-NEXT: "ModTU" +// CHECK-TU-NEXT: ], // CHECK-TU-NEXT: "command-line": [ // CHECK-TU: ], // CHECK-TU: "file-deps": [ diff --git a/clang/test/ClangScanDeps/modules-pch-common-via-submodule.c b/clang/test/ClangScanDeps/modules-pch-common-via-submodule.c index a12492c0bec70..9d53b988c0d4a 100644 --- a/clang/test/ClangScanDeps/modules-pch-common-via-submodule.c +++ b/clang/test/ClangScanDeps/modules-pch-common-via-submodule.c @@ -40,6 +40,9 @@ // CHECK-PCH-NEXT: "module-name": "ModCommon" // CHECK-PCH-NEXT: } // CHECK-PCH-NEXT: ], +// CHECK-PCH-NEXT: "visible-clang-modules": [ +// CHECK-PCH-NEXT: "ModCommon" +// CHECK-PCH-NEXT: ], // CHECK-PCH-NEXT: "command-line": [ // CHECK-PCH: ], // CHECK-PCH: "file-deps": [ @@ -89,6 +92,9 @@ // CHECK-TU-NEXT: "module-name": "ModTU" // CHECK-TU-NEXT: } // CHECK-TU-NEXT: ], +// CHECK-TU-NEXT: "visible-clang-modules": [ +// CHECK-TU-NEXT: "ModTU" +// CHECK-TU-NEXT: ], // CHECK-TU-NEXT: "command-line": [ // CHECK-TU: ], // CHECK-TU: "file-deps": [ diff --git a/clang/test/ClangScanDeps/modules-pch.c b/clang/test/ClangScanDeps/modules-pch.c index 92b7f41ac4b9f..7101b8ade1117 100644 --- a/clang/test/ClangScanDeps/modules-pch.c +++ b/clang/test/ClangScanDeps/modules-pch.c @@ -76,6 +76,11 @@ // CHECK-PCH-NEXT: "module-name": "ModPCH" // CHECK-PCH-NEXT: } // CHECK-PCH-NEXT: ], +// CHECK-PCH-NEXT: "visible-clang-modules": [ +// CHECK-PCH-NEXT: "ModCommon1", +// CHECK-PCH-NEXT: "ModCommon2", +// CHECK-PCH-NEXT: "ModPCH" +// CHECK-PCH-NEXT: ], // CHECK-PCH-NEXT: "command-line": [ // CHECK-PCH: ], // CHECK-PCH: "file-deps": [ @@ -129,6 +134,9 @@ // CHECK-TU-NEXT: "module-name": "ModTU" // CHECK-TU-NEXT: } // CHECK-TU-NEXT: ], +// CHECK-TU-NEXT: "visible-clang-modules": [ +// CHECK-TU-NEXT: "ModTU" +// CHECK-TU-NEXT: ], // CHECK-TU-NEXT: "command-line": [ // CHECK-TU: ], // CHECK-TU: "file-deps": [ @@ -179,6 +187,10 @@ // CHECK-TU-WITH-COMMON-NEXT: "module-name": "ModTUWithCommon" // CHECK-TU-WITH-COMMON-NEXT: } // CHECK-TU-WITH-COMMON-NEXT: ], +// CHECK-TU-WITH-COMMON-NEXT: "visible-clang-modules": [ +// CHECK-TU-WITH-COMMON-NEXT: "ModCommon1", +// CHECK-TU-WITH-COMMON-NEXT: "ModTUWithCommon" +// CHECK-TU-WITH-COMMON-NEXT: ], // CHECK-TU-WITH-COMMON-NEXT: "command-line": [ // CHECK-TU-WITH-COMMON: "-fmodule-file=[[PREFIX]]/build/{{.*}}/ModCommon2-{{.*}}.pcm" // CHECK-TU-WITH-COMMON: ], diff --git a/clang/test/ClangScanDeps/modules-priv-fw-from-pub.m b/clang/test/ClangScanDeps/modules-priv-fw-from-pub.m index dd314e1a3006a..efbf423e76f15 100644 --- a/clang/test/ClangScanDeps/modules-priv-fw-from-pub.m +++ b/clang/test/ClangScanDeps/modules-priv-fw-from-pub.m @@ -108,6 +108,10 @@ // CHECK-NEXT: "module-name": "FW" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "FW", +// CHECK-NEXT: "FW_Private" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: ], // CHECK: "file-deps": [ diff --git a/clang/test/ClangScanDeps/multiple-commands.c b/clang/test/ClangScanDeps/multiple-commands.c index bb169ea10995a..810f7d0648b06 100644 --- a/clang/test/ClangScanDeps/multiple-commands.c +++ b/clang/test/ClangScanDeps/multiple-commands.c @@ -45,6 +45,7 @@ // CHECK-NEXT: { // CHECK-NEXT: "clang-context-hash": // CHECK-NEXT: "clang-module-deps": [] +// CHECK-NEXT: "visible-clang-modules": [] // CHECK-NEXT: "command-line": [ // CHECK-NEXT: "-cc1" // CHECK: "-o" @@ -57,6 +58,7 @@ // CHECK-NEXT: { // CHECK-NEXT: "clang-context-hash": // CHECK-NEXT: "clang-module-deps": [] +// CHECK-NEXT: "visible-clang-modules": [] // CHECK-NEXT: "command-line": [ // CHECK-NEXT: "-cc1" // CHECK: "-o" @@ -77,6 +79,9 @@ // CHECK: "module-name": "Mod" // CHECK-NEXT: } // CHECK-NEXT: ] +// CHECK: "visible-clang-modules": [ +// CHECK-NEXT: "Mod" +// CHECK-NEXT: ] // CHECK-NEXT: "command-line": [ // CHECK-NEXT: "-cc1" // CHECK: "-o" @@ -94,6 +99,9 @@ // CHECK: "module-name": "Mod" // CHECK-NEXT: } // CHECK-NEXT: ] +// CHECK: "visible-clang-modules": [ +// CHECK-NEXT: "Mod" +// CHECK-NEXT: ] // CHECK-NEXT: "command-line": [ // CHECK-NEXT: "-cc1" // CHECK: "-o" @@ -111,6 +119,9 @@ // CHECK: "module-name": "Mod" // CHECK-NEXT: } // CHECK-NEXT: ] +// CHECK: "visible-clang-modules": [ +// CHECK-NEXT: "Mod" +// CHECK-NEXT: ] // CHECK-NEXT: "command-line": [ // CHECK-NEXT: "-cc1" // CHECK: "-o" @@ -127,6 +138,9 @@ // CHECK: "module-name": "Mod" // CHECK-NEXT: } // CHECK-NEXT: ] +// CHECK: "visible-clang-modules": [ +// CHECK-NEXT: "Mod" +// CHECK-NEXT: ] // CHECK-NEXT: "command-line": [ // CHECK-NEXT: "-cc1as" // CHECK: "-o" diff --git a/clang/test/ClangScanDeps/removed-args.c b/clang/test/ClangScanDeps/removed-args.c index 16f053f71e6ba..e09db0aefa95d 100644 --- a/clang/test/ClangScanDeps/removed-args.c +++ b/clang/test/ClangScanDeps/removed-args.c @@ -86,6 +86,10 @@ // CHECK-NEXT: "module-name": "ModTU" // CHECK-NEXT: } // CHECK-NEXT: ] +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "ModHeader", +// CHECK-NEXT: "ModTU" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK-NEXT: "-cc1", // CHECK-NOT: "-fmodules-cache-path= diff --git a/clang/test/ClangScanDeps/tu-buffer.c b/clang/test/ClangScanDeps/tu-buffer.c index b450b13ff434b..c0994a50390d2 100644 --- a/clang/test/ClangScanDeps/tu-buffer.c +++ b/clang/test/ClangScanDeps/tu-buffer.c @@ -98,6 +98,10 @@ module addition { header "addition.h" } // CHECK-NEXT: "module-name": "root" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "visible-clang-modules": [ +// CHECK-NEXT: "direct", +// CHECK-NEXT: "root" +// CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: ], // CHECK: "file-deps": [ _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits