1// UNSUPPORTED: target={{.*}}-aix{{.*}} 2// 3// The slash direction in linux and windows are different. 4// UNSUPPORTED: system-windows 5// 6// RUN: rm -fr %t 7// RUN: mkdir -p %t 8// RUN: split-file %s %t 9// 10// RUN: sed "s|DIR|%/t|g" %t/P1689.json.in > %t/P1689.json 11// RUN: clang-scan-deps -compilation-database %t/P1689.json -format=p1689 | FileCheck %t/Checks.cpp -DPREFIX=%/t 12// RUN: clang-scan-deps --mode=preprocess-dependency-directives -compilation-database %t/P1689.json -format=p1689 | FileCheck %t/Checks.cpp -DPREFIX=%/t 13// 14// Check the separated dependency format. This is required by CMake for the case 15// that we have non-exist files in a fresh build and potentially out-of-date after that. 16// So the build system need to wrtie a compilation database just for scanning purposes, 17// which is not so good. So here is the per file mode for P1689. 18// RUN: clang-scan-deps -format=p1689 \ 19// RUN: -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/M.cppm -o %t/M.o \ 20// RUN: | FileCheck %t/M.cppm -DPREFIX=%/t 21// RUN: clang-scan-deps -format=p1689 \ 22// RUN: -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/Impl.cpp -o %t/Impl.o \ 23// RUN: | FileCheck %t/Impl.cpp -DPREFIX=%/t 24// RUN: clang-scan-deps -format=p1689 \ 25// RUN: -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/impl_part.cppm -o %t/impl_part.o \ 26// RUN: | FileCheck %t/impl_part.cppm -DPREFIX=%/t 27// RUN: clang-scan-deps -format=p1689 \ 28// RUN: -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/interface_part.cppm -o %t/interface_part.o \ 29// RUN: | FileCheck %t/interface_part.cppm -DPREFIX=%/t 30// RUN: clang-scan-deps -format=p1689 \ 31// RUN: -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/User.cpp -o %t/User.o \ 32// RUN: | FileCheck %t/User.cpp -DPREFIX=%/t 33// 34// Check we can generate the make-style dependencies as expected. 35// RUN: clang-scan-deps -format=p1689 \ 36// RUN: -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/impl_part.cppm -o %t/impl_part.o \ 37// RUN: -MT %t/impl_part.o.ddi -MD -MF %t/impl_part.dep 38// RUN: cat %t/impl_part.dep | FileCheck %t/impl_part.cppm -DPREFIX=%/t --check-prefix=CHECK-MAKE 39// 40// Check that we can generate multiple make-style dependency information with compilation database. 41// RUN: cat %t/P1689.dep | FileCheck %t/Checks.cpp -DPREFIX=%/t --check-prefix=CHECK-MAKE 42// 43// Check that we can mix the use of -format=p1689 and -fmodules. 44// RUN: clang-scan-deps -format=p1689 \ 45// RUN: -- %clang++ -std=c++20 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -c %t/impl_part.cppm -o %t/impl_part.o \ 46// RUN: | FileCheck %t/impl_part.cppm -DPREFIX=%/t 47// 48// Check the path in the make style dependencies are generated in relative path form 49// RUN: cd %t 50// RUN: clang-scan-deps -format=p1689 \ 51// RUN: -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t impl_part.cppm -o impl_part.o \ 52// RUN: -MT impl_part.o.ddi -MD -MF impl_part.dep 53// RUN: cat impl_part.dep | FileCheck impl_part.cppm -DPREFIX=%/t --check-prefix=CHECK-MAKE-RELATIVE 54 55 56//--- P1689.json.in 57[ 58{ 59 "directory": "DIR", 60 "command": "clang++ -std=c++20 DIR/M.cppm -c -o DIR/M.o -MT DIR/M.o.ddi -MD -MF DIR/P1689.dep", 61 "file": "DIR/M.cppm", 62 "output": "DIR/M.o" 63}, 64{ 65 "directory": "DIR", 66 "command": "clang++ -std=c++20 DIR/Impl.cpp -c -o DIR/Impl.o -MT DIR/Impl.o.ddi -MD -MF DIR/P1689.dep", 67 "file": "DIR/Impl.cpp", 68 "output": "DIR/Impl.o" 69}, 70{ 71 "directory": "DIR", 72 "command": "clang++ -std=c++20 DIR/impl_part.cppm -c -o DIR/impl_part.o -MT DIR/impl_part.o.ddi -MD -MF DIR/P1689.dep", 73 "file": "DIR/impl_part.cppm", 74 "output": "DIR/impl_part.o" 75}, 76{ 77 "directory": "DIR", 78 "command": "clang++ -std=c++20 DIR/interface_part.cppm -c -o DIR/interface_part.o -MT DIR/interface_part.o.ddi -MD -MF DIR/P1689.dep", 79 "file": "DIR/interface_part.cppm", 80 "output": "DIR/interface_part.o" 81}, 82{ 83 "directory": "DIR", 84 "command": "clang++ -std=c++20 DIR/User.cpp -c -o DIR/User.o -MT DIR/User.o.ddi -MD -MF DIR/P1689.dep", 85 "file": "DIR/User.cpp", 86 "output": "DIR/User.o" 87} 88] 89 90//--- M.cppm 91export module M; 92export import :interface_part; 93import :impl_part; 94export void Hello(); 95 96// CHECK: { 97// CHECK-NEXT: "revision": 0, 98// CHECK-NEXT: "rules": [ 99// CHECK-NEXT: { 100// CHECK-NEXT: "primary-output": "[[PREFIX]]/M.o", 101// CHECK-NEXT: "provides": [ 102// CHECK-NEXT: { 103// CHECK-NEXT: "is-interface": true, 104// CHECK-NEXT: "logical-name": "M", 105// CHECK-NEXT: "source-path": "[[PREFIX]]/M.cppm" 106// CHECK-NEXT: } 107// CHECK-NEXT: ], 108// CHECK-NEXT: "requires": [ 109// CHECK-NEXT: { 110// CHECK-NEXT: "logical-name": "M:interface_part" 111// CHECK-NEXT: }, 112// CHECK-NEXT: { 113// CHECK-NEXT: "logical-name": "M:impl_part" 114// CHECK-NEXT: } 115// CHECK-NEXT: ] 116// CHECK-NEXT: } 117// CHECK-NEXT: ], 118// CHECK-NEXT: "version": 1 119// CHECK-NEXT: } 120 121//--- Impl.cpp 122module; 123#include "header.mock" 124module M; 125void Hello() { 126 std::cout << "Hello "; 127} 128 129// CHECK: { 130// CHECK-NEXT: "revision": 0, 131// CHECK-NEXT: "rules": [ 132// CHECK-NEXT: { 133// CHECK-NEXT: "primary-output": "[[PREFIX]]/Impl.o", 134// CHECK-NEXT: "requires": [ 135// CHECK-NEXT: { 136// CHECK-NEXT: "logical-name": "M" 137// CHECK-NEXT: } 138// CHECK-NEXT: ] 139// CHECK-NEXT: } 140// CHECK-NEXT: ], 141// CHECK-NEXT: "version": 1 142// CHECK-NEXT: } 143 144//--- impl_part.cppm 145module; 146#include "header.mock" 147module M:impl_part; 148import :interface_part; 149 150std::string W = "World."; 151void World() { 152 std::cout << W << std::endl; 153} 154 155// CHECK: { 156// CHECK-NEXT: "revision": 0, 157// CHECK-NEXT: "rules": [ 158// CHECK-NEXT: { 159// CHECK-NEXT: "primary-output": "[[PREFIX]]/impl_part.o", 160// CHECK-NEXT: "provides": [ 161// CHECK-NEXT: { 162// CHECK-NEXT: "is-interface": false, 163// CHECK-NEXT: "logical-name": "M:impl_part", 164// CHECK-NEXT: "source-path": "[[PREFIX]]/impl_part.cppm" 165// CHECK-NEXT: } 166// CHECK-NEXT: ], 167// CHECK-NEXT: "requires": [ 168// CHECK-NEXT: { 169// CHECK-NEXT: "logical-name": "M:interface_part" 170// CHECK-NEXT: } 171// CHECK-NEXT: ] 172// CHECK-NEXT: } 173// CHECK-NEXT: ], 174// CHECK-NEXT: "version": 1 175// CHECK-NEXT: } 176 177// CHECK-MAKE: [[PREFIX]]/impl_part.o.ddi: 178// CHECK-MAKE: [[PREFIX]]/impl_part.cppm 179// CHECK-MAKE: [[PREFIX]]/header.mock 180 181// CHECK-MAKE-RELATIVE: impl_part.o.ddi: impl_part.cppm header.mock 182 183//--- interface_part.cppm 184export module M:interface_part; 185export void World(); 186 187// CHECK: { 188// CHECK-NEXT: "revision": 0, 189// CHECK-NEXT: "rules": [ 190// CHECK-NEXT: { 191// CHECK-NEXT: "primary-output": "[[PREFIX]]/interface_part.o", 192// CHECK-NEXT: "provides": [ 193// CHECK-NEXT: { 194// CHECK-NEXT: "is-interface": true, 195// CHECK-NEXT: "logical-name": "M:interface_part", 196// CHECK-NEXT: "source-path": "[[PREFIX]]/interface_part.cppm" 197// CHECK-NEXT: } 198// CHECK-NEXT: ] 199// CHECK-NEXT: } 200// CHECK-NEXT: ], 201// CHECK-NEXT: "version": 1 202// CHECK-NEXT: } 203 204//--- User.cpp 205import M; 206import third_party_module; 207int main() { 208 Hello(); 209 World(); 210 return 0; 211} 212 213// CHECK: { 214// CHECK-NEXT: "revision": 0, 215// CHECK-NEXT: "rules": [ 216// CHECK-NEXT: { 217// CHECK-NEXT: "primary-output": "[[PREFIX]]/User.o", 218// CHECK-NEXT: "requires": [ 219// CHECK-NEXT: { 220// CHECK-NEXT: "logical-name": "M" 221// CHECK-NEXT: }, 222// CHECK-NEXT: { 223// CHECK-NEXT: "logical-name": "third_party_module" 224// CHECK-NEXT: } 225// CHECK-NEXT: ] 226// CHECK-NEXT: } 227// CHECK-NEXT: ], 228// CHECK-NEXT: "version": 1 229// CHECK-NEXT: } 230 231//--- Checks.cpp 232// CHECK: { 233// CHECK-NEXT: "revision": 0, 234// CHECK-NEXT: "rules": [ 235// CHECK-NEXT: { 236// CHECK-NEXT: "primary-output": "[[PREFIX]]/Impl.o", 237// CHECK-NEXT: "requires": [ 238// CHECK-NEXT: { 239// CHECK-NEXT: "logical-name": "M", 240// CHECK-NEXT: "source-path": "[[PREFIX]]/M.cppm" 241// CHECK-NEXT: } 242// CHECK-NEXT: ] 243// CHECK-NEXT: }, 244// CHECK-NEXT: { 245// CHECK-NEXT: "primary-output": "[[PREFIX]]/M.o", 246// CHECK-NEXT: "provides": [ 247// CHECK-NEXT: { 248// CHECK-NEXT: "is-interface": true, 249// CHECK-NEXT: "logical-name": "M", 250// CHECK-NEXT: "source-path": "[[PREFIX]]/M.cppm" 251// CHECK-NEXT: } 252// CHECK-NEXT: ], 253// CHECK-NEXT: "requires": [ 254// CHECK-NEXT: { 255// CHECK-NEXT: "logical-name": "M:interface_part", 256// CHECK-NEXT: "source-path": "[[PREFIX]]/interface_part.cppm" 257// CHECK-NEXT: }, 258// CHECK-NEXT: { 259// CHECK-NEXT: "logical-name": "M:impl_part", 260// CHECK-NEXT: "source-path": "[[PREFIX]]/impl_part.cppm" 261// CHECK-NEXT: } 262// CHECK-NEXT: ] 263// CHECK-NEXT: }, 264// CHECK-NEXT: { 265// CHECK-NEXT: "primary-output": "[[PREFIX]]/User.o", 266// CHECK-NEXT: "requires": [ 267// CHECK-NEXT: { 268// CHECK-NEXT: "logical-name": "M", 269// CHECK-NEXT: "source-path": "[[PREFIX]]/M.cppm" 270// CHECK-NEXT: }, 271// CHECK-NEXT: { 272// CHECK-NEXT: "logical-name": "third_party_module" 273// CHECK-NEXT: } 274// CHECK-NEXT: ] 275// CHECK-NEXT: }, 276// CHECK-NEXT: { 277// CHECK-NEXT: "primary-output": "[[PREFIX]]/impl_part.o", 278// CHECK-NEXT: "provides": [ 279// CHECK-NEXT: { 280// CHECK-NEXT: "is-interface": false, 281// CHECK-NEXT: "logical-name": "M:impl_part", 282// CHECK-NEXT: "source-path": "[[PREFIX]]/impl_part.cppm" 283// CHECK-NEXT: } 284// CHECK-NEXT: ], 285// CHECK-NEXT: "requires": [ 286// CHECK-NEXT: { 287// CHECK-NEXT: "logical-name": "M:interface_part", 288// CHECK-NEXT: "source-path": "[[PREFIX]]/interface_part.cppm" 289// CHECK-NEXT: } 290// CHECK-NEXT: ] 291// CHECK-NEXT: }, 292// CHECK-NEXT: { 293// CHECK-NEXT: "primary-output": "[[PREFIX]]/interface_part.o", 294// CHECK-NEXT: "provides": [ 295// CHECK-NEXT: { 296// CHECK-NEXT: "is-interface": true, 297// CHECK-NEXT: "logical-name": "M:interface_part", 298// CHECK-NEXT: "source-path": "[[PREFIX]]/interface_part.cppm" 299// CHECK-NEXT: } 300// CHECK-NEXT: ] 301// CHECK-NEXT: } 302// CHECK-NEXT: ], 303// CHECK-NEXT: "version": 1 304// CHECK-NEXT: } 305 306// CHECK-MAKE-DAG: [[PREFIX]]/impl_part.o.ddi: \ 307// CHECK-MAKE-DAG-NEXT: [[PREFIX]]/impl_part.cppm \ 308// CHECK-MAKE-DAG-NEXT: [[PREFIX]]/header.mock 309// CHECK-MAKE-DAG: [[PREFIX]]/interface_part.o.ddi: \ 310// CHECK-MAKE-DAG-NEXT: [[PREFIX]]/interface_part.cppm 311// CHECK-MAKE-DAG: [[PREFIX]]/M.o.ddi: \ 312// CHECK-MAKE-DAG-NEXT: [[PREFIX]]/M.cppm 313// CHECK-MAKE-DAG: [[PREFIX]]/User.o.ddi: \ 314// CHECK-MAKE-DAG-NEXT: [[PREFIX]]/User.cpp 315// CHECK-MAKE-DAG: [[PREFIX]]/Impl.o.ddi: \ 316// CHECK-MAKE-DAG-NEXT: [[PREFIX]]/Impl.cpp \ 317// CHECK-MAKE-DAG-NEXT: [[PREFIX]]/header.mock 318 319//--- module.modulemap 320module Mock { header "header.mock" } 321 322//--- header.mock 323