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