[clang] [clang][deps] Collect discovered module dependencies' Link Libraries (PR #93588)
Artem Chikin via cfe-commits
cfe-commits at lists.llvm.org
Tue May 28 11:02:17 PDT 2024
https://github.com/artemcm updated https://github.com/llvm/llvm-project/pull/93588
>From 034f567024c6766f68dcc73ddad9b0fe09b05baf Mon Sep 17 00:00:00 2001
From: artemcm <achikin at apple.com>
Date: Fri, 24 May 2024 15:13:45 -0700
Subject: [PATCH] [clang][deps] Collect discovered module dependencies' Link
Libraries
This will allow scanner clients to be able to compute e.g. auto-linking dependencies of the scanned translation unit.
---
.../DependencyScanning/ModuleDepCollector.h | 9 ++
.../DependencyScanning/ModuleDepCollector.cpp | 2 +
clang/test/ClangScanDeps/diagnostics.c | 1 +
.../header-search-pruning-transitive.c | 4 +
.../ClangScanDeps/header-search-pruning.cpp | 3 +
clang/test/ClangScanDeps/link-libraries.c | 121 ++++++++++++++++++
.../modules-canononical-module-map-case.c | 6 +
.../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 | 6 +
.../modules-implicit-dot-private.m | 12 ++
.../modules-incomplete-umbrella.c | 25 ++++
clang/test/ClangScanDeps/modules-inferred.m | 6 +
.../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 | 13 ++
.../test/ClangScanDeps/modules-redefinition.m | 1 +
.../ClangScanDeps/modules-symlink-dir-vfs.c | 6 +
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 | 5 +-
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 | 29 +++--
36 files changed, 287 insertions(+), 9 deletions(-)
create mode 100644 clang/test/ClangScanDeps/link-libraries.c
diff --git a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h b/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h
index da51292296a90..6c5ddef46e24d 100644
--- a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h
+++ b/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h
@@ -10,6 +10,7 @@
#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_MODULEDEPCOLLECTOR_H
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/Module.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/Utils.h"
@@ -138,6 +139,14 @@ struct ModuleDeps {
/// determined that the differences are benign for this compilation.
std::vector<ModuleID> ClangModuleDeps;
+ /// The set of libraries or frameworks to link against when
+ /// an entity from this module is used.
+ llvm::SmallVector<Module::LinkLibrary, 2> LinkLibraries;
+
+ /// Autolinking uses the framework name for linking purposes
+ /// when this is false and the export_as name otherwise.
+ bool UseExportAsModuleLinkName;
+
/// Get (or compute) the compiler invocation that can be used to build this
/// module. Does not include argv[0].
const std::vector<std::string> &getBuildArguments();
diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
index f46324ee9989e..6b2ea1a67b96b 100644
--- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
+++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
@@ -578,6 +578,8 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
MD.ID.ModuleName = M->getFullModuleName();
MD.IsSystem = M->IsSystem;
+ MD.LinkLibraries = M->LinkLibraries;
+ MD.UseExportAsModuleLinkName = M->UseExportAsModuleLinkName;
ModuleMap &ModMapInfo =
MDC.ScanInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
diff --git a/clang/test/ClangScanDeps/diagnostics.c b/clang/test/ClangScanDeps/diagnostics.c
index 42aeca16cddc4..bc05594f7828d 100644
--- a/clang/test/ClangScanDeps/diagnostics.c
+++ b/clang/test/ClangScanDeps/diagnostics.c
@@ -37,6 +37,7 @@ module mod { header "mod.h" }
// CHECK-NEXT: "[[PREFIX]]/mod.h"
// CHECK-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// 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 eb93b13692043..6c42265090268 100644
--- a/clang/test/ClangScanDeps/header-search-pruning-transitive.c
+++ b/clang/test/ClangScanDeps/header-search-pruning-transitive.c
@@ -75,6 +75,7 @@ module X { header "X.h" }
// CHECK-NEXT: "[[PREFIX]]/X.h",
// CHECK-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "X"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -90,6 +91,7 @@ module X { header "X.h" }
// CHECK-NEXT: "[[PREFIX]]/end/end.h",
// CHECK-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "Y"
// CHECK-NEXT: }
// CHECK-NEXT: ],
@@ -129,6 +131,7 @@ module X { header "X.h" }
// CHECK-NEXT: "[[PREFIX]]/X.h",
// CHECK-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "X"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -143,6 +146,7 @@ module X { header "X.h" }
// CHECK-NEXT: "[[PREFIX]]/end/end.h",
// CHECK-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// 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 daacd3d319fb0..6291698002751 100644
--- a/clang/test/ClangScanDeps/header-search-pruning.cpp
+++ b/clang/test/ClangScanDeps/header-search-pruning.cpp
@@ -33,6 +33,7 @@
// CHECK_A-NEXT: "context-hash": "{{.*}}",
// CHECK_A-NEXT: "file-deps": [
// CHECK_A: ],
+// CHECK_A-NEXT: "link-libraries": [],
// CHECK_A-NEXT: "name": "mod"
// CHECK_A-NEXT: }
// CHECK_A-NEXT: ]
@@ -55,6 +56,7 @@
// CHECK_B-NEXT: "context-hash": "{{.*}}",
// CHECK_B-NEXT: "file-deps": [
// CHECK_B: ],
+// CHECK_B-NEXT: "link-libraries": [],
// CHECK_B-NEXT: "name": "mod"
// CHECK_B-NEXT: }
// CHECK_B-NEXT: ]
@@ -79,6 +81,7 @@
// CHECK_AB-NEXT: "context-hash": "{{.*}}",
// CHECK_AB-NEXT: "file-deps": [
// CHECK_AB: ],
+// CHECK_AB-NEXT: "link-libraries": [],
// 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
new file mode 100644
index 0000000000000..c09691d2356ef
--- /dev/null
+++ b/clang/test/ClangScanDeps/link-libraries.c
@@ -0,0 +1,121 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: mkdir %t/Inputs
+// RUN: cp -R %S/Inputs/frameworks %t/Inputs/frameworks
+// RUN: split-file %s %t
+
+//--- module.modulemap
+module root { header "root.h" }
+module direct { header "direct.h" }
+module transitive {
+ header "transitive.h"
+ link framework "libTransitive"
+}
+//--- root.h
+#include "direct.h"
+#include "root/textual.h"
+#include "Framework/Framework.h"
+//--- direct.h
+#include "transitive.h"
+//--- transitive.h
+// empty
+
+//--- root/textual.h
+// This is here to verify that the "root" directory doesn't clash with name of
+// the "root" module.
+
+//--- cdb.json.template
+[{
+ "file": "",
+ "directory": "DIR",
+ "command": "clang -fmodules -fmodules-cache-path=DIR/cache -FDIR/Inputs/frameworks -I DIR -x c"
+}]
+
+// RUN: sed "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
+// RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-full -module-name=root > %t/result.json
+// RUN: cat %t/result.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s
+
+// CHECK: {
+// CHECK-NEXT: "modules": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "clang-module-deps": [],
+// CHECK-NEXT: "clang-modulemap-file": "{{.*}}/__inferred_module.map",
+// CHECK-NEXT: "command-line": [
+// CHECK: ],
+// CHECK-NEXT: "context-hash": "{{.*}}",
+// CHECK-NEXT: "file-deps": [
+// CHECK-NEXT: "{{.*}}/Framework.h"
+// CHECK-NEXT: "{{.*}}/__inferred_module.map"
+// CHECK-NEXT: "{{.*}}/module.modulemap"
+// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "isFramework": true,
+// CHECK-NEXT: "link-name": "Framework"
+// CHECK-NEXT: }
+// CHECK-NEXT: ],
+// CHECK-NEXT: "name": "Framework"
+// CHECK-NEXT: },
+// CHECK-NEXT: {
+// CHECK-NEXT: "clang-module-deps": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "context-hash": "{{.*}}",
+// CHECK-NEXT: "module-name": "transitive"
+// CHECK-NEXT: }
+// CHECK-NEXT: ],
+// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap",
+// CHECK-NEXT: "command-line": [
+// CHECK: ],
+// CHECK-NEXT: "context-hash": "{{.*}}",
+// CHECK-NEXT: "file-deps": [
+// CHECK-NEXT: "[[PREFIX]]/direct.h"
+// CHECK-NEXT: "[[PREFIX]]/module.modulemap"
+// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
+// CHECK-NEXT: "name": "direct"
+// CHECK-NEXT: },
+// CHECK-NEXT: {
+// CHECK-NEXT: "clang-module-deps": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "context-hash": "{{.*}}",
+// CHECK-NEXT: "module-name": "Framework"
+// CHECK-NEXT: },
+// CHECK-NEXT: {
+// CHECK-NEXT: "context-hash": "{{.*}}",
+// CHECK-NEXT: "module-name": "direct"
+// CHECK-NEXT: }
+// CHECK-NEXT: ],
+// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap",
+// CHECK-NEXT: "command-line": [
+// CHECK: ],
+// CHECK-NEXT: "context-hash": "{{.*}}",
+// CHECK-NEXT: "file-deps": [
+// CHECK-NEXT: "[[PREFIX]]/Inputs/frameworks/module.modulemap"
+// CHECK-NEXT: "[[PREFIX]]/module.modulemap"
+// CHECK-NEXT: "[[PREFIX]]/root.h"
+// CHECK-NEXT: "[[PREFIX]]/root/textual.h"
+// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
+// CHECK-NEXT: "name": "root"
+// CHECK-NEXT: },
+// CHECK-NEXT: {
+// CHECK-NEXT: "clang-module-deps": [],
+// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap",
+// CHECK-NEXT: "command-line": [
+// CHECK: ],
+// CHECK-NEXT: "context-hash": "{{.*}}",
+// CHECK-NEXT: "file-deps": [
+// CHECK-NEXT: "[[PREFIX]]/module.modulemap"
+// CHECK-NEXT: "[[PREFIX]]/transitive.h"
+// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "isFramework": true,
+// CHECK-NEXT: "link-name": "libTransitive"
+// CHECK-NEXT: }
+// CHECK-NEXT: ],
+// CHECK-NEXT: "name": "transitive"
+// CHECK-NEXT: }
+// CHECK-NEXT: ],
+// CHECK-NEXT: "translation-units": []
+// 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 a7c9624e2de71..ccb0653dfc5ec 100644
--- a/clang/test/ClangScanDeps/modules-canononical-module-map-case.c
+++ b/clang/test/ClangScanDeps/modules-canononical-module-map-case.c
@@ -65,6 +65,12 @@ framework module FW {
// CHECK-NEXT: "context-hash": "{{.*}}",
// CHECK-NEXT: "file-deps": [
// CHECK: ],
+// CHECK-NEXT: "link-libraries": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "isFramework": true,
+// CHECK-NEXT: "link-name": "FW"
+// CHECK-NEXT: }
+// CHECK-NEXT: ],
// 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 3108c924b0721..69fd8561a2b32 100644
--- a/clang/test/ClangScanDeps/modules-context-hash.c
+++ b/clang/test/ClangScanDeps/modules-context-hash.c
@@ -38,6 +38,7 @@
// CHECK-NEXT: "[[PREFIX]]/mod.h",
// CHECK-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "mod"
// CHECK-NEXT: }
// CHECK-NEXT: ],
@@ -75,6 +76,7 @@
// CHECK-NEXT: "[[PREFIX]]/mod.h",
// CHECK-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// 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 12bdb6eb1f7fd..14de2e8f4594a 100644
--- a/clang/test/ClangScanDeps/modules-dep-args.c
+++ b/clang/test/ClangScanDeps/modules-dep-args.c
@@ -61,6 +61,7 @@ module Direct { header "direct.h" }
// CHECK-NEXT: "[[PREFIX]]/direct.h",
// CHECK-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "Direct"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -73,6 +74,7 @@ module Direct { header "direct.h" }
// CHECK-NEXT: "[[PREFIX]]/module.modulemap",
// CHECK-NEXT: "[[PREFIX]]/transitive.h"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// 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 030c92247a689..302db55b61e03 100644
--- a/clang/test/ClangScanDeps/modules-excluded-header.m
+++ b/clang/test/ClangScanDeps/modules-excluded-header.m
@@ -42,6 +42,7 @@
// CHECK-NEXT: "context-hash": "{{.*}}",
// CHECK-NEXT: "file-deps": [
// CHECK: ],
+// CHECK-NEXT: "link-libraries": [],
// 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 61cc722e84bc0..92f2c749dd2c3 100644
--- a/clang/test/ClangScanDeps/modules-extern-submodule.c
+++ b/clang/test/ClangScanDeps/modules-extern-submodule.c
@@ -54,6 +54,7 @@ module third {}
// CHECK-NEXT: "[[PREFIX]]/second/second/module.modulemap",
// CHECK-NEXT: "[[PREFIX]]/second/second/sub.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "first"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -76,6 +77,7 @@ module third {}
// CHECK-NEXT: "[[PREFIX]]/second/second/sub.modulemap",
// CHECK-NEXT: "[[PREFIX]]/third/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "second"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -90,6 +92,7 @@ module third {}
// CHECK-NEXT: "file-deps": [
// CHECK-NEXT: "[[PREFIX]]/third/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// 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 957132fd5b185..724779c12a97b 100644
--- a/clang/test/ClangScanDeps/modules-extern-unrelated.m
+++ b/clang/test/ClangScanDeps/modules-extern-unrelated.m
@@ -40,6 +40,7 @@
// CHECK-NEXT: "file-deps": [
// CHECK-NEXT: "[[PREFIX]]/first/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "first"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -52,6 +53,7 @@
// CHECK-NEXT: "[[PREFIX]]/first/first_other.h",
// CHECK-NEXT: "[[PREFIX]]/first/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "first_other"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -71,6 +73,7 @@
// CHECK-NEXT: "[[PREFIX]]/second/second.h",
// CHECK-NEXT: "[[PREFIX]]/second/second.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "second"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -95,6 +98,7 @@
// CHECK-NEXT: "[[PREFIX]]/zeroth/module.modulemap",
// CHECK-NEXT: "[[PREFIX]]/zeroth/zeroth.h"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// 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 0e55bba753841..d4fef2f4fdd28 100644
--- a/clang/test/ClangScanDeps/modules-file-path-isolation.c
+++ b/clang/test/ClangScanDeps/modules-file-path-isolation.c
@@ -20,6 +20,7 @@
// CHECK-NEXT: "{{.*}}A.h",
// CHECK-NEXT: "{{.*}}module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// 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 a6206b1546751..e4d5caff9236e 100644
--- a/clang/test/ClangScanDeps/modules-fmodule-name-no-module-built.m
+++ b/clang/test/ClangScanDeps/modules-fmodule-name-no-module-built.m
@@ -28,6 +28,7 @@
// CHECK-NEXT: "[[PREFIX]]/Inputs/header2.h",
// CHECK-NEXT: "[[PREFIX]]/Inputs/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// 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 7ebd39d0dc1c9..dd2b3f62e3663 100644
--- a/clang/test/ClangScanDeps/modules-full-by-mod-name.c
+++ b/clang/test/ClangScanDeps/modules-full-by-mod-name.c
@@ -45,6 +45,7 @@ module transitive { header "transitive.h" }
// CHECK-NEXT: "[[PREFIX]]/direct.h"
// CHECK-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "direct"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -63,6 +64,7 @@ module transitive { header "transitive.h" }
// CHECK-NEXT: "[[PREFIX]]/root.h"
// CHECK-NEXT: "[[PREFIX]]/root/textual.h"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "root"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -75,6 +77,7 @@ module transitive { header "transitive.h" }
// CHECK-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-NEXT: "[[PREFIX]]/transitive.h"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// 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 a00a431eb5691..e9b4386da5b5e 100644
--- a/clang/test/ClangScanDeps/modules-full.cpp
+++ b/clang/test/ClangScanDeps/modules-full.cpp
@@ -44,6 +44,7 @@
// CHECK-NEXT: "[[PREFIX]]/Inputs/header.h",
// CHECK-NEXT: "[[PREFIX]]/Inputs/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "header1"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -62,6 +63,7 @@
// CHECK-NEXT: "[[PREFIX]]/Inputs/header.h",
// CHECK-NEXT: "[[PREFIX]]/Inputs/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "header1"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -80,6 +82,7 @@
// CHECK-NEXT: "[[PREFIX]]/Inputs/header2.h",
// CHECK-NEXT: "[[PREFIX]]/Inputs/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// 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 6a9d83c22678b..acc01017d6640 100644
--- a/clang/test/ClangScanDeps/modules-implementation-private.m
+++ b/clang/test/ClangScanDeps/modules-implementation-private.m
@@ -40,6 +40,12 @@
// CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/Modules/module.private.modulemap",
// CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/PrivateHeaders/FW_Private.h"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "isFramework": true,
+// CHECK-NEXT: "link-name": "FW"
+// CHECK-NEXT: }
+// CHECK-NEXT: ],
// 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 20b988d15de32..b3bc90f03f179 100644
--- a/clang/test/ClangScanDeps/modules-implicit-dot-private.m
+++ b/clang/test/ClangScanDeps/modules-implicit-dot-private.m
@@ -35,6 +35,12 @@
// CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/Headers/FW.h",
// CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/Modules/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "isFramework": true,
+// CHECK-NEXT: "link-name": "FW"
+// CHECK-NEXT: }
+// CHECK-NEXT: ],
// CHECK-NEXT: "name": "FW"
// CHECK: },
// CHECK: {
@@ -47,6 +53,12 @@
// CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/Modules/module.private.modulemap",
// CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/PrivateHeaders/FW_Private.h"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "isFramework": true,
+// CHECK-NEXT: "link-name": "FW"
+// CHECK-NEXT: }
+// CHECK-NEXT: ],
// 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 58ac25179a318..2c5d5f547f3e7 100644
--- a/clang/test/ClangScanDeps/modules-incomplete-umbrella.c
+++ b/clang/test/ClangScanDeps/modules-incomplete-umbrella.c
@@ -47,6 +47,12 @@ framework module FW_Private {
// CHECK_TU-NEXT: "[[PREFIX]]/frameworks/FW.framework/Headers/FW.h",
// CHECK_TU-NEXT: "[[PREFIX]]/frameworks/FW.framework/Modules/module.modulemap"
// CHECK_TU-NEXT: ],
+// CHECK_TU-NEXT: "link-libraries": [
+// CHECK_TU-NEXT: {
+// CHECK_TU-NEXT: "isFramework": true,
+// CHECK_TU-NEXT: "link-name": "FW"
+// CHECK_TU-NEXT: }
+// CHECK_TU-NEXT: ],
// CHECK_TU-NEXT: "name": "FW"
// CHECK_TU-NEXT: },
// CHECK_TU-NEXT: {
@@ -60,6 +66,12 @@ framework module FW_Private {
// CHECK_TU-NEXT: "[[PREFIX]]/frameworks/FW.framework/PrivateHeaders/FW_Private.h",
// CHECK_TU-NEXT: "[[PREFIX]]/frameworks/FW.framework/PrivateHeaders/One.h"
// CHECK_TU-NEXT: ],
+// CHECK_TU-NEXT: "link-libraries": [
+// CHECK_TU-NEXT: {
+// CHECK_TU-NEXT: "isFramework": true,
+// CHECK_TU-NEXT: "link-name": "FW"
+// CHECK_TU-NEXT: }
+// CHECK_TU-NEXT: ],
// CHECK_TU-NEXT: "name": "FW_Private"
// CHECK_TU-NEXT: }
// CHECK_TU-NEXT: ],
@@ -125,6 +137,12 @@ module Mod { header "Mod.h" }
// CHECK_MODULE-NEXT: "[[PREFIX]]/frameworks/FW.framework/Headers/FW.h",
// CHECK_MODULE-NEXT: "[[PREFIX]]/frameworks/FW.framework/Modules/module.modulemap"
// CHECK_MODULE-NEXT: ],
+// CHECK_MODULE-NEXT: "link-libraries": [
+// CHECK_MODULE-NEXT: {
+// CHECK_MODULE-NEXT: "isFramework": true,
+// CHECK_MODULE-NEXT: "link-name": "FW"
+// CHECK_MODULE-NEXT: }
+// CHECK_MODULE-NEXT: ],
// CHECK_MODULE-NEXT: "name": "FW"
// CHECK_MODULE-NEXT: },
// CHECK_MODULE-NEXT: {
@@ -138,6 +156,12 @@ module Mod { header "Mod.h" }
// CHECK_MODULE-NEXT: "[[PREFIX]]/frameworks/FW.framework/PrivateHeaders/FW_Private.h",
// CHECK_MODULE-NEXT: "[[PREFIX]]/frameworks/FW.framework/PrivateHeaders/One.h"
// CHECK_MODULE-NEXT: ],
+// CHECK_MODULE-NEXT: "link-libraries": [
+// CHECK_MODULE-NEXT: {
+// CHECK_MODULE-NEXT: "isFramework": true,
+// CHECK_MODULE-NEXT: "link-name": "FW"
+// CHECK_MODULE-NEXT: }
+// CHECK_MODULE-NEXT: ],
// CHECK_MODULE-NEXT: "name": "FW_Private"
// CHECK_MODULE-NEXT: },
// CHECK_MODULE-NEXT: {
@@ -164,6 +188,7 @@ module Mod { header "Mod.h" }
// CHECK_MODULE-NEXT: "[[PREFIX]]/frameworks/FW.framework/PrivateHeaders/Two.h",
// CHECK_MODULE-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK_MODULE-NEXT: ],
+// CHECK_MODULE-NEXT: "link-libraries": [],
// 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 4d18a20949205..b8f17b2208270 100644
--- a/clang/test/ClangScanDeps/modules-inferred.m
+++ b/clang/test/ClangScanDeps/modules-inferred.m
@@ -41,6 +41,12 @@
// CHECK-NEXT: "[[PREFIX]]/frameworks/Inferred.framework/Headers/Inferred.h",
// CHECK-NEXT: "[[PREFIX]]/frameworks/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "isFramework": true,
+// CHECK-NEXT: "link-name": "Inferred"
+// CHECK-NEXT: }
+// CHECK-NEXT: ],
// 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 ae84979710cce..d288095cb0bd7 100644
--- a/clang/test/ClangScanDeps/modules-no-undeclared-includes.c
+++ b/clang/test/ClangScanDeps/modules-no-undeclared-includes.c
@@ -47,6 +47,7 @@ module User [no_undeclared_includes] { header "user.h" }
// CHECK-NEXT: "[[PREFIX]]/undeclared/module.modulemap",
// CHECK-NEXT: "[[PREFIX]]/user.h"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// 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 afa3f8812e9e4..03ebc62c1ab3c 100644
--- a/clang/test/ClangScanDeps/modules-pch-common-submodule.c
+++ b/clang/test/ClangScanDeps/modules-pch-common-submodule.c
@@ -31,6 +31,7 @@
// CHECK-PCH-NEXT: "[[PREFIX]]/mod_common_sub.h",
// CHECK-PCH-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-PCH-NEXT: ],
+// CHECK-PCH-NEXT: "link-libraries": [],
// CHECK-PCH-NEXT: "name": "ModCommon"
// CHECK-PCH-NEXT: }
// CHECK-PCH-NEXT: ],
@@ -78,6 +79,7 @@
// CHECK-TU-NEXT: "[[PREFIX]]/mod_tu.h",
// CHECK-TU-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-TU-NEXT: ],
+// CHECK-TU-NEXT: "link-libraries": [],
// 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 93aa22891d2a2..725ac0e6b224f 100644
--- a/clang/test/ClangScanDeps/modules-pch-common-via-submodule.c
+++ b/clang/test/ClangScanDeps/modules-pch-common-via-submodule.c
@@ -27,6 +27,7 @@
// CHECK-PCH-NEXT: "[[PREFIX]]/mod_common.h",
// CHECK-PCH-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-PCH-NEXT: ],
+// CHECK-PCH-NEXT: "link-libraries": [],
// CHECK-PCH-NEXT: "name": "ModCommon"
// CHECK-PCH-NEXT: }
// CHECK-PCH-NEXT: ],
@@ -75,6 +76,7 @@
// CHECK-TU-NEXT: "[[PREFIX]]/mod_tu_sub.h",
// CHECK-TU-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-TU-NEXT: ],
+// CHECK-TU-NEXT: "link-libraries": [],
// 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 3e8471b810a57..467bfd9af47ae 100644
--- a/clang/test/ClangScanDeps/modules-pch.c
+++ b/clang/test/ClangScanDeps/modules-pch.c
@@ -28,6 +28,7 @@
// CHECK-PCH-NEXT: "[[PREFIX]]/mod_common_1.h",
// CHECK-PCH-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-PCH-NEXT: ],
+// CHECK-PCH-NEXT: "link-libraries": [],
// CHECK-PCH-NEXT: "name": "ModCommon1"
// CHECK-PCH-NEXT: },
// CHECK-PCH-NEXT: {
@@ -40,6 +41,7 @@
// CHECK-PCH-NEXT: "[[PREFIX]]/mod_common_2.h",
// CHECK-PCH-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-PCH-NEXT: ],
+// CHECK-PCH-NEXT: "link-libraries": [],
// CHECK-PCH-NEXT: "name": "ModCommon2"
// CHECK-PCH-NEXT: },
// CHECK-PCH-NEXT: {
@@ -57,6 +59,7 @@
// CHECK-PCH-NEXT: "[[PREFIX]]/mod_pch.h",
// CHECK-PCH-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-PCH-NEXT: ],
+// CHECK-PCH-NEXT: "link-libraries": [],
// CHECK-PCH-NEXT: "name": "ModPCH"
// CHECK-PCH-NEXT: }
// CHECK-PCH-NEXT: ],
@@ -113,6 +116,7 @@
// CHECK-TU-NEXT: "[[PREFIX]]/mod_tu.h",
// CHECK-TU-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-TU-NEXT: ],
+// CHECK-TU-NEXT: "link-libraries": [],
// CHECK-TU-NEXT: "name": "ModTU"
// CHECK-TU-NEXT: }
// CHECK-TU-NEXT: ],
@@ -162,6 +166,7 @@
// CHECK-TU-WITH-COMMON-NEXT: "[[PREFIX]]/mod_tu_with_common.h",
// CHECK-TU-WITH-COMMON-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-TU-WITH-COMMON-NEXT: ],
+// CHECK-TU-WITH-COMMON-NEXT: "link-libraries": [],
// 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 cb82e0c366322..4847fedac3bf6 100644
--- a/clang/test/ClangScanDeps/modules-priv-fw-from-pub.m
+++ b/clang/test/ClangScanDeps/modules-priv-fw-from-pub.m
@@ -45,6 +45,7 @@
// CHECK-NEXT: "[[PREFIX]]/modules/dependency.h",
// CHECK-NEXT: "[[PREFIX]]/modules/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "Dependency"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -63,6 +64,12 @@
// CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/Modules/module.modulemap",
// CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/Modules/module.private.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "isFramework": true,
+// CHECK-NEXT: "link-name": "FW"
+// CHECK-NEXT: }
+// CHECK-NEXT: ],
// CHECK-NEXT: "name": "FW"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -81,6 +88,12 @@
// CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/PrivateHeaders/FW_Private.h",
// CHECK-NEXT: "[[PREFIX]]/modules/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "isFramework": true,
+// CHECK-NEXT: "link-name": "FW"
+// CHECK-NEXT: }
+// CHECK-NEXT: ],
// 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 2125da5d3d887..6954e1ed72f16 100644
--- a/clang/test/ClangScanDeps/modules-redefinition.m
+++ b/clang/test/ClangScanDeps/modules-redefinition.m
@@ -49,6 +49,7 @@
// CHECK-NEXT: [[PREFIX]]/first/module.modulemap",
// CHECK-NEXT: [[PREFIX]]/third/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// 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 bc384b015e6f9..127c0c6b6d2ab 100644
--- a/clang/test/ClangScanDeps/modules-symlink-dir-vfs.c
+++ b/clang/test/ClangScanDeps/modules-symlink-dir-vfs.c
@@ -79,6 +79,12 @@ framework module FW { umbrella header "FW.h" }
// CHECK-NEXT: "[[PREFIX]]/copy/Header.h",
// CHECK-NEXT: "[[PREFIX]]/frameworks-symlink/FW.framework/Modules/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "isFramework": true,
+// CHECK-NEXT: "link-name": "FW"
+// CHECK-NEXT: }
+// CHECK-NEXT: ],
// 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 9ae1554d9811e..5d9bdbc95a7e9 100644
--- a/clang/test/ClangScanDeps/modules-transitive.c
+++ b/clang/test/ClangScanDeps/modules-transitive.c
@@ -52,6 +52,7 @@ module third { header "third.h" }
// CHECK-NEXT: "[[PREFIX]]/first/module.modulemap"
// CHECK-NEXT: "[[PREFIX]]/second/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// 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 b1b351ba56afc..46ae1c84ec7ba 100644
--- a/clang/test/ClangScanDeps/optimize-canonicalize-macros.m
+++ b/clang/test/ClangScanDeps/optimize-canonicalize-macros.m
@@ -24,6 +24,7 @@
// CHECK-NEXT: "context-hash": "{{.*}}",
// CHECK-NEXT: "file-deps": [
// CHECK: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -38,6 +39,7 @@
// CHECK-NEXT: "context-hash": "{{.*}}",
// CHECK-NEXT: "file-deps": [
// CHECK: ],
+// CHECK-NEXT: "link-libraries": [],
// 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 5e9affb30b9c1..84561d3a44a07 100644
--- a/clang/test/ClangScanDeps/optimize-fmodulemap.m
+++ b/clang/test/ClangScanDeps/optimize-fmodulemap.m
@@ -24,6 +24,7 @@
// CHECK-NEXT: "context-hash": "{{.*}}",
// CHECK-NEXT: "file-deps": [
// CHECK: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -35,6 +36,7 @@
// CHECK-NEXT: "context-hash": "{{.*}}",
// CHECK-NEXT: "file-deps": [
// CHECK: ],
+// CHECK-NEXT: "link-libraries": [],
// 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 0c6e544cc5229..710c9c30939c9 100644
--- a/clang/test/ClangScanDeps/optimize-system-warnings.m
+++ b/clang/test/ClangScanDeps/optimize-system-warnings.m
@@ -21,6 +21,7 @@
// CHECK-NEXT: "context-hash": "{{.*}}",
// CHECK-NEXT: "file-deps": [
// CHECK: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -32,6 +33,7 @@
// CHECK-NEXT: "context-hash": "{{.*}}",
// CHECK-NEXT: "file-deps": [
// CHECK: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "B"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -43,6 +45,7 @@
// CHECK-NEXT: "context-hash": "{{.*}}",
// CHECK-NEXT: "file-deps": [
// CHECK: ],
+// CHECK-NEXT: "link-libraries": [],
// 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 beda44cdfecb7..c0ccdbe0a2aea 100644
--- a/clang/test/ClangScanDeps/optimize-vfs-leak.m
+++ b/clang/test/ClangScanDeps/optimize-vfs-leak.m
@@ -29,6 +29,7 @@
// CHECK-NEXT: "context-hash": "{{.*}}",
// CHECK-NEXT: "file-deps": [
// CHECK: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -42,6 +43,7 @@
// CHECK-NEXT: "context-hash": "{{.*}}",
// CHECK-NEXT: "file-deps": [
// CHECK: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "B"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -54,6 +56,7 @@
// CHECK-NEXT: "context-hash": "{{.*}}",
// CHECK-NEXT: "file-deps": [
// CHECK: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "C"
// CHECK-NEXT: }
// CHECK-NEXT: ],
@@ -102,4 +105,4 @@
//--- moduleC/module.modulemap
module C { header "C.h" }
-//--- moduleC/C.h
\ No newline at end of file
+//--- moduleC/C.h
diff --git a/clang/test/ClangScanDeps/optimize-vfs.m b/clang/test/ClangScanDeps/optimize-vfs.m
index 20c97956087d2..05968715358ea 100644
--- a/clang/test/ClangScanDeps/optimize-vfs.m
+++ b/clang/test/ClangScanDeps/optimize-vfs.m
@@ -27,6 +27,7 @@
// CHECK-NEXT: "[[PREFIX]]/build/A.h",
// CHECK-NEXT: "[[PREFIX]]/build/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -40,6 +41,7 @@
// CHECK-NEXT: "[[PREFIX]]/modules/B/B.h",
// CHECK-NEXT: "[[PREFIX]]/modules/B/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "B"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -59,6 +61,7 @@
// CHECK-NEXT: "[[PREFIX]]/modules/C/C.h",
// CHECK-NEXT: "[[PREFIX]]/modules/C/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// 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 3e108f0549450..c1d779dbe0610 100644
--- a/clang/test/ClangScanDeps/removed-args.c
+++ b/clang/test/ClangScanDeps/removed-args.c
@@ -42,6 +42,7 @@
// CHECK-NEXT: "[[PREFIX]]/mod_header.h",
// CHECK-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "ModHeader"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -68,6 +69,7 @@
// CHECK-NEXT: "[[PREFIX]]/mod_tu.h",
// CHECK-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-NEXT: ],
+// CHECK-NEXT: "link-libraries": [],
// 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 a43df2351f67f..a04f8c2486b98 100644
--- a/clang/test/ClangScanDeps/working-dir.m
+++ b/clang/test/ClangScanDeps/working-dir.m
@@ -17,6 +17,7 @@
// CHECK-NEXT: "context-hash": "{{.*}}",
// CHECK-NEXT: "file-deps": [
// CHECK: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -27,6 +28,7 @@
// CHECK-NEXT: "context-hash": "{{.*}}",
// CHECK-NEXT: "file-deps": [
// CHECK: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -38,6 +40,7 @@
// CHECK-NEXT: "context-hash": "{{.*}}",
// CHECK-NEXT: "file-deps": [
// CHECK: ],
+// CHECK-NEXT: "link-libraries": [],
// CHECK-NEXT: "name": "B"
// CHECK-NEXT: },
// CHECK-NEXT: {
@@ -49,6 +52,7 @@
// CHECK-NEXT: "context-hash": "{{.*}}",
// CHECK-NEXT: "file-deps": [
// CHECK: ],
+// CHECK-NEXT: "link-libraries": [],
// 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 036e57c8d213b..a8f6150dd3493 100644
--- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp
+++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
@@ -348,6 +348,20 @@ static llvm::json::Array toJSONSorted(std::vector<ModuleID> V) {
return Ret;
}
+static llvm::json::Array
+toJSONSorted(llvm::SmallVector<Module::LinkLibrary, 2> &LinkLibs) {
+ llvm::sort(LinkLibs, [](const Module::LinkLibrary &lhs,
+ const Module::LinkLibrary &rhs) {
+ return lhs.Library < rhs.Library;
+ });
+
+ llvm::json::Array Ret;
+ for (const Module::LinkLibrary &LL : LinkLibs)
+ Ret.push_back(llvm::json::Object(
+ {{"link-name", LL.Library}, {"isFramework", LL.IsFramework}}));
+ return Ret;
+}
+
// Thread safe.
class FullDeps {
public:
@@ -439,14 +453,13 @@ class FullDeps {
Array OutModules;
for (auto &&ModID : ModuleIDs) {
auto &MD = Modules[ModID];
- Object O{
- {"name", MD.ID.ModuleName},
- {"context-hash", MD.ID.ContextHash},
- {"file-deps", toJSONSorted(MD.FileDeps)},
- {"clang-module-deps", toJSONSorted(MD.ClangModuleDeps)},
- {"clang-modulemap-file", MD.ClangModuleMapFile},
- {"command-line", MD.getBuildArguments()},
- };
+ Object O{{"name", MD.ID.ModuleName},
+ {"context-hash", MD.ID.ContextHash},
+ {"file-deps", toJSONSorted(MD.FileDeps)},
+ {"clang-module-deps", toJSONSorted(MD.ClangModuleDeps)},
+ {"clang-modulemap-file", MD.ClangModuleMapFile},
+ {"command-line", MD.getBuildArguments()},
+ {"link-libraries", toJSONSorted(MD.LinkLibraries)}};
OutModules.push_back(std::move(O));
}
More information about the cfe-commits
mailing list