diff options
Diffstat (limited to 'lib/Tooling/JSONCompilationDatabase.cpp')
-rw-r--r-- | lib/Tooling/JSONCompilationDatabase.cpp | 94 |
1 files changed, 57 insertions, 37 deletions
diff --git a/lib/Tooling/JSONCompilationDatabase.cpp b/lib/Tooling/JSONCompilationDatabase.cpp index cf35a2566637..254b069952da 100644 --- a/lib/Tooling/JSONCompilationDatabase.cpp +++ b/lib/Tooling/JSONCompilationDatabase.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #include "clang/Tooling/JSONCompilationDatabase.h" - #include "clang/Tooling/CompilationDatabase.h" #include "clang/Tooling/CompilationDatabasePluginRegistry.h" #include "clang/Tooling/Tooling.h" @@ -50,7 +49,9 @@ class CommandLineArgumentParser { bool parseStringInto(std::string &String) { do { if (*Position == '"') { - if (!parseQuotedStringInto(String)) return false; + if (!parseDoubleQuotedStringInto(String)) return false; + } else if (*Position == '\'') { + if (!parseSingleQuotedStringInto(String)) return false; } else { if (!parseFreeStringInto(String)) return false; } @@ -58,7 +59,7 @@ class CommandLineArgumentParser { return true; } - bool parseQuotedStringInto(std::string &String) { + bool parseDoubleQuotedStringInto(std::string &String) { if (!next()) return false; while (*Position != '"') { if (!skipEscapeCharacter()) return false; @@ -68,12 +69,21 @@ class CommandLineArgumentParser { return next(); } + bool parseSingleQuotedStringInto(std::string &String) { + if (!next()) return false; + while (*Position != '\'') { + String.push_back(*Position); + if (!next()) return false; + } + return next(); + } + bool parseFreeStringInto(std::string &String) { do { if (!skipEscapeCharacter()) return false; String.push_back(*Position); if (!next()) return false; - } while (*Position != ' ' && *Position != '"'); + } while (*Position != ' ' && *Position != '"' && *Position != '\''); return true; } @@ -112,9 +122,9 @@ std::vector<std::string> unescapeCommandLine( class JSONCompilationDatabasePlugin : public CompilationDatabasePlugin { virtual CompilationDatabase *loadFromDirectory( StringRef Directory, std::string &ErrorMessage) { - llvm::SmallString<1024> JSONDatabasePath(Directory); + SmallString<1024> JSONDatabasePath(Directory); llvm::sys::path::append(JSONDatabasePath, "compile_commands.json"); - llvm::OwningPtr<CompilationDatabase> Database( + OwningPtr<CompilationDatabase> Database( JSONCompilationDatabase::loadFromFile(JSONDatabasePath, ErrorMessage)); if (!Database) return NULL; @@ -134,14 +144,14 @@ volatile int JSONAnchorSource = 0; JSONCompilationDatabase * JSONCompilationDatabase::loadFromFile(StringRef FilePath, std::string &ErrorMessage) { - llvm::OwningPtr<llvm::MemoryBuffer> DatabaseBuffer; + OwningPtr<llvm::MemoryBuffer> DatabaseBuffer; llvm::error_code Result = llvm::MemoryBuffer::getFile(FilePath, DatabaseBuffer); if (Result != 0) { ErrorMessage = "Error while opening JSON database: " + Result.message(); return NULL; } - llvm::OwningPtr<JSONCompilationDatabase> Database( + OwningPtr<JSONCompilationDatabase> Database( new JSONCompilationDatabase(DatabaseBuffer.take())); if (!Database->parse(ErrorMessage)) return NULL; @@ -151,10 +161,10 @@ JSONCompilationDatabase::loadFromFile(StringRef FilePath, JSONCompilationDatabase * JSONCompilationDatabase::loadFromBuffer(StringRef DatabaseString, std::string &ErrorMessage) { - llvm::OwningPtr<llvm::MemoryBuffer> DatabaseBuffer( + OwningPtr<llvm::MemoryBuffer> DatabaseBuffer( llvm::MemoryBuffer::getMemBuffer(DatabaseString)); - llvm::OwningPtr<JSONCompilationDatabase> Database( - new JSONCompilationDatabase(DatabaseBuffer.take())); + OwningPtr<JSONCompilationDatabase> Database( + new JSONCompilationDatabase(DatabaseBuffer.take())); if (!Database->parse(ErrorMessage)) return NULL; return Database.take(); @@ -162,32 +172,20 @@ JSONCompilationDatabase::loadFromBuffer(StringRef DatabaseString, std::vector<CompileCommand> JSONCompilationDatabase::getCompileCommands(StringRef FilePath) const { - llvm::SmallString<128> NativeFilePath; + SmallString<128> NativeFilePath; llvm::sys::path::native(FilePath, NativeFilePath); std::vector<StringRef> PossibleMatches; std::string Error; llvm::raw_string_ostream ES(Error); StringRef Match = MatchTrie.findEquivalent(NativeFilePath.str(), ES); - if (Match.empty()) { - if (Error.empty()) - Error = "No match found."; - llvm::outs() << Error << "\n"; + if (Match.empty()) return std::vector<CompileCommand>(); - } llvm::StringMap< std::vector<CompileCommandRef> >::const_iterator CommandsRefI = IndexByFile.find(Match); if (CommandsRefI == IndexByFile.end()) return std::vector<CompileCommand>(); - 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->getValue(DirectoryStorage), - unescapeCommandLine(CommandsRef[I].second->getValue(CommandStorage)))); - } + getCommands(CommandsRefI->getValue(), Commands); return Commands; } @@ -206,6 +204,30 @@ JSONCompilationDatabase::getAllFiles() const { return Result; } +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); + } + return Commands; +} + +void JSONCompilationDatabase::getCommands( + ArrayRef<CompileCommandRef> CommandsRef, + std::vector<CompileCommand> &Commands) const { + for (int I = 0, E = CommandsRef.size(); I != E; ++I) { + SmallString<8> DirectoryStorage; + SmallString<1024> CommandStorage; + Commands.push_back(CompileCommand( + // FIXME: Escape correctly: + CommandsRef[I].first->getValue(DirectoryStorage), + unescapeCommandLine(CommandsRef[I].second->getValue(CommandStorage)))); + } +} + bool JSONCompilationDatabase::parse(std::string &ErrorMessage) { llvm::yaml::document_iterator I = YAMLStream.begin(); if (I == YAMLStream.end()) { @@ -217,8 +239,7 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) { ErrorMessage = "Error while parsing YAML."; return false; } - llvm::yaml::SequenceNode *Array = - llvm::dyn_cast<llvm::yaml::SequenceNode>(Root); + llvm::yaml::SequenceNode *Array = dyn_cast<llvm::yaml::SequenceNode>(Root); if (Array == NULL) { ErrorMessage = "Expected array."; return false; @@ -226,8 +247,7 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) { for (llvm::yaml::SequenceNode::iterator AI = Array->begin(), AE = Array->end(); AI != AE; ++AI) { - llvm::yaml::MappingNode *Object = - llvm::dyn_cast<llvm::yaml::MappingNode>(&*AI); + llvm::yaml::MappingNode *Object = dyn_cast<llvm::yaml::MappingNode>(&*AI); if (Object == NULL) { ErrorMessage = "Expected object."; return false; @@ -244,18 +264,18 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) { return false; } llvm::yaml::ScalarNode *ValueString = - llvm::dyn_cast<llvm::yaml::ScalarNode>(Value); + dyn_cast<llvm::yaml::ScalarNode>(Value); if (ValueString == NULL) { ErrorMessage = "Expected string as value."; return false; } llvm::yaml::ScalarNode *KeyString = - llvm::dyn_cast<llvm::yaml::ScalarNode>((*KVI).getKey()); + dyn_cast<llvm::yaml::ScalarNode>((*KVI).getKey()); if (KeyString == NULL) { ErrorMessage = "Expected strings as key."; return false; } - llvm::SmallString<8> KeyStorage; + SmallString<8> KeyStorage; if (KeyString->getValue(KeyStorage) == "directory") { Directory = ValueString; } else if (KeyString->getValue(KeyStorage) == "command") { @@ -280,12 +300,12 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) { ErrorMessage = "Missing key: \"directory\"."; return false; } - llvm::SmallString<8> FileStorage; + SmallString<8> FileStorage; StringRef FileName = File->getValue(FileStorage); - llvm::SmallString<128> NativeFilePath; + SmallString<128> NativeFilePath; if (llvm::sys::path::is_relative(FileName)) { - llvm::SmallString<8> DirectoryStorage; - llvm::SmallString<128> AbsolutePath( + SmallString<8> DirectoryStorage; + SmallString<128> AbsolutePath( Directory->getValue(DirectoryStorage)); llvm::sys::path::append(AbsolutePath, FileName); llvm::sys::path::native(AbsolutePath.str(), NativeFilePath); |