blob: c69a215a62dc17ac8c294c26828a2e3bd2b7d4d4 [file] [log] [blame]
// This checks that clang-scan-deps properly outputs named module dependencies
// when using the the scanning output format 'experimental-full'.
//
// See PR #72304.
// UNSUPPORTED: target={{.*}}-aix{{.*}}
//
// RUN: rm -fr %t
// RUN: mkdir -p %t
// RUN: split-file %s %t
//
// Check the separated dependency format.
// RUN: sed "s|DIR|%/t|g" %t/compile_commands.json.in > %t/compile_commands.json
// RUN: clang-scan-deps -format=experimental-full \
// RUN: -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/M.cppm -o %t/M.o \
// RUN: | sed 's:\\\\\?:/:g' \
// RUN: | FileCheck %t/M.cppm -DPREFIX=%/t
// RUN: clang-scan-deps -format=experimental-full \
// RUN: -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/Impl.cpp -o %t/Impl.o \
// RUN: | sed 's:\\\\\?:/:g' \
// RUN: | FileCheck %t/Impl.cpp -DPREFIX=%/t
// RUN: clang-scan-deps -format=experimental-full \
// RUN: -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/impl_part.cppm -o %t/impl_part.o \
// RUN: | sed 's:\\\\\?:/:g' \
// RUN: | FileCheck %t/impl_part.cppm -DPREFIX=%/t
// RUN: clang-scan-deps -format=experimental-full \
// RUN: -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/interface_part.cppm -o %t/interface_part.o \
// RUN: | sed 's:\\\\\?:/:g' \
// RUN: | FileCheck %t/interface_part.cppm -DPREFIX=%/t
// RUN: clang-scan-deps -format=experimental-full \
// RUN: -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/User.cpp -o %t/User.o \
// RUN: | sed 's:\\\\\?:/:g' \
// RUN: | FileCheck %t/User.cpp -DPREFIX=%/t
//
// Check the combined dependency format.
// RUN: clang-scan-deps -compilation-database %t/compile_commands.json -format=experimental-full \
// RUN: | sed 's:\\\\\?:/:g' \
// RUN: | FileCheck %t/Checks.cpp -DPREFIX=%/t
// RUN: clang-scan-deps --mode=preprocess-dependency-directives -compilation-database %t/compile_commands.json -format=experimental-full \
// RUN: | sed 's:\\\\\?:/:g' \
// RUN: | FileCheck %t/Checks.cpp -DPREFIX=%/t
//--- compile_commands.json.in
[
{
"directory": "DIR",
"command": "clang++ -std=c++20 DIR/M.cppm -c -o DIR/M.o -MT DIR/M.o.ddi -MD -MF DIR/P1689.dep",
"file": "DIR/M.cppm",
"output": "DIR/M.o"
},
{
"directory": "DIR",
"command": "clang++ -std=c++20 DIR/Impl.cpp -c -o DIR/Impl.o -MT DIR/Impl.o.ddi -MD -MF DIR/P1689.dep",
"file": "DIR/Impl.cpp",
"output": "DIR/Impl.o"
},
{
"directory": "DIR",
"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",
"file": "DIR/impl_part.cppm",
"output": "DIR/impl_part.o"
},
{
"directory": "DIR",
"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",
"file": "DIR/interface_part.cppm",
"output": "DIR/interface_part.o"
},
{
"directory": "DIR",
"command": "clang++ -std=c++20 DIR/User.cpp -c -o DIR/User.o -MT DIR/User.o.ddi -MD -MF DIR/P1689.dep",
"file": "DIR/User.cpp",
"output": "DIR/User.o"
}
]
//--- M.cppm
export module M;
export import :interface_part;
import :impl_part;
export void Hello();
// CHECK: {
// CHECK: "modules": []
// CHECK: "translation-units": [
// CHECK-NEXT: {
// CHECK: "commands": [
// CHECK-NEXT: {
// CHECK: "named-module": "M"
// CHECK-NEXT: "named-module-deps": [
// CHECK-NEXT: "M:interface_part",
// CHECK-NEXT: "M:impl_part"
// CHECK-NEXT: ]
// CHECK: "command-line": [
// CHECK: "-o",
// CHECK-NEXT: "{{.*}}/M.o"
// CHECK: ]
// CHECK: "input-file": "[[PREFIX]]/M.cppm"
// CHECK: }
// CHECK: ]
// CHECK: }
// CHECK: ]
// CHECK: }
//--- Impl.cpp
module;
#include "header.mock"
module M;
void Hello() {
std::cout << "Hello ";
}
// CHECK: {
// CHECK: "modules": []
// CHECK: "translation-units": [
// CHECK-NEXT: {
// CHECK: "commands": [
// CHECK-NEXT: {
// CHECK-NOT: "named-module":
// CHECK: "named-module-deps": [
// CHECK-NEXT: "M"
// CHECK-NEXT: ]
// CHECK: "command-line": [
// CHECK: "-o",
// CHECK-NEXT: "[[PREFIX]]/Impl.o"
// CHECK: ]
// CHECK: "input-file": "[[PREFIX]]/Impl.cpp"
// CHECK: }
// CHECK: ]
// CHECK: }
// CHECK: ]
// CHECK: }
//--- impl_part.cppm
module;
#include "header.mock"
module M:impl_part;
import :interface_part;
std::string W = "World.";
void World() {
std::cout << W << std::endl;
}
// CHECK: {
// CHECK: "modules": [],
// CHECK: "translation-units": [
// CHECK-NEXT: {
// CHECK: "commands": [
// CHECK-NEXT: {
// CHECK: "named-module": "M:impl_part"
// CHECK-NEXT: "named-module-deps": [
// CHECK-NEXT: "M:interface_part"
// CHECK-NEXT: ]
// CHECK: "command-line": [
// CHECK: "-o",
// CHECK-NEXT: "{{.*}}/impl_part.o",
// CHECK: ]
// CHECK: "input-file": "[[PREFIX]]/impl_part.cppm"
// CHECK: }
// CHECK: ]
// CHECK: }
// CHECK: ]
// CHECK: }
//--- interface_part.cppm
export module M:interface_part;
export void World();
// CHECK: {
// CHECK: "modules": []
// CHECK: "translation-units": [
// CHECK-NEXT: {
// CHECK: "commands": [
// CHECK-NEXT: {
// CHECK: "named-module": "M:interface_part"
// CHECK-NOT: "named-module-deps": []
// CHECK: "command-line": [
// CHECK: "-o",
// CHECK-NEXT: "{{.*}}/interface_part.o",
// CHECK: ]
// CHECK: "input-file": "[[PREFIX]]/interface_part.cppm"
// CHECK: }
// CHECK: ]
// CHECK: }
// CHECK: ]
// CHECK: }
//--- User.cpp
import M;
import third_party_module;
int main() {
Hello();
World();
return 0;
}
// CHECK: {
// CHECK-NEXT: "modules": []
// CHECK-NEXT: "translation-units": [
// CHECK-NEXT: {
// CHECK-NEXT: "commands": [
// CHECK-NEXT: {
// CHECK-NOT: "named-module":
// CHECK: "named-module-deps": [
// CHECK-NEXT: "M"
// CHECK-NEXT: "third_party_module"
// CHECK-NEXT: ]
// CHECK: "command-line": [
// CHECK: "-o",
// CHECK-NEXT: "[[PREFIX]]/User.o",
// CHECK: ]
// CHECK: "input-file": "[[PREFIX]]/User.cpp
// CHECK: }
// CHECK: ]
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK: }
//--- header.mock
//--- Checks.cpp
// CHECK: {
// CHECK: "modules": []
// CHECK: "translation-units": [
// CHECK-NEXT: {
// CHECK: "commands": [
// CHECK-NEXT: {
// CHECK: "named-module": "M"
// CHECK-NEXT: "named-module-deps": [
// CHECK-NEXT: "M:interface_part",
// CHECK-NEXT: "M:impl_part"
// CHECK-NEXT: ]
// CHECK: "command-line": [
// CHECK: "-o",
// CHECK-NEXT: "{{.*}}/M.o"
// CHECK: ]
// CHECK: "input-file": "[[PREFIX]]/M.cppm"
// CHECK: },
// CHECK: {
// CHECK-NOT: "named-module":
// CHECK: "named-module-deps": [
// CHECK-NEXT: "M"
// CHECK-NEXT: ]
// CHECK: "command-line": [
// CHECK: "-o",
// CHECK-NEXT: "[[PREFIX]]/Impl.o"
// CHECK: ]
// CHECK: "input-file": "[[PREFIX]]/Impl.cpp"
// CHECK: }
// CHECK: ]
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK: "commands": [
// CHECK-NEXT: {
// CHECK: "named-module": "M:impl_part"
// CHECK-NEXT: "named-module-deps": [
// CHECK-NEXT: "M:interface_part"
// CHECK-NEXT: ]
// CHECK: "command-line": [
// CHECK: "-o",
// CHECK-NEXT: "{{.*}}/impl_part.o",
// CHECK: ]
// CHECK: "input-file": "[[PREFIX]]/impl_part.cppm"
// CHECK: }
// CHECK: ]
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK: "commands": [
// CHECK-NEXT: {
// CHECK: "named-module": "M:interface_part"
// CHECK-NOT: "named-module-deps": []
// CHECK: "command-line": [
// CHECK: "-o",
// CHECK-NEXT: "{{.*}}/interface_part.o",
// CHECK: ]
// CHECK: "input-file": "[[PREFIX]]/interface_part.cppm"
// CHECK: }
// CHECK: ]
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK: "commands": [
// CHECK-NEXT: {
// CHECK-NOT: "named-module":
// CHECK: "named-module-deps": [
// CHECK-NEXT: "M"
// CHECK-NEXT: "third_party_module"
// CHECK-NEXT: ]
// CHECK: "command-line": [
// CHECK: "-o",
// CHECK-NEXT: "[[PREFIX]]/User.o",
// CHECK: ]
// CHECK: "input-file": "[[PREFIX]]/User.cpp
// CHECK: }
// CHECK: ]
// CHECK: }
// CHECK: ]
// CHECK: }