xref: /llvm-project/clang/test/ClangScanDeps/optimize-vfs-pch.m (revision de3b2c293b8bf336f8e1380148cf16b54a794c0c)
1// Check that tracking of VFSs works with PCH.
2
3// RUN: rm -rf %t
4// RUN: split-file %s %t
5// RUN: sed -e "s|DIR|%/t|g" %t/build/compile-commands-pch.json.in > %t/build/compile-commands-pch.json
6// RUN: sed -e "s|DIR|%/t|g" %t/build/compile-commands-tu.json.in > %t/build/compile-commands-tu.json
7// RUN: sed -e "s|DIR|%/t|g" %t/build/compile-commands-tu-no-vfs-error.json.in > %t/build/compile-commands-tu-no-vfs-error.json
8// RUN: sed -e "s|DIR|%/t|g" %t/build/compile-commands-tu1.json.in > %t/build/compile-commands-tu1.json
9// RUN: sed -e "s|DIR|%/t|g" %t/build/pch-overlay.yaml.in > %t/build/pch-overlay.yaml
10
11// RUN: clang-scan-deps -compilation-database %t/build/compile-commands-pch.json \
12// RUN:   -j 1 -format experimental-full --optimize-args=vfs,header-search > %t/pch-deps.db
13// RUN: %deps-to-rsp %t/pch-deps.db --module-name=A > %t/A.rsp
14// RUN: %deps-to-rsp %t/pch-deps.db --module-name=B > %t/B.rsp
15// RUN: %deps-to-rsp %t/pch-deps.db --tu-index=0 > %t/pch.rsp
16// RUN: %clang @%t/A.rsp
17// RUN: %clang @%t/B.rsp
18// RUN: %clang @%t/pch.rsp
19
20// RUN: clang-scan-deps -compilation-database %t/build/compile-commands-tu.json \
21// RUN:   -j 1 -format experimental-full --optimize-args=vfs,header-search > %t/tu-deps.db
22// RUN: %deps-to-rsp %t/tu-deps.db --module-name=C > %t/C.rsp
23// RUN: %deps-to-rsp %t/tu-deps.db --tu-index=0 > %t/tu.rsp
24// RUN: %clang @%t/C.rsp
25// RUN: %clang @%t/tu.rsp
26
27// RUN: not clang-scan-deps -compilation-database %t/build/compile-commands-tu-no-vfs-error.json \
28// RUN:   -j 1 -format experimental-full --optimize-args=vfs,header-search 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
29
30// CHECK-ERROR: error: PCH was compiled with different VFS overlay files than are currently in use
31// CHECK-ERROR: note: current translation unit has no VFS overlays
32
33// Next test is to verify that a module that doesn't use the VFS, that depends
34// on the PCH's A, which does use the VFS, still records that it needs the VFS.
35// This avoids a fatal error when emitting diagnostics.
36
37// RUN: clang-scan-deps -compilation-database %t/build/compile-commands-tu1.json \
38// RUN:   -j 1 -format experimental-full --optimize-args=vfs,header-search > %t/tu1-deps.db
39// RUN: %deps-to-rsp %t/tu1-deps.db --tu-index=0 > %t/tu1.rsp
40// Reuse existing B
41// RUN: %deps-to-rsp %t/tu1-deps.db --module-name=E > %t/E.rsp
42// RUN: %deps-to-rsp %t/tu1-deps.db --module-name=D > %t/D.rsp
43// The build of D depends on B which depend on the prebuilt A. D will only build
44// if it has A's VFS, as it needs to emit a diagnostic showing the content of A.
45// RUN: %clang @%t/E.rsp
46// RUN: %clang @%t/D.rsp -verify
47// RUN: %clang @%t/tu1.rsp
48// RUN: cat %t/tu1-deps.db | sed 's:\\\\\?:/:g' | FileCheck %s -DPREFIX=%/t
49
50// Check that D has the overlay, but E doesn't.
51// CHECK:      {
52// CHECK-NEXT:   "modules": [
53// CHECK-NEXT:     {
54// CHECK-NEXT:       "clang-module-deps": [
55// CHECK-NEXT:         {
56// CHECK-NEXT:           "context-hash": "{{.*}}",
57// CHECK-NEXT:           "module-name": "E"
58// CHECK-NEXT:         }
59// CHECK-NEXT:       ],
60// CHECK-NEXT:       "clang-modulemap-file": "[[PREFIX]]/modules/D/module.modulemap",
61// CHECK-NEXT:       "command-line": [
62// CHECK:              "-ivfsoverlay"
63// CHECK-NEXT:         "[[PREFIX]]/build/pch-overlay.yaml"
64// CHECK:            ],
65// CHECK-NEXT:       "context-hash": "{{.*}}",
66// CHECK-NEXT:       "file-deps": [
67// CHECK-NEXT:         "{{.*}}"
68// CHECK-NEXT:         "{{.*}}"
69// CHECK-NEXT:         "{{.*}}"
70// CHECK-NEXT:         "{{.*}}"
71// CHECK-NEXT:       ],
72// CHECK:            "name": "D"
73// CHECK-NEXT:     },
74// CHECK-NEXT:     {
75// CHECK-NEXT:       "clang-module-deps": [],
76// CHECK-NEXT:       "clang-modulemap-file": "[[PREFIX]]/modules/E/module.modulemap",
77// CHECK-NEXT:       "command-line": [
78// CHECK-NOT:          "-ivfsoverlay"
79// CHECK:            ],
80// CHECK-NEXT:       "context-hash": "{{.*}}",
81// CHECK-NEXT:       "file-deps": [
82// CHECK-NEXT:         "{{.*}}"
83// CHECK-NEXT:         "{{.*}}"
84// CHECK-NEXT:       ],
85// CHECK:            "name": "E"
86// CHECK-NEXT:     }
87
88//--- build/compile-commands-pch.json.in
89
90[
91{
92  "directory": "DIR",
93  "command": "clang -x objective-c-header DIR/pch.h -I DIR/modules/A -I DIR/modules/B -fmodules -fimplicit-module-maps -fmodules-cache-path=DIR/cache -o DIR/pch.h.pch -ivfsoverlay DIR/build/pch-overlay.yaml",
94  "file": "DIR/pch.h"
95}
96]
97
98//--- build/compile-commands-tu.json.in
99
100[
101{
102  "directory": "DIR",
103  "command": "clang -fsyntax-only DIR/tu.m -I DIR/modules/A -I DIR/modules/B -I DIR/modules/C -fmodules -fimplicit-module-maps -fmodules-cache-path=DIR/cache -include DIR/pch.h -o DIR/tu.o -ivfsoverlay DIR/build/pch-overlay.yaml",
104  "file": "DIR/tu.m"
105}
106]
107
108//--- build/compile-commands-tu-no-vfs-error.json.in
109
110[
111{
112  "directory": "DIR",
113  "command": "clang -Wpch-vfs-diff -Werror=pch-vfs-diff -fsyntax-only DIR/tu.m -I DIR/modules/A -I DIR/modules/B -I DIR/modules/C -fmodules -fimplicit-module-maps -fmodules-cache-path=DIR/cache -include DIR/pch.h -o DIR/tu.o",
114  "file": "DIR/tu.m"
115}
116]
117
118//--- build/compile-commands-tu1.json.in
119
120[
121{
122  "directory": "DIR",
123  "command": "clang -fsyntax-only DIR/tu1.m -I DIR/modules/B -I DIR/modules/D -I DIR/modules/E -fmodules -fimplicit-module-maps -fmodules-cache-path=DIR/cache -include DIR/pch.h -o DIR/tu1.o -ivfsoverlay DIR/build/pch-overlay.yaml",
124  "file": "DIR/tu1.m"
125}
126]
127
128//--- build/pch-overlay.yaml.in
129
130{
131   "version":0,
132   "case-sensitive":"false",
133   "roots":[
134      {
135         "contents":[
136         {
137            "external-contents":"DIR/build/module.modulemap",
138            "name":"module.modulemap",
139            "type":"file"
140         },
141         {
142            "external-contents":"DIR/build/A.h",
143            "name":"A.h",
144            "type":"file"
145         }
146         ],
147         "name":"DIR/modules/A",
148         "type":"directory"
149      }
150   ]
151}
152
153//--- pch.h
154#include <B.h>
155
156//--- build/module.modulemap
157
158module A {
159  umbrella header "A.h"
160}
161
162//--- build/A.h
163
164typedef int A_t __attribute__((deprecated("yep, it's depr")));
165
166//--- modules/B/module.modulemap
167
168module B {
169  umbrella header "B.h"
170  export *
171}
172
173//--- modules/B/B.h
174#include <A.h>
175
176typedef int B_t;
177
178//--- modules/C/module.modulemap
179
180module C {
181  umbrella header "C.h"
182}
183
184//--- modules/C/C.h
185#include <B.h>
186
187typedef int C_t;
188
189//--- tu.m
190
191#include <C.h>
192
193A_t a = 0;
194B_t b = 0;
195C_t c = 0;
196
197//--- modules/D/module.modulemap
198
199module D {
200  umbrella header "D.h"
201  export *
202}
203
204//--- modules/D/D.h
205#include <B.h>
206#include <E.h>
207
208typedef A_t D_t; // expected-warning{{'A_t' is deprecated}}
209// expected-note@*:* {{marked deprecated here}}
210
211//--- modules/E/module.modulemap
212
213module E {
214  umbrella header "E.h"
215}
216
217//--- modules/E/E.h
218typedef int E_t;
219
220//--- tu1.m
221
222#include <D.h>
223
224D_t d = 0;
225E_t e = 0;
226