ChuanqiXu updated this revision to Diff 477687.
ChuanqiXu added a comment.

Use `--` instead `-` for parameters in tests to avoid confusion.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137534/new/

https://reviews.llvm.org/D137534

Files:
  clang/test/ClangScanDeps/P1689.cppm
  clang/tools/clang-scan-deps/ClangScanDeps.cpp

Index: clang/tools/clang-scan-deps/ClangScanDeps.cpp
===================================================================
--- clang/tools/clang-scan-deps/ClangScanDeps.cpp
+++ clang/tools/clang-scan-deps/ClangScanDeps.cpp
@@ -167,7 +167,7 @@
 
 llvm::cl::opt<std::string>
     CompilationDB("compilation-database",
-                  llvm::cl::desc("Compilation database"), llvm::cl::Required,
+                  llvm::cl::desc("Compilation database"), llvm::cl::Optional,
                   llvm::cl::cat(DependencyScannerCategory));
 
 llvm::cl::opt<std::string> ModuleName(
@@ -175,6 +175,30 @@
     llvm::cl::desc("the module of which the dependencies are to be computed"),
     llvm::cl::cat(DependencyScannerCategory));
 
+llvm::cl::opt<std::string> P1689TargetedFileName(
+    "p1689-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::opt<std::string> P1689TargetedOutput(
+    "p1689-targeted-output", llvm::cl::Optional,
+    llvm::cl::desc("Only supported for P1689, the targeted output of which the "
+                   "dependencies are to be computed."),
+    llvm::cl::cat(DependencyScannerCategory));
+
+llvm::cl::opt<std::string> P1689TargetedDirectory(
+    "p1689-targeted-directory", llvm::cl::Optional,
+    llvm::cl::desc("Only supported for P1689, the targeted directory of which "
+                   "the dependencies are to be computed."),
+    llvm::cl::cat(DependencyScannerCategory));
+
+llvm::cl::opt<std::string> P1689TargetedCommand(
+    "p1689-targeted-command", llvm::cl::Optional,
+    llvm::cl::desc("Only supported for P1689, the targeted command of which "
+                   "the dependencies are to be computed."),
+    llvm::cl::cat(DependencyScannerCategory));
+
 llvm::cl::list<std::string> ModuleDepTargets(
     "dependency-target",
     llvm::cl::desc("The names of dependency targets for the dependency file"),
@@ -522,6 +546,46 @@
   return std::string(Path);
 }
 
+// getCompilationDataBase - If -compilation-database is set, load the
+// compilation database from the specified file. Otherwise if the we're
+// generating P1689 format, trying to generate the compilation database
+// form the p1689 related command lines. Otherwise, the invocation is
+// ill-formed.
+static std::unique_ptr<tooling::JSONCompilationDatabase>
+getCompilationDataBase(std::string &ErrorMessage) {
+  if (!CompilationDB.empty())
+    return tooling::JSONCompilationDatabase::loadFromFile(
+        CompilationDB, ErrorMessage,
+        tooling::JSONCommandLineSyntax::AutoDetect);
+
+  if (Format != ScanningOutputFormat::P1689) {
+    llvm::errs() << "the --compilation-database option: must be specified at "
+                    "least once!";
+    return nullptr;
+  }
+
+  if (P1689TargetedFileName.empty() || P1689TargetedOutput.empty() ||
+      P1689TargetedDirectory.empty() || P1689TargetedCommand.empty()) {
+    llvm::errs() << "missing compilation database and failed to contruct "
+                    "one by --p1689-targeted-file-name, --p1689-targeted-output"
+                    "--p1689-targeted-directory and --p1689-targeted-command";
+    return nullptr;
+  }
+
+  llvm::raw_string_ostream OS(CompilationDB);
+
+  using namespace llvm::json;
+  Array Entries;
+  Object Output{{"directory", P1689TargetedDirectory},
+                {"command", P1689TargetedCommand},
+                {"file", P1689TargetedFileName},
+                {"output", P1689TargetedOutput}};
+  Entries.push_back(std::move(Output));
+  OS << Value(std::move(Entries));
+  return tooling::JSONCompilationDatabase::loadFromBuffer(
+      CompilationDB, ErrorMessage, tooling::JSONCommandLineSyntax::AutoDetect);
+}
+
 int main(int argc, const char **argv) {
   llvm::InitLLVM X(argc, argv);
   llvm::cl::HideUnrelatedOptions(DependencyScannerCategory);
@@ -530,9 +594,7 @@
 
   std::string ErrorMessage;
   std::unique_ptr<tooling::JSONCompilationDatabase> Compilations =
-      tooling::JSONCompilationDatabase::loadFromFile(
-          CompilationDB, ErrorMessage,
-          tooling::JSONCommandLineSyntax::AutoDetect);
+      getCompilationDataBase(ErrorMessage);
   if (!Compilations) {
     llvm::errs() << "error: " << ErrorMessage << "\n";
     return 1;
Index: clang/test/ClangScanDeps/P1689.cppm
===================================================================
--- clang/test/ClangScanDeps/P1689.cppm
+++ clang/test/ClangScanDeps/P1689.cppm
@@ -3,8 +3,25 @@
 // RUN: split-file %s %t
 //
 // 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
+// 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 -format=p1689 --p1689-targeted-file-name=%t/M.cppm --p1689-targeted-output=%t/M.o \
+// RUN:   --p1689-targeted-directory=%t --p1689-targeted-command="clang++ -std=c++20 %t/M.cppm -c -o %t/M.o" \
+// RUN:   | FileCheck %t/M.cppm -DPREFIX=%/t
+// RUN: clang-scan-deps -format=p1689 --p1689-targeted-file-name=%t/Impl.cpp --p1689-targeted-output=%t/Impl.o \
+// RUN:   --p1689-targeted-directory=%t --p1689-targeted-command="clang++ -std=c++20 %t/Impl.cpp -c -o %t/Impl.o" \
+// RUN:   | FileCheck %t/Impl.cpp -DPREFIX=%/t
+// RUN: clang-scan-deps -format=p1689 --p1689-targeted-file-name=%t/impl_part.cppm --p1689-targeted-output=%t/impl_part.o \
+// RUN:   --p1689-targeted-directory=%t --p1689-targeted-command="clang++ -std=c++20 %t/impl_part.cppm -c -o %t/impl_part.o" \
+// RUN:   | FileCheck %t/impl_part.cppm -DPREFIX=%/t
+// RUN: clang-scan-deps -format=p1689 --p1689-targeted-file-name=%t/interface_part.cppm --p1689-targeted-output=%t/interface_part.o \
+// RUN:   --p1689-targeted-directory=%t --p1689-targeted-command="clang++ -std=c++20 %t/interface_part.cppm -c -o %t/interface_part.o" \
+// RUN:   | FileCheck %t/interface_part.cppm -DPREFIX=%/t
+// RUN: clang-scan-deps -format=p1689 --p1689-targeted-file-name=%t/User.cpp --p1689-targeted-output=%t/User.o \
+// RUN:   --p1689-targeted-directory=%t --p1689-targeted-command="clang++ -std=c++20 %t/User.cpp -c -o %t/User.o" \
+// RUN:   | FileCheck %t/User.cpp -DPREFIX=%/t
 
 //--- P1689.json.in
 [
@@ -47,6 +64,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 +97,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 +123,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 +175,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,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to