diff options
-rw-r--r-- | include/clang/Tooling/CompilationDatabase.h | 17 | ||||
-rw-r--r-- | lib/Tooling/CompilationDatabase.cpp | 81 |
2 files changed, 54 insertions, 44 deletions
diff --git a/include/clang/Tooling/CompilationDatabase.h b/include/clang/Tooling/CompilationDatabase.h index 3430320b51..60e9a080dc 100644 --- a/include/clang/Tooling/CompilationDatabase.h +++ b/include/clang/Tooling/CompilationDatabase.h @@ -34,13 +34,11 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/YAMLParser.h" #include <string> #include <vector> -namespace llvm { -class MemoryBuffer; -} // end namespace llvm - namespace clang { namespace tooling { @@ -139,7 +137,7 @@ public: private: /// \brief Constructs a JSON compilation database on a memory buffer. JSONCompilationDatabase(llvm::MemoryBuffer *Database) - : Database(Database) {} + : Database(Database), YAMLStream(Database->getBuffer(), SM) {} /// \brief Parses the database file and creates the index. /// @@ -147,14 +145,17 @@ private: /// failed. bool parse(std::string &ErrorMessage); - // Tuple (directory, commandline) where 'commandline' is a JSON escaped bash - // escaped command line. - typedef std::pair<StringRef, StringRef> CompileCommandRef; + // Tuple (directory, commandline) where 'commandline' pointing to the + // corresponding nodes in the YAML stream. + typedef std::pair<llvm::yaml::ScalarNode*, + llvm::yaml::ScalarNode*> CompileCommandRef; // Maps file paths to the compile command lines for that file. llvm::StringMap< std::vector<CompileCommandRef> > IndexByFile; llvm::OwningPtr<llvm::MemoryBuffer> Database; + llvm::SourceMgr SM; + llvm::yaml::Stream YAMLStream; }; } // end namespace tooling diff --git a/lib/Tooling/CompilationDatabase.cpp b/lib/Tooling/CompilationDatabase.cpp index eea1055f49..f8993658da 100644 --- a/lib/Tooling/CompilationDatabase.cpp +++ b/lib/Tooling/CompilationDatabase.cpp @@ -13,7 +13,7 @@ #include "clang/Tooling/CompilationDatabase.h" #include "llvm/ADT/SmallString.h" -#include "llvm/Support/JSONParser.h" +#include "llvm/Support/YAMLParser.h" #include "llvm/Support/Path.h" #include "llvm/Support/system_error.h" @@ -22,10 +22,10 @@ namespace tooling { namespace { -/// \brief A parser for JSON escaped strings of command line arguments. +/// \brief A parser for escaped strings of command line arguments. /// /// Assumes \-escaping for quoted arguments (see the documentation of -/// unescapeJSONCommandLine(...)). +/// unescapeCommandLine(...)). class CommandLineArgumentParser { public: CommandLineArgumentParser(StringRef CommandLine) @@ -90,9 +90,6 @@ class CommandLineArgumentParser { bool next() { ++Position; - if (Position == Input.end()) return false; - // Remove the JSON escaping first. This is done unconditionally. - if (*Position == '\\') ++Position; return Position != Input.end(); } @@ -101,9 +98,9 @@ class CommandLineArgumentParser { std::vector<std::string> CommandLine; }; -std::vector<std::string> unescapeJSONCommandLine( - StringRef JSONEscapedCommandLine) { - CommandLineArgumentParser parser(JSONEscapedCommandLine); +std::vector<std::string> unescapeCommandLine( + StringRef EscapedCommandLine) { + CommandLineArgumentParser parser(EscapedCommandLine); return parser.parse(); } @@ -162,65 +159,77 @@ JSONCompilationDatabase::getCompileCommands(StringRef FilePath) const { const std::vector<CompileCommandRef> &CommandsRef = CommandsRefI->getValue(); std::vector<CompileCommand> Commands; for (int I = 0, E = CommandsRef.size(); I != E; ++I) { + llvm::SmallString<8> DirectoryStorage; + llvm::SmallString<1024> CommandStorage; Commands.push_back(CompileCommand( // FIXME: Escape correctly: - CommandsRef[I].first, - unescapeJSONCommandLine(CommandsRef[I].second))); + CommandsRef[I].first->getValue(DirectoryStorage), + unescapeCommandLine(CommandsRef[I].second->getValue(CommandStorage)))); } return Commands; } bool JSONCompilationDatabase::parse(std::string &ErrorMessage) { - llvm::SourceMgr SM; - llvm::JSONParser Parser(Database->getBuffer(), &SM); - llvm::JSONValue *Root = Parser.parseRoot(); + llvm::yaml::document_iterator I = YAMLStream.begin(); + if (I == YAMLStream.end()) { + ErrorMessage = "Error while parsing YAML."; + return false; + } + llvm::yaml::Node *Root = I->getRoot(); if (Root == NULL) { - ErrorMessage = "Error while parsing JSON."; + ErrorMessage = "Error while parsing YAML."; return false; } - llvm::JSONArray *Array = dyn_cast<llvm::JSONArray>(Root); + llvm::yaml::SequenceNode *Array = + llvm::dyn_cast<llvm::yaml::SequenceNode>(Root); if (Array == NULL) { ErrorMessage = "Expected array."; return false; } - for (llvm::JSONArray::const_iterator AI = Array->begin(), AE = Array->end(); + for (llvm::yaml::SequenceNode::iterator AI = Array->begin(), + AE = Array->end(); AI != AE; ++AI) { - const llvm::JSONObject *Object = dyn_cast<llvm::JSONObject>(*AI); + llvm::yaml::MappingNode *Object = + llvm::dyn_cast<llvm::yaml::MappingNode>(&*AI); if (Object == NULL) { ErrorMessage = "Expected object."; return false; } - StringRef EntryDirectory; - StringRef EntryFile; - StringRef EntryCommand; - for (llvm::JSONObject::const_iterator KVI = Object->begin(), - KVE = Object->end(); + llvm::yaml::ScalarNode *Directory; + llvm::yaml::ScalarNode *Command; + llvm::SmallString<8> FileStorage; + llvm::StringRef File; + for (llvm::yaml::MappingNode::iterator KVI = Object->begin(), + KVE = Object->end(); KVI != KVE; ++KVI) { - const llvm::JSONValue *Value = (*KVI)->Value; + llvm::yaml::Node *Value = (*KVI).getValue(); if (Value == NULL) { ErrorMessage = "Expected value."; return false; } - const llvm::JSONString *ValueString = - dyn_cast<llvm::JSONString>(Value); + llvm::yaml::ScalarNode *ValueString = + llvm::dyn_cast<llvm::yaml::ScalarNode>(Value); if (ValueString == NULL) { ErrorMessage = "Expected string as value."; return false; } - if ((*KVI)->Key->getRawText() == "directory") { - EntryDirectory = ValueString->getRawText(); - } else if ((*KVI)->Key->getRawText() == "file") { - EntryFile = ValueString->getRawText(); - } else if ((*KVI)->Key->getRawText() == "command") { - EntryCommand = ValueString->getRawText(); + llvm::yaml::ScalarNode *KeyString = + llvm::dyn_cast<llvm::yaml::ScalarNode>((*KVI).getKey()); + llvm::SmallString<8> KeyStorage; + if (KeyString->getValue(KeyStorage) == "directory") { + Directory = ValueString; + } else if (KeyString->getValue(KeyStorage) == "command") { + Command = ValueString; + } else if (KeyString->getValue(KeyStorage) == "file") { + File = ValueString->getValue(FileStorage); } else { - ErrorMessage = (Twine("Unknown key: \"") + - (*KVI)->Key->getRawText() + "\"").str(); + ErrorMessage = ("Unknown key: \"" + + KeyString->getRawValue() + "\"").str(); return false; } } - IndexByFile[EntryFile].push_back( - CompileCommandRef(EntryDirectory, EntryCommand)); + IndexByFile[File].push_back( + CompileCommandRef(Directory, Command)); } return true; } |