summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/docs/JSONCompilationDatabase.rst3
-rw-r--r--clang/include/clang/Tooling/CompilationDatabase.h8
-rw-r--r--clang/include/clang/Tooling/JSONCompilationDatabase.h8
-rw-r--r--clang/lib/Tooling/CompilationDatabase.cpp3
-rw-r--r--clang/lib/Tooling/JSONCompilationDatabase.cpp10
-rw-r--r--clang/unittests/Tooling/CompilationDatabaseTest.cpp8
6 files changed, 31 insertions, 9 deletions
diff --git a/clang/docs/JSONCompilationDatabase.rst b/clang/docs/JSONCompilationDatabase.rst
index 2b219e536b5..8631e8365ce 100644
--- a/clang/docs/JSONCompilationDatabase.rst
+++ b/clang/docs/JSONCompilationDatabase.rst
@@ -80,6 +80,9 @@ The contracts for each field in the command object are:
supported.
- **arguments:** The compile command executed as list of strings.
Either **arguments** or **command** is required.
+- **output:** The name of the output created by this compilation step.
+ This field is optional. It can be used to distinguish different processing
+ modes of the same input file.
Build System Integration
========================
diff --git a/clang/include/clang/Tooling/CompilationDatabase.h b/clang/include/clang/Tooling/CompilationDatabase.h
index 08a0ffec9d6..4611d3cdae5 100644
--- a/clang/include/clang/Tooling/CompilationDatabase.h
+++ b/clang/include/clang/Tooling/CompilationDatabase.h
@@ -43,10 +43,11 @@ namespace tooling {
struct CompileCommand {
CompileCommand() {}
CompileCommand(Twine Directory, Twine Filename,
- std::vector<std::string> CommandLine)
+ std::vector<std::string> CommandLine, Twine Output)
: Directory(Directory.str()),
Filename(Filename.str()),
- CommandLine(std::move(CommandLine)) {}
+ CommandLine(std::move(CommandLine)),
+ Output(Output.str()){}
/// \brief The working directory the command was executed from.
std::string Directory;
@@ -57,6 +58,9 @@ struct CompileCommand {
/// \brief The command line that was executed.
std::vector<std::string> CommandLine;
+ /// The output file associated with the command.
+ std::string Output;
+
/// \brief An optional mapping from each file's path to its content for all
/// files needed for the compilation that are not available via the file
/// system.
diff --git a/clang/include/clang/Tooling/JSONCompilationDatabase.h b/clang/include/clang/Tooling/JSONCompilationDatabase.h
index baf868e74d6..9a6866240b0 100644
--- a/clang/include/clang/Tooling/JSONCompilationDatabase.h
+++ b/clang/include/clang/Tooling/JSONCompilationDatabase.h
@@ -103,15 +103,17 @@ private:
/// failed.
bool parse(std::string &ErrorMessage);
- // Tuple (directory, filename, commandline) where 'commandline' points to the
- // corresponding scalar nodes in the YAML stream.
+ // Tuple (directory, filename, commandline, output) where 'commandline'
+ // points to the corresponding scalar nodes in the YAML stream.
// If the command line contains a single argument, it is a shell-escaped
// command line.
// Otherwise, each entry in the command line vector is a literal
// argument to the compiler.
+ // The output field may be a nullptr.
typedef std::tuple<llvm::yaml::ScalarNode *,
llvm::yaml::ScalarNode *,
- std::vector<llvm::yaml::ScalarNode *>> CompileCommandRef;
+ std::vector<llvm::yaml::ScalarNode *>,
+ llvm::yaml::ScalarNode *> CompileCommandRef;
/// \brief Converts the given array of CompileCommandRefs to CompileCommands.
void getCommands(ArrayRef<CompileCommandRef> CommandsRef,
diff --git a/clang/lib/Tooling/CompilationDatabase.cpp b/clang/lib/Tooling/CompilationDatabase.cpp
index 01f62616fb0..8ca0b2df701 100644
--- a/clang/lib/Tooling/CompilationDatabase.cpp
+++ b/clang/lib/Tooling/CompilationDatabase.cpp
@@ -300,7 +300,8 @@ FixedCompilationDatabase(Twine Directory, ArrayRef<std::string> CommandLine) {
ToolCommandLine.insert(ToolCommandLine.end(),
CommandLine.begin(), CommandLine.end());
CompileCommands.emplace_back(Directory, StringRef(),
- std::move(ToolCommandLine));
+ std::move(ToolCommandLine),
+ StringRef());
}
std::vector<CompileCommand>
diff --git a/clang/lib/Tooling/JSONCompilationDatabase.cpp b/clang/lib/Tooling/JSONCompilationDatabase.cpp
index 152508fb7df..738e610ed94 100644
--- a/clang/lib/Tooling/JSONCompilationDatabase.cpp
+++ b/clang/lib/Tooling/JSONCompilationDatabase.cpp
@@ -257,10 +257,13 @@ void JSONCompilationDatabase::getCommands(
for (int I = 0, E = CommandsRef.size(); I != E; ++I) {
SmallString<8> DirectoryStorage;
SmallString<32> FilenameStorage;
+ SmallString<32> OutputStorage;
+ auto Output = std::get<3>(CommandsRef[I]);
Commands.emplace_back(
std::get<0>(CommandsRef[I])->getValue(DirectoryStorage),
std::get<1>(CommandsRef[I])->getValue(FilenameStorage),
- nodeToCommandLine(Syntax, std::get<2>(CommandsRef[I])));
+ nodeToCommandLine(Syntax, std::get<2>(CommandsRef[I])),
+ Output ? Output->getValue(OutputStorage) : "");
}
}
@@ -289,6 +292,7 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) {
llvm::yaml::ScalarNode *Directory = nullptr;
llvm::Optional<std::vector<llvm::yaml::ScalarNode *>> Command;
llvm::yaml::ScalarNode *File = nullptr;
+ llvm::yaml::ScalarNode *Output = nullptr;
for (auto& NextKeyValue : *Object) {
llvm::yaml::ScalarNode *KeyString =
dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
@@ -331,6 +335,8 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) {
Command = std::vector<llvm::yaml::ScalarNode *>(1, ValueString);
} else if (KeyValue == "file") {
File = ValueString;
+ } else if (KeyValue == "output") {
+ Output = ValueString;
} else {
ErrorMessage = ("Unknown key: \"" +
KeyString->getRawValue() + "\"").str();
@@ -361,7 +367,7 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) {
} else {
llvm::sys::path::native(FileName, NativeFilePath);
}
- auto Cmd = CompileCommandRef(Directory, File, *Command);
+ auto Cmd = CompileCommandRef(Directory, File, *Command, Output);
IndexByFile[NativeFilePath].push_back(Cmd);
AllCommands.push_back(Cmd);
MatchTrie.insert(NativeFilePath);
diff --git a/clang/unittests/Tooling/CompilationDatabaseTest.cpp b/clang/unittests/Tooling/CompilationDatabaseTest.cpp
index 48539836e5f..1a6fffec939 100644
--- a/clang/unittests/Tooling/CompilationDatabaseTest.cpp
+++ b/clang/unittests/Tooling/CompilationDatabaseTest.cpp
@@ -44,6 +44,7 @@ TEST(JSONCompilationDatabase, ErrsOnInvalidFormat) {
expectFailure("[{\"directory\":\"\",\"command\":[],\"file\":\"\"}]", "Command not string");
expectFailure("[{\"directory\":\"\",\"arguments\":[[]],\"file\":\"\"}]",
"Arguments contain non-string");
+ expectFailure("[{\"output\":[]}]", "Expected strings as value.");
}
static std::vector<std::string> getAllFiles(StringRef JSONDatabase,
@@ -105,16 +106,19 @@ TEST(JSONCompilationDatabase, GetAllCompileCommands) {
StringRef Directory1("//net/dir1");
StringRef FileName1("file1");
StringRef Command1("command1");
+ StringRef Output1("file1.o");
StringRef Directory2("//net/dir2");
StringRef FileName2("file2");
StringRef Command2("command2");
+ StringRef Output2("");
std::vector<CompileCommand> Commands = getAllCompileCommands(
JSONCommandLineSyntax::Gnu,
("[{\"directory\":\"" + Directory1 + "\"," + "\"command\":\"" + Command1 +
"\","
"\"file\":\"" +
- FileName1 + "\"},"
+ FileName1 + "\", \"output\":\"" +
+ Output1 + "\"},"
" {\"directory\":\"" +
Directory2 + "\"," + "\"command\":\"" + Command2 + "\","
"\"file\":\"" +
@@ -124,10 +128,12 @@ TEST(JSONCompilationDatabase, GetAllCompileCommands) {
EXPECT_EQ(2U, Commands.size()) << ErrorMessage;
EXPECT_EQ(Directory1, Commands[0].Directory) << ErrorMessage;
EXPECT_EQ(FileName1, Commands[0].Filename) << ErrorMessage;
+ EXPECT_EQ(Output1, Commands[0].Output) << ErrorMessage;
ASSERT_EQ(1u, Commands[0].CommandLine.size());
EXPECT_EQ(Command1, Commands[0].CommandLine[0]) << ErrorMessage;
EXPECT_EQ(Directory2, Commands[1].Directory) << ErrorMessage;
EXPECT_EQ(FileName2, Commands[1].Filename) << ErrorMessage;
+ EXPECT_EQ(Output2, Commands[1].Output) << ErrorMessage;
ASSERT_EQ(1u, Commands[1].CommandLine.size());
EXPECT_EQ(Command2, Commands[1].CommandLine[0]) << ErrorMessage;
OpenPOWER on IntegriCloud