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 > %t/results.json
58 // RUN: clang-scan-deps -compilation-database %t/cdb_without_a.json -format experimental-full -optimize-args >> %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]]/./X.h",
76 // CHECK-NEXT: "[[PREFIX]]/./module.modulemap"
78 // CHECK-NEXT: "name": "X"
81 // CHECK-NEXT: "clang-module-deps": [],
82 // CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap",
83 // CHECK-NEXT: "command-line": [
85 // CHECK-NEXT: "context-hash": "[[HASH_Y_WITH_A]]",
86 // CHECK-NEXT: "file-deps": [
87 // CHECK-NEXT: "[[PREFIX]]/./Y.h",
88 // CHECK-NEXT: "[[PREFIX]]/./a/a.h",
89 // CHECK-NEXT: "[[PREFIX]]/./begin/begin.h",
90 // CHECK-NEXT: "[[PREFIX]]/./end/end.h",
91 // CHECK-NEXT: "[[PREFIX]]/./module.modulemap"
93 // CHECK-NEXT: "name": "Y"
96 // CHECK-NEXT: "translation-units": [
98 // CHECK: "clang-context-hash": "{{.*}}",
99 // CHECK-NEXT: "clang-module-deps": [
101 // CHECK-NEXT: "context-hash": "[[HASH_X]]",
102 // CHECK-NEXT: "module-name": "X"
105 // CHECK-NEXT: "command-line": [
107 // CHECK: "file-deps": [
108 // CHECK-NEXT: "[[PREFIX]]/test.c"
110 // CHECK-NEXT: "input-file": "[[PREFIX]]/test.c"
114 // CHECK-NEXT: "modules": [
116 // CHECK-NEXT: "clang-module-deps": [
118 // CHECK-NEXT: "context-hash": "[[HASH_Y_WITHOUT_A:.*]]",
119 // CHECK-NEXT: "module-name": "Y"
122 // CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap",
123 // CHECK-NEXT: "command-line": [
125 // Here is the actual check that this module X (which imports different version of Y)
126 // also has a different context hash from the first version of module X.
127 // CHECK-NOT: "context-hash": "[[HASH_X]]",
128 // CHECK: "file-deps": [
129 // CHECK-NEXT: "[[PREFIX]]/./X.h",
130 // CHECK-NEXT: "[[PREFIX]]/./module.modulemap"
132 // CHECK-NEXT: "name": "X"
135 // CHECK-NEXT: "clang-module-deps": [],
136 // CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap",
137 // CHECK-NEXT: "command-line": [
139 // CHECK-NEXT: "context-hash": "[[HASH_Y_WITHOUT_A]]",
140 // CHECK-NEXT: "file-deps": [
141 // CHECK-NEXT: "[[PREFIX]]/./Y.h",
142 // CHECK-NEXT: "[[PREFIX]]/./begin/begin.h",
143 // CHECK-NEXT: "[[PREFIX]]/./end/end.h",
144 // CHECK-NEXT: "[[PREFIX]]/./module.modulemap"
146 // CHECK-NEXT: "name": "Y"
149 // CHECK-NEXT: "translation-units": [
151 // CHECK: "clang-context-hash": "{{.*}}",
152 // CHECK-NEXT: "clang-module-deps": [
154 // CHECK-NEXT: "context-hash": "{{.*}}",
155 // CHECK-NEXT: "module-name": "X"
158 // CHECK-NEXT: "command-line": [
160 // CHECK: "file-deps": [
161 // CHECK-NEXT: "[[PREFIX]]/test.c"
163 // CHECK-NEXT: "input-file": "[[PREFIX]]/test.c"