diltsman updated this revision to Diff 31824.
http://reviews.llvm.org/D10365
Files:
../llvm/tools/clang/include/clang/Tooling/JSONCompilationDatabase.h
../llvm/tools/clang/lib/Tooling/JSONCompilationDatabase.cpp
../llvm/tools/clang/unittests/Tooling/CompilationDatabaseTest.cpp
Index: ../llvm/tools/clang/unittests/Tooling/CompilationDatabaseTest.cpp
===================================================================
--- ../llvm/tools/clang/unittests/Tooling/CompilationDatabaseTest.cpp
+++ ../llvm/tools/clang/unittests/Tooling/CompilationDatabaseTest.cpp
@@ -36,8 +36,13 @@
expectFailure("[{[]:\"\"}]", "Incorrectly typed entry");
expectFailure("[{}]", "Empty entry");
expectFailure("[{\"directory\":\"\",\"command\":\"\"}]", "Missing file");
- expectFailure("[{\"directory\":\"\",\"file\":\"\"}]", "Missing command");
+ expectFailure("[{\"directory\":\"\",\"file\":\"\"}]", "Missing command or arguments");
expectFailure("[{\"command\":\"\",\"file\":\"\"}]", "Missing directory");
+ expectFailure("[{\"directory\":\"\",\"arguments\":[]}]", "Missing file");
+ expectFailure("[{\"arguments\":\"\",\"file\":\"\"}]", "Missing directory");
+ expectFailure("[{\"command\":\"\",\"arguments\":[],\"file\":\"\"}]", "Command and arguments");
+ expectFailure("[{\"directory\":\"\",\"arguments\":\"\",\"file\":\"\"}]", "Arguments not array");
+ expectFailure("[{\"directory\":\"\",\"command\":[],\"file\":\"\"}]", "Command not string");
}
static std::vector<std::string> getAllFiles(StringRef JSONDatabase,
Index: ../llvm/tools/clang/lib/Tooling/JSONCompilationDatabase.cpp
===================================================================
--- ../llvm/tools/clang/lib/Tooling/JSONCompilationDatabase.cpp
+++ ../llvm/tools/clang/lib/Tooling/JSONCompilationDatabase.cpp
@@ -221,9 +221,8 @@
SmallString<8> DirectoryStorage;
SmallString<1024> CommandStorage;
Commands.emplace_back(
- // FIXME: Escape correctly:
- CommandsRef[I].first->getValue(DirectoryStorage),
- unescapeCommandLine(CommandsRef[I].second->getValue(CommandStorage)));
+ CommandsRef[I].first->getValue(DirectoryStorage),
+ CommandsRef[I].second);
}
}
@@ -252,35 +251,63 @@
return false;
}
llvm::yaml::ScalarNode *Directory = nullptr;
- llvm::yaml::ScalarNode *Command = nullptr;
+ std::vector<std::string> Args;
+ bool CommandFound = false;
llvm::yaml::ScalarNode *File = nullptr;
for (llvm::yaml::MappingNode::iterator KVI = Object->begin(),
KVE = Object->end();
KVI != KVE; ++KVI) {
+ llvm::yaml::ScalarNode *KeyString =
+ dyn_cast<llvm::yaml::ScalarNode>((*KVI).getKey());
+ if (!KeyString) {
+ ErrorMessage = "Expected strings as key.";
+ return false;
+ }
+ SmallString<8> KeyStorage;
+ StringRef KeyValue = KeyString->getValue(KeyStorage);
llvm::yaml::Node *Value = (*KVI).getValue();
if (!Value) {
ErrorMessage = "Expected value.";
return false;
}
llvm::yaml::ScalarNode *ValueString =
dyn_cast<llvm::yaml::ScalarNode>(Value);
- if (!ValueString) {
- ErrorMessage = "Expected string as value.";
+ llvm::yaml::SequenceNode *SequenceString =
+ dyn_cast<llvm::yaml::SequenceNode>(Value);
+ if (KeyValue == "arguments" && !SequenceString) {
+ ErrorMessage = "Expected sequence as value.";
return false;
- }
- llvm::yaml::ScalarNode *KeyString =
- dyn_cast<llvm::yaml::ScalarNode>((*KVI).getKey());
- if (!KeyString) {
- ErrorMessage = "Expected strings as key.";
+ } else if (KeyValue != "arguments" && !ValueString) {
+ ErrorMessage = "Expected string as value.";
return false;
}
- SmallString<8> KeyStorage;
- if (KeyString->getValue(KeyStorage) == "directory") {
+ if (KeyValue == "directory") {
Directory = ValueString;
- } else if (KeyString->getValue(KeyStorage) == "command") {
- Command = ValueString;
- } else if (KeyString->getValue(KeyStorage) == "file") {
+ } else if (KeyValue == "command") {
+ if (CommandFound) {
+ ErrorMessage = "Multiple command and arguments found";
+ return false;
+ }
+ SmallString<1024> CommandStorage;
+ // FIXME: Escape correctly:
+ Args = unescapeCommandLine(ValueString->getValue(CommandStorage));
+ CommandFound = true;
+ } else if (KeyValue == "file") {
File = ValueString;
+ } else if (KeyValue == "arguments") {
+ if (CommandFound) {
+ ErrorMessage = "Multiple command and arguments found";
+ return false;
+ }
+ for (llvm::yaml::SequenceNode::iterator CI = SequenceString->begin(),
+ CE = SequenceString->end();
+ CI != CE; ++CI) {
+ SmallString<128> CommandStorage;
+ auto ValueString = dyn_cast<llvm::yaml::ScalarNode>(&*CI);
+
+ Args.push_back(ValueString->getValue(CommandStorage));
+ }
+ CommandFound = true;
} else {
ErrorMessage = ("Unknown key: \"" +
KeyString->getRawValue() + "\"").str();
@@ -291,8 +318,8 @@
ErrorMessage = "Missing key: \"file\".";
return false;
}
- if (!Command) {
- ErrorMessage = "Missing key: \"command\".";
+ if (!CommandFound) {
+ ErrorMessage = "Missing key: \"command\" or \"arguments\".";
return false;
}
if (!Directory) {
@@ -312,7 +339,7 @@
llvm::sys::path::native(FileName, NativeFilePath);
}
IndexByFile[NativeFilePath].push_back(
- CompileCommandRef(Directory, Command));
+ CompileCommandRef(Directory, Args));
MatchTrie.insert(NativeFilePath);
}
return true;
Index: ../llvm/tools/clang/include/clang/Tooling/JSONCompilationDatabase.h
===================================================================
--- ../llvm/tools/clang/include/clang/Tooling/JSONCompilationDatabase.h
+++ ../llvm/tools/clang/include/clang/Tooling/JSONCompilationDatabase.h
@@ -33,18 +33,26 @@
/// \brief A JSON based compilation database.
///
/// JSON compilation database files must contain a list of JSON objects which
-/// provide the command lines in the attributes 'directory', 'command' and
-/// 'file':
+/// provide the command lines in the attributes 'directory', 'command',
+/// 'arguments' and 'file':
/// [
/// { "directory": "<working directory of the compile>",
/// "command": "<compile command line>",
/// "file": "<path to source file>"
/// },
+/// { "directory": "<working directory of the compile>",
+/// "arguments": ["<raw>", "<command>" "<line>" "<parameters>"],
+/// "file": "<path to source file>"
+/// },
/// ...
/// ]
/// Each object entry defines one compile action. The specified file is
/// considered to be the main source file for the translation unit.
///
+/// 'command' is a full command line that will be unescaped.
+///
+/// 'arguments' is a list of command line arguments that will not be unescaped.
+///
/// JSON compilation databases can for example be generated in CMake projects
/// by setting the flag -DCMAKE_EXPORT_COMPILE_COMMANDS.
class JSONCompilationDatabase : public CompilationDatabase {
@@ -94,7 +102,7 @@
// Tuple (directory, commandline) where 'commandline' pointing to the
// corresponding nodes in the YAML stream.
typedef std::pair<llvm::yaml::ScalarNode*,
- llvm::yaml::ScalarNode*> CompileCommandRef;
+ std::vector<std::string>> CompileCommandRef;
/// \brief Converts the given array of CompileCommandRefs to CompileCommands.
void getCommands(ArrayRef<CompileCommandRef> CommandsRef,
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits