1 //===---- QueryTest.cpp - clang-query test --------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "Query.h" 11 #include "QueryParser.h" 12 #include "QuerySession.h" 13 #include "clang/ASTMatchers/ASTMatchers.h" 14 #include "clang/ASTMatchers/Dynamic/VariantValue.h" 15 #include "clang/Frontend/ASTUnit.h" 16 #include "clang/Tooling/Tooling.h" 17 #include "llvm/ADT/STLExtras.h" 18 #include "llvm/Support/raw_ostream.h" 19 #include "gtest/gtest.h" 20 #include <string> 21 22 using namespace clang; 23 using namespace clang::ast_matchers; 24 using namespace clang::ast_matchers::dynamic; 25 using namespace clang::query; 26 using namespace clang::tooling; 27 28 class QueryEngineTest : public ::testing::Test { 29 ArrayRef<ASTUnit *> mkASTUnit2(ASTUnit *a, ASTUnit *b) { 30 ASTs[0] = a; 31 ASTs[1] = b; 32 return ASTs; 33 } 34 35 protected: 36 QueryEngineTest() 37 : FooAST(buildASTFromCode("void foo1(void) {}\nvoid foo2(void) {}", 38 "foo.cc")), 39 BarAST(buildASTFromCode("void bar1(void) {}\nvoid bar2(void) {}", 40 "bar.cc")), 41 S(mkASTUnit2(FooAST.get(), BarAST.get())), OS(Str) {} 42 43 std::unique_ptr<ASTUnit> FooAST; 44 std::unique_ptr<ASTUnit> BarAST; 45 ASTUnit *ASTs[2]; 46 QuerySession S; 47 48 std::string Str; 49 llvm::raw_string_ostream OS; 50 }; 51 52 TEST_F(QueryEngineTest, Basic) { 53 DynTypedMatcher FnMatcher = functionDecl(); 54 DynTypedMatcher FooMatcher = functionDecl(hasName("foo1")); 55 56 EXPECT_TRUE(NoOpQuery().run(OS, S)); 57 58 EXPECT_EQ("", OS.str()); 59 60 Str.clear(); 61 62 EXPECT_FALSE(InvalidQuery("Parse error").run(OS, S)); 63 64 EXPECT_EQ("Parse error\n", OS.str()); 65 66 Str.clear(); 67 68 EXPECT_TRUE(HelpQuery().run(OS, S)); 69 70 EXPECT_TRUE(OS.str().find("Available commands:") != std::string::npos); 71 72 Str.clear(); 73 74 EXPECT_TRUE(MatchQuery(FnMatcher).run(OS, S)); 75 76 EXPECT_TRUE(OS.str().find("foo.cc:1:1: note: \"root\" binds here") != 77 std::string::npos); 78 EXPECT_TRUE(OS.str().find("foo.cc:2:1: note: \"root\" binds here") != 79 std::string::npos); 80 EXPECT_TRUE(OS.str().find("bar.cc:1:1: note: \"root\" binds here") != 81 std::string::npos); 82 EXPECT_TRUE(OS.str().find("bar.cc:2:1: note: \"root\" binds here") != 83 std::string::npos); 84 EXPECT_TRUE(OS.str().find("4 matches.") != std::string::npos); 85 86 Str.clear(); 87 88 EXPECT_TRUE(MatchQuery(FooMatcher).run(OS, S)); 89 90 EXPECT_TRUE(OS.str().find("foo.cc:1:1: note: \"root\" binds here") != 91 std::string::npos); 92 EXPECT_TRUE(OS.str().find("1 match.") != std::string::npos); 93 94 Str.clear(); 95 96 EXPECT_TRUE( 97 SetQuery<OutputKind>(&QuerySession::OutKind, OK_Print).run(OS, S)); 98 EXPECT_TRUE(MatchQuery(FooMatcher).run(OS, S)); 99 100 EXPECT_TRUE(OS.str().find("Binding for \"root\":\nvoid foo1()") != 101 std::string::npos); 102 103 Str.clear(); 104 105 EXPECT_TRUE(SetQuery<OutputKind>(&QuerySession::OutKind, OK_Dump).run(OS, S)); 106 EXPECT_TRUE(MatchQuery(FooMatcher).run(OS, S)); 107 108 EXPECT_TRUE(OS.str().find("FunctionDecl") != std::string::npos); 109 110 Str.clear(); 111 112 EXPECT_TRUE(SetQuery<bool>(&QuerySession::BindRoot, false).run(OS, S)); 113 EXPECT_TRUE(MatchQuery(FooMatcher).run(OS, S)); 114 115 EXPECT_TRUE(OS.str().find("No bindings.") != std::string::npos); 116 117 Str.clear(); 118 119 EXPECT_FALSE(MatchQuery(isArrow()).run(OS, S)); 120 121 EXPECT_EQ("Not a valid top-level matcher.\n", OS.str()); 122 } 123 124 TEST_F(QueryEngineTest, LetAndMatch) { 125 EXPECT_TRUE(QueryParser::parse("let x \"foo1\"", S)->run(OS, S)); 126 EXPECT_EQ("", OS.str()); 127 Str.clear(); 128 129 EXPECT_TRUE(QueryParser::parse("let y hasName(x)", S)->run(OS, S)); 130 EXPECT_EQ("", OS.str()); 131 Str.clear(); 132 133 EXPECT_TRUE(QueryParser::parse("match functionDecl(y)", S)->run(OS, S)); 134 EXPECT_TRUE(OS.str().find("foo.cc:1:1: note: \"root\" binds here") != 135 std::string::npos); 136 EXPECT_TRUE(OS.str().find("1 match.") != std::string::npos); 137 Str.clear(); 138 139 EXPECT_TRUE(QueryParser::parse("unlet x", S)->run(OS, S)); 140 EXPECT_EQ("", OS.str()); 141 Str.clear(); 142 143 EXPECT_FALSE(QueryParser::parse("let y hasName(x)", S)->run(OS, S)); 144 EXPECT_EQ("1:2: Error parsing argument 1 for matcher hasName.\n" 145 "1:10: Value not found: x\n", OS.str()); 146 Str.clear(); 147 } 148