1 // This test checks that pruning of header search paths produces consistent dependency graphs.
3 // When pruning header search paths for a module, we can't remove any paths its dependencies use.
4 // Otherwise, we could get either of the following dependency graphs depending on the search path
5 // configuration of the particular TU that first discovered the module:
6 // X:<hash1> -> Y:<hash2>
7 // X:<hash1> -> Y:<hash3>
8 // We can't have the same version of module X depend on multiple different versions of Y based on
9 // the TU configuration.
11 // Keeping all header search paths (transitive) dependencies use will ensure we get consistent
13 // X:<hash1> -> Y:<hash2>
14 // X:<hash4> -> Y:<hash3>
16 // RUN: rm -rf %t && mkdir %t
17 // RUN: split-file %s %t
25 #if __has_include("a.h")
33 //--- module.modulemap
34 module Y
{ header
"Y.h" }
35 module X
{ header
"X.h" }
40 //--- cdb_with_a.json.template
44 "command": "clang -fsyntax-only test.c -fmodules -fimplicit-modules -fmodules-cache-path=DIR/module-cache -fimplicit-module-maps -Ibegin -Ia -Ib -Iend"
47 //--- cdb_without_a.json.template
51 "command": "clang -fsyntax-only test.c -fmodules -fimplicit-modules -fmodules-cache-path=DIR/module-cache -fimplicit-module-maps -Ibegin -Ib -Iend"
54 // RUN: sed -e "s|DIR|%/t|g" %t/cdb_with_a.json.template > %t/cdb_with_a.json
55 // RUN: sed -e "s|DIR|%/t|g" %t/cdb_without_a.json.template > %t/cdb_without_a.json
57 // RUN: clang-scan-deps -compilation-database %t/cdb_with_a.json -format experimental-full -optimize-args=header-search > %t/results.json
58 // RUN: clang-scan-deps -compilation-database %t/cdb_without_a.json -format experimental-full -optimize-args=header-search >> %t/results.json
59 // RUN: cat %t/results.json | sed 's:\\\\\?:/:g' | FileCheck %s -DPREFIX=%/t
62 // CHECK-NEXT: "modules": [
64 // CHECK-NEXT: "clang-module-deps": [
66 // CHECK-NEXT: "context-hash": "[[HASH_Y_WITH_A:.*]]",
67 // CHECK-NEXT: "module-name": "Y"
70 // CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap",
71 // CHECK-NEXT: "command-line": [
73 // CHECK-NEXT: "context-hash": "[[HASH_X:.*]]",
74 // CHECK-NEXT: "file-deps": [
75 // CHECK-NEXT: "[[PREFIX]]/module.modulemap",
76 // CHECK-NEXT: "[[PREFIX]]/X.h"
78 // CHECK-NEXT: "link-libraries": [],
79 // CHECK-NEXT: "name": "X"
82 // CHECK-NEXT: "clang-module-deps": [],
83 // CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap",
84 // CHECK-NEXT: "command-line": [
86 // CHECK-NEXT: "context-hash": "[[HASH_Y_WITH_A]]",
87 // CHECK-NEXT: "file-deps": [
88 // CHECK-NEXT: "[[PREFIX]]/module.modulemap",
89 // CHECK-NEXT: "[[PREFIX]]/Y.h",
90 // CHECK-NEXT: "[[PREFIX]]/begin/begin.h",
91 // CHECK-NEXT: "[[PREFIX]]/a/a.h",
92 // CHECK-NEXT: "[[PREFIX]]/end/end.h"
94 // CHECK-NEXT: "link-libraries": [],
95 // CHECK-NEXT: "name": "Y"
98 // CHECK-NEXT: "translation-units": [
100 // CHECK: "clang-context-hash": "{{.*}}",
101 // CHECK-NEXT: "clang-module-deps": [
103 // CHECK-NEXT: "context-hash": "[[HASH_X]]",
104 // CHECK-NEXT: "module-name": "X"
107 // CHECK-NEXT: "command-line": [
109 // CHECK: "file-deps": [
110 // CHECK-NEXT: "[[PREFIX]]/test.c"
112 // CHECK-NEXT: "input-file": "[[PREFIX]]/test.c"
116 // CHECK-NEXT: "modules": [
118 // CHECK-NEXT: "clang-module-deps": [
120 // CHECK-NEXT: "context-hash": "[[HASH_Y_WITHOUT_A:.*]]",
121 // CHECK-NEXT: "module-name": "Y"
124 // CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap",
125 // CHECK-NEXT: "command-line": [
127 // Here is the actual check that this module X (which imports different version of Y)
128 // also has a different context hash from the first version of module X.
129 // CHECK-NOT: "context-hash": "[[HASH_X]]",
130 // CHECK: "file-deps": [
131 // CHECK-NEXT: "[[PREFIX]]/module.modulemap",
132 // CHECK-NEXT: "[[PREFIX]]/X.h"
134 // CHECK-NEXT: "link-libraries": [],
135 // CHECK-NEXT: "name": "X"
138 // CHECK-NEXT: "clang-module-deps": [],
139 // CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap",
140 // CHECK-NEXT: "command-line": [
142 // CHECK-NEXT: "context-hash": "[[HASH_Y_WITHOUT_A]]",
143 // CHECK-NEXT: "file-deps": [
144 // CHECK-NEXT: "[[PREFIX]]/module.modulemap",
145 // CHECK-NEXT: "[[PREFIX]]/Y.h",
146 // CHECK-NEXT: "[[PREFIX]]/begin/begin.h",
147 // CHECK-NEXT: "[[PREFIX]]/end/end.h"
149 // CHECK-NEXT: "link-libraries": [],
150 // CHECK-NEXT: "name": "Y"
153 // CHECK-NEXT: "translation-units": [
155 // CHECK: "clang-context-hash": "{{.*}}",
156 // CHECK-NEXT: "clang-module-deps": [
158 // CHECK-NEXT: "context-hash": "{{.*}}",
159 // CHECK-NEXT: "module-name": "X"
162 // CHECK-NEXT: "command-line": [
164 // CHECK: "file-deps": [
165 // CHECK-NEXT: "[[PREFIX]]/test.c"
167 // CHECK-NEXT: "input-file": "[[PREFIX]]/test.c"