https://github.com/qiongsiwu created https://github.com/llvm/llvm-project/pull/137421
We would like to report, for a module, what modules it exports during dependency scanning. This PR implements this reporting by augmenting `ModuleDep`'s `ClangModuleDeps` variable. `ClangModuleDeps` now contains instances of `ExtendedModuleID`, which is made of a `ModuleID` and a `bool`, indicating if a particular dependence is exported. >From 0093c2f13aad26b49ff6584ac56184549dcaca84 Mon Sep 17 00:00:00 2001 From: Qiongsi Wu <qiongsi...@apple.com> Date: Fri, 25 Apr 2025 15:51:07 -0700 Subject: [PATCH 1/2] Adding an API to report exported modules and update existing tests. --- .../DependencyScanning/ModuleDepCollector.h | 22 +++++-- .../DependencyScanning/ModuleDepCollector.cpp | 63 +++++++++++-------- clang/test/ClangScanDeps/diagnostics.c | 1 + .../header-search-pruning-transitive.c | 4 ++ .../ClangScanDeps/header-search-pruning.cpp | 3 + clang/test/ClangScanDeps/link-libraries.c | 4 ++ .../modules-canononical-module-map-case.c | 1 + .../test/ClangScanDeps/modules-context-hash.c | 2 + clang/test/ClangScanDeps/modules-dep-args.c | 2 + .../ClangScanDeps/modules-excluded-header.m | 1 + .../ClangScanDeps/modules-extern-submodule.c | 3 + .../ClangScanDeps/modules-extern-unrelated.m | 4 ++ .../modules-file-path-isolation.c | 1 + .../modules-fmodule-name-no-module-built.m | 1 + .../ClangScanDeps/modules-full-by-mod-name.c | 3 + clang/test/ClangScanDeps/modules-full.cpp | 3 + .../modules-implementation-private.m | 1 + .../modules-implicit-dot-private.m | 2 + .../modules-incomplete-umbrella.c | 5 ++ clang/test/ClangScanDeps/modules-inferred.m | 1 + .../modules-no-undeclared-includes.c | 1 + .../modules-pch-common-submodule.c | 2 + .../modules-pch-common-via-submodule.c | 2 + clang/test/ClangScanDeps/modules-pch.c | 5 ++ .../ClangScanDeps/modules-priv-fw-from-pub.m | 3 + .../test/ClangScanDeps/modules-redefinition.m | 1 + .../ClangScanDeps/modules-symlink-dir-vfs.c | 1 + clang/test/ClangScanDeps/modules-transitive.c | 1 + .../optimize-canonicalize-macros.m | 2 + .../test/ClangScanDeps/optimize-fmodulemap.m | 2 + .../ClangScanDeps/optimize-system-warnings.m | 3 + clang/test/ClangScanDeps/optimize-vfs-leak.m | 3 + clang/test/ClangScanDeps/optimize-vfs.m | 3 + clang/test/ClangScanDeps/removed-args.c | 2 + clang/test/ClangScanDeps/working-dir.m | 4 ++ clang/tools/clang-scan-deps/ClangScanDeps.cpp | 37 ++++++++--- 36 files changed, 159 insertions(+), 40 deletions(-) diff --git a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h b/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h index d2d0d56e5212c..24de3d843fc20 100644 --- a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h +++ b/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h @@ -115,6 +115,15 @@ struct ModuleID { } }; +struct ExtendedModuleID { + ModuleID ID; + bool Exported; + + bool operator<(const ExtendedModuleID &Other) const { + return std::tie(ID, Exported) < std::tie(Other.ID, Other.Exported); + } +}; + /// P1689ModuleInfo - Represents the needed information of standard C++20 /// modules for P1689 format. struct P1689ModuleInfo { @@ -183,7 +192,7 @@ struct ModuleDeps { /// /// This may include modules with a different context hash when it can be /// determined that the differences are benign for this compilation. - std::vector<ModuleID> ClangModuleDeps; + std::vector<ExtendedModuleID> ClangModuleDeps; /// The set of libraries or frameworks to link against when /// an entity from this module is used. @@ -270,7 +279,8 @@ class ModuleDepCollectorPP final : public PPCallbacks { llvm::DenseSet<const Module *> &AddedModules); /// Add discovered module dependency for the given module. - void addOneModuleDep(const Module *M, const ModuleID ID, ModuleDeps &MD); + void addOneModuleDep(const Module *M, bool Exported, const ModuleID ID, + ModuleDeps &MD); }; /// Collects modular and non-modular dependencies of the main file by attaching @@ -352,16 +362,16 @@ class ModuleDepCollector final : public DependencyCollector { /// Collect module map files for given modules. llvm::DenseSet<const FileEntry *> - collectModuleMapFiles(ArrayRef<ModuleID> ClangModuleDeps) const; + collectModuleMapFiles(ArrayRef<ExtendedModuleID> ClangModuleDeps) const; /// Add module map files to the invocation, if needed. void addModuleMapFiles(CompilerInvocation &CI, - ArrayRef<ModuleID> ClangModuleDeps) const; + ArrayRef<ExtendedModuleID> ClangModuleDeps) const; /// Add module files (pcm) to the invocation, if needed. void addModuleFiles(CompilerInvocation &CI, - ArrayRef<ModuleID> ClangModuleDeps) const; + ArrayRef<ExtendedModuleID> ClangModuleDeps) const; void addModuleFiles(CowCompilerInvocation &CI, - ArrayRef<ModuleID> ClangModuleDeps) const; + ArrayRef<ExtendedModuleID> ClangModuleDeps) const; /// Add paths that require looking up outputs to the given dependencies. void addOutputPaths(CowCompilerInvocation &CI, ModuleDeps &Deps); diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp index 07856dbdba4b4..721fed038a83e 100644 --- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp @@ -389,10 +389,10 @@ ModuleDepCollector::getInvocationAdjustedForModuleBuildWithoutOutputs( } llvm::DenseSet<const FileEntry *> ModuleDepCollector::collectModuleMapFiles( - ArrayRef<ModuleID> ClangModuleDeps) const { + ArrayRef<ExtendedModuleID> ClangModuleDeps) const { llvm::DenseSet<const FileEntry *> ModuleMapFiles; - for (const ModuleID &MID : ClangModuleDeps) { - ModuleDeps *MD = ModuleDepsByID.lookup(MID); + for (const auto &MID : ClangModuleDeps) { + ModuleDeps *MD = ModuleDepsByID.lookup(MID.ID); assert(MD && "Inconsistent dependency info"); // TODO: Track ClangModuleMapFile as `FileEntryRef`. auto FE = ScanInstance.getFileManager().getOptionalFileRef( @@ -404,21 +404,21 @@ llvm::DenseSet<const FileEntry *> ModuleDepCollector::collectModuleMapFiles( } void ModuleDepCollector::addModuleMapFiles( - CompilerInvocation &CI, ArrayRef<ModuleID> ClangModuleDeps) const { + CompilerInvocation &CI, ArrayRef<ExtendedModuleID> ClangModuleDeps) const { if (Service.shouldEagerLoadModules()) return; // Only pcm is needed for eager load. - for (const ModuleID &MID : ClangModuleDeps) { - ModuleDeps *MD = ModuleDepsByID.lookup(MID); + for (const auto &MID : ClangModuleDeps) { + ModuleDeps *MD = ModuleDepsByID.lookup(MID.ID); assert(MD && "Inconsistent dependency info"); CI.getFrontendOpts().ModuleMapFiles.push_back(MD->ClangModuleMapFile); } } void ModuleDepCollector::addModuleFiles( - CompilerInvocation &CI, ArrayRef<ModuleID> ClangModuleDeps) const { - for (const ModuleID &MID : ClangModuleDeps) { - ModuleDeps *MD = ModuleDepsByID.lookup(MID); + CompilerInvocation &CI, ArrayRef<ExtendedModuleID> ClangModuleDeps) const { + for (const auto &MID : ClangModuleDeps) { + ModuleDeps *MD = ModuleDepsByID.lookup(MID.ID); std::string PCMPath = Controller.lookupModuleOutput(*MD, ModuleOutputKind::ModuleFile); @@ -426,14 +426,15 @@ void ModuleDepCollector::addModuleFiles( CI.getFrontendOpts().ModuleFiles.push_back(std::move(PCMPath)); else CI.getHeaderSearchOpts().PrebuiltModuleFiles.insert( - {MID.ModuleName, std::move(PCMPath)}); + {MID.ID.ModuleName, std::move(PCMPath)}); } } void ModuleDepCollector::addModuleFiles( - CowCompilerInvocation &CI, ArrayRef<ModuleID> ClangModuleDeps) const { - for (const ModuleID &MID : ClangModuleDeps) { - ModuleDeps *MD = ModuleDepsByID.lookup(MID); + CowCompilerInvocation &CI, + ArrayRef<ExtendedModuleID> ClangModuleDeps) const { + for (const auto &MID : ClangModuleDeps) { + ModuleDeps *MD = ModuleDepsByID.lookup(MID.ID); std::string PCMPath = Controller.lookupModuleOutput(*MD, ModuleOutputKind::ModuleFile); @@ -441,7 +442,7 @@ void ModuleDepCollector::addModuleFiles( CI.getMutFrontendOpts().ModuleFiles.push_back(std::move(PCMPath)); else CI.getMutHeaderSearchOpts().PrebuiltModuleFiles.insert( - {MID.ModuleName, std::move(PCMPath)}); + {MID.ID.ModuleName, std::move(PCMPath)}); } } @@ -471,10 +472,10 @@ void ModuleDepCollector::applyDiscoveredDependencies(CompilerInvocation &CI) { CI.getFrontendOpts().ModuleMapFiles.emplace_back( CurrentModuleMap->getNameAsRequested()); - SmallVector<ModuleID> DirectDeps; + SmallVector<ExtendedModuleID> DirectDeps; for (const auto &KV : ModularDeps) if (DirectModularDeps.contains(KV.first)) - DirectDeps.push_back(KV.second->ID); + DirectDeps.push_back({KV.second->ID, /* Exported = */ false}); // TODO: Report module maps the same way it's done for modular dependencies. addModuleMapFiles(CI, DirectDeps); @@ -598,9 +599,9 @@ static std::string getModuleContextHash(const ModuleDeps &MD, // example, case-insensitive paths to modulemap files. Usually such a case // would indicate a missed optimization to canonicalize, but it may be // difficult to canonicalize all cases when there is a VFS. - for (const auto &ID : MD.ClangModuleDeps) { - HashBuilder.add(ID.ModuleName); - HashBuilder.add(ID.ContextHash); + for (const auto &EMID : MD.ClangModuleDeps) { + HashBuilder.add(EMID.ID.ModuleName); + HashBuilder.add(EMID.ID.ContextHash); } HashBuilder.add(EagerLoadModules); @@ -924,9 +925,10 @@ void ModuleDepCollectorPP::addAllSubmoduleDeps( }); } -void ModuleDepCollectorPP::addOneModuleDep(const Module *M, const ModuleID ID, - ModuleDeps &MD) { - MD.ClangModuleDeps.push_back(ID); +void ModuleDepCollectorPP::addOneModuleDep(const Module *M, bool Exported, + const ModuleID ID, ModuleDeps &MD) { + MD.ClangModuleDeps.push_back({ID, Exported}); + if (MD.IsInStableDirectories) MD.IsInStableDirectories = MDC.ModularDeps[M]->IsInStableDirectories; } @@ -934,12 +936,19 @@ void ModuleDepCollectorPP::addOneModuleDep(const Module *M, const ModuleID ID, void ModuleDepCollectorPP::addModuleDep( const Module *M, ModuleDeps &MD, llvm::DenseSet<const Module *> &AddedModules) { + SmallVector<Module *> ExportedModulesVector; + M->getExportedModules(ExportedModulesVector); + llvm::DenseSet<const Module *> ExportedModulesSet( + ExportedModulesVector.begin(), ExportedModulesVector.end()); for (const Module *Import : M->Imports) { - if (Import->getTopLevelModule() != M->getTopLevelModule() && + const Module *ImportedTopLevelModule = Import->getTopLevelModule(); + if (ImportedTopLevelModule != M->getTopLevelModule() && !MDC.isPrebuiltModule(Import)) { - if (auto ImportID = handleTopLevelModule(Import->getTopLevelModule())) - if (AddedModules.insert(Import->getTopLevelModule()).second) - addOneModuleDep(Import->getTopLevelModule(), *ImportID, MD); + if (auto ImportID = handleTopLevelModule(ImportedTopLevelModule)) + if (AddedModules.insert(ImportedTopLevelModule).second) { + bool Exported = ExportedModulesSet.contains(ImportedTopLevelModule); + addOneModuleDep(ImportedTopLevelModule, Exported, *ImportID, MD); + } } } } @@ -963,7 +972,7 @@ void ModuleDepCollectorPP::addAffectingClangModule( !MDC.isPrebuiltModule(Affecting)) { if (auto ImportID = handleTopLevelModule(Affecting)) if (AddedModules.insert(Affecting).second) - addOneModuleDep(Affecting, *ImportID, MD); + addOneModuleDep(Affecting, /* Exported = */ false, *ImportID, MD); } } } diff --git a/clang/test/ClangScanDeps/diagnostics.c b/clang/test/ClangScanDeps/diagnostics.c index 8e3cf4c9f9fa6..9bd3ce7cfb0dd 100644 --- a/clang/test/ClangScanDeps/diagnostics.c +++ b/clang/test/ClangScanDeps/diagnostics.c @@ -38,6 +38,7 @@ module mod { header "mod.h" } // CHECK-NEXT: "[[PREFIX]]/mod.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "mod" // CHECK-NEXT: } // CHECK-NEXT: ], diff --git a/clang/test/ClangScanDeps/header-search-pruning-transitive.c b/clang/test/ClangScanDeps/header-search-pruning-transitive.c index 1e829bb02ddc4..ad56c55edc845 100644 --- a/clang/test/ClangScanDeps/header-search-pruning-transitive.c +++ b/clang/test/ClangScanDeps/header-search-pruning-transitive.c @@ -76,6 +76,7 @@ module X { header "X.h" } // CHECK-NEXT: "[[PREFIX]]/X.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "X" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -92,6 +93,7 @@ module X { header "X.h" } // CHECK-NEXT: "[[PREFIX]]/end/end.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "Y" // CHECK-NEXT: } // CHECK-NEXT: ], @@ -132,6 +134,7 @@ module X { header "X.h" } // CHECK-NEXT: "[[PREFIX]]/X.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "X" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -147,6 +150,7 @@ module X { header "X.h" } // CHECK-NEXT: "[[PREFIX]]/end/end.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "Y" // CHECK-NEXT: } // CHECK-NEXT: ], diff --git a/clang/test/ClangScanDeps/header-search-pruning.cpp b/clang/test/ClangScanDeps/header-search-pruning.cpp index 6291698002751..c0083d2bc8a1e 100644 --- a/clang/test/ClangScanDeps/header-search-pruning.cpp +++ b/clang/test/ClangScanDeps/header-search-pruning.cpp @@ -34,6 +34,7 @@ // CHECK_A-NEXT: "file-deps": [ // CHECK_A: ], // CHECK_A-NEXT: "link-libraries": [], +// CHECK_A-NEXT: "clang-modules-exported": [], // CHECK_A-NEXT: "name": "mod" // CHECK_A-NEXT: } // CHECK_A-NEXT: ] @@ -57,6 +58,7 @@ // CHECK_B-NEXT: "file-deps": [ // CHECK_B: ], // CHECK_B-NEXT: "link-libraries": [], +// CHECK_B-NEXT: "clang-modules-exported": [], // CHECK_B-NEXT: "name": "mod" // CHECK_B-NEXT: } // CHECK_B-NEXT: ] @@ -82,6 +84,7 @@ // CHECK_AB-NEXT: "file-deps": [ // CHECK_AB: ], // CHECK_AB-NEXT: "link-libraries": [], +// CHECK_AB-NEXT: "clang-modules-exported": [], // CHECK_AB-NEXT: "name": "mod" // CHECK_AB-NEXT: } // CHECK_AB-NEXT: ] diff --git a/clang/test/ClangScanDeps/link-libraries.c b/clang/test/ClangScanDeps/link-libraries.c index cc2e223102024..ab548058b788a 100644 --- a/clang/test/ClangScanDeps/link-libraries.c +++ b/clang/test/ClangScanDeps/link-libraries.c @@ -53,6 +53,7 @@ module transitive { // CHECK-NEXT: "link-name": "Framework" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "Framework" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -71,6 +72,7 @@ module transitive { // CHECK-NEXT: "[[PREFIX]]/direct.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "direct" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -95,6 +97,7 @@ module transitive { // CHECK-NEXT: "[[PREFIX]]/Inputs/frameworks/module.modulemap" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "root" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -113,6 +116,7 @@ module transitive { // CHECK-NEXT: "link-name": "libTransitive" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "transitive" // CHECK-NEXT: } // CHECK-NEXT: ], diff --git a/clang/test/ClangScanDeps/modules-canononical-module-map-case.c b/clang/test/ClangScanDeps/modules-canononical-module-map-case.c index ccb0653dfc5ec..f84dd1335aed2 100644 --- a/clang/test/ClangScanDeps/modules-canononical-module-map-case.c +++ b/clang/test/ClangScanDeps/modules-canononical-module-map-case.c @@ -71,6 +71,7 @@ framework module FW { // CHECK-NEXT: "link-name": "FW" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "FW" // CHECK-NEXT: } // CHECK-NEXT: ] diff --git a/clang/test/ClangScanDeps/modules-context-hash.c b/clang/test/ClangScanDeps/modules-context-hash.c index 9489563576d3b..8ca1b8ce68c49 100644 --- a/clang/test/ClangScanDeps/modules-context-hash.c +++ b/clang/test/ClangScanDeps/modules-context-hash.c @@ -39,6 +39,7 @@ // CHECK-NEXT: "[[PREFIX]]/a/dep.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "mod" // CHECK-NEXT: } // CHECK-NEXT: ], @@ -77,6 +78,7 @@ // CHECK-NEXT: "[[PREFIX]]/b/dep.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "mod" // CHECK-NEXT: } // CHECK-NEXT: ], diff --git a/clang/test/ClangScanDeps/modules-dep-args.c b/clang/test/ClangScanDeps/modules-dep-args.c index 19f915923b84c..1dc682049a3d9 100644 --- a/clang/test/ClangScanDeps/modules-dep-args.c +++ b/clang/test/ClangScanDeps/modules-dep-args.c @@ -62,6 +62,7 @@ module Direct { header "direct.h" } // CHECK-NEXT: "[[PREFIX]]/direct.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "Direct" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -75,6 +76,7 @@ module Direct { header "direct.h" } // CHECK-NEXT: "[[PREFIX]]/transitive.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "Transitive" // CHECK-NEXT: } // CHECK-NEXT: ], diff --git a/clang/test/ClangScanDeps/modules-excluded-header.m b/clang/test/ClangScanDeps/modules-excluded-header.m index 302db55b61e03..6bb016da6c17d 100644 --- a/clang/test/ClangScanDeps/modules-excluded-header.m +++ b/clang/test/ClangScanDeps/modules-excluded-header.m @@ -43,6 +43,7 @@ // CHECK-NEXT: "file-deps": [ // CHECK: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "Mod" // CHECK-NEXT: } // CHECK-NEXT: ] diff --git a/clang/test/ClangScanDeps/modules-extern-submodule.c b/clang/test/ClangScanDeps/modules-extern-submodule.c index 01d3d6ba5e0d3..24fa59d946d52 100644 --- a/clang/test/ClangScanDeps/modules-extern-submodule.c +++ b/clang/test/ClangScanDeps/modules-extern-submodule.c @@ -55,6 +55,7 @@ module third {} // CHECK-NEXT: "[[PREFIX]]/second/second/sub.modulemap" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "first" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -78,6 +79,7 @@ module third {} // CHECK-NEXT: "[[PREFIX]]/third/module.modulemap" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "second" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -93,6 +95,7 @@ module third {} // CHECK-NEXT: "[[PREFIX]]/third/module.modulemap" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "third" // CHECK-NEXT: } // CHECK-NEXT: ], diff --git a/clang/test/ClangScanDeps/modules-extern-unrelated.m b/clang/test/ClangScanDeps/modules-extern-unrelated.m index c003f0d9a2ee8..8a197f3fdf4ce 100644 --- a/clang/test/ClangScanDeps/modules-extern-unrelated.m +++ b/clang/test/ClangScanDeps/modules-extern-unrelated.m @@ -41,6 +41,7 @@ // CHECK-NEXT: "[[PREFIX]]/first/module.modulemap" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "first" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -54,6 +55,7 @@ // CHECK-NEXT: "[[PREFIX]]/first/first_other.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "first_other" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -74,6 +76,7 @@ // CHECK-NEXT: "[[PREFIX]]/first/module.modulemap" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "second" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -99,6 +102,7 @@ // CHECK-NEXT: "[[PREFIX]]/second/second.modulemap" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "zeroth" // CHECK-NEXT: } // CHECK-NEXT: ], diff --git a/clang/test/ClangScanDeps/modules-file-path-isolation.c b/clang/test/ClangScanDeps/modules-file-path-isolation.c index 2bd0a58ca9ae6..81ac3e00f5cd1 100644 --- a/clang/test/ClangScanDeps/modules-file-path-isolation.c +++ b/clang/test/ClangScanDeps/modules-file-path-isolation.c @@ -21,6 +21,7 @@ // CHECK-NEXT: "{{.*}}A.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "A" // CHECK-NEXT: } 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..d77c2ea221df6 100644 --- a/clang/test/ClangScanDeps/modules-fmodule-name-no-module-built.m +++ b/clang/test/ClangScanDeps/modules-fmodule-name-no-module-built.m @@ -29,6 +29,7 @@ // CHECK-NEXT: "[[PREFIX]]/Inputs/header2.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "header2" // CHECK-NEXT: } // CHECK-NEXT: ], diff --git a/clang/test/ClangScanDeps/modules-full-by-mod-name.c b/clang/test/ClangScanDeps/modules-full-by-mod-name.c index c838614d0bfde..347c787c3fa7a 100644 --- a/clang/test/ClangScanDeps/modules-full-by-mod-name.c +++ b/clang/test/ClangScanDeps/modules-full-by-mod-name.c @@ -46,6 +46,7 @@ module transitive { header "transitive.h" } // CHECK-NEXT: "[[PREFIX]]/direct.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "direct" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -65,6 +66,7 @@ module transitive { header "transitive.h" } // CHECK-NEXT: "[[PREFIX]]/root/textual.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "root" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -78,6 +80,7 @@ module transitive { header "transitive.h" } // CHECK-NEXT: "[[PREFIX]]/transitive.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "transitive" // CHECK-NEXT: } // CHECK-NEXT: ], diff --git a/clang/test/ClangScanDeps/modules-full.cpp b/clang/test/ClangScanDeps/modules-full.cpp index 38db3af4403bb..714576c96537d 100644 --- a/clang/test/ClangScanDeps/modules-full.cpp +++ b/clang/test/ClangScanDeps/modules-full.cpp @@ -45,6 +45,7 @@ // CHECK-NEXT: "[[PREFIX]]/Inputs/header.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "header1" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -64,6 +65,7 @@ // CHECK-NEXT: "[[PREFIX]]/Inputs/header.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "header1" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -83,6 +85,7 @@ // CHECK-NEXT: "[[PREFIX]]/Inputs/header2.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "header2" // CHECK-NEXT: } // CHECK-NEXT: ], diff --git a/clang/test/ClangScanDeps/modules-implementation-private.m b/clang/test/ClangScanDeps/modules-implementation-private.m index b376073f4b9ee..0c1e0c263e093 100644 --- a/clang/test/ClangScanDeps/modules-implementation-private.m +++ b/clang/test/ClangScanDeps/modules-implementation-private.m @@ -46,6 +46,7 @@ // CHECK-NEXT: "link-name": "FW" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "FW_Private" // CHECK-NEXT: } // CHECK-NEXT: ], diff --git a/clang/test/ClangScanDeps/modules-implicit-dot-private.m b/clang/test/ClangScanDeps/modules-implicit-dot-private.m index aa8caf3451dc4..b2aaac53c27f3 100644 --- a/clang/test/ClangScanDeps/modules-implicit-dot-private.m +++ b/clang/test/ClangScanDeps/modules-implicit-dot-private.m @@ -41,6 +41,7 @@ // CHECK-NEXT: "link-name": "FW" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "FW" // CHECK: }, // CHECK: { @@ -59,6 +60,7 @@ // CHECK-NEXT: "link-name": "FW" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "FW_Private" // CHECK: } // CHECK: ], diff --git a/clang/test/ClangScanDeps/modules-incomplete-umbrella.c b/clang/test/ClangScanDeps/modules-incomplete-umbrella.c index 696e621960b6f..e425c36607ae7 100644 --- a/clang/test/ClangScanDeps/modules-incomplete-umbrella.c +++ b/clang/test/ClangScanDeps/modules-incomplete-umbrella.c @@ -53,6 +53,7 @@ framework module FW_Private { // CHECK_TU-NEXT: "link-name": "FW" // CHECK_TU-NEXT: } // CHECK_TU-NEXT: ], +// CHECK_TU-NEXT: "clang-modules-exported": [], // CHECK_TU-NEXT: "name": "FW" // CHECK_TU-NEXT: }, // CHECK_TU-NEXT: { @@ -72,6 +73,7 @@ framework module FW_Private { // CHECK_TU-NEXT: "link-name": "FW" // CHECK_TU-NEXT: } // CHECK_TU-NEXT: ], +// CHECK_TU-NEXT: "clang-modules-exported": [], // CHECK_TU-NEXT: "name": "FW_Private" // CHECK_TU-NEXT: } // CHECK_TU-NEXT: ], @@ -143,6 +145,7 @@ module Mod { header "Mod.h" } // CHECK_MODULE-NEXT: "link-name": "FW" // CHECK_MODULE-NEXT: } // CHECK_MODULE-NEXT: ], +// CHECK_MODULE-NEXT: "clang-modules-exported": [], // CHECK_MODULE-NEXT: "name": "FW" // CHECK_MODULE-NEXT: }, // CHECK_MODULE-NEXT: { @@ -162,6 +165,7 @@ module Mod { header "Mod.h" } // CHECK_MODULE-NEXT: "link-name": "FW" // CHECK_MODULE-NEXT: } // CHECK_MODULE-NEXT: ], +// CHECK_MODULE-NEXT: "clang-modules-exported": [], // CHECK_MODULE-NEXT: "name": "FW_Private" // CHECK_MODULE-NEXT: }, // CHECK_MODULE-NEXT: { @@ -189,6 +193,7 @@ module Mod { header "Mod.h" } // CHECK_MODULE-NEXT: "[[PREFIX]]/frameworks/FW.framework/PrivateHeaders/Two.h" // CHECK_MODULE-NEXT: ], // CHECK_MODULE-NEXT: "link-libraries": [], +// CHECK_MODULE-NEXT: "clang-modules-exported": [], // CHECK_MODULE-NEXT: "name": "Mod" // CHECK_MODULE-NEXT: } // CHECK_MODULE-NEXT: ], diff --git a/clang/test/ClangScanDeps/modules-inferred.m b/clang/test/ClangScanDeps/modules-inferred.m index 4c7a4095c9bef..9a95899274739 100644 --- a/clang/test/ClangScanDeps/modules-inferred.m +++ b/clang/test/ClangScanDeps/modules-inferred.m @@ -47,6 +47,7 @@ // CHECK-NEXT: "link-name": "Inferred" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "Inferred" // CHECK-NEXT: } // CHECK-NEXT: ], diff --git a/clang/test/ClangScanDeps/modules-no-undeclared-includes.c b/clang/test/ClangScanDeps/modules-no-undeclared-includes.c index 6110c419949f9..0435c0cf86080 100644 --- a/clang/test/ClangScanDeps/modules-no-undeclared-includes.c +++ b/clang/test/ClangScanDeps/modules-no-undeclared-includes.c @@ -48,6 +48,7 @@ module User [no_undeclared_includes] { header "user.h" } // CHECK-NEXT: "[[PREFIX]]/undeclared/module.modulemap" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "User" // CHECK-NEXT: } // CHECK-NEXT: ], diff --git a/clang/test/ClangScanDeps/modules-pch-common-submodule.c b/clang/test/ClangScanDeps/modules-pch-common-submodule.c index 59dd3f172d8ee..8fa463ca373d1 100644 --- a/clang/test/ClangScanDeps/modules-pch-common-submodule.c +++ b/clang/test/ClangScanDeps/modules-pch-common-submodule.c @@ -32,6 +32,7 @@ // CHECK-PCH-NEXT: "[[PREFIX]]/mod_common_sub.h" // CHECK-PCH-NEXT: ], // CHECK-PCH-NEXT: "link-libraries": [], +// CHECK-PCH-NEXT: "clang-modules-exported": [], // CHECK-PCH-NEXT: "name": "ModCommon" // CHECK-PCH-NEXT: } // CHECK-PCH-NEXT: ], @@ -80,6 +81,7 @@ // CHECK-TU-NEXT: "[[PREFIX]]/mod_tu.h" // CHECK-TU-NEXT: ], // CHECK-TU-NEXT: "link-libraries": [], +// CHECK-TU-NEXT: "clang-modules-exported": [], // CHECK-TU-NEXT: "name": "ModTU" // CHECK-TU-NEXT: } // CHECK-TU-NEXT: ], diff --git a/clang/test/ClangScanDeps/modules-pch-common-via-submodule.c b/clang/test/ClangScanDeps/modules-pch-common-via-submodule.c index a12492c0bec70..36728105d34b9 100644 --- a/clang/test/ClangScanDeps/modules-pch-common-via-submodule.c +++ b/clang/test/ClangScanDeps/modules-pch-common-via-submodule.c @@ -28,6 +28,7 @@ // CHECK-PCH-NEXT: "[[PREFIX]]/mod_common.h" // CHECK-PCH-NEXT: ], // CHECK-PCH-NEXT: "link-libraries": [], +// CHECK-PCH-NEXT: "clang-modules-exported": [], // CHECK-PCH-NEXT: "name": "ModCommon" // CHECK-PCH-NEXT: } // CHECK-PCH-NEXT: ], @@ -77,6 +78,7 @@ // CHECK-TU-NEXT: "[[PREFIX]]/mod_tu_sub.h" // CHECK-TU-NEXT: ], // CHECK-TU-NEXT: "link-libraries": [], +// CHECK-TU-NEXT: "clang-modules-exported": [], // CHECK-TU-NEXT: "name": "ModTU" // CHECK-TU-NEXT: } // CHECK-TU-NEXT: ], diff --git a/clang/test/ClangScanDeps/modules-pch.c b/clang/test/ClangScanDeps/modules-pch.c index 92b7f41ac4b9f..ed168be535aeb 100644 --- a/clang/test/ClangScanDeps/modules-pch.c +++ b/clang/test/ClangScanDeps/modules-pch.c @@ -29,6 +29,7 @@ // CHECK-PCH-NEXT: "[[PREFIX]]/mod_common_1.h" // CHECK-PCH-NEXT: ], // CHECK-PCH-NEXT: "link-libraries": [], +// CHECK-PCH-NEXT: "clang-modules-exported": [], // CHECK-PCH-NEXT: "name": "ModCommon1" // CHECK-PCH-NEXT: }, // CHECK-PCH-NEXT: { @@ -42,6 +43,7 @@ // CHECK-PCH-NEXT: "[[PREFIX]]/mod_common_2.h" // CHECK-PCH-NEXT: ], // CHECK-PCH-NEXT: "link-libraries": [], +// CHECK-PCH-NEXT: "clang-modules-exported": [], // CHECK-PCH-NEXT: "name": "ModCommon2" // CHECK-PCH-NEXT: }, // CHECK-PCH-NEXT: { @@ -60,6 +62,7 @@ // CHECK-PCH-NEXT: "[[PREFIX]]/mod_pch.h" // CHECK-PCH-NEXT: ], // CHECK-PCH-NEXT: "link-libraries": [], +// CHECK-PCH-NEXT: "clang-modules-exported": [], // CHECK-PCH-NEXT: "name": "ModPCH" // CHECK-PCH-NEXT: } // CHECK-PCH-NEXT: ], @@ -117,6 +120,7 @@ // CHECK-TU-NEXT: "[[PREFIX]]/mod_tu.h" // CHECK-TU-NEXT: ], // CHECK-TU-NEXT: "link-libraries": [], +// CHECK-TU-NEXT: "clang-modules-exported": [], // CHECK-TU-NEXT: "name": "ModTU" // CHECK-TU-NEXT: } // CHECK-TU-NEXT: ], @@ -167,6 +171,7 @@ // CHECK-TU-WITH-COMMON-NEXT: "[[PREFIX]]/mod_tu_with_common.h" // CHECK-TU-WITH-COMMON-NEXT: ], // CHECK-TU-WITH-COMMON-NEXT: "link-libraries": [], +// CHECK-TU-WITH-COMMON-NEXT: "clang-modules-exported": [], // CHECK-TU-WITH-COMMON-NEXT: "name": "ModTUWithCommon" // CHECK-TU-WITH-COMMON-NEXT: } // CHECK-TU-WITH-COMMON-NEXT: ], diff --git a/clang/test/ClangScanDeps/modules-priv-fw-from-pub.m b/clang/test/ClangScanDeps/modules-priv-fw-from-pub.m index dd314e1a3006a..7792988262732 100644 --- a/clang/test/ClangScanDeps/modules-priv-fw-from-pub.m +++ b/clang/test/ClangScanDeps/modules-priv-fw-from-pub.m @@ -46,6 +46,7 @@ // CHECK-NEXT: "[[PREFIX]]/modules/dependency.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "Dependency" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -70,6 +71,7 @@ // CHECK-NEXT: "link-name": "FW" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "FW" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -94,6 +96,7 @@ // CHECK-NEXT: "link-name": "FW" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "FW_Private" // CHECK-NEXT: } // CHECK-NEXT: ], diff --git a/clang/test/ClangScanDeps/modules-redefinition.m b/clang/test/ClangScanDeps/modules-redefinition.m index 3db06287241fe..51442384c7654 100644 --- a/clang/test/ClangScanDeps/modules-redefinition.m +++ b/clang/test/ClangScanDeps/modules-redefinition.m @@ -50,6 +50,7 @@ // CHECK-NEXT: [[PREFIX]]/third/module.modulemap" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "first" // CHECK-NEXT: } // CHECK: ] diff --git a/clang/test/ClangScanDeps/modules-symlink-dir-vfs.c b/clang/test/ClangScanDeps/modules-symlink-dir-vfs.c index f2e5758aa41fb..e8f014177296c 100644 --- a/clang/test/ClangScanDeps/modules-symlink-dir-vfs.c +++ b/clang/test/ClangScanDeps/modules-symlink-dir-vfs.c @@ -85,6 +85,7 @@ framework module FW { umbrella header "FW.h" } // CHECK-NEXT: "link-name": "FW" // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "FW" // CHECK-NEXT: } // CHECK-NEXT: ], diff --git a/clang/test/ClangScanDeps/modules-transitive.c b/clang/test/ClangScanDeps/modules-transitive.c index 1a3b8a3671181..536eb6da40f8d 100644 --- a/clang/test/ClangScanDeps/modules-transitive.c +++ b/clang/test/ClangScanDeps/modules-transitive.c @@ -53,6 +53,7 @@ module third { header "third.h" } // CHECK-NEXT: "[[PREFIX]]/second/module.modulemap" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "first" // CHECK-NEXT: } // CHECK: ] diff --git a/clang/test/ClangScanDeps/optimize-canonicalize-macros.m b/clang/test/ClangScanDeps/optimize-canonicalize-macros.m index 46ae1c84ec7ba..44a9e6a7d2373 100644 --- a/clang/test/ClangScanDeps/optimize-canonicalize-macros.m +++ b/clang/test/ClangScanDeps/optimize-canonicalize-macros.m @@ -25,6 +25,7 @@ // CHECK-NEXT: "file-deps": [ // CHECK: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "A" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -40,6 +41,7 @@ // CHECK-NEXT: "file-deps": [ // CHECK: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "A" // CHECK-NEXT: } // CHECK-NEXT: ], diff --git a/clang/test/ClangScanDeps/optimize-fmodulemap.m b/clang/test/ClangScanDeps/optimize-fmodulemap.m index 84561d3a44a07..89dca7a744b1d 100644 --- a/clang/test/ClangScanDeps/optimize-fmodulemap.m +++ b/clang/test/ClangScanDeps/optimize-fmodulemap.m @@ -25,6 +25,7 @@ // CHECK-NEXT: "file-deps": [ // CHECK: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "A" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -37,6 +38,7 @@ // CHECK-NEXT: "file-deps": [ // CHECK: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "B" // CHECK-NEXT: } // CHECK-NEXT: ], diff --git a/clang/test/ClangScanDeps/optimize-system-warnings.m b/clang/test/ClangScanDeps/optimize-system-warnings.m index 710c9c30939c9..4d7597ec08549 100644 --- a/clang/test/ClangScanDeps/optimize-system-warnings.m +++ b/clang/test/ClangScanDeps/optimize-system-warnings.m @@ -22,6 +22,7 @@ // CHECK-NEXT: "file-deps": [ // CHECK: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "A" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -34,6 +35,7 @@ // CHECK-NEXT: "file-deps": [ // CHECK: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "B" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -46,6 +48,7 @@ // CHECK-NEXT: "file-deps": [ // CHECK: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "C" // CHECK-NEXT: } // CHECK-NEXT: ], diff --git a/clang/test/ClangScanDeps/optimize-vfs-leak.m b/clang/test/ClangScanDeps/optimize-vfs-leak.m index c0ccdbe0a2aea..eeb16f5074d9e 100644 --- a/clang/test/ClangScanDeps/optimize-vfs-leak.m +++ b/clang/test/ClangScanDeps/optimize-vfs-leak.m @@ -30,6 +30,7 @@ // CHECK-NEXT: "file-deps": [ // CHECK: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "A" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -44,6 +45,7 @@ // CHECK-NEXT: "file-deps": [ // CHECK: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "B" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -57,6 +59,7 @@ // CHECK-NEXT: "file-deps": [ // CHECK: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "C" // CHECK-NEXT: } // CHECK-NEXT: ], diff --git a/clang/test/ClangScanDeps/optimize-vfs.m b/clang/test/ClangScanDeps/optimize-vfs.m index 2043a603179fe..6e456e03b4909 100644 --- a/clang/test/ClangScanDeps/optimize-vfs.m +++ b/clang/test/ClangScanDeps/optimize-vfs.m @@ -28,6 +28,7 @@ // CHECK-NEXT: "[[PREFIX]]/build/A.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "A" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -42,6 +43,7 @@ // CHECK-NEXT: "[[PREFIX]]/modules/B/B.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "B" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -62,6 +64,7 @@ // CHECK-NEXT: "[[PREFIX]]/modules/B/module.modulemap" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "C" // CHECK-NEXT: } // CHECK-NEXT: ], diff --git a/clang/test/ClangScanDeps/removed-args.c b/clang/test/ClangScanDeps/removed-args.c index 16f053f71e6ba..1f32514496ae2 100644 --- a/clang/test/ClangScanDeps/removed-args.c +++ b/clang/test/ClangScanDeps/removed-args.c @@ -43,6 +43,7 @@ // CHECK-NEXT: "[[PREFIX]]/mod_header.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "ModHeader" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -70,6 +71,7 @@ // CHECK-NEXT: "[[PREFIX]]/mod_tu.h" // CHECK-NEXT: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "ModTU" // CHECK-NEXT: } // CHECK-NEXT: ], diff --git a/clang/test/ClangScanDeps/working-dir.m b/clang/test/ClangScanDeps/working-dir.m index c6b7b1988d3cf..d622858a27566 100644 --- a/clang/test/ClangScanDeps/working-dir.m +++ b/clang/test/ClangScanDeps/working-dir.m @@ -18,6 +18,7 @@ // CHECK-NEXT: "file-deps": [ // CHECK: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "A" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -29,6 +30,7 @@ // CHECK-NEXT: "file-deps": [ // CHECK: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "A" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -41,6 +43,7 @@ // CHECK-NEXT: "file-deps": [ // CHECK: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "B" // CHECK-NEXT: }, // CHECK-NEXT: { @@ -53,6 +56,7 @@ // CHECK-NEXT: "file-deps": [ // CHECK: ], // CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [], // CHECK-NEXT: "name": "B" // CHECK-NEXT: } // CHECK-NEXT: ], diff --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp index 13dab6e445733..379394e64ebee 100644 --- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp +++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp @@ -350,16 +350,33 @@ static auto toJSONStrings(llvm::json::OStream &JOS, Container &&Strings) { }; } +static auto toJSONModuleID(llvm::json::OStream &JOS, StringRef ContextHash, + StringRef ModuleName) { + return JOS.object([&] { + JOS.attribute("context-hash", StringRef(ContextHash)); + JOS.attribute("module-name", StringRef(ModuleName)); + }); +} + // Technically, we don't need to sort the dependency list to get determinism. // Leaving these be will simply preserve the import order. static auto toJSONSorted(llvm::json::OStream &JOS, std::vector<ModuleID> V) { llvm::sort(V); return [&JOS, V = std::move(V)] { - for (const ModuleID &MID : V) - JOS.object([&] { - JOS.attribute("context-hash", StringRef(MID.ContextHash)); - JOS.attribute("module-name", StringRef(MID.ModuleName)); - }); + for (const auto &MID : V) + toJSONModuleID(JOS, MID.ContextHash, MID.ModuleName); + }; +} + +static auto toJSONSorted(llvm::json::OStream &JOS, + std::vector<ExtendedModuleID> V, + std::function<bool(const ExtendedModuleID &)> filter) { + llvm::sort(V); + return [&JOS, V = std::move(V), filter] { + for (const ExtendedModuleID &MID : V) + if (filter(MID)) { + toJSONModuleID(JOS, MID.ID.ContextHash, MID.ID.ModuleName); + } }; } @@ -474,8 +491,10 @@ class FullDeps { if (MD.IsInStableDirectories) JOS.attribute("is-in-stable-directories", MD.IsInStableDirectories); - JOS.attributeArray("clang-module-deps", - toJSONSorted(JOS, MD.ClangModuleDeps)); + JOS.attributeArray( + "clang-module-deps", + toJSONSorted(JOS, MD.ClangModuleDeps, + [](const auto &EMID) { return true; })); JOS.attribute("clang-modulemap-file", StringRef(MD.ClangModuleMapFile)); JOS.attributeArray("command-line", @@ -486,6 +505,10 @@ class FullDeps { }); JOS.attributeArray("link-libraries", toJSONSorted(JOS, MD.LinkLibraries)); + JOS.attributeArray( + "clang-modules-exported", + toJSONSorted(JOS, MD.ClangModuleDeps, + [](const auto &EMID) { return EMID.Exported; })); JOS.attribute("name", StringRef(MD.ID.ModuleName)); }); } >From 52515f82b516e2f8c2e4ade4266f888a4ba173e5 Mon Sep 17 00:00:00 2001 From: Qiongsi Wu <qiongsi...@apple.com> Date: Fri, 25 Apr 2025 16:43:56 -0700 Subject: [PATCH 2/2] Adding a test case. --- clang/test/ClangScanDeps/export.c | 164 ++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 clang/test/ClangScanDeps/export.c diff --git a/clang/test/ClangScanDeps/export.c b/clang/test/ClangScanDeps/export.c new file mode 100644 index 0000000000000..a926f61d659cb --- /dev/null +++ b/clang/test/ClangScanDeps/export.c @@ -0,0 +1,164 @@ +// Test correctly reporting what a module exports during dependency scanning. +// Module A depends on modules B, C and D, but only exports B and C. +// Module E depends on modules B, C and D, and exports all of them. + +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json +// RUN: clang-scan-deps -compilation-database \ +// RUN: %t/cdb.json -format experimental-full > %t/deps.db +// RUN: cat %t/deps.db | sed 's:\\\\\?:/:g' | FileCheck %s + +//--- cdb.json.template +[ + { + "directory": "DIR", + "command": "clang -c DIR/test.c -I DIR/AH -I DIR/BH -I DIR/CH -I DIR/DH -I DIR/EH -fmodules -fmodules-cache-path=DIR/cache", + "file": "DIR/test.c" + }, +] + +//--- AH/A.h +#include "B.h" +#include "C.h" +#include "D.h" + +int funcA(); + +//--- AH/module.modulemap +module A { + header "A.h" + + export B + export C +} + +//--- BH/B.h +//--- BH/module.modulemap +module B { + header "B.h" +} + +//--- CH/C.h +//--- CH/module.modulemap +module C { + header "C.h" +} + +//--- DH/D.h +//--- DH/module.modulemap +module D { + header "D.h" +} + +//--- EH/E.h +#include "B.h" +#include "C.h" +#include "D.h" + +//--- EH/module.modulemap +module E { + header "E.h" + export * +} + +//--- test.c +#include "A.h" +#include "E.h" + +int test1() { + return funcA(); +} + +// CHECK: { +// CHECK-NEXT: "modules": [ +// CHECK-NEXT: { +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH_MOD_B:.*]]", +// CHECK-NEXT: "module-name": "B" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH_MOD_C:.*]]", +// CHECK-NEXT: "module-name": "C" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH_MOD_D:.*]]", +// CHECK-NEXT: "module-name": "D" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "clang-modulemap-file":{{.*}}, +// CHECK-NEXT: "command-line": [ +// CHECK: ], +// CHECK-NEXT: "context-hash":{{.*}} +// CHECK-NEXT: "file-deps": [ +// CHECK: ], +// CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH_MOD_B]]", +// CHECK-NEXT: "module-name": "B" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH_MOD_C]]", +// CHECK-NEXT: "module-name": "C" +// CHECK-NEXT: } +// CHECK-NOT: { +// CHECK-NOT: "context-hash": "[[HASH_MOD_D]]", +// CHECK-NOT: "module-name": "D" +// CHECK-NOT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "name": "A" +// CHECK-NEXT: } +// CHECK: { +// CHECK: "name": "B" +// CHECK: } +// CHECK: { +// CHECK: "name": "C" +// CHECK: } +// CHECK: { +// CHECK: "name": "D" +// CHECK: } +// CHECK: { +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH_MOD_B]]", +// CHECK-NEXT: "module-name": "B" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH_MOD_C]]", +// CHECK-NEXT: "module-name": "C" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH_MOD_D]]", +// CHECK-NEXT: "module-name": "D" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "clang-modulemap-file":{{.*}}, +// CHECK-NEXT: "command-line": [ +// CHECK: ], +// CHECK-NEXT: "context-hash":{{.*}} +// CHECK-NEXT: "file-deps": [ +// CHECK: ], +// CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "clang-modules-exported": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH_MOD_B]]", +// CHECK-NEXT: "module-name": "B" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH_MOD_C]]", +// CHECK-NEXT: "module-name": "C" +// CHECK-NEXT: } +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH_MOD_D]]", +// CHECK-NEXT: "module-name": "D" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "name": "E" +// CHECK-NEXT: } +// CHECK: ] +// CHECK: } + + + _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits