ChuanqiXu updated this revision to Diff 485022.
ChuanqiXu added a comment.
Address comments: fix a typo.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D137534/new/
https://reviews.llvm.org/D137534
Files:
clang/include/clang/Tooling/CompilationDatabase.h
clang/lib/Tooling/CompilationDatabase.cpp
clang/test/ClangScanDeps/P1689.cppm
clang/tools/clang-scan-deps/ClangScanDeps.cpp
clang/unittests/Tooling/CompilationDatabaseTest.cpp
Index: clang/unittests/Tooling/CompilationDatabaseTest.cpp
===================================================================
--- clang/unittests/Tooling/CompilationDatabaseTest.cpp
+++ clang/unittests/Tooling/CompilationDatabaseTest.cpp
@@ -559,7 +559,7 @@
CommandLine.push_back("two");
FixedCompilationDatabase Database(".", CommandLine);
- EXPECT_EQ(0ul, Database.getAllCompileCommands().size());
+ EXPECT_EQ(1ul, Database.getAllCompileCommands().size());
}
TEST(FixedCompilationDatabase, FromBuffer) {
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,23 @@
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> P1689TargettedCommand(
+ llvm::cl::Positional, llvm::cl::ZeroOrMore,
+ llvm::cl::desc("The command line flags for the target of which "
+ "the dependencies are to be computed."));
+
llvm::cl::list<std::string> ModuleDepTargets(
"dependency-target",
llvm::cl::desc("The names of dependency targets for the dependency file"),
@@ -522,19 +539,57 @@
return std::string(Path);
}
-int main(int argc, const char **argv) {
+// 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::CompilationDatabase>
+getCompilationDataBase(int argc, const char **argv, std::string &ErrorMessage) {
llvm::InitLLVM X(argc, argv);
llvm::cl::HideUnrelatedOptions(DependencyScannerCategory);
if (!llvm::cl::ParseCommandLineOptions(argc, argv))
- return 1;
+ return nullptr;
+
+ 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()) {
+ llvm::errs()
+ << "missing compilation database and failed to contruct "
+ "one by --p1689-targeted-file-name, --p1689-targeted-output";
+ return nullptr;
+ }
+ // Use FixedCompilationDatabase to parse the command line flags after "--".
+ std::unique_ptr<tooling::FixedCompilationDatabase> FixedCompilationDatabase =
+ tooling::FixedCompilationDatabase::loadFromCommandLine(
+ argc, argv, ErrorMessage,
+ /*Directory=*/".", P1689TargetedFileName, P1689TargetedOutput);
+
+ if (!FixedCompilationDatabase) {
+ llvm::errs()
+ << "We need to pass the command line args after \"--\" marker.";
+ return nullptr;
+ }
+
+ return std::move(FixedCompilationDatabase);
+}
+
+int main(int argc, const char **argv) {
std::string ErrorMessage;
- std::unique_ptr<tooling::JSONCompilationDatabase> Compilations =
- tooling::JSONCompilationDatabase::loadFromFile(
- CompilationDB, ErrorMessage,
- tooling::JSONCommandLineSyntax::AutoDetect);
+ std::unique_ptr<tooling::CompilationDatabase> Compilations =
+ getCompilationDataBase(argc, argv, ErrorMessage);
if (!Compilations) {
- llvm::errs() << "error: " << ErrorMessage << "\n";
+ llvm::errs() << 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 separated dependency format.
+// RUN: clang-scan-deps -format=p1689 --p1689-targeted-file-name=%t/M.cppm --p1689-targeted-output=%t/M.o \
+// RUN: -- -std=c++20 -c \
+// 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: -- -std=c++20 -c \
+// 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: -- -std=c++20 -c \
+// 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: -- -std=c++20 -c \
+// 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: -- -std=c++20 -c \
+// 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,
Index: clang/lib/Tooling/CompilationDatabase.cpp
===================================================================
--- clang/lib/Tooling/CompilationDatabase.cpp
+++ clang/lib/Tooling/CompilationDatabase.cpp
@@ -320,10 +320,9 @@
}
std::unique_ptr<FixedCompilationDatabase>
-FixedCompilationDatabase::loadFromCommandLine(int &Argc,
- const char *const *Argv,
- std::string &ErrorMsg,
- const Twine &Directory) {
+FixedCompilationDatabase::loadFromCommandLine(
+ int &Argc, const char *const *Argv, std::string &ErrorMsg,
+ const Twine &Directory, StringRef FilePath, StringRef OutputPath) {
ErrorMsg.clear();
if (Argc == 0)
return nullptr;
@@ -336,7 +335,8 @@
std::vector<std::string> StrippedArgs;
if (!stripPositionalArgs(CommandLine, StrippedArgs, ErrorMsg))
return nullptr;
- return std::make_unique<FixedCompilationDatabase>(Directory, StrippedArgs);
+ return std::make_unique<FixedCompilationDatabase>(Directory, StrippedArgs,
+ FilePath, OutputPath);
}
std::unique_ptr<FixedCompilationDatabase>
@@ -369,17 +369,21 @@
}
FixedCompilationDatabase::FixedCompilationDatabase(
- const Twine &Directory, ArrayRef<std::string> CommandLine) {
+ const Twine &Directory, ArrayRef<std::string> CommandLine,
+ StringRef FilePath, StringRef OutputPath) {
std::vector<std::string> ToolCommandLine(1, GetClangToolCommand());
ToolCommandLine.insert(ToolCommandLine.end(),
CommandLine.begin(), CommandLine.end());
- CompileCommands.emplace_back(Directory, StringRef(),
- std::move(ToolCommandLine),
- StringRef());
+ if (!FilePath.empty())
+ ToolCommandLine.push_back(std::string(FilePath));
+ CompileCommands.emplace_back(Directory, FilePath, std::move(ToolCommandLine),
+ OutputPath);
}
std::vector<CompileCommand>
FixedCompilationDatabase::getCompileCommands(StringRef FilePath) const {
+ assert(CompileCommands[0].Filename.empty() &&
+ "We've already set the filename for the fixed compilation databse.");
std::vector<CompileCommand> Result(CompileCommands);
Result[0].CommandLine.push_back(std::string(FilePath));
Result[0].Filename = std::string(FilePath);
Index: clang/include/clang/Tooling/CompilationDatabase.h
===================================================================
--- clang/include/clang/Tooling/CompilationDatabase.h
+++ clang/include/clang/Tooling/CompilationDatabase.h
@@ -180,9 +180,13 @@
/// \param Argv Points to the command line arguments.
/// \param ErrorMsg Contains error text if the function returns null pointer.
/// \param Directory The base directory used in the FixedCompilationDatabase.
+ /// \param FilePath The file path used in the FixedCompilationDatabase.
+ /// \param OutputPath The output path used in the FixedCompilationDatabase.
static std::unique_ptr<FixedCompilationDatabase>
loadFromCommandLine(int &Argc, const char *const *Argv, std::string &ErrorMsg,
- const Twine &Directory = ".");
+ const Twine &Directory = ".",
+ StringRef FilePath = StringRef(),
+ StringRef OutputPath = StringRef());
/// Reads flags from the given file, one-per-line.
/// Returns nullptr and sets ErrorMessage if we can't read the file.
@@ -195,18 +199,28 @@
loadFromBuffer(StringRef Directory, StringRef Data, std::string &ErrorMsg);
/// Constructs a compilation data base from a specified directory
- /// and command line.
+ /// command line, file path (optional) and output path (Optional).
FixedCompilationDatabase(const Twine &Directory,
- ArrayRef<std::string> CommandLine);
+ ArrayRef<std::string> CommandLine,
+ StringRef FilePath = StringRef(),
+ StringRef OutputPath = StringRef());
/// Returns the given compile command.
///
/// Will always return a vector with one entry that contains the directory
/// and command line specified at construction with "clang-tool" as argv[0]
/// and 'FilePath' as positional argument.
+ ///
+ /// This requires the FixedCompilationDatabase haven't set FilePath when
+ /// construction.
std::vector<CompileCommand>
getCompileCommands(StringRef FilePath) const override;
+ /// Returns the compile commands.
+ std::vector<CompileCommand> getAllCompileCommands() const override {
+ return CompileCommands;
+ }
+
private:
/// This is built up to contain a single entry vector to be returned from
/// getCompileCommands after adding the positional argument.
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits