CompilationDatabase.cpp revision cb971c6726d16e12ecd2a340941d7f5c06698332
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"
16cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek#include "llvm/Support/JSONParser.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
25cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek/// \brief A parser for JSON escaped strings of command line arguments.
26cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek///
27cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek/// Assumes \-escaping for quoted arguments (see the documentation of
28cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek/// unescapeJSONCommandLine(...)).
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    if (Position == Input.end()) return false;
94cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    // Remove the JSON escaping first. This is done unconditionally.
95cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    if (*Position == '\\') ++Position;
96cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    return Position != Input.end();
97cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  }
98cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
99cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  const StringRef Input;
100cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  StringRef::iterator Position;
101cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::vector<std::string> CommandLine;
102cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek};
103cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
104cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimekstd::vector<std::string> unescapeJSONCommandLine(
105cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    StringRef JSONEscapedCommandLine) {
106cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  CommandLineArgumentParser parser(JSONEscapedCommandLine);
107cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  return parser.parse();
108cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
109cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
110cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek} // end namespace
111cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
112cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekCompilationDatabase::~CompilationDatabase() {}
113cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
114cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekCompilationDatabase *
115cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekCompilationDatabase::loadFromDirectory(StringRef BuildDirectory,
116cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek                                       std::string &ErrorMessage) {
117cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  llvm::SmallString<1024> JSONDatabasePath(BuildDirectory);
118cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  llvm::sys::path::append(JSONDatabasePath, "compile_commands.json");
119cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  llvm::OwningPtr<CompilationDatabase> Database(
120cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    JSONCompilationDatabase::loadFromFile(JSONDatabasePath, ErrorMessage));
121cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  if (!Database) {
122cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    return NULL;
123cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  }
124cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  return Database.take();
125cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
126cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
127cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekJSONCompilationDatabase *
128cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekJSONCompilationDatabase::loadFromFile(StringRef FilePath,
129cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek                                      std::string &ErrorMessage) {
130cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  llvm::OwningPtr<llvm::MemoryBuffer> DatabaseBuffer;
131cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  llvm::error_code Result =
132cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    llvm::MemoryBuffer::getFile(FilePath, DatabaseBuffer);
133cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  if (Result != 0) {
134cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    ErrorMessage = "Error while opening JSON database: " + Result.message();
135cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    return NULL;
136cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  }
137cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  llvm::OwningPtr<JSONCompilationDatabase> Database(
138cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    new JSONCompilationDatabase(DatabaseBuffer.take()));
139cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  if (!Database->parse(ErrorMessage))
140cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    return NULL;
141cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  return Database.take();
142cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
143cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
144cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekJSONCompilationDatabase *
145cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekJSONCompilationDatabase::loadFromBuffer(StringRef DatabaseString,
146cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek                                        std::string &ErrorMessage) {
147cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  llvm::OwningPtr<llvm::MemoryBuffer> DatabaseBuffer(
148cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      llvm::MemoryBuffer::getMemBuffer(DatabaseString));
149cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  llvm::OwningPtr<JSONCompilationDatabase> Database(
150cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    new JSONCompilationDatabase(DatabaseBuffer.take()));
151cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  if (!Database->parse(ErrorMessage))
152cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    return NULL;
153cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  return Database.take();
154cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
155cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
156cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimekstd::vector<CompileCommand>
157cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekJSONCompilationDatabase::getCompileCommands(StringRef FilePath) const {
158cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  llvm::StringMap< std::vector<CompileCommandRef> >::const_iterator
159cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    CommandsRefI = IndexByFile.find(FilePath);
160cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  if (CommandsRefI == IndexByFile.end())
161cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    return std::vector<CompileCommand>();
162cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  const std::vector<CompileCommandRef> &CommandsRef = CommandsRefI->getValue();
163cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  std::vector<CompileCommand> Commands;
164cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  for (int I = 0, E = CommandsRef.size(); I != E; ++I) {
165cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    Commands.push_back(CompileCommand(
166cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      // FIXME: Escape correctly:
167cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      CommandsRef[I].first,
168cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      unescapeJSONCommandLine(CommandsRef[I].second)));
169cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  }
170cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  return Commands;
171cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
172cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
173cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimekbool JSONCompilationDatabase::parse(std::string &ErrorMessage) {
174cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  llvm::SourceMgr SM;
175cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  llvm::JSONParser Parser(Database->getBuffer(), &SM);
176cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  llvm::JSONValue *Root = Parser.parseRoot();
177cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  if (Root == NULL) {
178cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    ErrorMessage = "Error while parsing JSON.";
179cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    return false;
180cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  }
181cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  llvm::JSONArray *Array = dyn_cast<llvm::JSONArray>(Root);
182cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  if (Array == NULL) {
183cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    ErrorMessage = "Expected array.";
184cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    return false;
185cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  }
186cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  for (llvm::JSONArray::const_iterator AI = Array->begin(), AE = Array->end();
187cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek       AI != AE; ++AI) {
188cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    const llvm::JSONObject *Object = dyn_cast<llvm::JSONObject>(*AI);
189cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    if (Object == NULL) {
190cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      ErrorMessage = "Expected object.";
191cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      return false;
192cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    }
193cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    StringRef EntryDirectory;
194cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    StringRef EntryFile;
195cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    StringRef EntryCommand;
196cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    for (llvm::JSONObject::const_iterator KVI = Object->begin(),
197cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek                                          KVE = Object->end();
198cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek         KVI != KVE; ++KVI) {
199cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      const llvm::JSONValue *Value = (*KVI)->Value;
200cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      if (Value == NULL) {
201cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek        ErrorMessage = "Expected value.";
202cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek        return false;
203cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      }
204cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      const llvm::JSONString *ValueString =
205cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek        dyn_cast<llvm::JSONString>(Value);
206cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      if (ValueString == NULL) {
207cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek        ErrorMessage = "Expected string as value.";
208cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek        return false;
209cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      }
210cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      if ((*KVI)->Key->getRawText() == "directory") {
211cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek        EntryDirectory = ValueString->getRawText();
212cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      } else if ((*KVI)->Key->getRawText() == "file") {
213cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek        EntryFile = ValueString->getRawText();
214cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      } else if ((*KVI)->Key->getRawText() == "command") {
215cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek        EntryCommand = ValueString->getRawText();
216cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      } else {
217cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek        ErrorMessage = (Twine("Unknown key: \"") +
218cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek                        (*KVI)->Key->getRawText() + "\"").str();
219cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek        return false;
220cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      }
221cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    }
222cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek    IndexByFile[EntryFile].push_back(
223cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek      CompileCommandRef(EntryDirectory, EntryCommand));
224cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  }
225cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek  return true;
226cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}
227cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
228cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek} // end namespace tooling
229cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek} // end namespace clang
230cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek
231