diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Tooling/JSONCompilationDatabase.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Tooling/JSONCompilationDatabase.cpp | 93 |
1 files changed, 58 insertions, 35 deletions
diff --git a/contrib/llvm/tools/clang/lib/Tooling/JSONCompilationDatabase.cpp b/contrib/llvm/tools/clang/lib/Tooling/JSONCompilationDatabase.cpp index 454a2ff..299fbdc 100644 --- a/contrib/llvm/tools/clang/lib/Tooling/JSONCompilationDatabase.cpp +++ b/contrib/llvm/tools/clang/lib/Tooling/JSONCompilationDatabase.cpp @@ -206,24 +206,33 @@ JSONCompilationDatabase::getAllFiles() const { std::vector<CompileCommand> JSONCompilationDatabase::getAllCompileCommands() const { std::vector<CompileCommand> Commands; - for (llvm::StringMap< std::vector<CompileCommandRef> >::const_iterator - CommandsRefI = IndexByFile.begin(), CommandsRefEnd = IndexByFile.end(); - CommandsRefI != CommandsRefEnd; ++CommandsRefI) { - getCommands(CommandsRefI->getValue(), Commands); - } + getCommands(AllCommands, Commands); return Commands; } +static std::vector<std::string> +nodeToCommandLine(const std::vector<llvm::yaml::ScalarNode *> &Nodes) { + SmallString<1024> Storage; + if (Nodes.size() == 1) { + return unescapeCommandLine(Nodes[0]->getValue(Storage)); + } + std::vector<std::string> Arguments; + for (auto *Node : Nodes) { + Arguments.push_back(Node->getValue(Storage)); + } + return Arguments; +} + void JSONCompilationDatabase::getCommands( - ArrayRef<CompileCommandRef> CommandsRef, - std::vector<CompileCommand> &Commands) const { + ArrayRef<CompileCommandRef> CommandsRef, + std::vector<CompileCommand> &Commands) const { for (int I = 0, E = CommandsRef.size(); I != E; ++I) { SmallString<8> DirectoryStorage; - SmallString<1024> CommandStorage; + SmallString<32> FilenameStorage; Commands.emplace_back( - // FIXME: Escape correctly: - CommandsRef[I].first->getValue(DirectoryStorage), - unescapeCommandLine(CommandsRef[I].second->getValue(CommandStorage))); + std::get<0>(CommandsRef[I])->getValue(DirectoryStorage), + std::get<1>(CommandsRef[I])->getValue(FilenameStorage), + nodeToCommandLine(std::get<2>(CommandsRef[I]))); } } @@ -243,43 +252,56 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) { ErrorMessage = "Expected array."; return false; } - for (llvm::yaml::SequenceNode::iterator AI = Array->begin(), - AE = Array->end(); - AI != AE; ++AI) { - llvm::yaml::MappingNode *Object = dyn_cast<llvm::yaml::MappingNode>(&*AI); + for (auto& NextObject : *Array) { + llvm::yaml::MappingNode *Object = dyn_cast<llvm::yaml::MappingNode>(&NextObject); if (!Object) { ErrorMessage = "Expected object."; return false; } llvm::yaml::ScalarNode *Directory = nullptr; - llvm::yaml::ScalarNode *Command = nullptr; + llvm::Optional<std::vector<llvm::yaml::ScalarNode *>> Command; llvm::yaml::ScalarNode *File = nullptr; - for (llvm::yaml::MappingNode::iterator KVI = Object->begin(), - KVE = Object->end(); - KVI != KVE; ++KVI) { - llvm::yaml::Node *Value = (*KVI).getValue(); + for (auto& NextKeyValue : *Object) { + llvm::yaml::ScalarNode *KeyString = + dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey()); + if (!KeyString) { + ErrorMessage = "Expected strings as key."; + return false; + } + SmallString<10> KeyStorage; + StringRef KeyValue = KeyString->getValue(KeyStorage); + llvm::yaml::Node *Value = NextKeyValue.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 == "arguments") { + Command = std::vector<llvm::yaml::ScalarNode *>(); + for (auto &Argument : *SequenceString) { + auto Scalar = dyn_cast<llvm::yaml::ScalarNode>(&Argument); + if (!Scalar) { + ErrorMessage = "Only strings are allowed in 'arguments'."; + return false; + } + Command->push_back(Scalar); + } + } else if (KeyValue == "command") { + if (!Command) + Command = std::vector<llvm::yaml::ScalarNode *>(1, ValueString); + } else if (KeyValue == "file") { File = ValueString; } else { ErrorMessage = ("Unknown key: \"" + @@ -292,7 +314,7 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) { return false; } if (!Command) { - ErrorMessage = "Missing key: \"command\"."; + ErrorMessage = "Missing key: \"command\" or \"arguments\"."; return false; } if (!Directory) { @@ -311,8 +333,9 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) { } else { llvm::sys::path::native(FileName, NativeFilePath); } - IndexByFile[NativeFilePath].push_back( - CompileCommandRef(Directory, Command)); + auto Cmd = CompileCommandRef(Directory, File, *Command); + IndexByFile[NativeFilePath].push_back(Cmd); + AllCommands.push_back(Cmd); MatchTrie.insert(NativeFilePath); } return true; |