1 //===- unittest/Tooling/CompilationDatabaseTest.cpp -----------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "clang/AST/DeclCXX.h"
11 #include "clang/AST/DeclGroup.h"
12 #include "clang/Frontend/FrontendAction.h"
13 #include "clang/Tooling/FileMatchTrie.h"
14 #include "clang/Tooling/JSONCompilationDatabase.h"
15 #include "clang/Tooling/Tooling.h"
16 #include "llvm/Support/Path.h"
17 #include "gtest/gtest.h"
22 static void expectFailure(StringRef JSONDatabase, StringRef Explanation) {
23 std::string ErrorMessage;
25 JSONCompilationDatabase::loadFromBuffer(JSONDatabase, ErrorMessage,
26 JSONCommandLineSyntax::Gnu))
27 << "Expected an error because of: " << Explanation.str();
30 TEST(JSONCompilationDatabase, ErrsOnInvalidFormat) {
31 expectFailure("", "Empty database");
32 expectFailure("{", "Invalid JSON");
33 expectFailure("[[]]", "Array instead of object");
34 expectFailure("[{\"a\":[]}]", "Array instead of value");
35 expectFailure("[{\"a\":\"b\"}]", "Unknown key");
36 expectFailure("[{[]:\"\"}]", "Incorrectly typed entry");
37 expectFailure("[{}]", "Empty entry");
38 expectFailure("[{\"directory\":\"\",\"command\":\"\"}]", "Missing file");
39 expectFailure("[{\"directory\":\"\",\"file\":\"\"}]", "Missing command or arguments");
40 expectFailure("[{\"command\":\"\",\"file\":\"\"}]", "Missing directory");
41 expectFailure("[{\"directory\":\"\",\"arguments\":[]}]", "Missing file");
42 expectFailure("[{\"arguments\":\"\",\"file\":\"\"}]", "Missing directory");
43 expectFailure("[{\"directory\":\"\",\"arguments\":\"\",\"file\":\"\"}]", "Arguments not array");
44 expectFailure("[{\"directory\":\"\",\"command\":[],\"file\":\"\"}]", "Command not string");
45 expectFailure("[{\"directory\":\"\",\"arguments\":[[]],\"file\":\"\"}]",
46 "Arguments contain non-string");
47 expectFailure("[{\"output\":[]}]", "Expected strings as value.");
50 static std::vector<std::string> getAllFiles(StringRef JSONDatabase,
51 std::string &ErrorMessage,
52 JSONCommandLineSyntax Syntax) {
53 std::unique_ptr<CompilationDatabase> Database(
54 JSONCompilationDatabase::loadFromBuffer(JSONDatabase, ErrorMessage,
57 ADD_FAILURE() << ErrorMessage;
58 return std::vector<std::string>();
60 return Database->getAllFiles();
63 static std::vector<CompileCommand>
64 getAllCompileCommands(JSONCommandLineSyntax Syntax, StringRef JSONDatabase,
65 std::string &ErrorMessage) {
66 std::unique_ptr<CompilationDatabase> Database(
67 JSONCompilationDatabase::loadFromBuffer(JSONDatabase, ErrorMessage,
70 ADD_FAILURE() << ErrorMessage;
71 return std::vector<CompileCommand>();
73 return Database->getAllCompileCommands();
76 TEST(JSONCompilationDatabase, GetAllFiles) {
77 std::string ErrorMessage;
78 EXPECT_EQ(std::vector<std::string>(),
79 getAllFiles("[]", ErrorMessage, JSONCommandLineSyntax::Gnu))
82 std::vector<std::string> expected_files;
83 SmallString<16> PathStorage;
84 llvm::sys::path::native("//net/dir/file1", PathStorage);
85 expected_files.push_back(PathStorage.str());
86 llvm::sys::path::native("//net/dir/file2", PathStorage);
87 expected_files.push_back(PathStorage.str());
88 EXPECT_EQ(expected_files,
89 getAllFiles("[{\"directory\":\"//net/dir\","
90 "\"command\":\"command\","
91 "\"file\":\"file1\"},"
92 " {\"directory\":\"//net/dir\","
93 "\"command\":\"command\","
94 "\"file\":\"file2\"}]",
95 ErrorMessage, JSONCommandLineSyntax::Gnu))
99 TEST(JSONCompilationDatabase, GetAllCompileCommands) {
100 std::string ErrorMessage;
102 0u, getAllCompileCommands(JSONCommandLineSyntax::Gnu, "[]", ErrorMessage)
106 StringRef Directory1("//net/dir1");
107 StringRef FileName1("file1");
108 StringRef Command1("command1");
109 StringRef Output1("file1.o");
110 StringRef Directory2("//net/dir2");
111 StringRef FileName2("file2");
112 StringRef Command2("command2");
113 StringRef Output2("");
115 std::vector<CompileCommand> Commands = getAllCompileCommands(
116 JSONCommandLineSyntax::Gnu,
117 ("[{\"directory\":\"" + Directory1 + "\"," + "\"command\":\"" + Command1 +
120 FileName1 + "\", \"output\":\"" +
122 " {\"directory\":\"" +
123 Directory2 + "\"," + "\"command\":\"" + Command2 + "\","
128 EXPECT_EQ(2U, Commands.size()) << ErrorMessage;
129 EXPECT_EQ(Directory1, Commands[0].Directory) << ErrorMessage;
130 EXPECT_EQ(FileName1, Commands[0].Filename) << ErrorMessage;
131 EXPECT_EQ(Output1, Commands[0].Output) << ErrorMessage;
132 ASSERT_EQ(1u, Commands[0].CommandLine.size());
133 EXPECT_EQ(Command1, Commands[0].CommandLine[0]) << ErrorMessage;
134 EXPECT_EQ(Directory2, Commands[1].Directory) << ErrorMessage;
135 EXPECT_EQ(FileName2, Commands[1].Filename) << ErrorMessage;
136 EXPECT_EQ(Output2, Commands[1].Output) << ErrorMessage;
137 ASSERT_EQ(1u, Commands[1].CommandLine.size());
138 EXPECT_EQ(Command2, Commands[1].CommandLine[0]) << ErrorMessage;
140 // Check that order is preserved.
141 Commands = getAllCompileCommands(
142 JSONCommandLineSyntax::Gnu,
143 ("[{\"directory\":\"" + Directory2 + "\"," + "\"command\":\"" + Command2 +
147 " {\"directory\":\"" +
148 Directory1 + "\"," + "\"command\":\"" + Command1 + "\","
153 EXPECT_EQ(2U, Commands.size()) << ErrorMessage;
154 EXPECT_EQ(Directory2, Commands[0].Directory) << ErrorMessage;
155 EXPECT_EQ(FileName2, Commands[0].Filename) << ErrorMessage;
156 ASSERT_EQ(1u, Commands[0].CommandLine.size());
157 EXPECT_EQ(Command2, Commands[0].CommandLine[0]) << ErrorMessage;
158 EXPECT_EQ(Directory1, Commands[1].Directory) << ErrorMessage;
159 EXPECT_EQ(FileName1, Commands[1].Filename) << ErrorMessage;
160 ASSERT_EQ(1u, Commands[1].CommandLine.size());
161 EXPECT_EQ(Command1, Commands[1].CommandLine[0]) << ErrorMessage;
164 static CompileCommand findCompileArgsInJsonDatabase(StringRef FileName,
165 StringRef JSONDatabase,
166 std::string &ErrorMessage) {
167 std::unique_ptr<CompilationDatabase> Database(
168 JSONCompilationDatabase::loadFromBuffer(JSONDatabase, ErrorMessage,
169 JSONCommandLineSyntax::Gnu));
171 return CompileCommand();
172 std::vector<CompileCommand> Commands = Database->getCompileCommands(FileName);
173 EXPECT_LE(Commands.size(), 1u);
174 if (Commands.empty())
175 return CompileCommand();
179 TEST(JSONCompilationDatabase, ArgumentsPreferredOverCommand) {
180 StringRef Directory("//net/dir");
181 StringRef FileName("//net/dir/filename");
182 StringRef Command("command");
183 StringRef Arguments = "arguments";
184 Twine ArgumentsAccumulate;
185 std::string ErrorMessage;
186 CompileCommand FoundCommand = findCompileArgsInJsonDatabase(
188 ("[{\"directory\":\"" + Directory + "\","
189 "\"arguments\":[\"" + Arguments + "\"],"
190 "\"command\":\"" + Command + "\","
191 "\"file\":\"" + FileName + "\"}]").str(),
193 EXPECT_EQ(Directory, FoundCommand.Directory) << ErrorMessage;
194 EXPECT_EQ(1u, FoundCommand.CommandLine.size()) << ErrorMessage;
195 EXPECT_EQ(Arguments, FoundCommand.CommandLine[0]) << ErrorMessage;
198 struct FakeComparator : public PathComparator {
199 ~FakeComparator() override {}
200 bool equivalent(StringRef FileA, StringRef FileB) const override {
201 return FileA.equals_lower(FileB);
205 class FileMatchTrieTest : public ::testing::Test {
207 FileMatchTrieTest() : Trie(new FakeComparator()) {}
209 StringRef find(StringRef Path) {
210 llvm::raw_string_ostream ES(Error);
211 return Trie.findEquivalent(Path, ES);
218 TEST_F(FileMatchTrieTest, InsertingRelativePath) {
219 Trie.insert("//net/path/file.cc");
220 Trie.insert("file.cc");
221 EXPECT_EQ("//net/path/file.cc", find("//net/path/file.cc"));
224 TEST_F(FileMatchTrieTest, MatchingRelativePath) {
225 EXPECT_EQ("", find("file.cc"));
228 TEST_F(FileMatchTrieTest, ReturnsBestResults) {
229 Trie.insert("//net/d/c/b.cc");
230 Trie.insert("//net/d/b/b.cc");
231 EXPECT_EQ("//net/d/b/b.cc", find("//net/d/b/b.cc"));
234 TEST_F(FileMatchTrieTest, HandlesSymlinks) {
235 Trie.insert("//net/AA/file.cc");
236 EXPECT_EQ("//net/AA/file.cc", find("//net/aa/file.cc"));
239 TEST_F(FileMatchTrieTest, ReportsSymlinkAmbiguity) {
240 Trie.insert("//net/Aa/file.cc");
241 Trie.insert("//net/aA/file.cc");
242 EXPECT_TRUE(find("//net/aa/file.cc").empty());
243 EXPECT_EQ("Path is ambiguous", Error);
246 TEST_F(FileMatchTrieTest, LongerMatchingSuffixPreferred) {
247 Trie.insert("//net/src/Aa/file.cc");
248 Trie.insert("//net/src/aA/file.cc");
249 Trie.insert("//net/SRC/aa/file.cc");
250 EXPECT_EQ("//net/SRC/aa/file.cc", find("//net/src/aa/file.cc"));
253 TEST_F(FileMatchTrieTest, EmptyTrie) {
254 EXPECT_TRUE(find("//net/some/path").empty());
257 TEST_F(FileMatchTrieTest, NoResult) {
258 Trie.insert("//net/somepath/otherfile.cc");
259 Trie.insert("//net/otherpath/somefile.cc");
260 EXPECT_EQ("", find("//net/somepath/somefile.cc"));
263 TEST_F(FileMatchTrieTest, RootElementDifferent) {
264 Trie.insert("//net/path/file.cc");
265 Trie.insert("//net/otherpath/file.cc");
266 EXPECT_EQ("//net/path/file.cc", find("//net/path/file.cc"));
269 TEST_F(FileMatchTrieTest, CannotResolveRelativePath) {
270 EXPECT_EQ("", find("relative-path.cc"));
271 EXPECT_EQ("Cannot resolve relative paths", Error);
274 TEST(findCompileArgsInJsonDatabase, FindsNothingIfEmpty) {
275 std::string ErrorMessage;
276 CompileCommand NotFound = findCompileArgsInJsonDatabase(
277 "a-file.cpp", "", ErrorMessage);
278 EXPECT_TRUE(NotFound.CommandLine.empty()) << ErrorMessage;
279 EXPECT_TRUE(NotFound.Directory.empty()) << ErrorMessage;
282 TEST(findCompileArgsInJsonDatabase, ReadsSingleEntry) {
283 StringRef Directory("//net/some/directory");
284 StringRef FileName("//net/path/to/a-file.cpp");
285 StringRef Command("//net/path/to/compiler and some arguments");
286 std::string ErrorMessage;
287 CompileCommand FoundCommand = findCompileArgsInJsonDatabase(
289 ("[{\"directory\":\"" + Directory + "\"," +
290 "\"command\":\"" + Command + "\","
291 "\"file\":\"" + FileName + "\"}]").str(),
293 EXPECT_EQ(Directory, FoundCommand.Directory) << ErrorMessage;
294 ASSERT_EQ(4u, FoundCommand.CommandLine.size()) << ErrorMessage;
295 EXPECT_EQ("//net/path/to/compiler",
296 FoundCommand.CommandLine[0]) << ErrorMessage;
297 EXPECT_EQ("and", FoundCommand.CommandLine[1]) << ErrorMessage;
298 EXPECT_EQ("some", FoundCommand.CommandLine[2]) << ErrorMessage;
299 EXPECT_EQ("arguments", FoundCommand.CommandLine[3]) << ErrorMessage;
301 CompileCommand NotFound = findCompileArgsInJsonDatabase(
303 ("[{\"directory\":\"" + Directory + "\"," +
304 "\"command\":\"" + Command + "\","
305 "\"file\":\"" + FileName + "\"}]").str(),
307 EXPECT_TRUE(NotFound.Directory.empty()) << ErrorMessage;
308 EXPECT_TRUE(NotFound.CommandLine.empty()) << ErrorMessage;
311 TEST(findCompileArgsInJsonDatabase, ReadsCompileCommandLinesWithSpaces) {
312 StringRef Directory("//net/some/directory");
313 StringRef FileName("//net/path/to/a-file.cpp");
314 StringRef Command("\\\"//net/path to compiler\\\" \\\"and an argument\\\"");
315 std::string ErrorMessage;
316 CompileCommand FoundCommand = findCompileArgsInJsonDatabase(
318 ("[{\"directory\":\"" + Directory + "\"," +
319 "\"command\":\"" + Command + "\","
320 "\"file\":\"" + FileName + "\"}]").str(),
322 ASSERT_EQ(2u, FoundCommand.CommandLine.size());
323 EXPECT_EQ("//net/path to compiler",
324 FoundCommand.CommandLine[0]) << ErrorMessage;
325 EXPECT_EQ("and an argument", FoundCommand.CommandLine[1]) << ErrorMessage;
328 TEST(findCompileArgsInJsonDatabase, ReadsDirectoryWithSpaces) {
329 StringRef Directory("//net/some directory / with spaces");
330 StringRef FileName("//net/path/to/a-file.cpp");
331 StringRef Command("a command");
332 std::string ErrorMessage;
333 CompileCommand FoundCommand = findCompileArgsInJsonDatabase(
335 ("[{\"directory\":\"" + Directory + "\"," +
336 "\"command\":\"" + Command + "\","
337 "\"file\":\"" + FileName + "\"}]").str(),
339 EXPECT_EQ(Directory, FoundCommand.Directory) << ErrorMessage;
342 TEST(findCompileArgsInJsonDatabase, FindsEntry) {
343 StringRef Directory("//net/directory");
344 StringRef FileName("file");
345 StringRef Command("command");
346 std::string JsonDatabase = "[";
347 for (int I = 0; I < 10; ++I) {
348 if (I > 0) JsonDatabase += ",";
350 ("{\"directory\":\"" + Directory + Twine(I) + "\"," +
351 "\"command\":\"" + Command + Twine(I) + "\","
352 "\"file\":\"" + FileName + Twine(I) + "\"}").str();
355 std::string ErrorMessage;
356 CompileCommand FoundCommand = findCompileArgsInJsonDatabase(
357 "//net/directory4/file4", JsonDatabase, ErrorMessage);
358 EXPECT_EQ("//net/directory4", FoundCommand.Directory) << ErrorMessage;
359 ASSERT_EQ(1u, FoundCommand.CommandLine.size()) << ErrorMessage;
360 EXPECT_EQ("command4", FoundCommand.CommandLine[0]) << ErrorMessage;
363 static std::vector<std::string> unescapeJsonCommandLine(StringRef Command) {
364 std::string JsonDatabase =
365 ("[{\"directory\":\"//net/root\", \"file\":\"test\", \"command\": \"" +
366 Command + "\"}]").str();
367 std::string ErrorMessage;
368 CompileCommand FoundCommand = findCompileArgsInJsonDatabase(
369 "//net/root/test", JsonDatabase, ErrorMessage);
370 EXPECT_TRUE(ErrorMessage.empty()) << ErrorMessage;
371 return FoundCommand.CommandLine;
374 TEST(unescapeJsonCommandLine, ReturnsEmptyArrayOnEmptyString) {
375 std::vector<std::string> Result = unescapeJsonCommandLine("");
376 EXPECT_TRUE(Result.empty());
379 TEST(unescapeJsonCommandLine, SplitsOnSpaces) {
380 std::vector<std::string> Result = unescapeJsonCommandLine("a b c");
381 ASSERT_EQ(3ul, Result.size());
382 EXPECT_EQ("a", Result[0]);
383 EXPECT_EQ("b", Result[1]);
384 EXPECT_EQ("c", Result[2]);
387 TEST(unescapeJsonCommandLine, MungesMultipleSpaces) {
388 std::vector<std::string> Result = unescapeJsonCommandLine(" a b ");
389 ASSERT_EQ(2ul, Result.size());
390 EXPECT_EQ("a", Result[0]);
391 EXPECT_EQ("b", Result[1]);
394 TEST(unescapeJsonCommandLine, UnescapesBackslashCharacters) {
395 std::vector<std::string> Backslash = unescapeJsonCommandLine("a\\\\\\\\");
396 ASSERT_EQ(1ul, Backslash.size());
397 EXPECT_EQ("a\\", Backslash[0]);
398 std::vector<std::string> Quote = unescapeJsonCommandLine("a\\\\\\\"");
399 ASSERT_EQ(1ul, Quote.size());
400 EXPECT_EQ("a\"", Quote[0]);
403 TEST(unescapeJsonCommandLine, DoesNotMungeSpacesBetweenQuotes) {
404 std::vector<std::string> Result = unescapeJsonCommandLine("\\\" a b \\\"");
405 ASSERT_EQ(1ul, Result.size());
406 EXPECT_EQ(" a b ", Result[0]);
409 TEST(unescapeJsonCommandLine, AllowsMultipleQuotedArguments) {
410 std::vector<std::string> Result = unescapeJsonCommandLine(
411 " \\\" a \\\" \\\" b \\\" ");
412 ASSERT_EQ(2ul, Result.size());
413 EXPECT_EQ(" a ", Result[0]);
414 EXPECT_EQ(" b ", Result[1]);
417 TEST(unescapeJsonCommandLine, AllowsEmptyArgumentsInQuotes) {
418 std::vector<std::string> Result = unescapeJsonCommandLine(
420 ASSERT_EQ(1ul, Result.size());
421 EXPECT_TRUE(Result[0].empty()) << Result[0];
424 TEST(unescapeJsonCommandLine, ParsesEscapedQuotesInQuotedStrings) {
425 std::vector<std::string> Result = unescapeJsonCommandLine(
427 ASSERT_EQ(1ul, Result.size());
428 EXPECT_EQ("\"", Result[0]);
431 TEST(unescapeJsonCommandLine, ParsesMultipleArgumentsWithEscapedCharacters) {
432 std::vector<std::string> Result = unescapeJsonCommandLine(
433 " \\\\\\\" \\\"a \\\\\\\" b \\\" \\\"and\\\\\\\\c\\\" \\\\\\\"");
434 ASSERT_EQ(4ul, Result.size());
435 EXPECT_EQ("\"", Result[0]);
436 EXPECT_EQ("a \" b ", Result[1]);
437 EXPECT_EQ("and\\c", Result[2]);
438 EXPECT_EQ("\"", Result[3]);
441 TEST(unescapeJsonCommandLine, ParsesStringsWithoutSpacesIntoSingleArgument) {
442 std::vector<std::string> QuotedNoSpaces = unescapeJsonCommandLine(
443 "\\\"a\\\"\\\"b\\\"");
444 ASSERT_EQ(1ul, QuotedNoSpaces.size());
445 EXPECT_EQ("ab", QuotedNoSpaces[0]);
447 std::vector<std::string> MixedNoSpaces = unescapeJsonCommandLine(
448 "\\\"a\\\"bcd\\\"ef\\\"\\\"\\\"\\\"g\\\"");
449 ASSERT_EQ(1ul, MixedNoSpaces.size());
450 EXPECT_EQ("abcdefg", MixedNoSpaces[0]);
453 TEST(unescapeJsonCommandLine, ParsesQuotedStringWithoutClosingQuote) {
454 std::vector<std::string> Unclosed = unescapeJsonCommandLine("\\\"abc");
455 ASSERT_EQ(1ul, Unclosed.size());
456 EXPECT_EQ("abc", Unclosed[0]);
458 std::vector<std::string> Empty = unescapeJsonCommandLine("\\\"");
459 ASSERT_EQ(1ul, Empty.size());
460 EXPECT_EQ("", Empty[0]);
463 TEST(unescapeJsonCommandLine, ParsesSingleQuotedString) {
464 std::vector<std::string> Args = unescapeJsonCommandLine("a'\\\\b \\\"c\\\"'");
465 ASSERT_EQ(1ul, Args.size());
466 EXPECT_EQ("a\\b \"c\"", Args[0]);
469 TEST(FixedCompilationDatabase, ReturnsFixedCommandLine) {
470 std::vector<std::string> CommandLine;
471 CommandLine.push_back("one");
472 CommandLine.push_back("two");
473 FixedCompilationDatabase Database(".", CommandLine);
474 StringRef FileName("source");
475 std::vector<CompileCommand> Result =
476 Database.getCompileCommands(FileName);
477 ASSERT_EQ(1ul, Result.size());
478 std::vector<std::string> ExpectedCommandLine(1, "clang-tool");
479 ExpectedCommandLine.insert(ExpectedCommandLine.end(),
480 CommandLine.begin(), CommandLine.end());
481 ExpectedCommandLine.push_back("source");
482 EXPECT_EQ(".", Result[0].Directory);
483 EXPECT_EQ(FileName, Result[0].Filename);
484 EXPECT_EQ(ExpectedCommandLine, Result[0].CommandLine);
487 TEST(FixedCompilationDatabase, GetAllFiles) {
488 std::vector<std::string> CommandLine;
489 CommandLine.push_back("one");
490 CommandLine.push_back("two");
491 FixedCompilationDatabase Database(".", CommandLine);
493 EXPECT_EQ(0ul, Database.getAllFiles().size());
496 TEST(FixedCompilationDatabase, GetAllCompileCommands) {
497 std::vector<std::string> CommandLine;
498 CommandLine.push_back("one");
499 CommandLine.push_back("two");
500 FixedCompilationDatabase Database(".", CommandLine);
502 EXPECT_EQ(0ul, Database.getAllCompileCommands().size());
505 TEST(ParseFixedCompilationDatabase, ReturnsNullOnEmptyArgumentList) {
507 std::unique_ptr<FixedCompilationDatabase> Database(
508 FixedCompilationDatabase::loadFromCommandLine(Argc, nullptr));
509 EXPECT_FALSE(Database);
513 TEST(ParseFixedCompilationDatabase, ReturnsNullWithoutDoubleDash) {
515 const char *Argv[] = { "1", "2" };
516 std::unique_ptr<FixedCompilationDatabase> Database(
517 FixedCompilationDatabase::loadFromCommandLine(Argc, Argv));
518 EXPECT_FALSE(Database);
522 TEST(ParseFixedCompilationDatabase, ReturnsArgumentsAfterDoubleDash) {
524 const char *Argv[] = {
525 "1", "2", "--\0no-constant-folding", "-DDEF3", "-DDEF4"
527 std::unique_ptr<FixedCompilationDatabase> Database(
528 FixedCompilationDatabase::loadFromCommandLine(Argc, Argv));
529 ASSERT_TRUE((bool)Database);
530 std::vector<CompileCommand> Result =
531 Database->getCompileCommands("source");
532 ASSERT_EQ(1ul, Result.size());
533 ASSERT_EQ(".", Result[0].Directory);
534 std::vector<std::string> CommandLine;
535 CommandLine.push_back("clang-tool");
536 CommandLine.push_back("-DDEF3");
537 CommandLine.push_back("-DDEF4");
538 CommandLine.push_back("source");
539 ASSERT_EQ(CommandLine, Result[0].CommandLine);
543 TEST(ParseFixedCompilationDatabase, ReturnsEmptyCommandLine) {
545 const char *Argv[] = { "1", "2", "--\0no-constant-folding" };
546 std::unique_ptr<FixedCompilationDatabase> Database(
547 FixedCompilationDatabase::loadFromCommandLine(Argc, Argv));
548 ASSERT_TRUE((bool)Database);
549 std::vector<CompileCommand> Result =
550 Database->getCompileCommands("source");
551 ASSERT_EQ(1ul, Result.size());
552 ASSERT_EQ(".", Result[0].Directory);
553 std::vector<std::string> CommandLine;
554 CommandLine.push_back("clang-tool");
555 CommandLine.push_back("source");
556 ASSERT_EQ(CommandLine, Result[0].CommandLine);
560 TEST(ParseFixedCompilationDatabase, HandlesPositionalArgs) {
561 const char *Argv[] = {"1", "2", "--", "-c", "somefile.cpp", "-DDEF3"};
562 int Argc = sizeof(Argv) / sizeof(char*);
563 std::unique_ptr<FixedCompilationDatabase> Database(
564 FixedCompilationDatabase::loadFromCommandLine(Argc, Argv));
565 ASSERT_TRUE((bool)Database);
566 std::vector<CompileCommand> Result =
567 Database->getCompileCommands("source");
568 ASSERT_EQ(1ul, Result.size());
569 ASSERT_EQ(".", Result[0].Directory);
570 std::vector<std::string> Expected;
571 Expected.push_back("clang-tool");
572 Expected.push_back("-c");
573 Expected.push_back("-DDEF3");
574 Expected.push_back("source");
575 ASSERT_EQ(Expected, Result[0].CommandLine);
579 TEST(ParseFixedCompilationDatabase, HandlesArgv0) {
580 const char *Argv[] = {"1", "2", "--", "mytool", "somefile.cpp"};
581 int Argc = sizeof(Argv) / sizeof(char*);
582 std::unique_ptr<FixedCompilationDatabase> Database(
583 FixedCompilationDatabase::loadFromCommandLine(Argc, Argv));
584 ASSERT_TRUE((bool)Database);
585 std::vector<CompileCommand> Result =
586 Database->getCompileCommands("source");
587 ASSERT_EQ(1ul, Result.size());
588 ASSERT_EQ(".", Result[0].Directory);
589 std::vector<std::string> Expected;
590 Expected.push_back("clang-tool");
591 Expected.push_back("source");
592 ASSERT_EQ(Expected, Result[0].CommandLine);
596 } // end namespace tooling
597 } // end namespace clang