CompilationDatabase.cpp revision 30318e6df9c8c24d080211dfb92ef8065fa7381c
1cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek//===--- CompilationDatabase.cpp - ----------------------------------------===// 2cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek// 3cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek// The LLVM Compiler Infrastructure 4cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek// 5cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek// This file is distributed under the University of Illinois Open Source 6cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek// License. See LICENSE.TXT for details. 7cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek// 8cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek//===----------------------------------------------------------------------===// 9cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek// 10cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek// This file contains multiple implementations for CompilationDatabases. 11cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek// 12cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek//===----------------------------------------------------------------------===// 13cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 14cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek#include "clang/Tooling/CompilationDatabase.h" 15cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek#include "llvm/ADT/SmallString.h" 16c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek#include "llvm/Support/YAMLParser.h" 17cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek#include "llvm/Support/Path.h" 18cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek#include "llvm/Support/system_error.h" 19cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 20cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimeknamespace clang { 21cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimeknamespace tooling { 22cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 23cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimeknamespace { 24cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 25c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek/// \brief A parser for escaped strings of command line arguments. 26cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek/// 27cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek/// Assumes \-escaping for quoted arguments (see the documentation of 28c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek/// unescapeCommandLine(...)). 29cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimekclass CommandLineArgumentParser { 30cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek public: 31cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek CommandLineArgumentParser(StringRef CommandLine) 32cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek : Input(CommandLine), Position(Input.begin()-1) {} 33cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 34cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek std::vector<std::string> parse() { 35cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek bool HasMoreInput = true; 36cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek while (HasMoreInput && nextNonWhitespace()) { 37cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek std::string Argument; 38cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek HasMoreInput = parseStringInto(Argument); 39cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek CommandLine.push_back(Argument); 40cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 41cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return CommandLine; 42cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 43cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 44cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek private: 45cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek // All private methods return true if there is more input available. 46cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 47cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek bool parseStringInto(std::string &String) { 48cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek do { 49cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek if (*Position == '"') { 50cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek if (!parseQuotedStringInto(String)) return false; 51cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } else { 52cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek if (!parseFreeStringInto(String)) return false; 53cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 54cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } while (*Position != ' '); 55cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return true; 56cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 57cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 58cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek bool parseQuotedStringInto(std::string &String) { 59cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek if (!next()) return false; 60cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek while (*Position != '"') { 61cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek if (!skipEscapeCharacter()) return false; 62cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek String.push_back(*Position); 63cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek if (!next()) return false; 64cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 65cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return next(); 66cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 67cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 68cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek bool parseFreeStringInto(std::string &String) { 69cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek do { 70cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek if (!skipEscapeCharacter()) return false; 71cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek String.push_back(*Position); 72cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek if (!next()) return false; 73cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } while (*Position != ' ' && *Position != '"'); 74cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return true; 75cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 76cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 77cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek bool skipEscapeCharacter() { 78cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek if (*Position == '\\') { 79cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return next(); 80cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 81cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return true; 82cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 83cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 84cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek bool nextNonWhitespace() { 85cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek do { 86cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek if (!next()) return false; 87cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } while (*Position == ' '); 88cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return true; 89cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 90cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 91cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek bool next() { 92cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek ++Position; 93cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return Position != Input.end(); 94cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 95cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 96cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek const StringRef Input; 97cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek StringRef::iterator Position; 98cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek std::vector<std::string> CommandLine; 99cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}; 100cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 101c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimekstd::vector<std::string> unescapeCommandLine( 102c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek StringRef EscapedCommandLine) { 103c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek CommandLineArgumentParser parser(EscapedCommandLine); 104cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return parser.parse(); 105cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek} 106cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 107cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek} // end namespace 108cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 109cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekCompilationDatabase::~CompilationDatabase() {} 110cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 111cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekCompilationDatabase * 112cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekCompilationDatabase::loadFromDirectory(StringRef BuildDirectory, 113cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek std::string &ErrorMessage) { 114cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek llvm::SmallString<1024> JSONDatabasePath(BuildDirectory); 115cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek llvm::sys::path::append(JSONDatabasePath, "compile_commands.json"); 116cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek llvm::OwningPtr<CompilationDatabase> Database( 117cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek JSONCompilationDatabase::loadFromFile(JSONDatabasePath, ErrorMessage)); 118cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek if (!Database) { 119cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return NULL; 120cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 121cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return Database.take(); 122cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek} 123cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 12430318e6df9c8c24d080211dfb92ef8065fa7381cManuel KlimekFixedCompilationDatabase * 12530318e6df9c8c24d080211dfb92ef8065fa7381cManuel KlimekFixedCompilationDatabase::loadFromCommandLine(int &Argc, 12630318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek const char **Argv, 12730318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek Twine Directory) { 12830318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek const char **DoubleDash = std::find(Argv, Argv + Argc, StringRef("--")); 12930318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek if (DoubleDash == Argv + Argc) 13030318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek return NULL; 13130318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek std::vector<std::string> CommandLine(DoubleDash + 1, Argv + Argc); 13230318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek Argc = DoubleDash - Argv; 13330318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek return new FixedCompilationDatabase(Directory, CommandLine); 13430318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek} 13530318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek 13630318e6df9c8c24d080211dfb92ef8065fa7381cManuel KlimekFixedCompilationDatabase:: 13730318e6df9c8c24d080211dfb92ef8065fa7381cManuel KlimekFixedCompilationDatabase(Twine Directory, ArrayRef<std::string> CommandLine) { 13830318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek std::vector<std::string> ToolCommandLine(1, "clang-tool"); 13930318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek ToolCommandLine.insert(ToolCommandLine.end(), 14030318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek CommandLine.begin(), CommandLine.end()); 14130318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek CompileCommands.push_back(CompileCommand(Directory, ToolCommandLine)); 14230318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek} 14330318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek 14430318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimekstd::vector<CompileCommand> 14530318e6df9c8c24d080211dfb92ef8065fa7381cManuel KlimekFixedCompilationDatabase::getCompileCommands(StringRef FilePath) const { 14630318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek std::vector<CompileCommand> Result(CompileCommands); 14730318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek Result[0].CommandLine.push_back(FilePath); 14830318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek return Result; 14930318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek} 15030318e6df9c8c24d080211dfb92ef8065fa7381cManuel Klimek 151cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekJSONCompilationDatabase * 152cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekJSONCompilationDatabase::loadFromFile(StringRef FilePath, 153cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek std::string &ErrorMessage) { 154cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek llvm::OwningPtr<llvm::MemoryBuffer> DatabaseBuffer; 155cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek llvm::error_code Result = 156cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek llvm::MemoryBuffer::getFile(FilePath, DatabaseBuffer); 157cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek if (Result != 0) { 158cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek ErrorMessage = "Error while opening JSON database: " + Result.message(); 159cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return NULL; 160cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 161cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek llvm::OwningPtr<JSONCompilationDatabase> Database( 162cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek new JSONCompilationDatabase(DatabaseBuffer.take())); 163cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek if (!Database->parse(ErrorMessage)) 164cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return NULL; 165cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return Database.take(); 166cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek} 167cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 168cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekJSONCompilationDatabase * 169cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekJSONCompilationDatabase::loadFromBuffer(StringRef DatabaseString, 170cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek std::string &ErrorMessage) { 171cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek llvm::OwningPtr<llvm::MemoryBuffer> DatabaseBuffer( 172cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek llvm::MemoryBuffer::getMemBuffer(DatabaseString)); 173cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek llvm::OwningPtr<JSONCompilationDatabase> Database( 174cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek new JSONCompilationDatabase(DatabaseBuffer.take())); 175cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek if (!Database->parse(ErrorMessage)) 176cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return NULL; 177cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return Database.take(); 178cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek} 179cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 180cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimekstd::vector<CompileCommand> 181cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekJSONCompilationDatabase::getCompileCommands(StringRef FilePath) const { 182cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek llvm::StringMap< std::vector<CompileCommandRef> >::const_iterator 183cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek CommandsRefI = IndexByFile.find(FilePath); 184cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek if (CommandsRefI == IndexByFile.end()) 185cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return std::vector<CompileCommand>(); 186cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek const std::vector<CompileCommandRef> &CommandsRef = CommandsRefI->getValue(); 187cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek std::vector<CompileCommand> Commands; 188cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek for (int I = 0, E = CommandsRef.size(); I != E; ++I) { 189c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek llvm::SmallString<8> DirectoryStorage; 190c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek llvm::SmallString<1024> CommandStorage; 191cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek Commands.push_back(CompileCommand( 192cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek // FIXME: Escape correctly: 193c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek CommandsRef[I].first->getValue(DirectoryStorage), 194c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek unescapeCommandLine(CommandsRef[I].second->getValue(CommandStorage)))); 195cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 196cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return Commands; 197cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek} 198cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 199cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimekbool JSONCompilationDatabase::parse(std::string &ErrorMessage) { 200c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek llvm::yaml::document_iterator I = YAMLStream.begin(); 201c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek if (I == YAMLStream.end()) { 202c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek ErrorMessage = "Error while parsing YAML."; 203c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek return false; 204c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek } 205c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek llvm::yaml::Node *Root = I->getRoot(); 206cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek if (Root == NULL) { 207c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek ErrorMessage = "Error while parsing YAML."; 208cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return false; 209cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 210c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek llvm::yaml::SequenceNode *Array = 211c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek llvm::dyn_cast<llvm::yaml::SequenceNode>(Root); 212cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek if (Array == NULL) { 213cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek ErrorMessage = "Expected array."; 214cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return false; 215cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 216c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek for (llvm::yaml::SequenceNode::iterator AI = Array->begin(), 217c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek AE = Array->end(); 218cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek AI != AE; ++AI) { 219c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek llvm::yaml::MappingNode *Object = 220c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek llvm::dyn_cast<llvm::yaml::MappingNode>(&*AI); 221cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek if (Object == NULL) { 222cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek ErrorMessage = "Expected object."; 223cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return false; 224cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 225c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek llvm::yaml::ScalarNode *Directory; 226c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek llvm::yaml::ScalarNode *Command; 227c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek llvm::SmallString<8> FileStorage; 228c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek llvm::StringRef File; 229c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek for (llvm::yaml::MappingNode::iterator KVI = Object->begin(), 230c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek KVE = Object->end(); 231cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek KVI != KVE; ++KVI) { 232c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek llvm::yaml::Node *Value = (*KVI).getValue(); 233cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek if (Value == NULL) { 234cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek ErrorMessage = "Expected value."; 235cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return false; 236cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 237c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek llvm::yaml::ScalarNode *ValueString = 238c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek llvm::dyn_cast<llvm::yaml::ScalarNode>(Value); 239cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek if (ValueString == NULL) { 240cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek ErrorMessage = "Expected string as value."; 241cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return false; 242cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 243c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek llvm::yaml::ScalarNode *KeyString = 244c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek llvm::dyn_cast<llvm::yaml::ScalarNode>((*KVI).getKey()); 245c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek llvm::SmallString<8> KeyStorage; 246c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek if (KeyString->getValue(KeyStorage) == "directory") { 247c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek Directory = ValueString; 248c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek } else if (KeyString->getValue(KeyStorage) == "command") { 249c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek Command = ValueString; 250c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek } else if (KeyString->getValue(KeyStorage) == "file") { 251c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek File = ValueString->getValue(FileStorage); 252cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } else { 253c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek ErrorMessage = ("Unknown key: \"" + 254c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek KeyString->getRawValue() + "\"").str(); 255cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return false; 256cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 257cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 258c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek IndexByFile[File].push_back( 259c661f1467a84a0a3a83a396b067188b647844ee9Manuel Klimek CompileCommandRef(Directory, Command)); 260cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 261cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return true; 262cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek} 263cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 264cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek} // end namespace tooling 265cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek} // end namespace clang 266cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 267