In the compilation database command must be escaped. This can cause problems
on some systems (Windows). cmd is added as a list of command line arguments
that will not be escaped.
http://reviews.llvm.org/D10365
Files:
include/clang/Tooling/JSONCompilationDatabase.h
lib/Tooling/JSONCompilationDatabase.cpp
unittests/Tooling/CompilationDatabaseTest.cpp
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
Index: include/clang/Tooling/JSONCompilationDatabase.h
===================================================================
--- include/clang/Tooling/JSONCompilationDatabase.h
+++ include/clang/Tooling/JSONCompilationDatabase.h
@@ -94,7 +94,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,
Index: lib/Tooling/JSONCompilationDatabase.cpp
===================================================================
--- lib/Tooling/JSONCompilationDatabase.cpp
+++ 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,11 +251,20 @@
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.";
@@ -264,23 +272,42 @@
}
llvm::yaml::ScalarNode *ValueString =
dyn_cast<llvm::yaml::ScalarNode>(Value);
- if (!ValueString) {
+ llvm::yaml::SequenceNode *SequenceString =
+ dyn_cast<llvm::yaml::SequenceNode>(Value);
+ if (KeyValue == "cmd" && !SequenceString) {
+ ErrorMessage = "Expected sequence as value.";
+ return false;
+ } else if (KeyValue != "cmd" && !ValueString) {
ErrorMessage = "Expected string as value.";
return false;
}
- llvm::yaml::ScalarNode *KeyString =
- dyn_cast<llvm::yaml::ScalarNode>((*KVI).getKey());
- if (!KeyString) {
- ErrorMessage = "Expected strings as key.";
- 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 cmd 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 == "cmd") {
+ if (CommandFound) {
+ ErrorMessage = "Multiple command and cmd 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 \"cmd\".";
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: unittests/Tooling/CompilationDatabaseTest.cpp
===================================================================
--- unittests/Tooling/CompilationDatabaseTest.cpp
+++ 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 cmd");
expectFailure("[{\"command\":\"\",\"file\":\"\"}]", "Missing directory");
+ expectFailure("[{\"directory\":\"\",\"cmd\":[]}]", "Missing file");
+ expectFailure("[{\"cmd\":\"\",\"file\":\"\"}]", "Missing directory");
+ expectFailure("[{\"command\":\"\",\"cmd\":[],\"file\":\"\"}]", "Command and cmd");
+ expectFailure("[{\"directory\":\"\",\"cmd\":\"\",\"file\":\"\"}]", "Cmd not array");
+ expectFailure("[{\"directory\":\"\",\"command\":[],\"file\":\"\"}]", "Command not string");
}
static std::vector<std::string> getAllFiles(StringRef JSONDatabase,
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits