xref: /llvm-project/clang/test/ClangScanDeps/modules-pch-imports.c (revision e06a91c5996b039cacd55e6ead0baf14424c740c)
1 // Check that a module from -fmodule-name= does not accidentally pick up extra
2 // dependencies that come from a PCH.
3 
4 // RUN: rm -rf %t
5 // RUN: split-file %s %t
6 // RUN: sed "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
7 // RUN: sed "s|DIR|%/t|g" %t/cdb_pch.json.template > %t/cdb_pch.json
8 
9 // Scan PCH
10 // RUN: clang-scan-deps -compilation-database %t/cdb_pch.json \
11 // RUN:   -format experimental-full -mode preprocess-dependency-directives \
12 // RUN:   > %t/deps_pch.json
13 
14 // Build PCH
15 // RUN: %deps-to-rsp %t/deps_pch.json --module-name A > %t/A.rsp
16 // RUN: %deps-to-rsp %t/deps_pch.json --module-name B > %t/B.rsp
17 // RUN: %deps-to-rsp %t/deps_pch.json --tu-index 0 > %t/pch.rsp
18 // RUN: %clang @%t/A.rsp
19 // RUN: %clang @%t/B.rsp
20 // RUN: %clang @%t/pch.rsp
21 
22 // Scan TU with PCH
23 // RUN: clang-scan-deps -compilation-database %t/cdb.json \
24 // RUN:   -format experimental-full -mode preprocess-dependency-directives \
25 // RUN:   > %t/deps.json
26 
27 // RUN: cat %t/deps.json | sed 's:\\\\\?:/:g' | FileCheck %s -DPREFIX=%/t
28 
29 // Verify that the only modular import in C is E and not the unrelated modules
30 // A or B that come from the PCH.
31 
32 // CHECK:      {
33 // CHECK-NEXT:  "modules": [
34 // CHECK-NEXT:     {
35 // CHECK:            "clang-module-deps": [
36 // CHECK-NEXT:         {
37 // CHECK:                "module-name": "E"
38 // CHECK:              }
39 // CHECK-NEXT:       ]
40 // CHECK:            "clang-modulemap-file": "[[PREFIX]]/module.modulemap"
41 // CHECK:            "command-line": [
42 // CHECK-NOT:          "-fmodule-file=
43 // CHECK:              "-fmodule-file={{(E=)?}}[[PREFIX]]/{{.*}}/E-{{.*}}.pcm"
44 // CHECK-NOT:          "-fmodule-file=
45 // CHECK:            ]
46 // CHECK:            "name": "C"
47 // CHECK:          }
48 
49 
50 //--- cdb_pch.json.template
51 [{
52   "file": "DIR/prefix.h",
53   "directory": "DIR",
54   "command": "clang -x c-header DIR/prefix.h -o DIR/prefix.h.pch -fmodules -fimplicit-modules -fimplicit-module-maps -fmodules-cache-path=DIR/module-cache"
55 }]
56 
57 //--- cdb.json.template
58 [{
59   "file": "DIR/tu.c",
60   "directory": "DIR",
61   "command": "clang -fsyntax-only DIR/tu.c -include DIR/prefix.h -fmodule-name=C -fmodules -fimplicit-modules -fimplicit-module-maps -fmodules-cache-path=DIR/module-cache"
62 }]
63 
64 //--- module.modulemap
65 module A { header "A.h" export * }
66 module B { header "B.h" export * }
67 module C { header "C.h" export * }
68 module D { header "D.h" export * }
69 module E { header "E.h" export * }
70 
71 //--- A.h
72 #pragma once
73 struct A { int x; };
74 
75 //--- B.h
76 #pragma once
77 #include "A.h"
78 struct B { struct A a; };
79 
80 //--- C.h
81 #pragma once
82 #include "E.h"
83 struct C { struct E e; };
84 
85 //--- D.h
86 #pragma once
87 #include "C.h"
88 struct D { struct C c; };
89 
90 //--- E.h
91 #pragma once
92 struct E { int y; };
93 
94 //--- prefix.h
95 #include "B.h"
96 
97 //--- tu.c
98 // C.h is first included textually due to -fmodule-name=C.
99 #include "C.h"
100 // importing D pulls in a modular import of C; it's this build of C that we
101 // are verifying above
102 #include "D.h"
103 
tu(void)104 void tu(void) {
105   struct A a;
106   struct B b;
107   struct C c;
108 }
109