Index: clang/test/ClangScanDeps/P1689.cppm =================================================================== --- clang/test/ClangScanDeps/P1689.cppm +++ clang/test/ClangScanDeps/P1689.cppm @@ -5,6 +5,18 @@ // RUN: sed "s|DIR|%/t|g" %t/P1689.json.in > %t/P1689.json // RUN: clang-scan-deps -compilation-database %t/P1689.json -format=p1689 | FileCheck %t/Checks.cpp -DPREFIX=%/t // RUN: clang-scan-deps --mode=preprocess-dependency-directives -compilation-database %t/P1689.json -format=p1689 | FileCheck %t/Checks.cpp -DPREFIX=%/t +// +// Check the seperated dependency format. +// RUN: clang-scan-deps -compilation-database %t/P1689.json -format=p1689 -targeted-file-name=%t/M.cppm \ +// RUN: | FileCheck %t/M.cppm -DPREFIX=%/t +// RUN: clang-scan-deps -compilation-database %t/P1689.json -format=p1689 -targeted-file-name=%t/Impl.cpp \ +// RUN: | FileCheck %t/Impl.cpp -DPREFIX=%/t +// RUN: clang-scan-deps -compilation-database %t/P1689.json -format=p1689 -targeted-file-name=%t/impl_part.cppm \ +// RUN: | FileCheck %t/impl_part.cppm -DPREFIX=%/t +// RUN: clang-scan-deps -compilation-database %t/P1689.json -format=p1689 -targeted-file-name=%t/interface_part.cppm \ +// RUN: | FileCheck %t/interface_part.cppm -DPREFIX=%/t +// RUN: clang-scan-deps -compilation-database %t/P1689.json -format=p1689 -targeted-file-name=%t/User.cpp \ +// RUN: | FileCheck %t/User.cpp -DPREFIX=%/t //--- P1689.json.in [ @@ -47,6 +59,31 @@ import :impl_part; export void Hello(); +// CHECK: { +// CHECK-NEXT: "revision": 0, +// CHECK-NEXT: "rules": [ +// CHECK-NEXT: { +// CHECK-NEXT: "primary-output": "[[PREFIX]]/M.o", +// CHECK-NEXT: "provides": [ +// CHECK-NEXT: { +// CHECK-NEXT: "is-interface": true, +// CHECK-NEXT: "logical-name": "M", +// CHECK-NEXT: "source-path": "[[PREFIX]]/M.cppm" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "requires": [ +// CHECK-NEXT: { +// CHECK-NEXT: "logical-name": "M:interface_part" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "logical-name": "M:impl_part" +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "version": 1 +// CHECK-NEXT: } + //--- Impl.cpp module; #include "header.mock" @@ -55,6 +92,21 @@ std::cout << "Hello "; } +// CHECK: { +// CHECK-NEXT: "revision": 0, +// CHECK-NEXT: "rules": [ +// CHECK-NEXT: { +// CHECK-NEXT: "primary-output": "[[PREFIX]]/Impl.o", +// CHECK-NEXT: "requires": [ +// CHECK-NEXT: { +// CHECK-NEXT: "logical-name": "M" +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "version": 1 +// CHECK-NEXT: } + //--- impl_part.cppm module; #include "header.mock" @@ -66,10 +118,49 @@ std::cout << W << std::endl; } +// CHECK: { +// CHECK-NEXT: "revision": 0, +// CHECK-NEXT: "rules": [ +// CHECK-NEXT: { +// CHECK-NEXT: "primary-output": "[[PREFIX]]/impl_part.o", +// CHECK-NEXT: "provides": [ +// CHECK-NEXT: { +// CHECK-NEXT: "is-interface": false, +// CHECK-NEXT: "logical-name": "M:impl_part", +// CHECK-NEXT: "source-path": "[[PREFIX]]/impl_part.cppm" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "requires": [ +// CHECK-NEXT: { +// CHECK-NEXT: "logical-name": "M:interface_part" +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "version": 1 +// CHECK-NEXT: } + //--- interface_part.cppm export module M:interface_part; export void World(); +// CHECK: { +// CHECK-NEXT: "revision": 0, +// CHECK-NEXT: "rules": [ +// CHECK-NEXT: { +// CHECK-NEXT: "primary-output": "[[PREFIX]]/interface_part.o", +// CHECK-NEXT: "provides": [ +// CHECK-NEXT: { +// CHECK-NEXT: "is-interface": true, +// CHECK-NEXT: "logical-name": "M:interface_part", +// CHECK-NEXT: "source-path": "[[PREFIX]]/interface_part.cppm" +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "version": 1 +// CHECK-NEXT: } + //--- User.cpp import M; import third_party_module; @@ -79,6 +170,24 @@ return 0; } +// CHECK: { +// CHECK-NEXT: "revision": 0, +// CHECK-NEXT: "rules": [ +// CHECK-NEXT: { +// CHECK-NEXT: "primary-output": "[[PREFIX]]/User.o", +// CHECK-NEXT: "requires": [ +// CHECK-NEXT: { +// CHECK-NEXT: "logical-name": "M" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "logical-name": "third_party_module" +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "version": 1 +// CHECK-NEXT: } + //--- Checks.cpp // CHECK: { // CHECK-NEXT: "revision": 0, Index: clang/tools/clang-scan-deps/ClangScanDeps.cpp =================================================================== --- clang/tools/clang-scan-deps/ClangScanDeps.cpp +++ clang/tools/clang-scan-deps/ClangScanDeps.cpp @@ -175,6 +175,12 @@ llvm::cl::desc("the module of which the dependencies are to be computed"), llvm::cl::cat(DependencyScannerCategory)); +llvm::cl::opt TargetedFileName( + "targeted-file-name", llvm::cl::Optional, + llvm::cl::desc("Only supported for P1689, the targeted file name of which the dependencies are to be computed."), + llvm::cl::cat(DependencyScannerCategory) +); + llvm::cl::list ModuleDepTargets( "dependency-target", llvm::cl::desc("The names of dependency targets for the dependency file"), @@ -617,7 +623,9 @@ WorkerTools.push_back(std::make_unique(Service)); std::vector Inputs = - AdjustingCompilations->getAllCompileCommands(); + TargetedFileName.empty() ? + AdjustingCompilations->getAllCompileCommands() : + AdjustingCompilations->getCompileCommands(TargetedFileName); std::atomic HadErrors(false); FullDeps FD;