xref: /aosp_15_r20/external/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //== unittests/ASTMatchers/ASTMatchersNodeTest.cpp - AST matcher unit tests ==//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li 
10*67e74705SXin Li #include "ASTMatchersTest.h"
11*67e74705SXin Li #include "clang/AST/PrettyPrinter.h"
12*67e74705SXin Li #include "clang/ASTMatchers/ASTMatchFinder.h"
13*67e74705SXin Li #include "clang/ASTMatchers/ASTMatchers.h"
14*67e74705SXin Li #include "clang/Tooling/Tooling.h"
15*67e74705SXin Li #include "llvm/ADT/Triple.h"
16*67e74705SXin Li #include "llvm/Support/Host.h"
17*67e74705SXin Li #include "gtest/gtest.h"
18*67e74705SXin Li 
19*67e74705SXin Li namespace clang {
20*67e74705SXin Li namespace ast_matchers {
21*67e74705SXin Li 
TEST(Finder,DynamicOnlyAcceptsSomeMatchers)22*67e74705SXin Li TEST(Finder, DynamicOnlyAcceptsSomeMatchers) {
23*67e74705SXin Li   MatchFinder Finder;
24*67e74705SXin Li   EXPECT_TRUE(Finder.addDynamicMatcher(decl(), nullptr));
25*67e74705SXin Li   EXPECT_TRUE(Finder.addDynamicMatcher(callExpr(), nullptr));
26*67e74705SXin Li   EXPECT_TRUE(Finder.addDynamicMatcher(constantArrayType(hasSize(42)),
27*67e74705SXin Li                                        nullptr));
28*67e74705SXin Li 
29*67e74705SXin Li   // Do not accept non-toplevel matchers.
30*67e74705SXin Li   EXPECT_FALSE(Finder.addDynamicMatcher(isArrow(), nullptr));
31*67e74705SXin Li   EXPECT_FALSE(Finder.addDynamicMatcher(hasName("x"), nullptr));
32*67e74705SXin Li }
33*67e74705SXin Li 
TEST(Decl,MatchesDeclarations)34*67e74705SXin Li TEST(Decl, MatchesDeclarations) {
35*67e74705SXin Li   EXPECT_TRUE(notMatches("", decl(usingDecl())));
36*67e74705SXin Li   EXPECT_TRUE(matches("namespace x { class X {}; } using x::X;",
37*67e74705SXin Li                       decl(usingDecl())));
38*67e74705SXin Li }
39*67e74705SXin Li 
TEST(NameableDeclaration,MatchesVariousDecls)40*67e74705SXin Li TEST(NameableDeclaration, MatchesVariousDecls) {
41*67e74705SXin Li   DeclarationMatcher NamedX = namedDecl(hasName("X"));
42*67e74705SXin Li   EXPECT_TRUE(matches("typedef int X;", NamedX));
43*67e74705SXin Li   EXPECT_TRUE(matches("int X;", NamedX));
44*67e74705SXin Li   EXPECT_TRUE(matches("class foo { virtual void X(); };", NamedX));
45*67e74705SXin Li   EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", NamedX));
46*67e74705SXin Li   EXPECT_TRUE(matches("void foo() { int X; }", NamedX));
47*67e74705SXin Li   EXPECT_TRUE(matches("namespace X { }", NamedX));
48*67e74705SXin Li   EXPECT_TRUE(matches("enum X { A, B, C };", NamedX));
49*67e74705SXin Li 
50*67e74705SXin Li   EXPECT_TRUE(notMatches("#define X 1", NamedX));
51*67e74705SXin Li }
52*67e74705SXin Li 
TEST(NameableDeclaration,REMatchesVariousDecls)53*67e74705SXin Li TEST(NameableDeclaration, REMatchesVariousDecls) {
54*67e74705SXin Li   DeclarationMatcher NamedX = namedDecl(matchesName("::X"));
55*67e74705SXin Li   EXPECT_TRUE(matches("typedef int Xa;", NamedX));
56*67e74705SXin Li   EXPECT_TRUE(matches("int Xb;", NamedX));
57*67e74705SXin Li   EXPECT_TRUE(matches("class foo { virtual void Xc(); };", NamedX));
58*67e74705SXin Li   EXPECT_TRUE(matches("void foo() try { } catch(int Xdef) { }", NamedX));
59*67e74705SXin Li   EXPECT_TRUE(matches("void foo() { int Xgh; }", NamedX));
60*67e74705SXin Li   EXPECT_TRUE(matches("namespace Xij { }", NamedX));
61*67e74705SXin Li   EXPECT_TRUE(matches("enum X { A, B, C };", NamedX));
62*67e74705SXin Li 
63*67e74705SXin Li   EXPECT_TRUE(notMatches("#define Xkl 1", NamedX));
64*67e74705SXin Li 
65*67e74705SXin Li   DeclarationMatcher StartsWithNo = namedDecl(matchesName("::no"));
66*67e74705SXin Li   EXPECT_TRUE(matches("int no_foo;", StartsWithNo));
67*67e74705SXin Li   EXPECT_TRUE(matches("class foo { virtual void nobody(); };", StartsWithNo));
68*67e74705SXin Li 
69*67e74705SXin Li   DeclarationMatcher Abc = namedDecl(matchesName("a.*b.*c"));
70*67e74705SXin Li   EXPECT_TRUE(matches("int abc;", Abc));
71*67e74705SXin Li   EXPECT_TRUE(matches("int aFOObBARc;", Abc));
72*67e74705SXin Li   EXPECT_TRUE(notMatches("int cab;", Abc));
73*67e74705SXin Li   EXPECT_TRUE(matches("int cabc;", Abc));
74*67e74705SXin Li 
75*67e74705SXin Li   DeclarationMatcher StartsWithK = namedDecl(matchesName(":k[^:]*$"));
76*67e74705SXin Li   EXPECT_TRUE(matches("int k;", StartsWithK));
77*67e74705SXin Li   EXPECT_TRUE(matches("int kAbc;", StartsWithK));
78*67e74705SXin Li   EXPECT_TRUE(matches("namespace x { int kTest; }", StartsWithK));
79*67e74705SXin Li   EXPECT_TRUE(matches("class C { int k; };", StartsWithK));
80*67e74705SXin Li   EXPECT_TRUE(notMatches("class C { int ckc; };", StartsWithK));
81*67e74705SXin Li }
82*67e74705SXin Li 
TEST(DeclarationMatcher,MatchClass)83*67e74705SXin Li TEST(DeclarationMatcher, MatchClass) {
84*67e74705SXin Li   DeclarationMatcher ClassMatcher(recordDecl());
85*67e74705SXin Li 
86*67e74705SXin Li   // This passes on Windows only because we explicitly pass -target
87*67e74705SXin Li   // i386-unknown-unknown.  If we were to compile with the default target
88*67e74705SXin Li   // triple, we'd want to EXPECT_TRUE if it's Win32 or MSVC.
89*67e74705SXin Li   EXPECT_FALSE(matches("", ClassMatcher));
90*67e74705SXin Li 
91*67e74705SXin Li   DeclarationMatcher ClassX = recordDecl(recordDecl(hasName("X")));
92*67e74705SXin Li   EXPECT_TRUE(matches("class X;", ClassX));
93*67e74705SXin Li   EXPECT_TRUE(matches("class X {};", ClassX));
94*67e74705SXin Li   EXPECT_TRUE(matches("template<class T> class X {};", ClassX));
95*67e74705SXin Li   EXPECT_TRUE(notMatches("", ClassX));
96*67e74705SXin Li }
97*67e74705SXin Li 
TEST(DeclarationMatcher,translationUnitDecl)98*67e74705SXin Li TEST(DeclarationMatcher, translationUnitDecl) {
99*67e74705SXin Li   const std::string Code = "int MyVar1;\n"
100*67e74705SXin Li     "namespace NameSpace {\n"
101*67e74705SXin Li     "int MyVar2;\n"
102*67e74705SXin Li     "}  // namespace NameSpace\n";
103*67e74705SXin Li   EXPECT_TRUE(matches(
104*67e74705SXin Li     Code, varDecl(hasName("MyVar1"), hasDeclContext(translationUnitDecl()))));
105*67e74705SXin Li   EXPECT_FALSE(matches(
106*67e74705SXin Li     Code, varDecl(hasName("MyVar2"), hasDeclContext(translationUnitDecl()))));
107*67e74705SXin Li   EXPECT_TRUE(matches(
108*67e74705SXin Li     Code,
109*67e74705SXin Li     varDecl(hasName("MyVar2"),
110*67e74705SXin Li             hasDeclContext(decl(hasDeclContext(translationUnitDecl()))))));
111*67e74705SXin Li }
112*67e74705SXin Li 
TEST(DeclarationMatcher,LinkageSpecification)113*67e74705SXin Li TEST(DeclarationMatcher, LinkageSpecification) {
114*67e74705SXin Li   EXPECT_TRUE(matches("extern \"C\" { void foo() {}; }", linkageSpecDecl()));
115*67e74705SXin Li   EXPECT_TRUE(notMatches("void foo() {};", linkageSpecDecl()));
116*67e74705SXin Li }
117*67e74705SXin Li 
TEST(ClassTemplate,DoesNotMatchClass)118*67e74705SXin Li TEST(ClassTemplate, DoesNotMatchClass) {
119*67e74705SXin Li   DeclarationMatcher ClassX = classTemplateDecl(hasName("X"));
120*67e74705SXin Li   EXPECT_TRUE(notMatches("class X;", ClassX));
121*67e74705SXin Li   EXPECT_TRUE(notMatches("class X {};", ClassX));
122*67e74705SXin Li }
123*67e74705SXin Li 
TEST(ClassTemplate,MatchesClassTemplate)124*67e74705SXin Li TEST(ClassTemplate, MatchesClassTemplate) {
125*67e74705SXin Li   DeclarationMatcher ClassX = classTemplateDecl(hasName("X"));
126*67e74705SXin Li   EXPECT_TRUE(matches("template<typename T> class X {};", ClassX));
127*67e74705SXin Li   EXPECT_TRUE(matches("class Z { template<class T> class X {}; };", ClassX));
128*67e74705SXin Li }
129*67e74705SXin Li 
TEST(ClassTemplate,DoesNotMatchClassTemplateExplicitSpecialization)130*67e74705SXin Li TEST(ClassTemplate, DoesNotMatchClassTemplateExplicitSpecialization) {
131*67e74705SXin Li   EXPECT_TRUE(notMatches("template<typename T> class X { };"
132*67e74705SXin Li                            "template<> class X<int> { int a; };",
133*67e74705SXin Li                          classTemplateDecl(hasName("X"),
134*67e74705SXin Li                                            hasDescendant(fieldDecl(hasName("a"))))));
135*67e74705SXin Li }
136*67e74705SXin Li 
TEST(ClassTemplate,DoesNotMatchClassTemplatePartialSpecialization)137*67e74705SXin Li TEST(ClassTemplate, DoesNotMatchClassTemplatePartialSpecialization) {
138*67e74705SXin Li   EXPECT_TRUE(notMatches("template<typename T, typename U> class X { };"
139*67e74705SXin Li                            "template<typename T> class X<T, int> { int a; };",
140*67e74705SXin Li                          classTemplateDecl(hasName("X"),
141*67e74705SXin Li                                            hasDescendant(fieldDecl(hasName("a"))))));
142*67e74705SXin Li }
143*67e74705SXin Li 
TEST(DeclarationMatcher,MatchCudaDecl)144*67e74705SXin Li TEST(DeclarationMatcher, MatchCudaDecl) {
145*67e74705SXin Li   EXPECT_TRUE(matchesWithCuda("__global__ void f() { }"
146*67e74705SXin Li                                 "void g() { f<<<1, 2>>>(); }",
147*67e74705SXin Li                               cudaKernelCallExpr()));
148*67e74705SXin Li   EXPECT_TRUE(matchesWithCuda("__attribute__((device)) void f() {}",
149*67e74705SXin Li                               hasAttr(clang::attr::CUDADevice)));
150*67e74705SXin Li   EXPECT_TRUE(notMatchesWithCuda("void f() {}",
151*67e74705SXin Li                                  cudaKernelCallExpr()));
152*67e74705SXin Li   EXPECT_FALSE(notMatchesWithCuda("__attribute__((global)) void f() {}",
153*67e74705SXin Li                                   hasAttr(clang::attr::CUDAGlobal)));
154*67e74705SXin Li }
155*67e74705SXin Li 
TEST(ValueDecl,Matches)156*67e74705SXin Li TEST(ValueDecl, Matches) {
157*67e74705SXin Li   EXPECT_TRUE(matches("enum EnumType { EnumValue };",
158*67e74705SXin Li                       valueDecl(hasType(asString("enum EnumType")))));
159*67e74705SXin Li   EXPECT_TRUE(matches("void FunctionDecl();",
160*67e74705SXin Li                       valueDecl(hasType(asString("void (void)")))));
161*67e74705SXin Li }
162*67e74705SXin Li 
TEST(Enum,DoesNotMatchClasses)163*67e74705SXin Li TEST(Enum, DoesNotMatchClasses) {
164*67e74705SXin Li   EXPECT_TRUE(notMatches("class X {};", enumDecl(hasName("X"))));
165*67e74705SXin Li }
166*67e74705SXin Li 
TEST(Enum,MatchesEnums)167*67e74705SXin Li TEST(Enum, MatchesEnums) {
168*67e74705SXin Li   EXPECT_TRUE(matches("enum X {};", enumDecl(hasName("X"))));
169*67e74705SXin Li }
170*67e74705SXin Li 
TEST(EnumConstant,Matches)171*67e74705SXin Li TEST(EnumConstant, Matches) {
172*67e74705SXin Li   DeclarationMatcher Matcher = enumConstantDecl(hasName("A"));
173*67e74705SXin Li   EXPECT_TRUE(matches("enum X{ A };", Matcher));
174*67e74705SXin Li   EXPECT_TRUE(notMatches("enum X{ B };", Matcher));
175*67e74705SXin Li   EXPECT_TRUE(notMatches("enum X {};", Matcher));
176*67e74705SXin Li }
177*67e74705SXin Li 
TEST(Matcher,UnresolvedLookupExpr)178*67e74705SXin Li TEST(Matcher, UnresolvedLookupExpr) {
179*67e74705SXin Li   // FIXME: The test is known to be broken on Windows with delayed template
180*67e74705SXin Li   // parsing.
181*67e74705SXin Li   EXPECT_TRUE(matchesConditionally("template<typename T>"
182*67e74705SXin Li                                    "T foo() { T a; return a; }"
183*67e74705SXin Li                                    "template<typename T>"
184*67e74705SXin Li                                    "void bar() {"
185*67e74705SXin Li                                    "  foo<T>();"
186*67e74705SXin Li                                    "}",
187*67e74705SXin Li                                    unresolvedLookupExpr(),
188*67e74705SXin Li                                    /*ExpectMatch=*/true,
189*67e74705SXin Li                                    "-fno-delayed-template-parsing"));
190*67e74705SXin Li }
191*67e74705SXin Li 
TEST(Matcher,Call)192*67e74705SXin Li TEST(Matcher, Call) {
193*67e74705SXin Li   // FIXME: Do we want to overload Call() to directly take
194*67e74705SXin Li   // Matcher<Decl>, too?
195*67e74705SXin Li   StatementMatcher MethodX =
196*67e74705SXin Li     callExpr(hasDeclaration(cxxMethodDecl(hasName("x"))));
197*67e74705SXin Li 
198*67e74705SXin Li   EXPECT_TRUE(matches("class Y { void x() { x(); } };", MethodX));
199*67e74705SXin Li   EXPECT_TRUE(notMatches("class Y { void x() {} };", MethodX));
200*67e74705SXin Li 
201*67e74705SXin Li   StatementMatcher MethodOnY =
202*67e74705SXin Li     cxxMemberCallExpr(on(hasType(recordDecl(hasName("Y")))));
203*67e74705SXin Li 
204*67e74705SXin Li   EXPECT_TRUE(
205*67e74705SXin Li     matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
206*67e74705SXin Li             MethodOnY));
207*67e74705SXin Li   EXPECT_TRUE(
208*67e74705SXin Li     matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
209*67e74705SXin Li             MethodOnY));
210*67e74705SXin Li   EXPECT_TRUE(
211*67e74705SXin Li     notMatches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
212*67e74705SXin Li                MethodOnY));
213*67e74705SXin Li   EXPECT_TRUE(
214*67e74705SXin Li     notMatches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
215*67e74705SXin Li                MethodOnY));
216*67e74705SXin Li   EXPECT_TRUE(
217*67e74705SXin Li     notMatches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
218*67e74705SXin Li                MethodOnY));
219*67e74705SXin Li 
220*67e74705SXin Li   StatementMatcher MethodOnYPointer =
221*67e74705SXin Li     cxxMemberCallExpr(on(hasType(pointsTo(recordDecl(hasName("Y"))))));
222*67e74705SXin Li 
223*67e74705SXin Li   EXPECT_TRUE(
224*67e74705SXin Li     matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
225*67e74705SXin Li             MethodOnYPointer));
226*67e74705SXin Li   EXPECT_TRUE(
227*67e74705SXin Li     matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
228*67e74705SXin Li             MethodOnYPointer));
229*67e74705SXin Li   EXPECT_TRUE(
230*67e74705SXin Li     matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
231*67e74705SXin Li             MethodOnYPointer));
232*67e74705SXin Li   EXPECT_TRUE(
233*67e74705SXin Li     notMatches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
234*67e74705SXin Li                MethodOnYPointer));
235*67e74705SXin Li   EXPECT_TRUE(
236*67e74705SXin Li     notMatches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
237*67e74705SXin Li                MethodOnYPointer));
238*67e74705SXin Li }
TEST(Matcher,Lambda)239*67e74705SXin Li TEST(Matcher, Lambda) {
240*67e74705SXin Li   EXPECT_TRUE(matches("auto f = [] (int i) { return i; };",
241*67e74705SXin Li                       lambdaExpr()));
242*67e74705SXin Li }
243*67e74705SXin Li 
TEST(Matcher,ForRange)244*67e74705SXin Li TEST(Matcher, ForRange) {
245*67e74705SXin Li   EXPECT_TRUE(matches("int as[] = { 1, 2, 3 };"
246*67e74705SXin Li                         "void f() { for (auto &a : as); }",
247*67e74705SXin Li                       cxxForRangeStmt()));
248*67e74705SXin Li   EXPECT_TRUE(notMatches("void f() { for (int i; i<5; ++i); }",
249*67e74705SXin Li                          cxxForRangeStmt()));
250*67e74705SXin Li }
251*67e74705SXin Li 
TEST(Matcher,SubstNonTypeTemplateParm)252*67e74705SXin Li TEST(Matcher, SubstNonTypeTemplateParm) {
253*67e74705SXin Li   EXPECT_FALSE(matches("template<int N>\n"
254*67e74705SXin Li                          "struct A {  static const int n = 0; };\n"
255*67e74705SXin Li                          "struct B : public A<42> {};",
256*67e74705SXin Li                        substNonTypeTemplateParmExpr()));
257*67e74705SXin Li   EXPECT_TRUE(matches("template<int N>\n"
258*67e74705SXin Li                         "struct A {  static const int n = N; };\n"
259*67e74705SXin Li                         "struct B : public A<42> {};",
260*67e74705SXin Li                       substNonTypeTemplateParmExpr()));
261*67e74705SXin Li }
262*67e74705SXin Li 
TEST(Matcher,NonTypeTemplateParmDecl)263*67e74705SXin Li TEST(Matcher, NonTypeTemplateParmDecl) {
264*67e74705SXin Li   EXPECT_TRUE(matches("template <int N> void f();",
265*67e74705SXin Li                       nonTypeTemplateParmDecl(hasName("N"))));
266*67e74705SXin Li   EXPECT_TRUE(
267*67e74705SXin Li     notMatches("template <typename T> void f();", nonTypeTemplateParmDecl()));
268*67e74705SXin Li }
269*67e74705SXin Li 
TEST(Matcher,templateTypeParmDecl)270*67e74705SXin Li TEST(Matcher, templateTypeParmDecl) {
271*67e74705SXin Li   EXPECT_TRUE(matches("template <typename T> void f();",
272*67e74705SXin Li                       templateTypeParmDecl(hasName("T"))));
273*67e74705SXin Li   EXPECT_TRUE(
274*67e74705SXin Li     notMatches("template <int N> void f();", templateTypeParmDecl()));
275*67e74705SXin Li }
276*67e74705SXin Li 
TEST(Matcher,UserDefinedLiteral)277*67e74705SXin Li TEST(Matcher, UserDefinedLiteral) {
278*67e74705SXin Li   EXPECT_TRUE(matches("constexpr char operator \"\" _inc (const char i) {"
279*67e74705SXin Li                         "  return i + 1;"
280*67e74705SXin Li                         "}"
281*67e74705SXin Li                         "char c = 'a'_inc;",
282*67e74705SXin Li                       userDefinedLiteral()));
283*67e74705SXin Li }
284*67e74705SXin Li 
TEST(Matcher,FlowControl)285*67e74705SXin Li TEST(Matcher, FlowControl) {
286*67e74705SXin Li   EXPECT_TRUE(matches("void f() { while(true) { break; } }", breakStmt()));
287*67e74705SXin Li   EXPECT_TRUE(matches("void f() { while(true) { continue; } }",
288*67e74705SXin Li                       continueStmt()));
289*67e74705SXin Li   EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", gotoStmt()));
290*67e74705SXin Li   EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}",
291*67e74705SXin Li                       labelStmt(
292*67e74705SXin Li                         hasDeclaration(
293*67e74705SXin Li                           labelDecl(hasName("FOO"))))));
294*67e74705SXin Li   EXPECT_TRUE(matches("void f() { FOO: ; void *ptr = &&FOO; goto *ptr; }",
295*67e74705SXin Li                       addrLabelExpr()));
296*67e74705SXin Li   EXPECT_TRUE(matches("void f() { return; }", returnStmt()));
297*67e74705SXin Li }
298*67e74705SXin Li 
TEST(Matcher,OverloadedOperatorCall)299*67e74705SXin Li TEST(Matcher, OverloadedOperatorCall) {
300*67e74705SXin Li   StatementMatcher OpCall = cxxOperatorCallExpr();
301*67e74705SXin Li   // Unary operator
302*67e74705SXin Li   EXPECT_TRUE(matches("class Y { }; "
303*67e74705SXin Li                         "bool operator!(Y x) { return false; }; "
304*67e74705SXin Li                         "Y y; bool c = !y;", OpCall));
305*67e74705SXin Li   // No match -- special operators like "new", "delete"
306*67e74705SXin Li   // FIXME: operator new takes size_t, for which we need stddef.h, for which
307*67e74705SXin Li   // we need to figure out include paths in the test.
308*67e74705SXin Li   // EXPECT_TRUE(NotMatches("#include <stddef.h>\n"
309*67e74705SXin Li   //             "class Y { }; "
310*67e74705SXin Li   //             "void *operator new(size_t size) { return 0; } "
311*67e74705SXin Li   //             "Y *y = new Y;", OpCall));
312*67e74705SXin Li   EXPECT_TRUE(notMatches("class Y { }; "
313*67e74705SXin Li                            "void operator delete(void *p) { } "
314*67e74705SXin Li                            "void a() {Y *y = new Y; delete y;}", OpCall));
315*67e74705SXin Li   // Binary operator
316*67e74705SXin Li   EXPECT_TRUE(matches("class Y { }; "
317*67e74705SXin Li                         "bool operator&&(Y x, Y y) { return true; }; "
318*67e74705SXin Li                         "Y a; Y b; bool c = a && b;",
319*67e74705SXin Li                       OpCall));
320*67e74705SXin Li   // No match -- normal operator, not an overloaded one.
321*67e74705SXin Li   EXPECT_TRUE(notMatches("bool x = true, y = true; bool t = x && y;", OpCall));
322*67e74705SXin Li   EXPECT_TRUE(notMatches("int t = 5 << 2;", OpCall));
323*67e74705SXin Li }
324*67e74705SXin Li 
TEST(Matcher,ThisPointerType)325*67e74705SXin Li TEST(Matcher, ThisPointerType) {
326*67e74705SXin Li   StatementMatcher MethodOnY =
327*67e74705SXin Li     cxxMemberCallExpr(thisPointerType(recordDecl(hasName("Y"))));
328*67e74705SXin Li 
329*67e74705SXin Li   EXPECT_TRUE(
330*67e74705SXin Li     matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
331*67e74705SXin Li             MethodOnY));
332*67e74705SXin Li   EXPECT_TRUE(
333*67e74705SXin Li     matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
334*67e74705SXin Li             MethodOnY));
335*67e74705SXin Li   EXPECT_TRUE(
336*67e74705SXin Li     matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
337*67e74705SXin Li             MethodOnY));
338*67e74705SXin Li   EXPECT_TRUE(
339*67e74705SXin Li     matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
340*67e74705SXin Li             MethodOnY));
341*67e74705SXin Li   EXPECT_TRUE(
342*67e74705SXin Li     matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
343*67e74705SXin Li             MethodOnY));
344*67e74705SXin Li 
345*67e74705SXin Li   EXPECT_TRUE(matches(
346*67e74705SXin Li     "class Y {"
347*67e74705SXin Li       "  public: virtual void x();"
348*67e74705SXin Li       "};"
349*67e74705SXin Li       "class X : public Y {"
350*67e74705SXin Li       "  public: virtual void x();"
351*67e74705SXin Li       "};"
352*67e74705SXin Li       "void z() { X *x; x->Y::x(); }", MethodOnY));
353*67e74705SXin Li }
354*67e74705SXin Li 
TEST(Matcher,VariableUsage)355*67e74705SXin Li TEST(Matcher, VariableUsage) {
356*67e74705SXin Li   StatementMatcher Reference =
357*67e74705SXin Li     declRefExpr(to(
358*67e74705SXin Li       varDecl(hasInitializer(
359*67e74705SXin Li         cxxMemberCallExpr(thisPointerType(recordDecl(hasName("Y"))))))));
360*67e74705SXin Li 
361*67e74705SXin Li   EXPECT_TRUE(matches(
362*67e74705SXin Li     "class Y {"
363*67e74705SXin Li       " public:"
364*67e74705SXin Li       "  bool x() const;"
365*67e74705SXin Li       "};"
366*67e74705SXin Li       "void z(const Y &y) {"
367*67e74705SXin Li       "  bool b = y.x();"
368*67e74705SXin Li       "  if (b) {}"
369*67e74705SXin Li       "}", Reference));
370*67e74705SXin Li 
371*67e74705SXin Li   EXPECT_TRUE(notMatches(
372*67e74705SXin Li     "class Y {"
373*67e74705SXin Li       " public:"
374*67e74705SXin Li       "  bool x() const;"
375*67e74705SXin Li       "};"
376*67e74705SXin Li       "void z(const Y &y) {"
377*67e74705SXin Li       "  bool b = y.x();"
378*67e74705SXin Li       "}", Reference));
379*67e74705SXin Li }
380*67e74705SXin Li 
TEST(Matcher,CalledVariable)381*67e74705SXin Li TEST(Matcher, CalledVariable) {
382*67e74705SXin Li   StatementMatcher CallOnVariableY =
383*67e74705SXin Li     cxxMemberCallExpr(on(declRefExpr(to(varDecl(hasName("y"))))));
384*67e74705SXin Li 
385*67e74705SXin Li   EXPECT_TRUE(matches(
386*67e74705SXin Li     "class Y { public: void x() { Y y; y.x(); } };", CallOnVariableY));
387*67e74705SXin Li   EXPECT_TRUE(matches(
388*67e74705SXin Li     "class Y { public: void x() const { Y y; y.x(); } };", CallOnVariableY));
389*67e74705SXin Li   EXPECT_TRUE(matches(
390*67e74705SXin Li     "class Y { public: void x(); };"
391*67e74705SXin Li       "class X : public Y { void z() { X y; y.x(); } };", CallOnVariableY));
392*67e74705SXin Li   EXPECT_TRUE(matches(
393*67e74705SXin Li     "class Y { public: void x(); };"
394*67e74705SXin Li       "class X : public Y { void z() { X *y; y->x(); } };", CallOnVariableY));
395*67e74705SXin Li   EXPECT_TRUE(notMatches(
396*67e74705SXin Li     "class Y { public: void x(); };"
397*67e74705SXin Li       "class X : public Y { void z() { unsigned long y; ((X*)y)->x(); } };",
398*67e74705SXin Li     CallOnVariableY));
399*67e74705SXin Li }
400*67e74705SXin Li 
TEST(UnaryExprOrTypeTraitExpr,MatchesSizeOfAndAlignOf)401*67e74705SXin Li TEST(UnaryExprOrTypeTraitExpr, MatchesSizeOfAndAlignOf) {
402*67e74705SXin Li   EXPECT_TRUE(matches("void x() { int a = sizeof(a); }",
403*67e74705SXin Li                       unaryExprOrTypeTraitExpr()));
404*67e74705SXin Li   EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }",
405*67e74705SXin Li                          alignOfExpr(anything())));
406*67e74705SXin Li   // FIXME: Uncomment once alignof is enabled.
407*67e74705SXin Li   // EXPECT_TRUE(matches("void x() { int a = alignof(a); }",
408*67e74705SXin Li   //                     unaryExprOrTypeTraitExpr()));
409*67e74705SXin Li   // EXPECT_TRUE(notMatches("void x() { int a = alignof(a); }",
410*67e74705SXin Li   //                        sizeOfExpr()));
411*67e74705SXin Li }
412*67e74705SXin Li 
TEST(MemberExpression,DoesNotMatchClasses)413*67e74705SXin Li TEST(MemberExpression, DoesNotMatchClasses) {
414*67e74705SXin Li   EXPECT_TRUE(notMatches("class Y { void x() {} };", memberExpr()));
415*67e74705SXin Li }
416*67e74705SXin Li 
TEST(MemberExpression,MatchesMemberFunctionCall)417*67e74705SXin Li TEST(MemberExpression, MatchesMemberFunctionCall) {
418*67e74705SXin Li   EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpr()));
419*67e74705SXin Li }
420*67e74705SXin Li 
TEST(MemberExpression,MatchesVariable)421*67e74705SXin Li TEST(MemberExpression, MatchesVariable) {
422*67e74705SXin Li   EXPECT_TRUE(
423*67e74705SXin Li     matches("class Y { void x() { this->y; } int y; };", memberExpr()));
424*67e74705SXin Li   EXPECT_TRUE(
425*67e74705SXin Li     matches("class Y { void x() { y; } int y; };", memberExpr()));
426*67e74705SXin Li   EXPECT_TRUE(
427*67e74705SXin Li     matches("class Y { void x() { Y y; y.y; } int y; };", memberExpr()));
428*67e74705SXin Li }
429*67e74705SXin Li 
TEST(MemberExpression,MatchesStaticVariable)430*67e74705SXin Li TEST(MemberExpression, MatchesStaticVariable) {
431*67e74705SXin Li   EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
432*67e74705SXin Li                       memberExpr()));
433*67e74705SXin Li   EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
434*67e74705SXin Li                          memberExpr()));
435*67e74705SXin Li   EXPECT_TRUE(notMatches("class Y { void x() { Y::y; } static int y; };",
436*67e74705SXin Li                          memberExpr()));
437*67e74705SXin Li }
438*67e74705SXin Li 
TEST(Function,MatchesFunctionDeclarations)439*67e74705SXin Li TEST(Function, MatchesFunctionDeclarations) {
440*67e74705SXin Li   StatementMatcher CallFunctionF = callExpr(callee(functionDecl(hasName("f"))));
441*67e74705SXin Li 
442*67e74705SXin Li   EXPECT_TRUE(matches("void f() { f(); }", CallFunctionF));
443*67e74705SXin Li   EXPECT_TRUE(notMatches("void f() { }", CallFunctionF));
444*67e74705SXin Li 
445*67e74705SXin Li   if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getOS() !=
446*67e74705SXin Li     llvm::Triple::Win32) {
447*67e74705SXin Li     // FIXME: Make this work for MSVC.
448*67e74705SXin Li     // Dependent contexts, but a non-dependent call.
449*67e74705SXin Li     EXPECT_TRUE(matches("void f(); template <int N> void g() { f(); }",
450*67e74705SXin Li                         CallFunctionF));
451*67e74705SXin Li     EXPECT_TRUE(
452*67e74705SXin Li       matches("void f(); template <int N> struct S { void g() { f(); } };",
453*67e74705SXin Li               CallFunctionF));
454*67e74705SXin Li   }
455*67e74705SXin Li 
456*67e74705SXin Li   // Depedent calls don't match.
457*67e74705SXin Li   EXPECT_TRUE(
458*67e74705SXin Li     notMatches("void f(int); template <typename T> void g(T t) { f(t); }",
459*67e74705SXin Li                CallFunctionF));
460*67e74705SXin Li   EXPECT_TRUE(
461*67e74705SXin Li     notMatches("void f(int);"
462*67e74705SXin Li                  "template <typename T> struct S { void g(T t) { f(t); } };",
463*67e74705SXin Li                CallFunctionF));
464*67e74705SXin Li 
465*67e74705SXin Li   EXPECT_TRUE(matches("void f(...);", functionDecl(isVariadic())));
466*67e74705SXin Li   EXPECT_TRUE(notMatches("void f(int);", functionDecl(isVariadic())));
467*67e74705SXin Li   EXPECT_TRUE(notMatches("template <typename... Ts> void f(Ts...);",
468*67e74705SXin Li                          functionDecl(isVariadic())));
469*67e74705SXin Li   EXPECT_TRUE(notMatches("void f();", functionDecl(isVariadic())));
470*67e74705SXin Li   EXPECT_TRUE(notMatchesC("void f();", functionDecl(isVariadic())));
471*67e74705SXin Li   EXPECT_TRUE(matches("void f(...);", functionDecl(parameterCountIs(0))));
472*67e74705SXin Li   EXPECT_TRUE(matchesC("void f();", functionDecl(parameterCountIs(0))));
473*67e74705SXin Li   EXPECT_TRUE(matches("void f(int, ...);", functionDecl(parameterCountIs(1))));
474*67e74705SXin Li }
475*67e74705SXin Li 
TEST(FunctionTemplate,MatchesFunctionTemplateDeclarations)476*67e74705SXin Li TEST(FunctionTemplate, MatchesFunctionTemplateDeclarations) {
477*67e74705SXin Li   EXPECT_TRUE(
478*67e74705SXin Li     matches("template <typename T> void f(T t) {}",
479*67e74705SXin Li             functionTemplateDecl(hasName("f"))));
480*67e74705SXin Li }
481*67e74705SXin Li 
TEST(FunctionTemplate,DoesNotMatchFunctionDeclarations)482*67e74705SXin Li TEST(FunctionTemplate, DoesNotMatchFunctionDeclarations) {
483*67e74705SXin Li   EXPECT_TRUE(
484*67e74705SXin Li     notMatches("void f(double d); void f(int t) {}",
485*67e74705SXin Li                functionTemplateDecl(hasName("f"))));
486*67e74705SXin Li }
487*67e74705SXin Li 
TEST(FunctionTemplate,DoesNotMatchFunctionTemplateSpecializations)488*67e74705SXin Li TEST(FunctionTemplate, DoesNotMatchFunctionTemplateSpecializations) {
489*67e74705SXin Li   EXPECT_TRUE(
490*67e74705SXin Li     notMatches("void g(); template <typename T> void f(T t) {}"
491*67e74705SXin Li                  "template <> void f(int t) { g(); }",
492*67e74705SXin Li                functionTemplateDecl(hasName("f"),
493*67e74705SXin Li                                     hasDescendant(declRefExpr(to(
494*67e74705SXin Li                                       functionDecl(hasName("g"))))))));
495*67e74705SXin Li }
496*67e74705SXin Li 
TEST(Matcher,MatchesClassTemplateSpecialization)497*67e74705SXin Li TEST(Matcher, MatchesClassTemplateSpecialization) {
498*67e74705SXin Li   EXPECT_TRUE(matches("template<typename T> struct A {};"
499*67e74705SXin Li                         "template<> struct A<int> {};",
500*67e74705SXin Li                       classTemplateSpecializationDecl()));
501*67e74705SXin Li   EXPECT_TRUE(matches("template<typename T> struct A {}; A<int> a;",
502*67e74705SXin Li                       classTemplateSpecializationDecl()));
503*67e74705SXin Li   EXPECT_TRUE(notMatches("template<typename T> struct A {};",
504*67e74705SXin Li                          classTemplateSpecializationDecl()));
505*67e74705SXin Li }
506*67e74705SXin Li 
TEST(DeclaratorDecl,MatchesDeclaratorDecls)507*67e74705SXin Li TEST(DeclaratorDecl, MatchesDeclaratorDecls) {
508*67e74705SXin Li   EXPECT_TRUE(matches("int x;", declaratorDecl()));
509*67e74705SXin Li   EXPECT_TRUE(notMatches("class A {};", declaratorDecl()));
510*67e74705SXin Li }
511*67e74705SXin Li 
TEST(ParmVarDecl,MatchesParmVars)512*67e74705SXin Li TEST(ParmVarDecl, MatchesParmVars) {
513*67e74705SXin Li   EXPECT_TRUE(matches("void f(int x);", parmVarDecl()));
514*67e74705SXin Li   EXPECT_TRUE(notMatches("void f();", parmVarDecl()));
515*67e74705SXin Li }
516*67e74705SXin Li 
TEST(Matcher,ConstructorCall)517*67e74705SXin Li TEST(Matcher, ConstructorCall) {
518*67e74705SXin Li   StatementMatcher Constructor = cxxConstructExpr();
519*67e74705SXin Li 
520*67e74705SXin Li   EXPECT_TRUE(
521*67e74705SXin Li     matches("class X { public: X(); }; void x() { X x; }", Constructor));
522*67e74705SXin Li   EXPECT_TRUE(
523*67e74705SXin Li     matches("class X { public: X(); }; void x() { X x = X(); }",
524*67e74705SXin Li             Constructor));
525*67e74705SXin Li   EXPECT_TRUE(
526*67e74705SXin Li     matches("class X { public: X(int); }; void x() { X x = 0; }",
527*67e74705SXin Li             Constructor));
528*67e74705SXin Li   EXPECT_TRUE(matches("class X {}; void x(int) { X x; }", Constructor));
529*67e74705SXin Li }
530*67e74705SXin Li 
TEST(Matcher,ThisExpr)531*67e74705SXin Li TEST(Matcher, ThisExpr) {
532*67e74705SXin Li   EXPECT_TRUE(
533*67e74705SXin Li     matches("struct X { int a; int f () { return a; } };", cxxThisExpr()));
534*67e74705SXin Li   EXPECT_TRUE(
535*67e74705SXin Li     notMatches("struct X { int f () { int a; return a; } };", cxxThisExpr()));
536*67e74705SXin Li }
537*67e74705SXin Li 
TEST(Matcher,BindTemporaryExpression)538*67e74705SXin Li TEST(Matcher, BindTemporaryExpression) {
539*67e74705SXin Li   StatementMatcher TempExpression = cxxBindTemporaryExpr();
540*67e74705SXin Li 
541*67e74705SXin Li   std::string ClassString = "class string { public: string(); ~string(); }; ";
542*67e74705SXin Li 
543*67e74705SXin Li   EXPECT_TRUE(
544*67e74705SXin Li     matches(ClassString +
545*67e74705SXin Li               "string GetStringByValue();"
546*67e74705SXin Li                 "void FunctionTakesString(string s);"
547*67e74705SXin Li                 "void run() { FunctionTakesString(GetStringByValue()); }",
548*67e74705SXin Li             TempExpression));
549*67e74705SXin Li 
550*67e74705SXin Li   EXPECT_TRUE(
551*67e74705SXin Li     notMatches(ClassString +
552*67e74705SXin Li                  "string* GetStringPointer(); "
553*67e74705SXin Li                    "void FunctionTakesStringPtr(string* s);"
554*67e74705SXin Li                    "void run() {"
555*67e74705SXin Li                    "  string* s = GetStringPointer();"
556*67e74705SXin Li                    "  FunctionTakesStringPtr(GetStringPointer());"
557*67e74705SXin Li                    "  FunctionTakesStringPtr(s);"
558*67e74705SXin Li                    "}",
559*67e74705SXin Li                TempExpression));
560*67e74705SXin Li 
561*67e74705SXin Li   EXPECT_TRUE(
562*67e74705SXin Li     notMatches("class no_dtor {};"
563*67e74705SXin Li                  "no_dtor GetObjByValue();"
564*67e74705SXin Li                  "void ConsumeObj(no_dtor param);"
565*67e74705SXin Li                  "void run() { ConsumeObj(GetObjByValue()); }",
566*67e74705SXin Li                TempExpression));
567*67e74705SXin Li }
568*67e74705SXin Li 
TEST(MaterializeTemporaryExpr,MatchesTemporary)569*67e74705SXin Li TEST(MaterializeTemporaryExpr, MatchesTemporary) {
570*67e74705SXin Li   std::string ClassString =
571*67e74705SXin Li     "class string { public: string(); int length(); }; ";
572*67e74705SXin Li 
573*67e74705SXin Li   EXPECT_TRUE(
574*67e74705SXin Li     matches(ClassString +
575*67e74705SXin Li               "string GetStringByValue();"
576*67e74705SXin Li                 "void FunctionTakesString(string s);"
577*67e74705SXin Li                 "void run() { FunctionTakesString(GetStringByValue()); }",
578*67e74705SXin Li             materializeTemporaryExpr()));
579*67e74705SXin Li 
580*67e74705SXin Li   EXPECT_TRUE(
581*67e74705SXin Li     notMatches(ClassString +
582*67e74705SXin Li                  "string* GetStringPointer(); "
583*67e74705SXin Li                    "void FunctionTakesStringPtr(string* s);"
584*67e74705SXin Li                    "void run() {"
585*67e74705SXin Li                    "  string* s = GetStringPointer();"
586*67e74705SXin Li                    "  FunctionTakesStringPtr(GetStringPointer());"
587*67e74705SXin Li                    "  FunctionTakesStringPtr(s);"
588*67e74705SXin Li                    "}",
589*67e74705SXin Li                materializeTemporaryExpr()));
590*67e74705SXin Li 
591*67e74705SXin Li   EXPECT_TRUE(
592*67e74705SXin Li     notMatches(ClassString +
593*67e74705SXin Li                  "string GetStringByValue();"
594*67e74705SXin Li                    "void run() { int k = GetStringByValue().length(); }",
595*67e74705SXin Li                materializeTemporaryExpr()));
596*67e74705SXin Li 
597*67e74705SXin Li   EXPECT_TRUE(
598*67e74705SXin Li     notMatches(ClassString +
599*67e74705SXin Li                  "string GetStringByValue();"
600*67e74705SXin Li                    "void run() { GetStringByValue(); }",
601*67e74705SXin Li                materializeTemporaryExpr()));
602*67e74705SXin Li }
603*67e74705SXin Li 
TEST(Matcher,NewExpression)604*67e74705SXin Li TEST(Matcher, NewExpression) {
605*67e74705SXin Li   StatementMatcher New = cxxNewExpr();
606*67e74705SXin Li 
607*67e74705SXin Li   EXPECT_TRUE(matches("class X { public: X(); }; void x() { new X; }", New));
608*67e74705SXin Li   EXPECT_TRUE(
609*67e74705SXin Li     matches("class X { public: X(); }; void x() { new X(); }", New));
610*67e74705SXin Li   EXPECT_TRUE(
611*67e74705SXin Li     matches("class X { public: X(int); }; void x() { new X(0); }", New));
612*67e74705SXin Li   EXPECT_TRUE(matches("class X {}; void x(int) { new X; }", New));
613*67e74705SXin Li }
614*67e74705SXin Li 
TEST(Matcher,DeleteExpression)615*67e74705SXin Li TEST(Matcher, DeleteExpression) {
616*67e74705SXin Li   EXPECT_TRUE(matches("struct A {}; void f(A* a) { delete a; }",
617*67e74705SXin Li                       cxxDeleteExpr()));
618*67e74705SXin Li }
619*67e74705SXin Li 
TEST(Matcher,DefaultArgument)620*67e74705SXin Li TEST(Matcher, DefaultArgument) {
621*67e74705SXin Li   StatementMatcher Arg = cxxDefaultArgExpr();
622*67e74705SXin Li 
623*67e74705SXin Li   EXPECT_TRUE(matches("void x(int, int = 0) { int y; x(y); }", Arg));
624*67e74705SXin Li   EXPECT_TRUE(
625*67e74705SXin Li     matches("class X { void x(int, int = 0) { int y; x(y); } };", Arg));
626*67e74705SXin Li   EXPECT_TRUE(notMatches("void x(int, int = 0) { int y; x(y, 0); }", Arg));
627*67e74705SXin Li }
628*67e74705SXin Li 
TEST(Matcher,StringLiterals)629*67e74705SXin Li TEST(Matcher, StringLiterals) {
630*67e74705SXin Li   StatementMatcher Literal = stringLiteral();
631*67e74705SXin Li   EXPECT_TRUE(matches("const char *s = \"string\";", Literal));
632*67e74705SXin Li   // wide string
633*67e74705SXin Li   EXPECT_TRUE(matches("const wchar_t *s = L\"string\";", Literal));
634*67e74705SXin Li   // with escaped characters
635*67e74705SXin Li   EXPECT_TRUE(matches("const char *s = \"\x05five\";", Literal));
636*67e74705SXin Li   // no matching -- though the data type is the same, there is no string literal
637*67e74705SXin Li   EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));
638*67e74705SXin Li }
639*67e74705SXin Li 
TEST(Matcher,CharacterLiterals)640*67e74705SXin Li TEST(Matcher, CharacterLiterals) {
641*67e74705SXin Li   StatementMatcher CharLiteral = characterLiteral();
642*67e74705SXin Li   EXPECT_TRUE(matches("const char c = 'c';", CharLiteral));
643*67e74705SXin Li   // wide character
644*67e74705SXin Li   EXPECT_TRUE(matches("const char c = L'c';", CharLiteral));
645*67e74705SXin Li   // wide character, Hex encoded, NOT MATCHED!
646*67e74705SXin Li   EXPECT_TRUE(notMatches("const wchar_t c = 0x2126;", CharLiteral));
647*67e74705SXin Li   EXPECT_TRUE(notMatches("const char c = 0x1;", CharLiteral));
648*67e74705SXin Li }
649*67e74705SXin Li 
TEST(Matcher,IntegerLiterals)650*67e74705SXin Li TEST(Matcher, IntegerLiterals) {
651*67e74705SXin Li   StatementMatcher HasIntLiteral = integerLiteral();
652*67e74705SXin Li   EXPECT_TRUE(matches("int i = 10;", HasIntLiteral));
653*67e74705SXin Li   EXPECT_TRUE(matches("int i = 0x1AB;", HasIntLiteral));
654*67e74705SXin Li   EXPECT_TRUE(matches("int i = 10L;", HasIntLiteral));
655*67e74705SXin Li   EXPECT_TRUE(matches("int i = 10U;", HasIntLiteral));
656*67e74705SXin Li 
657*67e74705SXin Li   // Non-matching cases (character literals, float and double)
658*67e74705SXin Li   EXPECT_TRUE(notMatches("int i = L'a';",
659*67e74705SXin Li                          HasIntLiteral));  // this is actually a character
660*67e74705SXin Li   // literal cast to int
661*67e74705SXin Li   EXPECT_TRUE(notMatches("int i = 'a';", HasIntLiteral));
662*67e74705SXin Li   EXPECT_TRUE(notMatches("int i = 1e10;", HasIntLiteral));
663*67e74705SXin Li   EXPECT_TRUE(notMatches("int i = 10.0;", HasIntLiteral));
664*67e74705SXin Li }
665*67e74705SXin Li 
TEST(Matcher,FloatLiterals)666*67e74705SXin Li TEST(Matcher, FloatLiterals) {
667*67e74705SXin Li   StatementMatcher HasFloatLiteral = floatLiteral();
668*67e74705SXin Li   EXPECT_TRUE(matches("float i = 10.0;", HasFloatLiteral));
669*67e74705SXin Li   EXPECT_TRUE(matches("float i = 10.0f;", HasFloatLiteral));
670*67e74705SXin Li   EXPECT_TRUE(matches("double i = 10.0;", HasFloatLiteral));
671*67e74705SXin Li   EXPECT_TRUE(matches("double i = 10.0L;", HasFloatLiteral));
672*67e74705SXin Li   EXPECT_TRUE(matches("double i = 1e10;", HasFloatLiteral));
673*67e74705SXin Li   EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0))));
674*67e74705SXin Li   EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0f))));
675*67e74705SXin Li   EXPECT_TRUE(
676*67e74705SXin Li     matches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(5.0)))));
677*67e74705SXin Li 
678*67e74705SXin Li   EXPECT_TRUE(notMatches("float i = 10;", HasFloatLiteral));
679*67e74705SXin Li   EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0))));
680*67e74705SXin Li   EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0f))));
681*67e74705SXin Li   EXPECT_TRUE(
682*67e74705SXin Li     notMatches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(6.0)))));
683*67e74705SXin Li }
684*67e74705SXin Li 
TEST(Matcher,NullPtrLiteral)685*67e74705SXin Li TEST(Matcher, NullPtrLiteral) {
686*67e74705SXin Li   EXPECT_TRUE(matches("int* i = nullptr;", cxxNullPtrLiteralExpr()));
687*67e74705SXin Li }
688*67e74705SXin Li 
TEST(Matcher,GNUNullExpr)689*67e74705SXin Li TEST(Matcher, GNUNullExpr) {
690*67e74705SXin Li   EXPECT_TRUE(matches("int* i = __null;", gnuNullExpr()));
691*67e74705SXin Li }
692*67e74705SXin Li 
TEST(Matcher,AtomicExpr)693*67e74705SXin Li TEST(Matcher, AtomicExpr) {
694*67e74705SXin Li   EXPECT_TRUE(matches("void foo() { int *ptr; __atomic_load_n(ptr, 1); }",
695*67e74705SXin Li                       atomicExpr()));
696*67e74705SXin Li }
697*67e74705SXin Li 
TEST(Matcher,Initializers)698*67e74705SXin Li TEST(Matcher, Initializers) {
699*67e74705SXin Li   const char *ToMatch = "void foo() { struct point { double x; double y; };"
700*67e74705SXin Li     "  struct point ptarray[10] = "
701*67e74705SXin Li     "      { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }";
702*67e74705SXin Li   EXPECT_TRUE(matchesConditionally(
703*67e74705SXin Li     ToMatch,
704*67e74705SXin Li     initListExpr(
705*67e74705SXin Li       has(
706*67e74705SXin Li         cxxConstructExpr(
707*67e74705SXin Li           requiresZeroInitialization())),
708*67e74705SXin Li       has(
709*67e74705SXin Li         initListExpr(
710*67e74705SXin Li           hasType(asString("struct point")),
711*67e74705SXin Li           has(floatLiteral(equals(1.0))),
712*67e74705SXin Li           has(implicitValueInitExpr(
713*67e74705SXin Li             hasType(asString("double")))))),
714*67e74705SXin Li       has(
715*67e74705SXin Li         initListExpr(
716*67e74705SXin Li           hasType(asString("struct point")),
717*67e74705SXin Li           has(floatLiteral(equals(2.0))),
718*67e74705SXin Li           has(floatLiteral(equals(1.0)))))
719*67e74705SXin Li     ), true, "-std=gnu++98"));
720*67e74705SXin Li 
721*67e74705SXin Li   EXPECT_TRUE(matchesC99(ToMatch,
722*67e74705SXin Li                          initListExpr(
723*67e74705SXin Li                            hasSyntacticForm(
724*67e74705SXin Li                              initListExpr(
725*67e74705SXin Li                                has(
726*67e74705SXin Li                                  designatedInitExpr(
727*67e74705SXin Li                                    designatorCountIs(2),
728*67e74705SXin Li                                    has(floatLiteral(
729*67e74705SXin Li                                      equals(1.0))),
730*67e74705SXin Li                                    has(integerLiteral(
731*67e74705SXin Li                                      equals(2))))),
732*67e74705SXin Li                                has(
733*67e74705SXin Li                                  designatedInitExpr(
734*67e74705SXin Li                                    designatorCountIs(2),
735*67e74705SXin Li                                    has(floatLiteral(
736*67e74705SXin Li                                      equals(2.0))),
737*67e74705SXin Li                                    has(integerLiteral(
738*67e74705SXin Li                                      equals(2))))),
739*67e74705SXin Li                                has(
740*67e74705SXin Li                                  designatedInitExpr(
741*67e74705SXin Li                                    designatorCountIs(2),
742*67e74705SXin Li                                    has(floatLiteral(
743*67e74705SXin Li                                      equals(1.0))),
744*67e74705SXin Li                                    has(integerLiteral(
745*67e74705SXin Li                                      equals(0)))))
746*67e74705SXin Li                              )))));
747*67e74705SXin Li }
748*67e74705SXin Li 
TEST(Matcher,ParenListExpr)749*67e74705SXin Li TEST(Matcher, ParenListExpr) {
750*67e74705SXin Li   EXPECT_TRUE(
751*67e74705SXin Li     matches("template<typename T> class foo { void bar() { foo X(*this); } };"
752*67e74705SXin Li               "template class foo<int>;",
753*67e74705SXin Li             varDecl(hasInitializer(parenListExpr(has(unaryOperator()))))));
754*67e74705SXin Li }
755*67e74705SXin Li 
TEST(Matcher,StmtExpr)756*67e74705SXin Li TEST(Matcher, StmtExpr) {
757*67e74705SXin Li   EXPECT_TRUE(matches("void declToImport() { int C = ({int X=4; X;}); }",
758*67e74705SXin Li                       varDecl(hasInitializer(stmtExpr()))));
759*67e74705SXin Li }
760*67e74705SXin Li 
TEST(Matcher,ImportPredefinedExpr)761*67e74705SXin Li TEST(Matcher, ImportPredefinedExpr) {
762*67e74705SXin Li   // __func__ expands as StringLiteral("foo")
763*67e74705SXin Li   EXPECT_TRUE(matches("void foo() { __func__; }",
764*67e74705SXin Li                       predefinedExpr(
765*67e74705SXin Li                         hasType(asString("const char [4]")),
766*67e74705SXin Li                         has(stringLiteral()))));
767*67e74705SXin Li }
768*67e74705SXin Li 
TEST(Matcher,AsmStatement)769*67e74705SXin Li TEST(Matcher, AsmStatement) {
770*67e74705SXin Li   EXPECT_TRUE(matches("void foo() { __asm(\"mov al, 2\"); }", asmStmt()));
771*67e74705SXin Li }
772*67e74705SXin Li 
TEST(Matcher,Conditions)773*67e74705SXin Li TEST(Matcher, Conditions) {
774*67e74705SXin Li   StatementMatcher Condition =
775*67e74705SXin Li     ifStmt(hasCondition(cxxBoolLiteral(equals(true))));
776*67e74705SXin Li 
777*67e74705SXin Li   EXPECT_TRUE(matches("void x() { if (true) {} }", Condition));
778*67e74705SXin Li   EXPECT_TRUE(notMatches("void x() { if (false) {} }", Condition));
779*67e74705SXin Li   EXPECT_TRUE(notMatches("void x() { bool a = true; if (a) {} }", Condition));
780*67e74705SXin Li   EXPECT_TRUE(notMatches("void x() { if (true || false) {} }", Condition));
781*67e74705SXin Li   EXPECT_TRUE(notMatches("void x() { if (1) {} }", Condition));
782*67e74705SXin Li }
783*67e74705SXin Li 
TEST(Matcher,ConditionalOperator)784*67e74705SXin Li TEST(Matcher, ConditionalOperator) {
785*67e74705SXin Li   StatementMatcher Conditional = conditionalOperator(
786*67e74705SXin Li     hasCondition(cxxBoolLiteral(equals(true))),
787*67e74705SXin Li     hasTrueExpression(cxxBoolLiteral(equals(false))));
788*67e74705SXin Li 
789*67e74705SXin Li   EXPECT_TRUE(matches("void x() { true ? false : true; }", Conditional));
790*67e74705SXin Li   EXPECT_TRUE(notMatches("void x() { false ? false : true; }", Conditional));
791*67e74705SXin Li   EXPECT_TRUE(notMatches("void x() { true ? true : false; }", Conditional));
792*67e74705SXin Li 
793*67e74705SXin Li   StatementMatcher ConditionalFalse = conditionalOperator(
794*67e74705SXin Li     hasFalseExpression(cxxBoolLiteral(equals(false))));
795*67e74705SXin Li 
796*67e74705SXin Li   EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
797*67e74705SXin Li   EXPECT_TRUE(
798*67e74705SXin Li     notMatches("void x() { true ? false : true; }", ConditionalFalse));
799*67e74705SXin Li 
800*67e74705SXin Li   EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
801*67e74705SXin Li   EXPECT_TRUE(
802*67e74705SXin Li     notMatches("void x() { true ? false : true; }", ConditionalFalse));
803*67e74705SXin Li }
804*67e74705SXin Li 
TEST(Matcher,BinaryConditionalOperator)805*67e74705SXin Li TEST(Matcher, BinaryConditionalOperator) {
806*67e74705SXin Li   StatementMatcher AlwaysOne = binaryConditionalOperator(
807*67e74705SXin Li     hasCondition(implicitCastExpr(
808*67e74705SXin Li       has(
809*67e74705SXin Li         opaqueValueExpr(
810*67e74705SXin Li           hasSourceExpression((integerLiteral(equals(1)))))))),
811*67e74705SXin Li     hasFalseExpression(integerLiteral(equals(0))));
812*67e74705SXin Li 
813*67e74705SXin Li   EXPECT_TRUE(matches("void x() { 1 ?: 0; }", AlwaysOne));
814*67e74705SXin Li 
815*67e74705SXin Li   StatementMatcher FourNotFive = binaryConditionalOperator(
816*67e74705SXin Li     hasTrueExpression(opaqueValueExpr(
817*67e74705SXin Li       hasSourceExpression((integerLiteral(equals(4)))))),
818*67e74705SXin Li     hasFalseExpression(integerLiteral(equals(5))));
819*67e74705SXin Li 
820*67e74705SXin Li   EXPECT_TRUE(matches("void x() { 4 ?: 5; }", FourNotFive));
821*67e74705SXin Li }
822*67e74705SXin Li 
TEST(ArraySubscriptMatchers,ArraySubscripts)823*67e74705SXin Li TEST(ArraySubscriptMatchers, ArraySubscripts) {
824*67e74705SXin Li   EXPECT_TRUE(matches("int i[2]; void f() { i[1] = 1; }",
825*67e74705SXin Li                       arraySubscriptExpr()));
826*67e74705SXin Li   EXPECT_TRUE(notMatches("int i; void f() { i = 1; }",
827*67e74705SXin Li                          arraySubscriptExpr()));
828*67e74705SXin Li }
829*67e74705SXin Li 
TEST(For,FindsForLoops)830*67e74705SXin Li TEST(For, FindsForLoops) {
831*67e74705SXin Li   EXPECT_TRUE(matches("void f() { for(;;); }", forStmt()));
832*67e74705SXin Li   EXPECT_TRUE(matches("void f() { if(true) for(;;); }", forStmt()));
833*67e74705SXin Li   EXPECT_TRUE(notMatches("int as[] = { 1, 2, 3 };"
834*67e74705SXin Li                            "void f() { for (auto &a : as); }",
835*67e74705SXin Li                          forStmt()));
836*67e74705SXin Li }
837*67e74705SXin Li 
TEST(For,ReportsNoFalsePositives)838*67e74705SXin Li TEST(For, ReportsNoFalsePositives) {
839*67e74705SXin Li   EXPECT_TRUE(notMatches("void f() { ; }", forStmt()));
840*67e74705SXin Li   EXPECT_TRUE(notMatches("void f() { if(true); }", forStmt()));
841*67e74705SXin Li }
842*67e74705SXin Li 
TEST(CompoundStatement,HandlesSimpleCases)843*67e74705SXin Li TEST(CompoundStatement, HandlesSimpleCases) {
844*67e74705SXin Li   EXPECT_TRUE(notMatches("void f();", compoundStmt()));
845*67e74705SXin Li   EXPECT_TRUE(matches("void f() {}", compoundStmt()));
846*67e74705SXin Li   EXPECT_TRUE(matches("void f() {{}}", compoundStmt()));
847*67e74705SXin Li }
848*67e74705SXin Li 
TEST(CompoundStatement,DoesNotMatchEmptyStruct)849*67e74705SXin Li TEST(CompoundStatement, DoesNotMatchEmptyStruct) {
850*67e74705SXin Li   // It's not a compound statement just because there's "{}" in the source
851*67e74705SXin Li   // text. This is an AST search, not grep.
852*67e74705SXin Li   EXPECT_TRUE(notMatches("namespace n { struct S {}; }",
853*67e74705SXin Li                          compoundStmt()));
854*67e74705SXin Li   EXPECT_TRUE(matches("namespace n { struct S { void f() {{}} }; }",
855*67e74705SXin Li                       compoundStmt()));
856*67e74705SXin Li }
857*67e74705SXin Li 
TEST(CastExpression,MatchesExplicitCasts)858*67e74705SXin Li TEST(CastExpression, MatchesExplicitCasts) {
859*67e74705SXin Li   EXPECT_TRUE(matches("char *p = reinterpret_cast<char *>(&p);",castExpr()));
860*67e74705SXin Li   EXPECT_TRUE(matches("void *p = (void *)(&p);", castExpr()));
861*67e74705SXin Li   EXPECT_TRUE(matches("char q, *p = const_cast<char *>(&q);", castExpr()));
862*67e74705SXin Li   EXPECT_TRUE(matches("char c = char(0);", castExpr()));
863*67e74705SXin Li }
TEST(CastExpression,MatchesImplicitCasts)864*67e74705SXin Li TEST(CastExpression, MatchesImplicitCasts) {
865*67e74705SXin Li   // This test creates an implicit cast from int to char.
866*67e74705SXin Li   EXPECT_TRUE(matches("char c = 0;", castExpr()));
867*67e74705SXin Li   // This test creates an implicit cast from lvalue to rvalue.
868*67e74705SXin Li   EXPECT_TRUE(matches("char c = 0, d = c;", castExpr()));
869*67e74705SXin Li }
870*67e74705SXin Li 
TEST(CastExpression,DoesNotMatchNonCasts)871*67e74705SXin Li TEST(CastExpression, DoesNotMatchNonCasts) {
872*67e74705SXin Li   EXPECT_TRUE(notMatches("char c = '0';", castExpr()));
873*67e74705SXin Li   EXPECT_TRUE(notMatches("char c, &q = c;", castExpr()));
874*67e74705SXin Li   EXPECT_TRUE(notMatches("int i = (0);", castExpr()));
875*67e74705SXin Li   EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
876*67e74705SXin Li }
877*67e74705SXin Li 
TEST(ReinterpretCast,MatchesSimpleCase)878*67e74705SXin Li TEST(ReinterpretCast, MatchesSimpleCase) {
879*67e74705SXin Li   EXPECT_TRUE(matches("char* p = reinterpret_cast<char*>(&p);",
880*67e74705SXin Li                       cxxReinterpretCastExpr()));
881*67e74705SXin Li }
882*67e74705SXin Li 
TEST(ReinterpretCast,DoesNotMatchOtherCasts)883*67e74705SXin Li TEST(ReinterpretCast, DoesNotMatchOtherCasts) {
884*67e74705SXin Li   EXPECT_TRUE(notMatches("char* p = (char*)(&p);", cxxReinterpretCastExpr()));
885*67e74705SXin Li   EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
886*67e74705SXin Li                          cxxReinterpretCastExpr()));
887*67e74705SXin Li   EXPECT_TRUE(notMatches("void* p = static_cast<void*>(&p);",
888*67e74705SXin Li                          cxxReinterpretCastExpr()));
889*67e74705SXin Li   EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
890*67e74705SXin Li                            "B b;"
891*67e74705SXin Li                            "D* p = dynamic_cast<D*>(&b);",
892*67e74705SXin Li                          cxxReinterpretCastExpr()));
893*67e74705SXin Li }
894*67e74705SXin Li 
TEST(FunctionalCast,MatchesSimpleCase)895*67e74705SXin Li TEST(FunctionalCast, MatchesSimpleCase) {
896*67e74705SXin Li   std::string foo_class = "class Foo { public: Foo(const char*); };";
897*67e74705SXin Li   EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",
898*67e74705SXin Li                       cxxFunctionalCastExpr()));
899*67e74705SXin Li }
900*67e74705SXin Li 
TEST(FunctionalCast,DoesNotMatchOtherCasts)901*67e74705SXin Li TEST(FunctionalCast, DoesNotMatchOtherCasts) {
902*67e74705SXin Li   std::string FooClass = "class Foo { public: Foo(const char*); };";
903*67e74705SXin Li   EXPECT_TRUE(
904*67e74705SXin Li     notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",
905*67e74705SXin Li                cxxFunctionalCastExpr()));
906*67e74705SXin Li   EXPECT_TRUE(
907*67e74705SXin Li     notMatches(FooClass + "void r() { Foo f = \"hello world\"; }",
908*67e74705SXin Li                cxxFunctionalCastExpr()));
909*67e74705SXin Li }
910*67e74705SXin Li 
TEST(DynamicCast,MatchesSimpleCase)911*67e74705SXin Li TEST(DynamicCast, MatchesSimpleCase) {
912*67e74705SXin Li   EXPECT_TRUE(matches("struct B { virtual ~B() {} }; struct D : B {};"
913*67e74705SXin Li                         "B b;"
914*67e74705SXin Li                         "D* p = dynamic_cast<D*>(&b);",
915*67e74705SXin Li                       cxxDynamicCastExpr()));
916*67e74705SXin Li }
917*67e74705SXin Li 
TEST(StaticCast,MatchesSimpleCase)918*67e74705SXin Li TEST(StaticCast, MatchesSimpleCase) {
919*67e74705SXin Li   EXPECT_TRUE(matches("void* p(static_cast<void*>(&p));",
920*67e74705SXin Li                       cxxStaticCastExpr()));
921*67e74705SXin Li }
922*67e74705SXin Li 
TEST(StaticCast,DoesNotMatchOtherCasts)923*67e74705SXin Li TEST(StaticCast, DoesNotMatchOtherCasts) {
924*67e74705SXin Li   EXPECT_TRUE(notMatches("char* p = (char*)(&p);", cxxStaticCastExpr()));
925*67e74705SXin Li   EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
926*67e74705SXin Li                          cxxStaticCastExpr()));
927*67e74705SXin Li   EXPECT_TRUE(notMatches("void* p = reinterpret_cast<char*>(&p);",
928*67e74705SXin Li                          cxxStaticCastExpr()));
929*67e74705SXin Li   EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
930*67e74705SXin Li                            "B b;"
931*67e74705SXin Li                            "D* p = dynamic_cast<D*>(&b);",
932*67e74705SXin Li                          cxxStaticCastExpr()));
933*67e74705SXin Li }
934*67e74705SXin Li 
TEST(CStyleCast,MatchesSimpleCase)935*67e74705SXin Li TEST(CStyleCast, MatchesSimpleCase) {
936*67e74705SXin Li   EXPECT_TRUE(matches("int i = (int) 2.2f;", cStyleCastExpr()));
937*67e74705SXin Li }
938*67e74705SXin Li 
TEST(CStyleCast,DoesNotMatchOtherCasts)939*67e74705SXin Li TEST(CStyleCast, DoesNotMatchOtherCasts) {
940*67e74705SXin Li   EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);"
941*67e74705SXin Li                            "char q, *r = const_cast<char*>(&q);"
942*67e74705SXin Li                            "void* s = reinterpret_cast<char*>(&s);"
943*67e74705SXin Li                            "struct B { virtual ~B() {} }; struct D : B {};"
944*67e74705SXin Li                            "B b;"
945*67e74705SXin Li                            "D* t = dynamic_cast<D*>(&b);",
946*67e74705SXin Li                          cStyleCastExpr()));
947*67e74705SXin Li }
948*67e74705SXin Li 
TEST(ImplicitCast,MatchesSimpleCase)949*67e74705SXin Li TEST(ImplicitCast, MatchesSimpleCase) {
950*67e74705SXin Li   // This test creates an implicit const cast.
951*67e74705SXin Li   EXPECT_TRUE(matches("int x = 0; const int y = x;",
952*67e74705SXin Li                       varDecl(hasInitializer(implicitCastExpr()))));
953*67e74705SXin Li   // This test creates an implicit cast from int to char.
954*67e74705SXin Li   EXPECT_TRUE(matches("char c = 0;",
955*67e74705SXin Li                       varDecl(hasInitializer(implicitCastExpr()))));
956*67e74705SXin Li   // This test creates an implicit array-to-pointer cast.
957*67e74705SXin Li   EXPECT_TRUE(matches("int arr[6]; int *p = arr;",
958*67e74705SXin Li                       varDecl(hasInitializer(implicitCastExpr()))));
959*67e74705SXin Li }
960*67e74705SXin Li 
TEST(ImplicitCast,DoesNotMatchIncorrectly)961*67e74705SXin Li TEST(ImplicitCast, DoesNotMatchIncorrectly) {
962*67e74705SXin Li   // This test verifies that implicitCastExpr() matches exactly when implicit casts
963*67e74705SXin Li   // are present, and that it ignores explicit and paren casts.
964*67e74705SXin Li 
965*67e74705SXin Li   // These two test cases have no casts.
966*67e74705SXin Li   EXPECT_TRUE(notMatches("int x = 0;",
967*67e74705SXin Li                          varDecl(hasInitializer(implicitCastExpr()))));
968*67e74705SXin Li   EXPECT_TRUE(notMatches("int x = 0, &y = x;",
969*67e74705SXin Li                          varDecl(hasInitializer(implicitCastExpr()))));
970*67e74705SXin Li 
971*67e74705SXin Li   EXPECT_TRUE(notMatches("int x = 0; double d = (double) x;",
972*67e74705SXin Li                          varDecl(hasInitializer(implicitCastExpr()))));
973*67e74705SXin Li   EXPECT_TRUE(notMatches("const int *p; int *q = const_cast<int *>(p);",
974*67e74705SXin Li                          varDecl(hasInitializer(implicitCastExpr()))));
975*67e74705SXin Li 
976*67e74705SXin Li   EXPECT_TRUE(notMatches("int x = (0);",
977*67e74705SXin Li                          varDecl(hasInitializer(implicitCastExpr()))));
978*67e74705SXin Li }
979*67e74705SXin Li 
TEST(Statement,DoesNotMatchDeclarations)980*67e74705SXin Li TEST(Statement, DoesNotMatchDeclarations) {
981*67e74705SXin Li   EXPECT_TRUE(notMatches("class X {};", stmt()));
982*67e74705SXin Li }
983*67e74705SXin Li 
TEST(Statement,MatchesCompoundStatments)984*67e74705SXin Li TEST(Statement, MatchesCompoundStatments) {
985*67e74705SXin Li   EXPECT_TRUE(matches("void x() {}", stmt()));
986*67e74705SXin Li }
987*67e74705SXin Li 
TEST(DeclarationStatement,DoesNotMatchCompoundStatements)988*67e74705SXin Li TEST(DeclarationStatement, DoesNotMatchCompoundStatements) {
989*67e74705SXin Li   EXPECT_TRUE(notMatches("void x() {}", declStmt()));
990*67e74705SXin Li }
991*67e74705SXin Li 
TEST(DeclarationStatement,MatchesVariableDeclarationStatements)992*67e74705SXin Li TEST(DeclarationStatement, MatchesVariableDeclarationStatements) {
993*67e74705SXin Li   EXPECT_TRUE(matches("void x() { int a; }", declStmt()));
994*67e74705SXin Li }
995*67e74705SXin Li 
TEST(ExprWithCleanups,MatchesExprWithCleanups)996*67e74705SXin Li TEST(ExprWithCleanups, MatchesExprWithCleanups) {
997*67e74705SXin Li   EXPECT_TRUE(matches("struct Foo { ~Foo(); };"
998*67e74705SXin Li                         "const Foo f = Foo();",
999*67e74705SXin Li                       varDecl(hasInitializer(exprWithCleanups()))));
1000*67e74705SXin Li   EXPECT_FALSE(matches("struct Foo { }; Foo a;"
1001*67e74705SXin Li                        "const Foo f = a;",
1002*67e74705SXin Li                        varDecl(hasInitializer(exprWithCleanups()))));
1003*67e74705SXin Li }
1004*67e74705SXin Li 
TEST(InitListExpression,MatchesInitListExpression)1005*67e74705SXin Li TEST(InitListExpression, MatchesInitListExpression) {
1006*67e74705SXin Li   EXPECT_TRUE(matches("int a[] = { 1, 2 };",
1007*67e74705SXin Li                       initListExpr(hasType(asString("int [2]")))));
1008*67e74705SXin Li   EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };",
1009*67e74705SXin Li                       initListExpr(hasType(recordDecl(hasName("B"))))));
1010*67e74705SXin Li   EXPECT_TRUE(matches("struct S { S(void (*a)()); };"
1011*67e74705SXin Li                         "void f();"
1012*67e74705SXin Li                         "S s[1] = { &f };",
1013*67e74705SXin Li                       declRefExpr(to(functionDecl(hasName("f"))))));
1014*67e74705SXin Li   EXPECT_TRUE(
1015*67e74705SXin Li     matches("int i[1] = {42, [0] = 43};", integerLiteral(equals(42))));
1016*67e74705SXin Li }
1017*67e74705SXin Li 
TEST(UsingDeclaration,MatchesUsingDeclarations)1018*67e74705SXin Li TEST(UsingDeclaration, MatchesUsingDeclarations) {
1019*67e74705SXin Li   EXPECT_TRUE(matches("namespace X { int x; } using X::x;",
1020*67e74705SXin Li                       usingDecl()));
1021*67e74705SXin Li }
1022*67e74705SXin Li 
TEST(UsingDeclaration,MatchesShadowUsingDelcarations)1023*67e74705SXin Li TEST(UsingDeclaration, MatchesShadowUsingDelcarations) {
1024*67e74705SXin Li   EXPECT_TRUE(matches("namespace f { int a; } using f::a;",
1025*67e74705SXin Li                       usingDecl(hasAnyUsingShadowDecl(hasName("a")))));
1026*67e74705SXin Li }
1027*67e74705SXin Li 
TEST(UsingDirectiveDeclaration,MatchesUsingNamespace)1028*67e74705SXin Li TEST(UsingDirectiveDeclaration, MatchesUsingNamespace) {
1029*67e74705SXin Li   EXPECT_TRUE(matches("namespace X { int x; } using namespace X;",
1030*67e74705SXin Li                       usingDirectiveDecl()));
1031*67e74705SXin Li   EXPECT_FALSE(
1032*67e74705SXin Li     matches("namespace X { int x; } using X::x;", usingDirectiveDecl()));
1033*67e74705SXin Li }
1034*67e74705SXin Li 
1035*67e74705SXin Li 
TEST(While,MatchesWhileLoops)1036*67e74705SXin Li TEST(While, MatchesWhileLoops) {
1037*67e74705SXin Li   EXPECT_TRUE(notMatches("void x() {}", whileStmt()));
1038*67e74705SXin Li   EXPECT_TRUE(matches("void x() { while(true); }", whileStmt()));
1039*67e74705SXin Li   EXPECT_TRUE(notMatches("void x() { do {} while(true); }", whileStmt()));
1040*67e74705SXin Li }
1041*67e74705SXin Li 
TEST(Do,MatchesDoLoops)1042*67e74705SXin Li TEST(Do, MatchesDoLoops) {
1043*67e74705SXin Li   EXPECT_TRUE(matches("void x() { do {} while(true); }", doStmt()));
1044*67e74705SXin Li   EXPECT_TRUE(matches("void x() { do ; while(false); }", doStmt()));
1045*67e74705SXin Li }
1046*67e74705SXin Li 
TEST(Do,DoesNotMatchWhileLoops)1047*67e74705SXin Li TEST(Do, DoesNotMatchWhileLoops) {
1048*67e74705SXin Li   EXPECT_TRUE(notMatches("void x() { while(true) {} }", doStmt()));
1049*67e74705SXin Li }
1050*67e74705SXin Li 
TEST(SwitchCase,MatchesCase)1051*67e74705SXin Li TEST(SwitchCase, MatchesCase) {
1052*67e74705SXin Li   EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchCase()));
1053*67e74705SXin Li   EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchCase()));
1054*67e74705SXin Li   EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchCase()));
1055*67e74705SXin Li   EXPECT_TRUE(notMatches("void x() { switch(42) {} }", switchCase()));
1056*67e74705SXin Li }
1057*67e74705SXin Li 
TEST(SwitchCase,MatchesSwitch)1058*67e74705SXin Li TEST(SwitchCase, MatchesSwitch) {
1059*67e74705SXin Li   EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchStmt()));
1060*67e74705SXin Li   EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchStmt()));
1061*67e74705SXin Li   EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchStmt()));
1062*67e74705SXin Li   EXPECT_TRUE(notMatches("void x() {}", switchStmt()));
1063*67e74705SXin Li }
1064*67e74705SXin Li 
TEST(ExceptionHandling,SimpleCases)1065*67e74705SXin Li TEST(ExceptionHandling, SimpleCases) {
1066*67e74705SXin Li   EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", cxxCatchStmt()));
1067*67e74705SXin Li   EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", cxxTryStmt()));
1068*67e74705SXin Li   EXPECT_TRUE(
1069*67e74705SXin Li     notMatches("void foo() try { } catch(int X) { }", cxxThrowExpr()));
1070*67e74705SXin Li   EXPECT_TRUE(matches("void foo() try { throw; } catch(int X) { }",
1071*67e74705SXin Li                       cxxThrowExpr()));
1072*67e74705SXin Li   EXPECT_TRUE(matches("void foo() try { throw 5;} catch(int X) { }",
1073*67e74705SXin Li                       cxxThrowExpr()));
1074*67e74705SXin Li   EXPECT_TRUE(matches("void foo() try { throw; } catch(...) { }",
1075*67e74705SXin Li                       cxxCatchStmt(isCatchAll())));
1076*67e74705SXin Li   EXPECT_TRUE(notMatches("void foo() try { throw; } catch(int) { }",
1077*67e74705SXin Li                          cxxCatchStmt(isCatchAll())));
1078*67e74705SXin Li   EXPECT_TRUE(matches("void foo() try {} catch(int X) { }",
1079*67e74705SXin Li                       varDecl(isExceptionVariable())));
1080*67e74705SXin Li   EXPECT_TRUE(notMatches("void foo() try { int X; } catch (...) { }",
1081*67e74705SXin Li                          varDecl(isExceptionVariable())));
1082*67e74705SXin Li }
1083*67e74705SXin Li 
TEST(ParenExpression,SimpleCases)1084*67e74705SXin Li TEST(ParenExpression, SimpleCases) {
1085*67e74705SXin Li   EXPECT_TRUE(matches("int i = (3);", parenExpr()));
1086*67e74705SXin Li   EXPECT_TRUE(matches("int i = (3 + 7);", parenExpr()));
1087*67e74705SXin Li   EXPECT_TRUE(notMatches("int i = 3;", parenExpr()));
1088*67e74705SXin Li   EXPECT_TRUE(notMatches("int foo() { return 1; }; int a = foo();",
1089*67e74705SXin Li                          parenExpr()));
1090*67e74705SXin Li }
1091*67e74705SXin Li 
TEST(TypeMatching,MatchesTypes)1092*67e74705SXin Li TEST(TypeMatching, MatchesTypes) {
1093*67e74705SXin Li   EXPECT_TRUE(matches("struct S {};", qualType().bind("loc")));
1094*67e74705SXin Li }
1095*67e74705SXin Li 
TEST(TypeMatching,MatchesConstantArrayTypes)1096*67e74705SXin Li TEST(TypeMatching, MatchesConstantArrayTypes) {
1097*67e74705SXin Li   EXPECT_TRUE(matches("int a[2];", constantArrayType()));
1098*67e74705SXin Li   EXPECT_TRUE(notMatches(
1099*67e74705SXin Li     "void f() { int a[] = { 2, 3 }; int b[a[0]]; }",
1100*67e74705SXin Li     constantArrayType(hasElementType(builtinType()))));
1101*67e74705SXin Li 
1102*67e74705SXin Li   EXPECT_TRUE(matches("int a[42];", constantArrayType(hasSize(42))));
1103*67e74705SXin Li   EXPECT_TRUE(matches("int b[2*21];", constantArrayType(hasSize(42))));
1104*67e74705SXin Li   EXPECT_TRUE(notMatches("int c[41], d[43];", constantArrayType(hasSize(42))));
1105*67e74705SXin Li }
1106*67e74705SXin Li 
TEST(TypeMatching,MatchesDependentSizedArrayTypes)1107*67e74705SXin Li TEST(TypeMatching, MatchesDependentSizedArrayTypes) {
1108*67e74705SXin Li   EXPECT_TRUE(matches(
1109*67e74705SXin Li     "template <typename T, int Size> class array { T data[Size]; };",
1110*67e74705SXin Li     dependentSizedArrayType()));
1111*67e74705SXin Li   EXPECT_TRUE(notMatches(
1112*67e74705SXin Li     "int a[42]; int b[] = { 2, 3 }; void f() { int c[b[0]]; }",
1113*67e74705SXin Li     dependentSizedArrayType()));
1114*67e74705SXin Li }
1115*67e74705SXin Li 
TEST(TypeMatching,MatchesIncompleteArrayType)1116*67e74705SXin Li TEST(TypeMatching, MatchesIncompleteArrayType) {
1117*67e74705SXin Li   EXPECT_TRUE(matches("int a[] = { 2, 3 };", incompleteArrayType()));
1118*67e74705SXin Li   EXPECT_TRUE(matches("void f(int a[]) {}", incompleteArrayType()));
1119*67e74705SXin Li 
1120*67e74705SXin Li   EXPECT_TRUE(notMatches("int a[42]; void f() { int b[a[0]]; }",
1121*67e74705SXin Li                          incompleteArrayType()));
1122*67e74705SXin Li }
1123*67e74705SXin Li 
TEST(TypeMatching,MatchesVariableArrayType)1124*67e74705SXin Li TEST(TypeMatching, MatchesVariableArrayType) {
1125*67e74705SXin Li   EXPECT_TRUE(matches("void f(int b) { int a[b]; }", variableArrayType()));
1126*67e74705SXin Li   EXPECT_TRUE(notMatches("int a[] = {2, 3}; int b[42];", variableArrayType()));
1127*67e74705SXin Li 
1128*67e74705SXin Li   EXPECT_TRUE(matches(
1129*67e74705SXin Li     "void f(int b) { int a[b]; }",
1130*67e74705SXin Li     variableArrayType(hasSizeExpr(ignoringImpCasts(declRefExpr(to(
1131*67e74705SXin Li       varDecl(hasName("b")))))))));
1132*67e74705SXin Li }
1133*67e74705SXin Li 
1134*67e74705SXin Li 
TEST(TypeMatching,MatchesAtomicTypes)1135*67e74705SXin Li TEST(TypeMatching, MatchesAtomicTypes) {
1136*67e74705SXin Li   if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getOS() !=
1137*67e74705SXin Li     llvm::Triple::Win32) {
1138*67e74705SXin Li     // FIXME: Make this work for MSVC.
1139*67e74705SXin Li     EXPECT_TRUE(matches("_Atomic(int) i;", atomicType()));
1140*67e74705SXin Li 
1141*67e74705SXin Li     EXPECT_TRUE(matches("_Atomic(int) i;",
1142*67e74705SXin Li                         atomicType(hasValueType(isInteger()))));
1143*67e74705SXin Li     EXPECT_TRUE(notMatches("_Atomic(float) f;",
1144*67e74705SXin Li                            atomicType(hasValueType(isInteger()))));
1145*67e74705SXin Li   }
1146*67e74705SXin Li }
1147*67e74705SXin Li 
TEST(TypeMatching,MatchesAutoTypes)1148*67e74705SXin Li TEST(TypeMatching, MatchesAutoTypes) {
1149*67e74705SXin Li   EXPECT_TRUE(matches("auto i = 2;", autoType()));
1150*67e74705SXin Li   EXPECT_TRUE(matches("int v[] = { 2, 3 }; void f() { for (int i : v) {} }",
1151*67e74705SXin Li                       autoType()));
1152*67e74705SXin Li 
1153*67e74705SXin Li   // FIXME: Matching against the type-as-written can't work here, because the
1154*67e74705SXin Li   //        type as written was not deduced.
1155*67e74705SXin Li   //EXPECT_TRUE(matches("auto a = 1;",
1156*67e74705SXin Li   //                    autoType(hasDeducedType(isInteger()))));
1157*67e74705SXin Li   //EXPECT_TRUE(notMatches("auto b = 2.0;",
1158*67e74705SXin Li   //                       autoType(hasDeducedType(isInteger()))));
1159*67e74705SXin Li }
1160*67e74705SXin Li 
TEST(TypeMatching,MatchesFunctionTypes)1161*67e74705SXin Li TEST(TypeMatching, MatchesFunctionTypes) {
1162*67e74705SXin Li   EXPECT_TRUE(matches("int (*f)(int);", functionType()));
1163*67e74705SXin Li   EXPECT_TRUE(matches("void f(int i) {}", functionType()));
1164*67e74705SXin Li }
1165*67e74705SXin Li 
TEST(TypeMatching,IgnoringParens)1166*67e74705SXin Li TEST(TypeMatching, IgnoringParens) {
1167*67e74705SXin Li   EXPECT_TRUE(
1168*67e74705SXin Li       notMatches("void (*fp)(void);", pointerType(pointee(functionType()))));
1169*67e74705SXin Li   EXPECT_TRUE(matches("void (*fp)(void);",
1170*67e74705SXin Li                       pointerType(pointee(ignoringParens(functionType())))));
1171*67e74705SXin Li }
1172*67e74705SXin Li 
TEST(TypeMatching,MatchesFunctionProtoTypes)1173*67e74705SXin Li TEST(TypeMatching, MatchesFunctionProtoTypes) {
1174*67e74705SXin Li   EXPECT_TRUE(matches("int (*f)(int);", functionProtoType()));
1175*67e74705SXin Li   EXPECT_TRUE(matches("void f(int i);", functionProtoType()));
1176*67e74705SXin Li   EXPECT_TRUE(matches("void f();", functionProtoType(parameterCountIs(0))));
1177*67e74705SXin Li   EXPECT_TRUE(notMatchesC("void f();", functionProtoType()));
1178*67e74705SXin Li   EXPECT_TRUE(
1179*67e74705SXin Li     matchesC("void f(void);", functionProtoType(parameterCountIs(0))));
1180*67e74705SXin Li }
1181*67e74705SXin Li 
TEST(TypeMatching,MatchesParenType)1182*67e74705SXin Li TEST(TypeMatching, MatchesParenType) {
1183*67e74705SXin Li   EXPECT_TRUE(
1184*67e74705SXin Li     matches("int (*array)[4];", varDecl(hasType(pointsTo(parenType())))));
1185*67e74705SXin Li   EXPECT_TRUE(notMatches("int *array[4];", varDecl(hasType(parenType()))));
1186*67e74705SXin Li 
1187*67e74705SXin Li   EXPECT_TRUE(matches(
1188*67e74705SXin Li     "int (*ptr_to_func)(int);",
1189*67e74705SXin Li     varDecl(hasType(pointsTo(parenType(innerType(functionType())))))));
1190*67e74705SXin Li   EXPECT_TRUE(notMatches(
1191*67e74705SXin Li     "int (*ptr_to_array)[4];",
1192*67e74705SXin Li     varDecl(hasType(pointsTo(parenType(innerType(functionType())))))));
1193*67e74705SXin Li }
1194*67e74705SXin Li 
TEST(TypeMatching,PointerTypes)1195*67e74705SXin Li TEST(TypeMatching, PointerTypes) {
1196*67e74705SXin Li   // FIXME: Reactive when these tests can be more specific (not matching
1197*67e74705SXin Li   // implicit code on certain platforms), likely when we have hasDescendant for
1198*67e74705SXin Li   // Types/TypeLocs.
1199*67e74705SXin Li   //EXPECT_TRUE(matchAndVerifyResultTrue(
1200*67e74705SXin Li   //    "int* a;",
1201*67e74705SXin Li   //    pointerTypeLoc(pointeeLoc(typeLoc().bind("loc"))),
1202*67e74705SXin Li   //    llvm::make_unique<VerifyIdIsBoundTo<TypeLoc>>("loc", 1)));
1203*67e74705SXin Li   //EXPECT_TRUE(matchAndVerifyResultTrue(
1204*67e74705SXin Li   //    "int* a;",
1205*67e74705SXin Li   //    pointerTypeLoc().bind("loc"),
1206*67e74705SXin Li   //    llvm::make_unique<VerifyIdIsBoundTo<TypeLoc>>("loc", 1)));
1207*67e74705SXin Li   EXPECT_TRUE(matches(
1208*67e74705SXin Li     "int** a;",
1209*67e74705SXin Li     loc(pointerType(pointee(qualType())))));
1210*67e74705SXin Li   EXPECT_TRUE(matches(
1211*67e74705SXin Li     "int** a;",
1212*67e74705SXin Li     loc(pointerType(pointee(pointerType())))));
1213*67e74705SXin Li   EXPECT_TRUE(matches(
1214*67e74705SXin Li     "int* b; int* * const a = &b;",
1215*67e74705SXin Li     loc(qualType(isConstQualified(), pointerType()))));
1216*67e74705SXin Li 
1217*67e74705SXin Li   std::string Fragment = "struct A { int i; }; int A::* ptr = &A::i;";
1218*67e74705SXin Li   EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
1219*67e74705SXin Li                                            hasType(blockPointerType()))));
1220*67e74705SXin Li   EXPECT_TRUE(matches(Fragment, varDecl(hasName("ptr"),
1221*67e74705SXin Li                                         hasType(memberPointerType()))));
1222*67e74705SXin Li   EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
1223*67e74705SXin Li                                            hasType(pointerType()))));
1224*67e74705SXin Li   EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
1225*67e74705SXin Li                                            hasType(referenceType()))));
1226*67e74705SXin Li   EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
1227*67e74705SXin Li                                            hasType(lValueReferenceType()))));
1228*67e74705SXin Li   EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
1229*67e74705SXin Li                                            hasType(rValueReferenceType()))));
1230*67e74705SXin Li 
1231*67e74705SXin Li   Fragment = "int *ptr;";
1232*67e74705SXin Li   EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
1233*67e74705SXin Li                                            hasType(blockPointerType()))));
1234*67e74705SXin Li   EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
1235*67e74705SXin Li                                            hasType(memberPointerType()))));
1236*67e74705SXin Li   EXPECT_TRUE(matches(Fragment, varDecl(hasName("ptr"),
1237*67e74705SXin Li                                         hasType(pointerType()))));
1238*67e74705SXin Li   EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
1239*67e74705SXin Li                                            hasType(referenceType()))));
1240*67e74705SXin Li 
1241*67e74705SXin Li   Fragment = "int a; int &ref = a;";
1242*67e74705SXin Li   EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
1243*67e74705SXin Li                                            hasType(blockPointerType()))));
1244*67e74705SXin Li   EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
1245*67e74705SXin Li                                            hasType(memberPointerType()))));
1246*67e74705SXin Li   EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
1247*67e74705SXin Li                                            hasType(pointerType()))));
1248*67e74705SXin Li   EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
1249*67e74705SXin Li                                         hasType(referenceType()))));
1250*67e74705SXin Li   EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
1251*67e74705SXin Li                                         hasType(lValueReferenceType()))));
1252*67e74705SXin Li   EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
1253*67e74705SXin Li                                            hasType(rValueReferenceType()))));
1254*67e74705SXin Li 
1255*67e74705SXin Li   Fragment = "int &&ref = 2;";
1256*67e74705SXin Li   EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
1257*67e74705SXin Li                                            hasType(blockPointerType()))));
1258*67e74705SXin Li   EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
1259*67e74705SXin Li                                            hasType(memberPointerType()))));
1260*67e74705SXin Li   EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
1261*67e74705SXin Li                                            hasType(pointerType()))));
1262*67e74705SXin Li   EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
1263*67e74705SXin Li                                         hasType(referenceType()))));
1264*67e74705SXin Li   EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
1265*67e74705SXin Li                                            hasType(lValueReferenceType()))));
1266*67e74705SXin Li   EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
1267*67e74705SXin Li                                         hasType(rValueReferenceType()))));
1268*67e74705SXin Li }
1269*67e74705SXin Li 
TEST(TypeMatching,AutoRefTypes)1270*67e74705SXin Li TEST(TypeMatching, AutoRefTypes) {
1271*67e74705SXin Li   std::string Fragment = "auto a = 1;"
1272*67e74705SXin Li     "auto b = a;"
1273*67e74705SXin Li     "auto &c = a;"
1274*67e74705SXin Li     "auto &&d = c;"
1275*67e74705SXin Li     "auto &&e = 2;";
1276*67e74705SXin Li   EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("a"),
1277*67e74705SXin Li                                            hasType(referenceType()))));
1278*67e74705SXin Li   EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("b"),
1279*67e74705SXin Li                                            hasType(referenceType()))));
1280*67e74705SXin Li   EXPECT_TRUE(matches(Fragment, varDecl(hasName("c"),
1281*67e74705SXin Li                                         hasType(referenceType()))));
1282*67e74705SXin Li   EXPECT_TRUE(matches(Fragment, varDecl(hasName("c"),
1283*67e74705SXin Li                                         hasType(lValueReferenceType()))));
1284*67e74705SXin Li   EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("c"),
1285*67e74705SXin Li                                            hasType(rValueReferenceType()))));
1286*67e74705SXin Li   EXPECT_TRUE(matches(Fragment, varDecl(hasName("d"),
1287*67e74705SXin Li                                         hasType(referenceType()))));
1288*67e74705SXin Li   EXPECT_TRUE(matches(Fragment, varDecl(hasName("d"),
1289*67e74705SXin Li                                         hasType(lValueReferenceType()))));
1290*67e74705SXin Li   EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("d"),
1291*67e74705SXin Li                                            hasType(rValueReferenceType()))));
1292*67e74705SXin Li   EXPECT_TRUE(matches(Fragment, varDecl(hasName("e"),
1293*67e74705SXin Li                                         hasType(referenceType()))));
1294*67e74705SXin Li   EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("e"),
1295*67e74705SXin Li                                            hasType(lValueReferenceType()))));
1296*67e74705SXin Li   EXPECT_TRUE(matches(Fragment, varDecl(hasName("e"),
1297*67e74705SXin Li                                         hasType(rValueReferenceType()))));
1298*67e74705SXin Li }
1299*67e74705SXin Li 
TEST(TypeMatching,MatchesEnumTypes)1300*67e74705SXin Li TEST(TypeMatching, MatchesEnumTypes) {
1301*67e74705SXin Li   EXPECT_TRUE(matches("enum Color { Green }; Color color;",
1302*67e74705SXin Li                       loc(enumType())));
1303*67e74705SXin Li   EXPECT_TRUE(matches("enum class Color { Green }; Color color;",
1304*67e74705SXin Li                       loc(enumType())));
1305*67e74705SXin Li }
1306*67e74705SXin Li 
TEST(TypeMatching,MatchesPointersToConstTypes)1307*67e74705SXin Li TEST(TypeMatching, MatchesPointersToConstTypes) {
1308*67e74705SXin Li   EXPECT_TRUE(matches("int b; int * const a = &b;",
1309*67e74705SXin Li                       loc(pointerType())));
1310*67e74705SXin Li   EXPECT_TRUE(matches("int b; int * const a = &b;",
1311*67e74705SXin Li                       loc(pointerType())));
1312*67e74705SXin Li   EXPECT_TRUE(matches(
1313*67e74705SXin Li     "int b; const int * a = &b;",
1314*67e74705SXin Li     loc(pointerType(pointee(builtinType())))));
1315*67e74705SXin Li   EXPECT_TRUE(matches(
1316*67e74705SXin Li     "int b; const int * a = &b;",
1317*67e74705SXin Li     pointerType(pointee(builtinType()))));
1318*67e74705SXin Li }
1319*67e74705SXin Li 
TEST(TypeMatching,MatchesTypedefTypes)1320*67e74705SXin Li TEST(TypeMatching, MatchesTypedefTypes) {
1321*67e74705SXin Li   EXPECT_TRUE(matches("typedef int X; X a;", varDecl(hasName("a"),
1322*67e74705SXin Li                                                      hasType(typedefType()))));
1323*67e74705SXin Li }
1324*67e74705SXin Li 
TEST(TypeMatching,MatchesTemplateSpecializationType)1325*67e74705SXin Li TEST(TypeMatching, MatchesTemplateSpecializationType) {
1326*67e74705SXin Li   EXPECT_TRUE(matches("template <typename T> class A{}; A<int> a;",
1327*67e74705SXin Li                       templateSpecializationType()));
1328*67e74705SXin Li }
1329*67e74705SXin Li 
TEST(TypeMatching,MatchesRecordType)1330*67e74705SXin Li TEST(TypeMatching, MatchesRecordType) {
1331*67e74705SXin Li   EXPECT_TRUE(matches("class C{}; C c;", recordType()));
1332*67e74705SXin Li   EXPECT_TRUE(matches("struct S{}; S s;",
1333*67e74705SXin Li                       recordType(hasDeclaration(recordDecl(hasName("S"))))));
1334*67e74705SXin Li   EXPECT_TRUE(notMatches("int i;",
1335*67e74705SXin Li                          recordType(hasDeclaration(recordDecl(hasName("S"))))));
1336*67e74705SXin Li }
1337*67e74705SXin Li 
TEST(TypeMatching,MatchesElaboratedType)1338*67e74705SXin Li TEST(TypeMatching, MatchesElaboratedType) {
1339*67e74705SXin Li   EXPECT_TRUE(matches(
1340*67e74705SXin Li     "namespace N {"
1341*67e74705SXin Li       "  namespace M {"
1342*67e74705SXin Li       "    class D {};"
1343*67e74705SXin Li       "  }"
1344*67e74705SXin Li       "}"
1345*67e74705SXin Li       "N::M::D d;", elaboratedType()));
1346*67e74705SXin Li   EXPECT_TRUE(matches("class C {} c;", elaboratedType()));
1347*67e74705SXin Li   EXPECT_TRUE(notMatches("class C {}; C c;", elaboratedType()));
1348*67e74705SXin Li }
1349*67e74705SXin Li 
TEST(TypeMatching,MatchesSubstTemplateTypeParmType)1350*67e74705SXin Li TEST(TypeMatching, MatchesSubstTemplateTypeParmType) {
1351*67e74705SXin Li   const std::string code = "template <typename T>"
1352*67e74705SXin Li     "int F() {"
1353*67e74705SXin Li     "  return 1 + T();"
1354*67e74705SXin Li     "}"
1355*67e74705SXin Li     "int i = F<int>();";
1356*67e74705SXin Li   EXPECT_FALSE(matches(code, binaryOperator(hasLHS(
1357*67e74705SXin Li     expr(hasType(substTemplateTypeParmType()))))));
1358*67e74705SXin Li   EXPECT_TRUE(matches(code, binaryOperator(hasRHS(
1359*67e74705SXin Li     expr(hasType(substTemplateTypeParmType()))))));
1360*67e74705SXin Li }
1361*67e74705SXin Li 
TEST(NNS,MatchesNestedNameSpecifiers)1362*67e74705SXin Li TEST(NNS, MatchesNestedNameSpecifiers) {
1363*67e74705SXin Li   EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;",
1364*67e74705SXin Li                       nestedNameSpecifier()));
1365*67e74705SXin Li   EXPECT_TRUE(matches("template <typename T> class A { typename T::B b; };",
1366*67e74705SXin Li                       nestedNameSpecifier()));
1367*67e74705SXin Li   EXPECT_TRUE(matches("struct A { void f(); }; void A::f() {}",
1368*67e74705SXin Li                       nestedNameSpecifier()));
1369*67e74705SXin Li   EXPECT_TRUE(matches("namespace a { namespace b {} } namespace ab = a::b;",
1370*67e74705SXin Li                       nestedNameSpecifier()));
1371*67e74705SXin Li 
1372*67e74705SXin Li   EXPECT_TRUE(matches(
1373*67e74705SXin Li     "struct A { static void f() {} }; void g() { A::f(); }",
1374*67e74705SXin Li     nestedNameSpecifier()));
1375*67e74705SXin Li   EXPECT_TRUE(notMatches(
1376*67e74705SXin Li     "struct A { static void f() {} }; void g(A* a) { a->f(); }",
1377*67e74705SXin Li     nestedNameSpecifier()));
1378*67e74705SXin Li }
1379*67e74705SXin Li 
TEST(NullStatement,SimpleCases)1380*67e74705SXin Li TEST(NullStatement, SimpleCases) {
1381*67e74705SXin Li   EXPECT_TRUE(matches("void f() {int i;;}", nullStmt()));
1382*67e74705SXin Li   EXPECT_TRUE(notMatches("void f() {int i;}", nullStmt()));
1383*67e74705SXin Li }
1384*67e74705SXin Li 
TEST(NS,Alias)1385*67e74705SXin Li TEST(NS, Alias) {
1386*67e74705SXin Li   EXPECT_TRUE(matches("namespace test {} namespace alias = ::test;",
1387*67e74705SXin Li                       namespaceAliasDecl(hasName("alias"))));
1388*67e74705SXin Li }
1389*67e74705SXin Li 
TEST(NNS,MatchesTypes)1390*67e74705SXin Li TEST(NNS, MatchesTypes) {
1391*67e74705SXin Li   NestedNameSpecifierMatcher Matcher = nestedNameSpecifier(
1392*67e74705SXin Li     specifiesType(hasDeclaration(recordDecl(hasName("A")))));
1393*67e74705SXin Li   EXPECT_TRUE(matches("struct A { struct B {}; }; A::B b;", Matcher));
1394*67e74705SXin Li   EXPECT_TRUE(matches("struct A { struct B { struct C {}; }; }; A::B::C c;",
1395*67e74705SXin Li                       Matcher));
1396*67e74705SXin Li   EXPECT_TRUE(notMatches("namespace A { struct B {}; } A::B b;", Matcher));
1397*67e74705SXin Li }
1398*67e74705SXin Li 
TEST(NNS,MatchesNamespaceDecls)1399*67e74705SXin Li TEST(NNS, MatchesNamespaceDecls) {
1400*67e74705SXin Li   NestedNameSpecifierMatcher Matcher = nestedNameSpecifier(
1401*67e74705SXin Li     specifiesNamespace(hasName("ns")));
1402*67e74705SXin Li   EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;", Matcher));
1403*67e74705SXin Li   EXPECT_TRUE(notMatches("namespace xx { struct A {}; } xx::A a;", Matcher));
1404*67e74705SXin Li   EXPECT_TRUE(notMatches("struct ns { struct A {}; }; ns::A a;", Matcher));
1405*67e74705SXin Li }
1406*67e74705SXin Li 
TEST(NNS,MatchesNestedNameSpecifierPrefixes)1407*67e74705SXin Li TEST(NNS, MatchesNestedNameSpecifierPrefixes) {
1408*67e74705SXin Li   EXPECT_TRUE(matches(
1409*67e74705SXin Li     "struct A { struct B { struct C {}; }; }; A::B::C c;",
1410*67e74705SXin Li     nestedNameSpecifier(hasPrefix(specifiesType(asString("struct A"))))));
1411*67e74705SXin Li   EXPECT_TRUE(matches(
1412*67e74705SXin Li     "struct A { struct B { struct C {}; }; }; A::B::C c;",
1413*67e74705SXin Li     nestedNameSpecifierLoc(hasPrefix(
1414*67e74705SXin Li       specifiesTypeLoc(loc(qualType(asString("struct A"))))))));
1415*67e74705SXin Li }
1416*67e74705SXin Li 
1417*67e74705SXin Li 
1418*67e74705SXin Li template <typename T>
1419*67e74705SXin Li class VerifyAncestorHasChildIsEqual : public BoundNodesCallback {
1420*67e74705SXin Li public:
run(const BoundNodes * Nodes)1421*67e74705SXin Li   bool run(const BoundNodes *Nodes) override { return false; }
1422*67e74705SXin Li 
run(const BoundNodes * Nodes,ASTContext * Context)1423*67e74705SXin Li   bool run(const BoundNodes *Nodes, ASTContext *Context) override {
1424*67e74705SXin Li     const T *Node = Nodes->getNodeAs<T>("");
1425*67e74705SXin Li     return verify(*Nodes, *Context, Node);
1426*67e74705SXin Li   }
1427*67e74705SXin Li 
verify(const BoundNodes & Nodes,ASTContext & Context,const Stmt * Node)1428*67e74705SXin Li   bool verify(const BoundNodes &Nodes, ASTContext &Context, const Stmt *Node) {
1429*67e74705SXin Li     // Use the original typed pointer to verify we can pass pointers to subtypes
1430*67e74705SXin Li     // to equalsNode.
1431*67e74705SXin Li     const T *TypedNode = cast<T>(Node);
1432*67e74705SXin Li     return selectFirst<T>(
1433*67e74705SXin Li       "", match(stmt(hasParent(
1434*67e74705SXin Li         stmt(has(stmt(equalsNode(TypedNode)))).bind(""))),
1435*67e74705SXin Li                 *Node, Context)) != nullptr;
1436*67e74705SXin Li   }
verify(const BoundNodes & Nodes,ASTContext & Context,const Decl * Node)1437*67e74705SXin Li   bool verify(const BoundNodes &Nodes, ASTContext &Context, const Decl *Node) {
1438*67e74705SXin Li     // Use the original typed pointer to verify we can pass pointers to subtypes
1439*67e74705SXin Li     // to equalsNode.
1440*67e74705SXin Li     const T *TypedNode = cast<T>(Node);
1441*67e74705SXin Li     return selectFirst<T>(
1442*67e74705SXin Li       "", match(decl(hasParent(
1443*67e74705SXin Li         decl(has(decl(equalsNode(TypedNode)))).bind(""))),
1444*67e74705SXin Li                 *Node, Context)) != nullptr;
1445*67e74705SXin Li   }
verify(const BoundNodes & Nodes,ASTContext & Context,const Type * Node)1446*67e74705SXin Li   bool verify(const BoundNodes &Nodes, ASTContext &Context, const Type *Node) {
1447*67e74705SXin Li     // Use the original typed pointer to verify we can pass pointers to subtypes
1448*67e74705SXin Li     // to equalsNode.
1449*67e74705SXin Li     const T *TypedNode = cast<T>(Node);
1450*67e74705SXin Li     const auto *Dec = Nodes.getNodeAs<FieldDecl>("decl");
1451*67e74705SXin Li     return selectFirst<T>(
1452*67e74705SXin Li       "", match(fieldDecl(hasParent(decl(has(fieldDecl(
1453*67e74705SXin Li         hasType(type(equalsNode(TypedNode)).bind(""))))))),
1454*67e74705SXin Li                 *Dec, Context)) != nullptr;
1455*67e74705SXin Li   }
1456*67e74705SXin Li };
1457*67e74705SXin Li 
TEST(IsEqualTo,MatchesNodesByIdentity)1458*67e74705SXin Li TEST(IsEqualTo, MatchesNodesByIdentity) {
1459*67e74705SXin Li   EXPECT_TRUE(matchAndVerifyResultTrue(
1460*67e74705SXin Li     "class X { class Y {}; };", recordDecl(hasName("::X::Y")).bind(""),
1461*67e74705SXin Li     llvm::make_unique<VerifyAncestorHasChildIsEqual<CXXRecordDecl>>()));
1462*67e74705SXin Li   EXPECT_TRUE(matchAndVerifyResultTrue(
1463*67e74705SXin Li     "void f() { if (true) if(true) {} }", ifStmt().bind(""),
1464*67e74705SXin Li     llvm::make_unique<VerifyAncestorHasChildIsEqual<IfStmt>>()));
1465*67e74705SXin Li   EXPECT_TRUE(matchAndVerifyResultTrue(
1466*67e74705SXin Li     "class X { class Y {} y; };",
1467*67e74705SXin Li     fieldDecl(hasName("y"), hasType(type().bind(""))).bind("decl"),
1468*67e74705SXin Li     llvm::make_unique<VerifyAncestorHasChildIsEqual<Type>>()));
1469*67e74705SXin Li }
1470*67e74705SXin Li 
TEST(TypedefDeclMatcher,Match)1471*67e74705SXin Li TEST(TypedefDeclMatcher, Match) {
1472*67e74705SXin Li   EXPECT_TRUE(matches("typedef int typedefDeclTest;",
1473*67e74705SXin Li                       typedefDecl(hasName("typedefDeclTest"))));
1474*67e74705SXin Li   EXPECT_TRUE(notMatches("using typedefDeclTest2 = int;",
1475*67e74705SXin Li                          typedefDecl(hasName("typedefDeclTest2"))));
1476*67e74705SXin Li }
1477*67e74705SXin Li 
TEST(TypeAliasDeclMatcher,Match)1478*67e74705SXin Li TEST(TypeAliasDeclMatcher, Match) {
1479*67e74705SXin Li   EXPECT_TRUE(matches("using typeAliasTest2 = int;",
1480*67e74705SXin Li                       typeAliasDecl(hasName("typeAliasTest2"))));
1481*67e74705SXin Li   EXPECT_TRUE(notMatches("typedef int typeAliasTest;",
1482*67e74705SXin Li                          typeAliasDecl(hasName("typeAliasTest"))));
1483*67e74705SXin Li }
1484*67e74705SXin Li 
TEST(TypedefNameDeclMatcher,Match)1485*67e74705SXin Li TEST(TypedefNameDeclMatcher, Match) {
1486*67e74705SXin Li   EXPECT_TRUE(matches("typedef int typedefNameDeclTest1;",
1487*67e74705SXin Li                       typedefNameDecl(hasName("typedefNameDeclTest1"))));
1488*67e74705SXin Li   EXPECT_TRUE(matches("using typedefNameDeclTest2 = int;",
1489*67e74705SXin Li                       typedefNameDecl(hasName("typedefNameDeclTest2"))));
1490*67e74705SXin Li }
1491*67e74705SXin Li 
TEST(ObjCMessageExprMatcher,SimpleExprs)1492*67e74705SXin Li TEST(ObjCMessageExprMatcher, SimpleExprs) {
1493*67e74705SXin Li   // don't find ObjCMessageExpr where none are present
1494*67e74705SXin Li   EXPECT_TRUE(notMatchesObjC("", objcMessageExpr(anything())));
1495*67e74705SXin Li 
1496*67e74705SXin Li   std::string Objc1String =
1497*67e74705SXin Li     "@interface Str "
1498*67e74705SXin Li       " - (Str *)uppercaseString:(Str *)str;"
1499*67e74705SXin Li       "@end "
1500*67e74705SXin Li       "@interface foo "
1501*67e74705SXin Li       "- (void)meth:(Str *)text;"
1502*67e74705SXin Li       "@end "
1503*67e74705SXin Li       " "
1504*67e74705SXin Li       "@implementation foo "
1505*67e74705SXin Li       "- (void) meth:(Str *)text { "
1506*67e74705SXin Li       "  [self contents];"
1507*67e74705SXin Li       "  Str *up = [text uppercaseString];"
1508*67e74705SXin Li       "} "
1509*67e74705SXin Li       "@end ";
1510*67e74705SXin Li   EXPECT_TRUE(matchesObjC(
1511*67e74705SXin Li     Objc1String,
1512*67e74705SXin Li     objcMessageExpr(anything())));
1513*67e74705SXin Li   EXPECT_TRUE(matchesObjC(
1514*67e74705SXin Li     Objc1String,
1515*67e74705SXin Li     objcMessageExpr(hasSelector("contents"))));
1516*67e74705SXin Li   EXPECT_TRUE(matchesObjC(
1517*67e74705SXin Li     Objc1String,
1518*67e74705SXin Li     objcMessageExpr(matchesSelector("cont*"))));
1519*67e74705SXin Li   EXPECT_FALSE(matchesObjC(
1520*67e74705SXin Li     Objc1String,
1521*67e74705SXin Li     objcMessageExpr(matchesSelector("?cont*"))));
1522*67e74705SXin Li   EXPECT_TRUE(notMatchesObjC(
1523*67e74705SXin Li     Objc1String,
1524*67e74705SXin Li     objcMessageExpr(hasSelector("contents"), hasNullSelector())));
1525*67e74705SXin Li   EXPECT_TRUE(matchesObjC(
1526*67e74705SXin Li     Objc1String,
1527*67e74705SXin Li     objcMessageExpr(hasSelector("contents"), hasUnarySelector())));
1528*67e74705SXin Li   EXPECT_TRUE(matchesObjC(
1529*67e74705SXin Li     Objc1String,
1530*67e74705SXin Li     objcMessageExpr(hasSelector("contents"), numSelectorArgs(0))));
1531*67e74705SXin Li   EXPECT_TRUE(matchesObjC(
1532*67e74705SXin Li     Objc1String,
1533*67e74705SXin Li     objcMessageExpr(matchesSelector("uppercase*"),
1534*67e74705SXin Li                     argumentCountIs(0)
1535*67e74705SXin Li     )));
1536*67e74705SXin Li }
1537*67e74705SXin Li 
1538*67e74705SXin Li } // namespace ast_matchers
1539*67e74705SXin Li } // namespace clang
1540