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