xref: /aosp_15_r20/external/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // unittests/ASTMatchers/ASTMatchersNarrowingTest.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 
22*67e74705SXin Li 
TEST(AllOf,AllOverloadsWork)23*67e74705SXin Li TEST(AllOf, AllOverloadsWork) {
24*67e74705SXin Li   const char Program[] =
25*67e74705SXin Li       "struct T { };"
26*67e74705SXin Li       "int f(int, T*, int, int);"
27*67e74705SXin Li       "void g(int x) { T t; f(x, &t, 3, 4); }";
28*67e74705SXin Li   EXPECT_TRUE(matches(Program,
29*67e74705SXin Li       callExpr(allOf(callee(functionDecl(hasName("f"))),
30*67e74705SXin Li                      hasArgument(0, declRefExpr(to(varDecl())))))));
31*67e74705SXin Li   EXPECT_TRUE(matches(Program,
32*67e74705SXin Li       callExpr(allOf(callee(functionDecl(hasName("f"))),
33*67e74705SXin Li                      hasArgument(0, declRefExpr(to(varDecl()))),
34*67e74705SXin Li                      hasArgument(1, hasType(pointsTo(
35*67e74705SXin Li                                         recordDecl(hasName("T")))))))));
36*67e74705SXin Li   EXPECT_TRUE(matches(Program,
37*67e74705SXin Li       callExpr(allOf(callee(functionDecl(hasName("f"))),
38*67e74705SXin Li                      hasArgument(0, declRefExpr(to(varDecl()))),
39*67e74705SXin Li                      hasArgument(1, hasType(pointsTo(
40*67e74705SXin Li                                         recordDecl(hasName("T"))))),
41*67e74705SXin Li                      hasArgument(2, integerLiteral(equals(3)))))));
42*67e74705SXin Li   EXPECT_TRUE(matches(Program,
43*67e74705SXin Li       callExpr(allOf(callee(functionDecl(hasName("f"))),
44*67e74705SXin Li                      hasArgument(0, declRefExpr(to(varDecl()))),
45*67e74705SXin Li                      hasArgument(1, hasType(pointsTo(
46*67e74705SXin Li                                         recordDecl(hasName("T"))))),
47*67e74705SXin Li                      hasArgument(2, integerLiteral(equals(3))),
48*67e74705SXin Li                      hasArgument(3, integerLiteral(equals(4)))))));
49*67e74705SXin Li }
50*67e74705SXin Li 
TEST(DeclarationMatcher,MatchHas)51*67e74705SXin Li TEST(DeclarationMatcher, MatchHas) {
52*67e74705SXin Li   DeclarationMatcher HasClassX = recordDecl(has(recordDecl(hasName("X"))));
53*67e74705SXin Li   EXPECT_TRUE(matches("class Y { class X {}; };", HasClassX));
54*67e74705SXin Li   EXPECT_TRUE(matches("class X {};", HasClassX));
55*67e74705SXin Li 
56*67e74705SXin Li   DeclarationMatcher YHasClassX =
57*67e74705SXin Li     recordDecl(hasName("Y"), has(recordDecl(hasName("X"))));
58*67e74705SXin Li   EXPECT_TRUE(matches("class Y { class X {}; };", YHasClassX));
59*67e74705SXin Li   EXPECT_TRUE(notMatches("class X {};", YHasClassX));
60*67e74705SXin Li   EXPECT_TRUE(
61*67e74705SXin Li     notMatches("class Y { class Z { class X {}; }; };", YHasClassX));
62*67e74705SXin Li }
63*67e74705SXin Li 
TEST(DeclarationMatcher,MatchHasRecursiveAllOf)64*67e74705SXin Li TEST(DeclarationMatcher, MatchHasRecursiveAllOf) {
65*67e74705SXin Li   DeclarationMatcher Recursive =
66*67e74705SXin Li     recordDecl(
67*67e74705SXin Li       has(recordDecl(
68*67e74705SXin Li         has(recordDecl(hasName("X"))),
69*67e74705SXin Li         has(recordDecl(hasName("Y"))),
70*67e74705SXin Li         hasName("Z"))),
71*67e74705SXin Li       has(recordDecl(
72*67e74705SXin Li         has(recordDecl(hasName("A"))),
73*67e74705SXin Li         has(recordDecl(hasName("B"))),
74*67e74705SXin Li         hasName("C"))),
75*67e74705SXin Li       hasName("F"));
76*67e74705SXin Li 
77*67e74705SXin Li   EXPECT_TRUE(matches(
78*67e74705SXin Li     "class F {"
79*67e74705SXin Li       "  class Z {"
80*67e74705SXin Li       "    class X {};"
81*67e74705SXin Li       "    class Y {};"
82*67e74705SXin Li       "  };"
83*67e74705SXin Li       "  class C {"
84*67e74705SXin Li       "    class A {};"
85*67e74705SXin Li       "    class B {};"
86*67e74705SXin Li       "  };"
87*67e74705SXin Li       "};", Recursive));
88*67e74705SXin Li 
89*67e74705SXin Li   EXPECT_TRUE(matches(
90*67e74705SXin Li     "class F {"
91*67e74705SXin Li       "  class Z {"
92*67e74705SXin Li       "    class A {};"
93*67e74705SXin Li       "    class X {};"
94*67e74705SXin Li       "    class Y {};"
95*67e74705SXin Li       "  };"
96*67e74705SXin Li       "  class C {"
97*67e74705SXin Li       "    class X {};"
98*67e74705SXin Li       "    class A {};"
99*67e74705SXin Li       "    class B {};"
100*67e74705SXin Li       "  };"
101*67e74705SXin Li       "};", Recursive));
102*67e74705SXin Li 
103*67e74705SXin Li   EXPECT_TRUE(matches(
104*67e74705SXin Li     "class O1 {"
105*67e74705SXin Li       "  class O2 {"
106*67e74705SXin Li       "    class F {"
107*67e74705SXin Li       "      class Z {"
108*67e74705SXin Li       "        class A {};"
109*67e74705SXin Li       "        class X {};"
110*67e74705SXin Li       "        class Y {};"
111*67e74705SXin Li       "      };"
112*67e74705SXin Li       "      class C {"
113*67e74705SXin Li       "        class X {};"
114*67e74705SXin Li       "        class A {};"
115*67e74705SXin Li       "        class B {};"
116*67e74705SXin Li       "      };"
117*67e74705SXin Li       "    };"
118*67e74705SXin Li       "  };"
119*67e74705SXin Li       "};", Recursive));
120*67e74705SXin Li }
121*67e74705SXin Li 
TEST(DeclarationMatcher,MatchHasRecursiveAnyOf)122*67e74705SXin Li TEST(DeclarationMatcher, MatchHasRecursiveAnyOf) {
123*67e74705SXin Li   DeclarationMatcher Recursive =
124*67e74705SXin Li     recordDecl(
125*67e74705SXin Li       anyOf(
126*67e74705SXin Li         has(recordDecl(
127*67e74705SXin Li           anyOf(
128*67e74705SXin Li             has(recordDecl(
129*67e74705SXin Li               hasName("X"))),
130*67e74705SXin Li             has(recordDecl(
131*67e74705SXin Li               hasName("Y"))),
132*67e74705SXin Li             hasName("Z")))),
133*67e74705SXin Li         has(recordDecl(
134*67e74705SXin Li           anyOf(
135*67e74705SXin Li             hasName("C"),
136*67e74705SXin Li             has(recordDecl(
137*67e74705SXin Li               hasName("A"))),
138*67e74705SXin Li             has(recordDecl(
139*67e74705SXin Li               hasName("B")))))),
140*67e74705SXin Li         hasName("F")));
141*67e74705SXin Li 
142*67e74705SXin Li   EXPECT_TRUE(matches("class F {};", Recursive));
143*67e74705SXin Li   EXPECT_TRUE(matches("class Z {};", Recursive));
144*67e74705SXin Li   EXPECT_TRUE(matches("class C {};", Recursive));
145*67e74705SXin Li   EXPECT_TRUE(matches("class M { class N { class X {}; }; };", Recursive));
146*67e74705SXin Li   EXPECT_TRUE(matches("class M { class N { class B {}; }; };", Recursive));
147*67e74705SXin Li   EXPECT_TRUE(
148*67e74705SXin Li     matches("class O1 { class O2 {"
149*67e74705SXin Li               "  class M { class N { class B {}; }; }; "
150*67e74705SXin Li               "}; };", Recursive));
151*67e74705SXin Li }
152*67e74705SXin Li 
TEST(DeclarationMatcher,MatchNot)153*67e74705SXin Li TEST(DeclarationMatcher, MatchNot) {
154*67e74705SXin Li   DeclarationMatcher NotClassX =
155*67e74705SXin Li     cxxRecordDecl(
156*67e74705SXin Li       isDerivedFrom("Y"),
157*67e74705SXin Li       unless(hasName("X")));
158*67e74705SXin Li   EXPECT_TRUE(notMatches("", NotClassX));
159*67e74705SXin Li   EXPECT_TRUE(notMatches("class Y {};", NotClassX));
160*67e74705SXin Li   EXPECT_TRUE(matches("class Y {}; class Z : public Y {};", NotClassX));
161*67e74705SXin Li   EXPECT_TRUE(notMatches("class Y {}; class X : public Y {};", NotClassX));
162*67e74705SXin Li   EXPECT_TRUE(
163*67e74705SXin Li     notMatches("class Y {}; class Z {}; class X : public Y {};",
164*67e74705SXin Li                NotClassX));
165*67e74705SXin Li 
166*67e74705SXin Li   DeclarationMatcher ClassXHasNotClassY =
167*67e74705SXin Li     recordDecl(
168*67e74705SXin Li       hasName("X"),
169*67e74705SXin Li       has(recordDecl(hasName("Z"))),
170*67e74705SXin Li       unless(
171*67e74705SXin Li         has(recordDecl(hasName("Y")))));
172*67e74705SXin Li   EXPECT_TRUE(matches("class X { class Z {}; };", ClassXHasNotClassY));
173*67e74705SXin Li   EXPECT_TRUE(notMatches("class X { class Y {}; class Z {}; };",
174*67e74705SXin Li                          ClassXHasNotClassY));
175*67e74705SXin Li 
176*67e74705SXin Li   DeclarationMatcher NamedNotRecord =
177*67e74705SXin Li     namedDecl(hasName("Foo"), unless(recordDecl()));
178*67e74705SXin Li   EXPECT_TRUE(matches("void Foo(){}", NamedNotRecord));
179*67e74705SXin Li   EXPECT_TRUE(notMatches("struct Foo {};", NamedNotRecord));
180*67e74705SXin Li }
181*67e74705SXin Li 
TEST(CastExpression,HasCastKind)182*67e74705SXin Li TEST(CastExpression, HasCastKind) {
183*67e74705SXin Li   EXPECT_TRUE(matches("char *p = 0;",
184*67e74705SXin Li               castExpr(hasCastKind(CK_NullToPointer))));
185*67e74705SXin Li   EXPECT_TRUE(notMatches("char *p = 0;",
186*67e74705SXin Li               castExpr(hasCastKind(CK_DerivedToBase))));
187*67e74705SXin Li   EXPECT_TRUE(matches("char *p = 0;",
188*67e74705SXin Li               implicitCastExpr(hasCastKind(CK_NullToPointer))));
189*67e74705SXin Li }
190*67e74705SXin Li 
TEST(DeclarationMatcher,HasDescendant)191*67e74705SXin Li TEST(DeclarationMatcher, HasDescendant) {
192*67e74705SXin Li   DeclarationMatcher ZDescendantClassX =
193*67e74705SXin Li     recordDecl(
194*67e74705SXin Li       hasDescendant(recordDecl(hasName("X"))),
195*67e74705SXin Li       hasName("Z"));
196*67e74705SXin Li   EXPECT_TRUE(matches("class Z { class X {}; };", ZDescendantClassX));
197*67e74705SXin Li   EXPECT_TRUE(
198*67e74705SXin Li     matches("class Z { class Y { class X {}; }; };", ZDescendantClassX));
199*67e74705SXin Li   EXPECT_TRUE(
200*67e74705SXin Li     matches("class Z { class A { class Y { class X {}; }; }; };",
201*67e74705SXin Li             ZDescendantClassX));
202*67e74705SXin Li   EXPECT_TRUE(
203*67e74705SXin Li     matches("class Z { class A { class B { class Y { class X {}; }; }; }; };",
204*67e74705SXin Li             ZDescendantClassX));
205*67e74705SXin Li   EXPECT_TRUE(notMatches("class Z {};", ZDescendantClassX));
206*67e74705SXin Li 
207*67e74705SXin Li   DeclarationMatcher ZDescendantClassXHasClassY =
208*67e74705SXin Li     recordDecl(
209*67e74705SXin Li       hasDescendant(recordDecl(has(recordDecl(hasName("Y"))),
210*67e74705SXin Li                                hasName("X"))),
211*67e74705SXin Li       hasName("Z"));
212*67e74705SXin Li   EXPECT_TRUE(matches("class Z { class X { class Y {}; }; };",
213*67e74705SXin Li                       ZDescendantClassXHasClassY));
214*67e74705SXin Li   EXPECT_TRUE(
215*67e74705SXin Li     matches("class Z { class A { class B { class X { class Y {}; }; }; }; };",
216*67e74705SXin Li             ZDescendantClassXHasClassY));
217*67e74705SXin Li   EXPECT_TRUE(notMatches(
218*67e74705SXin Li     "class Z {"
219*67e74705SXin Li       "  class A {"
220*67e74705SXin Li       "    class B {"
221*67e74705SXin Li       "      class X {"
222*67e74705SXin Li       "        class C {"
223*67e74705SXin Li       "          class Y {};"
224*67e74705SXin Li       "        };"
225*67e74705SXin Li       "      };"
226*67e74705SXin Li       "    }; "
227*67e74705SXin Li       "  };"
228*67e74705SXin Li       "};", ZDescendantClassXHasClassY));
229*67e74705SXin Li 
230*67e74705SXin Li   DeclarationMatcher ZDescendantClassXDescendantClassY =
231*67e74705SXin Li     recordDecl(
232*67e74705SXin Li       hasDescendant(recordDecl(hasDescendant(recordDecl(hasName("Y"))),
233*67e74705SXin Li                                hasName("X"))),
234*67e74705SXin Li       hasName("Z"));
235*67e74705SXin Li   EXPECT_TRUE(
236*67e74705SXin Li     matches("class Z { class A { class X { class B { class Y {}; }; }; }; };",
237*67e74705SXin Li             ZDescendantClassXDescendantClassY));
238*67e74705SXin Li   EXPECT_TRUE(matches(
239*67e74705SXin Li     "class Z {"
240*67e74705SXin Li       "  class A {"
241*67e74705SXin Li       "    class X {"
242*67e74705SXin Li       "      class B {"
243*67e74705SXin Li       "        class Y {};"
244*67e74705SXin Li       "      };"
245*67e74705SXin Li       "      class Y {};"
246*67e74705SXin Li       "    };"
247*67e74705SXin Li       "  };"
248*67e74705SXin Li       "};", ZDescendantClassXDescendantClassY));
249*67e74705SXin Li }
250*67e74705SXin Li 
TEST(DeclarationMatcher,HasDescendantMemoization)251*67e74705SXin Li TEST(DeclarationMatcher, HasDescendantMemoization) {
252*67e74705SXin Li   DeclarationMatcher CannotMemoize =
253*67e74705SXin Li     decl(hasDescendant(typeLoc().bind("x")), has(decl()));
254*67e74705SXin Li   EXPECT_TRUE(matches("void f() { int i; }", CannotMemoize));
255*67e74705SXin Li }
256*67e74705SXin Li 
TEST(DeclarationMatcher,HasDescendantMemoizationUsesRestrictKind)257*67e74705SXin Li TEST(DeclarationMatcher, HasDescendantMemoizationUsesRestrictKind) {
258*67e74705SXin Li   auto Name = hasName("i");
259*67e74705SXin Li   auto VD = internal::Matcher<VarDecl>(Name).dynCastTo<Decl>();
260*67e74705SXin Li   auto RD = internal::Matcher<RecordDecl>(Name).dynCastTo<Decl>();
261*67e74705SXin Li   // Matching VD first should not make a cache hit for RD.
262*67e74705SXin Li   EXPECT_TRUE(notMatches("void f() { int i; }",
263*67e74705SXin Li                          decl(hasDescendant(VD), hasDescendant(RD))));
264*67e74705SXin Li   EXPECT_TRUE(notMatches("void f() { int i; }",
265*67e74705SXin Li                          decl(hasDescendant(RD), hasDescendant(VD))));
266*67e74705SXin Li   // Not matching RD first should not make a cache hit for VD either.
267*67e74705SXin Li   EXPECT_TRUE(matches("void f() { int i; }",
268*67e74705SXin Li                       decl(anyOf(hasDescendant(RD), hasDescendant(VD)))));
269*67e74705SXin Li }
270*67e74705SXin Li 
TEST(DeclarationMatcher,HasAncestorMemoization)271*67e74705SXin Li TEST(DeclarationMatcher, HasAncestorMemoization) {
272*67e74705SXin Li   // This triggers an hasAncestor with a TemplateArgument in the bound nodes.
273*67e74705SXin Li   // That node can't be memoized so we have to check for it before trying to put
274*67e74705SXin Li   // it on the cache.
275*67e74705SXin Li   DeclarationMatcher CannotMemoize = classTemplateSpecializationDecl(
276*67e74705SXin Li     hasAnyTemplateArgument(templateArgument().bind("targ")),
277*67e74705SXin Li     forEach(fieldDecl(hasAncestor(forStmt()))));
278*67e74705SXin Li 
279*67e74705SXin Li   EXPECT_TRUE(notMatches("template <typename T> struct S;"
280*67e74705SXin Li                            "template <> struct S<int>{ int i; int j; };",
281*67e74705SXin Li                          CannotMemoize));
282*67e74705SXin Li }
283*67e74705SXin Li 
TEST(DeclarationMatcher,HasAttr)284*67e74705SXin Li TEST(DeclarationMatcher, HasAttr) {
285*67e74705SXin Li   EXPECT_TRUE(matches("struct __attribute__((warn_unused)) X {};",
286*67e74705SXin Li                       decl(hasAttr(clang::attr::WarnUnused))));
287*67e74705SXin Li   EXPECT_FALSE(matches("struct X {};",
288*67e74705SXin Li                        decl(hasAttr(clang::attr::WarnUnused))));
289*67e74705SXin Li }
290*67e74705SXin Li 
291*67e74705SXin Li 
TEST(DeclarationMatcher,MatchAnyOf)292*67e74705SXin Li TEST(DeclarationMatcher, MatchAnyOf) {
293*67e74705SXin Li   DeclarationMatcher YOrZDerivedFromX = cxxRecordDecl(
294*67e74705SXin Li     anyOf(hasName("Y"), allOf(isDerivedFrom("X"), hasName("Z"))));
295*67e74705SXin Li   EXPECT_TRUE(matches("class X {}; class Z : public X {};", YOrZDerivedFromX));
296*67e74705SXin Li   EXPECT_TRUE(matches("class Y {};", YOrZDerivedFromX));
297*67e74705SXin Li   EXPECT_TRUE(
298*67e74705SXin Li     notMatches("class X {}; class W : public X {};", YOrZDerivedFromX));
299*67e74705SXin Li   EXPECT_TRUE(notMatches("class Z {};", YOrZDerivedFromX));
300*67e74705SXin Li 
301*67e74705SXin Li   DeclarationMatcher XOrYOrZOrU =
302*67e74705SXin Li     recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U")));
303*67e74705SXin Li   EXPECT_TRUE(matches("class X {};", XOrYOrZOrU));
304*67e74705SXin Li   EXPECT_TRUE(notMatches("class V {};", XOrYOrZOrU));
305*67e74705SXin Li 
306*67e74705SXin Li   DeclarationMatcher XOrYOrZOrUOrV =
307*67e74705SXin Li     recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U"),
308*67e74705SXin Li                      hasName("V")));
309*67e74705SXin Li   EXPECT_TRUE(matches("class X {};", XOrYOrZOrUOrV));
310*67e74705SXin Li   EXPECT_TRUE(matches("class Y {};", XOrYOrZOrUOrV));
311*67e74705SXin Li   EXPECT_TRUE(matches("class Z {};", XOrYOrZOrUOrV));
312*67e74705SXin Li   EXPECT_TRUE(matches("class U {};", XOrYOrZOrUOrV));
313*67e74705SXin Li   EXPECT_TRUE(matches("class V {};", XOrYOrZOrUOrV));
314*67e74705SXin Li   EXPECT_TRUE(notMatches("class A {};", XOrYOrZOrUOrV));
315*67e74705SXin Li 
316*67e74705SXin Li   StatementMatcher MixedTypes = stmt(anyOf(ifStmt(), binaryOperator()));
317*67e74705SXin Li   EXPECT_TRUE(matches("int F() { return 1 + 2; }", MixedTypes));
318*67e74705SXin Li   EXPECT_TRUE(matches("int F() { if (true) return 1; }", MixedTypes));
319*67e74705SXin Li   EXPECT_TRUE(notMatches("int F() { return 1; }", MixedTypes));
320*67e74705SXin Li 
321*67e74705SXin Li   EXPECT_TRUE(
322*67e74705SXin Li     matches("void f() try { } catch (int) { } catch (...) { }",
323*67e74705SXin Li             cxxCatchStmt(anyOf(hasDescendant(varDecl()), isCatchAll()))));
324*67e74705SXin Li }
325*67e74705SXin Li 
TEST(DeclarationMatcher,ClassIsDerived)326*67e74705SXin Li TEST(DeclarationMatcher, ClassIsDerived) {
327*67e74705SXin Li   DeclarationMatcher IsDerivedFromX = cxxRecordDecl(isDerivedFrom("X"));
328*67e74705SXin Li 
329*67e74705SXin Li   EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsDerivedFromX));
330*67e74705SXin Li   EXPECT_TRUE(notMatches("class X {};", IsDerivedFromX));
331*67e74705SXin Li   EXPECT_TRUE(notMatches("class X;", IsDerivedFromX));
332*67e74705SXin Li   EXPECT_TRUE(notMatches("class Y;", IsDerivedFromX));
333*67e74705SXin Li   EXPECT_TRUE(notMatches("", IsDerivedFromX));
334*67e74705SXin Li 
335*67e74705SXin Li   DeclarationMatcher IsAX = cxxRecordDecl(isSameOrDerivedFrom("X"));
336*67e74705SXin Li 
337*67e74705SXin Li   EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsAX));
338*67e74705SXin Li   EXPECT_TRUE(matches("class X {};", IsAX));
339*67e74705SXin Li   EXPECT_TRUE(matches("class X;", IsAX));
340*67e74705SXin Li   EXPECT_TRUE(notMatches("class Y;", IsAX));
341*67e74705SXin Li   EXPECT_TRUE(notMatches("", IsAX));
342*67e74705SXin Li 
343*67e74705SXin Li   DeclarationMatcher ZIsDerivedFromX =
344*67e74705SXin Li     cxxRecordDecl(hasName("Z"), isDerivedFrom("X"));
345*67e74705SXin Li   EXPECT_TRUE(
346*67e74705SXin Li     matches("class X {}; class Y : public X {}; class Z : public Y {};",
347*67e74705SXin Li             ZIsDerivedFromX));
348*67e74705SXin Li   EXPECT_TRUE(
349*67e74705SXin Li     matches("class X {};"
350*67e74705SXin Li               "template<class T> class Y : public X {};"
351*67e74705SXin Li               "class Z : public Y<int> {};", ZIsDerivedFromX));
352*67e74705SXin Li   EXPECT_TRUE(matches("class X {}; template<class T> class Z : public X {};",
353*67e74705SXin Li                       ZIsDerivedFromX));
354*67e74705SXin Li   EXPECT_TRUE(
355*67e74705SXin Li     matches("template<class T> class X {}; "
356*67e74705SXin Li               "template<class T> class Z : public X<T> {};",
357*67e74705SXin Li             ZIsDerivedFromX));
358*67e74705SXin Li   EXPECT_TRUE(
359*67e74705SXin Li     matches("template<class T, class U=T> class X {}; "
360*67e74705SXin Li               "template<class T> class Z : public X<T> {};",
361*67e74705SXin Li             ZIsDerivedFromX));
362*67e74705SXin Li   EXPECT_TRUE(
363*67e74705SXin Li     notMatches("template<class X> class A { class Z : public X {}; };",
364*67e74705SXin Li                ZIsDerivedFromX));
365*67e74705SXin Li   EXPECT_TRUE(
366*67e74705SXin Li     matches("template<class X> class A { public: class Z : public X {}; }; "
367*67e74705SXin Li               "class X{}; void y() { A<X>::Z z; }", ZIsDerivedFromX));
368*67e74705SXin Li   EXPECT_TRUE(
369*67e74705SXin Li     matches("template <class T> class X {}; "
370*67e74705SXin Li               "template<class Y> class A { class Z : public X<Y> {}; };",
371*67e74705SXin Li             ZIsDerivedFromX));
372*67e74705SXin Li   EXPECT_TRUE(
373*67e74705SXin Li     notMatches("template<template<class T> class X> class A { "
374*67e74705SXin Li                  "  class Z : public X<int> {}; };", ZIsDerivedFromX));
375*67e74705SXin Li   EXPECT_TRUE(
376*67e74705SXin Li     matches("template<template<class T> class X> class A { "
377*67e74705SXin Li               "  public: class Z : public X<int> {}; }; "
378*67e74705SXin Li               "template<class T> class X {}; void y() { A<X>::Z z; }",
379*67e74705SXin Li             ZIsDerivedFromX));
380*67e74705SXin Li   EXPECT_TRUE(
381*67e74705SXin Li     notMatches("template<class X> class A { class Z : public X::D {}; };",
382*67e74705SXin Li                ZIsDerivedFromX));
383*67e74705SXin Li   EXPECT_TRUE(
384*67e74705SXin Li     matches("template<class X> class A { public: "
385*67e74705SXin Li               "  class Z : public X::D {}; }; "
386*67e74705SXin Li               "class Y { public: class X {}; typedef X D; }; "
387*67e74705SXin Li               "void y() { A<Y>::Z z; }", ZIsDerivedFromX));
388*67e74705SXin Li   EXPECT_TRUE(
389*67e74705SXin Li     matches("class X {}; typedef X Y; class Z : public Y {};",
390*67e74705SXin Li             ZIsDerivedFromX));
391*67e74705SXin Li   EXPECT_TRUE(
392*67e74705SXin Li     matches("template<class T> class Y { typedef typename T::U X; "
393*67e74705SXin Li               "  class Z : public X {}; };", ZIsDerivedFromX));
394*67e74705SXin Li   EXPECT_TRUE(matches("class X {}; class Z : public ::X {};",
395*67e74705SXin Li                       ZIsDerivedFromX));
396*67e74705SXin Li   EXPECT_TRUE(
397*67e74705SXin Li     notMatches("template<class T> class X {}; "
398*67e74705SXin Li                  "template<class T> class A { class Z : public X<T>::D {}; };",
399*67e74705SXin Li                ZIsDerivedFromX));
400*67e74705SXin Li   EXPECT_TRUE(
401*67e74705SXin Li     matches("template<class T> class X { public: typedef X<T> D; }; "
402*67e74705SXin Li               "template<class T> class A { public: "
403*67e74705SXin Li               "  class Z : public X<T>::D {}; }; void y() { A<int>::Z z; }",
404*67e74705SXin Li             ZIsDerivedFromX));
405*67e74705SXin Li   EXPECT_TRUE(
406*67e74705SXin Li     notMatches("template<class X> class A { class Z : public X::D::E {}; };",
407*67e74705SXin Li                ZIsDerivedFromX));
408*67e74705SXin Li   EXPECT_TRUE(
409*67e74705SXin Li     matches("class X {}; typedef X V; typedef V W; class Z : public W {};",
410*67e74705SXin Li             ZIsDerivedFromX));
411*67e74705SXin Li   EXPECT_TRUE(
412*67e74705SXin Li     matches("class X {}; class Y : public X {}; "
413*67e74705SXin Li               "typedef Y V; typedef V W; class Z : public W {};",
414*67e74705SXin Li             ZIsDerivedFromX));
415*67e74705SXin Li   EXPECT_TRUE(
416*67e74705SXin Li     matches("template<class T, class U> class X {}; "
417*67e74705SXin Li               "template<class T> class A { class Z : public X<T, int> {}; };",
418*67e74705SXin Li             ZIsDerivedFromX));
419*67e74705SXin Li   EXPECT_TRUE(
420*67e74705SXin Li     notMatches("template<class X> class D { typedef X A; typedef A B; "
421*67e74705SXin Li                  "  typedef B C; class Z : public C {}; };",
422*67e74705SXin Li                ZIsDerivedFromX));
423*67e74705SXin Li   EXPECT_TRUE(
424*67e74705SXin Li     matches("class X {}; typedef X A; typedef A B; "
425*67e74705SXin Li               "class Z : public B {};", ZIsDerivedFromX));
426*67e74705SXin Li   EXPECT_TRUE(
427*67e74705SXin Li     matches("class X {}; typedef X A; typedef A B; typedef B C; "
428*67e74705SXin Li               "class Z : public C {};", ZIsDerivedFromX));
429*67e74705SXin Li   EXPECT_TRUE(
430*67e74705SXin Li     matches("class U {}; typedef U X; typedef X V; "
431*67e74705SXin Li               "class Z : public V {};", ZIsDerivedFromX));
432*67e74705SXin Li   EXPECT_TRUE(
433*67e74705SXin Li     matches("class Base {}; typedef Base X; "
434*67e74705SXin Li               "class Z : public Base {};", ZIsDerivedFromX));
435*67e74705SXin Li   EXPECT_TRUE(
436*67e74705SXin Li     matches("class Base {}; typedef Base Base2; typedef Base2 X; "
437*67e74705SXin Li               "class Z : public Base {};", ZIsDerivedFromX));
438*67e74705SXin Li   EXPECT_TRUE(
439*67e74705SXin Li     notMatches("class Base {}; class Base2 {}; typedef Base2 X; "
440*67e74705SXin Li                  "class Z : public Base {};", ZIsDerivedFromX));
441*67e74705SXin Li   EXPECT_TRUE(
442*67e74705SXin Li     matches("class A {}; typedef A X; typedef A Y; "
443*67e74705SXin Li               "class Z : public Y {};", ZIsDerivedFromX));
444*67e74705SXin Li   EXPECT_TRUE(
445*67e74705SXin Li     notMatches("template <typename T> class Z;"
446*67e74705SXin Li                  "template <> class Z<void> {};"
447*67e74705SXin Li                  "template <typename T> class Z : public Z<void> {};",
448*67e74705SXin Li                IsDerivedFromX));
449*67e74705SXin Li   EXPECT_TRUE(
450*67e74705SXin Li     matches("template <typename T> class X;"
451*67e74705SXin Li               "template <> class X<void> {};"
452*67e74705SXin Li               "template <typename T> class X : public X<void> {};",
453*67e74705SXin Li             IsDerivedFromX));
454*67e74705SXin Li   EXPECT_TRUE(matches(
455*67e74705SXin Li     "class X {};"
456*67e74705SXin Li       "template <typename T> class Z;"
457*67e74705SXin Li       "template <> class Z<void> {};"
458*67e74705SXin Li       "template <typename T> class Z : public Z<void>, public X {};",
459*67e74705SXin Li     ZIsDerivedFromX));
460*67e74705SXin Li   EXPECT_TRUE(
461*67e74705SXin Li     notMatches("template<int> struct X;"
462*67e74705SXin Li                  "template<int i> struct X : public X<i-1> {};",
463*67e74705SXin Li                cxxRecordDecl(isDerivedFrom(recordDecl(hasName("Some"))))));
464*67e74705SXin Li   EXPECT_TRUE(matches(
465*67e74705SXin Li     "struct A {};"
466*67e74705SXin Li       "template<int> struct X;"
467*67e74705SXin Li       "template<int i> struct X : public X<i-1> {};"
468*67e74705SXin Li       "template<> struct X<0> : public A {};"
469*67e74705SXin Li       "struct B : public X<42> {};",
470*67e74705SXin Li     cxxRecordDecl(hasName("B"), isDerivedFrom(recordDecl(hasName("A"))))));
471*67e74705SXin Li 
472*67e74705SXin Li   // FIXME: Once we have better matchers for template type matching,
473*67e74705SXin Li   // get rid of the Variable(...) matching and match the right template
474*67e74705SXin Li   // declarations directly.
475*67e74705SXin Li   const char *RecursiveTemplateOneParameter =
476*67e74705SXin Li     "class Base1 {}; class Base2 {};"
477*67e74705SXin Li       "template <typename T> class Z;"
478*67e74705SXin Li       "template <> class Z<void> : public Base1 {};"
479*67e74705SXin Li       "template <> class Z<int> : public Base2 {};"
480*67e74705SXin Li       "template <> class Z<float> : public Z<void> {};"
481*67e74705SXin Li       "template <> class Z<double> : public Z<int> {};"
482*67e74705SXin Li       "template <typename T> class Z : public Z<float>, public Z<double> {};"
483*67e74705SXin Li       "void f() { Z<float> z_float; Z<double> z_double; Z<char> z_char; }";
484*67e74705SXin Li   EXPECT_TRUE(matches(
485*67e74705SXin Li     RecursiveTemplateOneParameter,
486*67e74705SXin Li     varDecl(hasName("z_float"),
487*67e74705SXin Li             hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1")))))));
488*67e74705SXin Li   EXPECT_TRUE(notMatches(
489*67e74705SXin Li     RecursiveTemplateOneParameter,
490*67e74705SXin Li     varDecl(hasName("z_float"),
491*67e74705SXin Li             hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2")))))));
492*67e74705SXin Li   EXPECT_TRUE(matches(
493*67e74705SXin Li     RecursiveTemplateOneParameter,
494*67e74705SXin Li     varDecl(hasName("z_char"),
495*67e74705SXin Li             hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1"),
496*67e74705SXin Li                                                  isDerivedFrom("Base2")))))));
497*67e74705SXin Li 
498*67e74705SXin Li   const char *RecursiveTemplateTwoParameters =
499*67e74705SXin Li     "class Base1 {}; class Base2 {};"
500*67e74705SXin Li       "template <typename T1, typename T2> class Z;"
501*67e74705SXin Li       "template <typename T> class Z<void, T> : public Base1 {};"
502*67e74705SXin Li       "template <typename T> class Z<int, T> : public Base2 {};"
503*67e74705SXin Li       "template <typename T> class Z<float, T> : public Z<void, T> {};"
504*67e74705SXin Li       "template <typename T> class Z<double, T> : public Z<int, T> {};"
505*67e74705SXin Li       "template <typename T1, typename T2> class Z : "
506*67e74705SXin Li       "    public Z<float, T2>, public Z<double, T2> {};"
507*67e74705SXin Li       "void f() { Z<float, void> z_float; Z<double, void> z_double; "
508*67e74705SXin Li       "           Z<char, void> z_char; }";
509*67e74705SXin Li   EXPECT_TRUE(matches(
510*67e74705SXin Li     RecursiveTemplateTwoParameters,
511*67e74705SXin Li     varDecl(hasName("z_float"),
512*67e74705SXin Li             hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1")))))));
513*67e74705SXin Li   EXPECT_TRUE(notMatches(
514*67e74705SXin Li     RecursiveTemplateTwoParameters,
515*67e74705SXin Li     varDecl(hasName("z_float"),
516*67e74705SXin Li             hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2")))))));
517*67e74705SXin Li   EXPECT_TRUE(matches(
518*67e74705SXin Li     RecursiveTemplateTwoParameters,
519*67e74705SXin Li     varDecl(hasName("z_char"),
520*67e74705SXin Li             hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1"),
521*67e74705SXin Li                                                  isDerivedFrom("Base2")))))));
522*67e74705SXin Li   EXPECT_TRUE(matches(
523*67e74705SXin Li     "namespace ns { class X {}; class Y : public X {}; }",
524*67e74705SXin Li     cxxRecordDecl(isDerivedFrom("::ns::X"))));
525*67e74705SXin Li   EXPECT_TRUE(notMatches(
526*67e74705SXin Li     "class X {}; class Y : public X {};",
527*67e74705SXin Li     cxxRecordDecl(isDerivedFrom("::ns::X"))));
528*67e74705SXin Li 
529*67e74705SXin Li   EXPECT_TRUE(matches(
530*67e74705SXin Li     "class X {}; class Y : public X {};",
531*67e74705SXin Li     cxxRecordDecl(isDerivedFrom(recordDecl(hasName("X")).bind("test")))));
532*67e74705SXin Li 
533*67e74705SXin Li   EXPECT_TRUE(matches(
534*67e74705SXin Li     "template<typename T> class X {};"
535*67e74705SXin Li       "template<typename T> using Z = X<T>;"
536*67e74705SXin Li       "template <typename T> class Y : Z<T> {};",
537*67e74705SXin Li     cxxRecordDecl(isDerivedFrom(namedDecl(hasName("X"))))));
538*67e74705SXin Li }
539*67e74705SXin Li 
TEST(DeclarationMatcher,IsLambda)540*67e74705SXin Li TEST(DeclarationMatcher, IsLambda) {
541*67e74705SXin Li   const auto IsLambda = cxxMethodDecl(ofClass(cxxRecordDecl(isLambda())));
542*67e74705SXin Li   EXPECT_TRUE(matches("auto x = []{};", IsLambda));
543*67e74705SXin Li   EXPECT_TRUE(notMatches("struct S { void operator()() const; };", IsLambda));
544*67e74705SXin Li }
545*67e74705SXin Li 
TEST(Matcher,BindMatchedNodes)546*67e74705SXin Li TEST(Matcher, BindMatchedNodes) {
547*67e74705SXin Li   DeclarationMatcher ClassX = has(recordDecl(hasName("::X")).bind("x"));
548*67e74705SXin Li 
549*67e74705SXin Li   EXPECT_TRUE(matchAndVerifyResultTrue("class X {};",
550*67e74705SXin Li                                        ClassX, llvm::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("x")));
551*67e74705SXin Li 
552*67e74705SXin Li   EXPECT_TRUE(matchAndVerifyResultFalse("class X {};",
553*67e74705SXin Li                                         ClassX, llvm::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("other-id")));
554*67e74705SXin Li 
555*67e74705SXin Li   TypeMatcher TypeAHasClassB = hasDeclaration(
556*67e74705SXin Li     recordDecl(hasName("A"), has(recordDecl(hasName("B")).bind("b"))));
557*67e74705SXin Li 
558*67e74705SXin Li   EXPECT_TRUE(matchAndVerifyResultTrue("class A { public: A *a; class B {}; };",
559*67e74705SXin Li                                        TypeAHasClassB,
560*67e74705SXin Li                                        llvm::make_unique<VerifyIdIsBoundTo<Decl>>("b")));
561*67e74705SXin Li 
562*67e74705SXin Li   StatementMatcher MethodX =
563*67e74705SXin Li     callExpr(callee(cxxMethodDecl(hasName("x")))).bind("x");
564*67e74705SXin Li 
565*67e74705SXin Li   EXPECT_TRUE(matchAndVerifyResultTrue("class A { void x() { x(); } };",
566*67e74705SXin Li                                        MethodX,
567*67e74705SXin Li                                        llvm::make_unique<VerifyIdIsBoundTo<CXXMemberCallExpr>>("x")));
568*67e74705SXin Li }
569*67e74705SXin Li 
TEST(Matcher,BindTheSameNameInAlternatives)570*67e74705SXin Li TEST(Matcher, BindTheSameNameInAlternatives) {
571*67e74705SXin Li   StatementMatcher matcher = anyOf(
572*67e74705SXin Li     binaryOperator(hasOperatorName("+"),
573*67e74705SXin Li                    hasLHS(expr().bind("x")),
574*67e74705SXin Li                    hasRHS(integerLiteral(equals(0)))),
575*67e74705SXin Li     binaryOperator(hasOperatorName("+"),
576*67e74705SXin Li                    hasLHS(integerLiteral(equals(0))),
577*67e74705SXin Li                    hasRHS(expr().bind("x"))));
578*67e74705SXin Li 
579*67e74705SXin Li   EXPECT_TRUE(matchAndVerifyResultTrue(
580*67e74705SXin Li     // The first branch of the matcher binds x to 0 but then fails.
581*67e74705SXin Li     // The second branch binds x to f() and succeeds.
582*67e74705SXin Li     "int f() { return 0 + f(); }",
583*67e74705SXin Li     matcher,
584*67e74705SXin Li     llvm::make_unique<VerifyIdIsBoundTo<CallExpr>>("x")));
585*67e74705SXin Li }
586*67e74705SXin Li 
TEST(Matcher,BindsIDForMemoizedResults)587*67e74705SXin Li TEST(Matcher, BindsIDForMemoizedResults) {
588*67e74705SXin Li   // Using the same matcher in two match expressions will make memoization
589*67e74705SXin Li   // kick in.
590*67e74705SXin Li   DeclarationMatcher ClassX = recordDecl(hasName("X")).bind("x");
591*67e74705SXin Li   EXPECT_TRUE(matchAndVerifyResultTrue(
592*67e74705SXin Li     "class A { class B { class X {}; }; };",
593*67e74705SXin Li     DeclarationMatcher(anyOf(
594*67e74705SXin Li       recordDecl(hasName("A"), hasDescendant(ClassX)),
595*67e74705SXin Li       recordDecl(hasName("B"), hasDescendant(ClassX)))),
596*67e74705SXin Li     llvm::make_unique<VerifyIdIsBoundTo<Decl>>("x", 2)));
597*67e74705SXin Li }
598*67e74705SXin Li 
TEST(HasType,MatchesAsString)599*67e74705SXin Li TEST(HasType, MatchesAsString) {
600*67e74705SXin Li   EXPECT_TRUE(
601*67e74705SXin Li     matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }",
602*67e74705SXin Li             cxxMemberCallExpr(on(hasType(asString("class Y *"))))));
603*67e74705SXin Li   EXPECT_TRUE(
604*67e74705SXin Li     matches("class X { void x(int x) {} };",
605*67e74705SXin Li             cxxMethodDecl(hasParameter(0, hasType(asString("int"))))));
606*67e74705SXin Li   EXPECT_TRUE(matches("namespace ns { struct A {}; }  struct B { ns::A a; };",
607*67e74705SXin Li                       fieldDecl(hasType(asString("ns::A")))));
608*67e74705SXin Li   EXPECT_TRUE(matches("namespace { struct A {}; }  struct B { A a; };",
609*67e74705SXin Li                       fieldDecl(hasType(asString("struct (anonymous namespace)::A")))));
610*67e74705SXin Li }
611*67e74705SXin Li 
TEST(Matcher,HasOperatorNameForOverloadedOperatorCall)612*67e74705SXin Li TEST(Matcher, HasOperatorNameForOverloadedOperatorCall) {
613*67e74705SXin Li   StatementMatcher OpCallAndAnd =
614*67e74705SXin Li     cxxOperatorCallExpr(hasOverloadedOperatorName("&&"));
615*67e74705SXin Li   EXPECT_TRUE(matches("class Y { }; "
616*67e74705SXin Li                         "bool operator&&(Y x, Y y) { return true; }; "
617*67e74705SXin Li                         "Y a; Y b; bool c = a && b;", OpCallAndAnd));
618*67e74705SXin Li   StatementMatcher OpCallLessLess =
619*67e74705SXin Li     cxxOperatorCallExpr(hasOverloadedOperatorName("<<"));
620*67e74705SXin Li   EXPECT_TRUE(notMatches("class Y { }; "
621*67e74705SXin Li                            "bool operator&&(Y x, Y y) { return true; }; "
622*67e74705SXin Li                            "Y a; Y b; bool c = a && b;",
623*67e74705SXin Li                          OpCallLessLess));
624*67e74705SXin Li   StatementMatcher OpStarCall =
625*67e74705SXin Li     cxxOperatorCallExpr(hasOverloadedOperatorName("*"));
626*67e74705SXin Li   EXPECT_TRUE(matches("class Y; int operator*(Y &); void f(Y &y) { *y; }",
627*67e74705SXin Li                       OpStarCall));
628*67e74705SXin Li   DeclarationMatcher ClassWithOpStar =
629*67e74705SXin Li     cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*")));
630*67e74705SXin Li   EXPECT_TRUE(matches("class Y { int operator*(); };",
631*67e74705SXin Li                       ClassWithOpStar));
632*67e74705SXin Li   EXPECT_TRUE(notMatches("class Y { void myOperator(); };",
633*67e74705SXin Li                          ClassWithOpStar)) ;
634*67e74705SXin Li   DeclarationMatcher AnyOpStar = functionDecl(hasOverloadedOperatorName("*"));
635*67e74705SXin Li   EXPECT_TRUE(matches("class Y; int operator*(Y &);", AnyOpStar));
636*67e74705SXin Li   EXPECT_TRUE(matches("class Y { int operator*(); };", AnyOpStar));
637*67e74705SXin Li }
638*67e74705SXin Li 
639*67e74705SXin Li 
TEST(Matcher,NestedOverloadedOperatorCalls)640*67e74705SXin Li TEST(Matcher, NestedOverloadedOperatorCalls) {
641*67e74705SXin Li   EXPECT_TRUE(matchAndVerifyResultTrue(
642*67e74705SXin Li     "class Y { }; "
643*67e74705SXin Li       "Y& operator&&(Y& x, Y& y) { return x; }; "
644*67e74705SXin Li       "Y a; Y b; Y c; Y d = a && b && c;",
645*67e74705SXin Li     cxxOperatorCallExpr(hasOverloadedOperatorName("&&")).bind("x"),
646*67e74705SXin Li     llvm::make_unique<VerifyIdIsBoundTo<CXXOperatorCallExpr>>("x", 2)));
647*67e74705SXin Li   EXPECT_TRUE(matches("class Y { }; "
648*67e74705SXin Li                         "Y& operator&&(Y& x, Y& y) { return x; }; "
649*67e74705SXin Li                         "Y a; Y b; Y c; Y d = a && b && c;",
650*67e74705SXin Li                       cxxOperatorCallExpr(hasParent(cxxOperatorCallExpr()))));
651*67e74705SXin Li   EXPECT_TRUE(
652*67e74705SXin Li     matches("class Y { }; "
653*67e74705SXin Li               "Y& operator&&(Y& x, Y& y) { return x; }; "
654*67e74705SXin Li               "Y a; Y b; Y c; Y d = a && b && c;",
655*67e74705SXin Li             cxxOperatorCallExpr(hasDescendant(cxxOperatorCallExpr()))));
656*67e74705SXin Li }
657*67e74705SXin Li 
TEST(Matcher,VarDecl_Storage)658*67e74705SXin Li TEST(Matcher, VarDecl_Storage) {
659*67e74705SXin Li   auto M = varDecl(hasName("X"), hasLocalStorage());
660*67e74705SXin Li   EXPECT_TRUE(matches("void f() { int X; }", M));
661*67e74705SXin Li   EXPECT_TRUE(notMatches("int X;", M));
662*67e74705SXin Li   EXPECT_TRUE(notMatches("void f() { static int X; }", M));
663*67e74705SXin Li 
664*67e74705SXin Li   M = varDecl(hasName("X"), hasGlobalStorage());
665*67e74705SXin Li   EXPECT_TRUE(notMatches("void f() { int X; }", M));
666*67e74705SXin Li   EXPECT_TRUE(matches("int X;", M));
667*67e74705SXin Li   EXPECT_TRUE(matches("void f() { static int X; }", M));
668*67e74705SXin Li }
669*67e74705SXin Li 
TEST(Matcher,VarDecl_StorageDuration)670*67e74705SXin Li TEST(Matcher, VarDecl_StorageDuration) {
671*67e74705SXin Li   std::string T =
672*67e74705SXin Li     "void f() { int x; static int y; } int a;";
673*67e74705SXin Li 
674*67e74705SXin Li   EXPECT_TRUE(matches(T, varDecl(hasName("x"), hasAutomaticStorageDuration())));
675*67e74705SXin Li   EXPECT_TRUE(
676*67e74705SXin Li     notMatches(T, varDecl(hasName("y"), hasAutomaticStorageDuration())));
677*67e74705SXin Li   EXPECT_TRUE(
678*67e74705SXin Li     notMatches(T, varDecl(hasName("a"), hasAutomaticStorageDuration())));
679*67e74705SXin Li 
680*67e74705SXin Li   EXPECT_TRUE(matches(T, varDecl(hasName("y"), hasStaticStorageDuration())));
681*67e74705SXin Li   EXPECT_TRUE(matches(T, varDecl(hasName("a"), hasStaticStorageDuration())));
682*67e74705SXin Li   EXPECT_TRUE(notMatches(T, varDecl(hasName("x"), hasStaticStorageDuration())));
683*67e74705SXin Li 
684*67e74705SXin Li   // FIXME: It is really hard to test with thread_local itself because not all
685*67e74705SXin Li   // targets support TLS, which causes this to be an error depending on what
686*67e74705SXin Li   // platform the test is being run on. We do not have access to the TargetInfo
687*67e74705SXin Li   // object to be able to test whether the platform supports TLS or not.
688*67e74705SXin Li   EXPECT_TRUE(notMatches(T, varDecl(hasName("x"), hasThreadStorageDuration())));
689*67e74705SXin Li   EXPECT_TRUE(notMatches(T, varDecl(hasName("y"), hasThreadStorageDuration())));
690*67e74705SXin Li   EXPECT_TRUE(notMatches(T, varDecl(hasName("a"), hasThreadStorageDuration())));
691*67e74705SXin Li }
692*67e74705SXin Li 
TEST(Matcher,FindsVarDeclInFunctionParameter)693*67e74705SXin Li TEST(Matcher, FindsVarDeclInFunctionParameter) {
694*67e74705SXin Li   EXPECT_TRUE(matches(
695*67e74705SXin Li     "void f(int i) {}",
696*67e74705SXin Li     varDecl(hasName("i"))));
697*67e74705SXin Li }
698*67e74705SXin Li 
TEST(UnaryExpressionOrTypeTraitExpression,MatchesCorrectType)699*67e74705SXin Li TEST(UnaryExpressionOrTypeTraitExpression, MatchesCorrectType) {
700*67e74705SXin Li   EXPECT_TRUE(matches("void x() { int a = sizeof(a); }", sizeOfExpr(
701*67e74705SXin Li     hasArgumentOfType(asString("int")))));
702*67e74705SXin Li   EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
703*67e74705SXin Li     hasArgumentOfType(asString("float")))));
704*67e74705SXin Li   EXPECT_TRUE(matches(
705*67e74705SXin Li     "struct A {}; void x() { A a; int b = sizeof(a); }",
706*67e74705SXin Li     sizeOfExpr(hasArgumentOfType(hasDeclaration(recordDecl(hasName("A")))))));
707*67e74705SXin Li   EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
708*67e74705SXin Li     hasArgumentOfType(hasDeclaration(recordDecl(hasName("string")))))));
709*67e74705SXin Li }
710*67e74705SXin Li 
TEST(IsInteger,MatchesIntegers)711*67e74705SXin Li TEST(IsInteger, MatchesIntegers) {
712*67e74705SXin Li   EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isInteger()))));
713*67e74705SXin Li   EXPECT_TRUE(matches(
714*67e74705SXin Li     "long long i = 0; void f(long long) { }; void g() {f(i);}",
715*67e74705SXin Li     callExpr(hasArgument(0, declRefExpr(
716*67e74705SXin Li       to(varDecl(hasType(isInteger()))))))));
717*67e74705SXin Li }
718*67e74705SXin Li 
TEST(IsInteger,ReportsNoFalsePositives)719*67e74705SXin Li TEST(IsInteger, ReportsNoFalsePositives) {
720*67e74705SXin Li   EXPECT_TRUE(notMatches("int *i;", varDecl(hasType(isInteger()))));
721*67e74705SXin Li   EXPECT_TRUE(notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}",
722*67e74705SXin Li                          callExpr(hasArgument(0, declRefExpr(
723*67e74705SXin Li                            to(varDecl(hasType(isInteger()))))))));
724*67e74705SXin Li }
725*67e74705SXin Li 
TEST(IsSignedInteger,MatchesSignedIntegers)726*67e74705SXin Li TEST(IsSignedInteger, MatchesSignedIntegers) {
727*67e74705SXin Li   EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isSignedInteger()))));
728*67e74705SXin Li   EXPECT_TRUE(notMatches("unsigned i = 0;",
729*67e74705SXin Li                          varDecl(hasType(isSignedInteger()))));
730*67e74705SXin Li }
731*67e74705SXin Li 
TEST(IsUnsignedInteger,MatchesUnsignedIntegers)732*67e74705SXin Li TEST(IsUnsignedInteger, MatchesUnsignedIntegers) {
733*67e74705SXin Li   EXPECT_TRUE(notMatches("int i = 0;", varDecl(hasType(isUnsignedInteger()))));
734*67e74705SXin Li   EXPECT_TRUE(matches("unsigned i = 0;",
735*67e74705SXin Li                       varDecl(hasType(isUnsignedInteger()))));
736*67e74705SXin Li }
737*67e74705SXin Li 
TEST(IsAnyPointer,MatchesPointers)738*67e74705SXin Li TEST(IsAnyPointer, MatchesPointers) {
739*67e74705SXin Li   EXPECT_TRUE(matches("int* i = nullptr;", varDecl(hasType(isAnyPointer()))));
740*67e74705SXin Li }
741*67e74705SXin Li 
TEST(IsAnyPointer,MatchesObjcPointer)742*67e74705SXin Li TEST(IsAnyPointer, MatchesObjcPointer) {
743*67e74705SXin Li   EXPECT_TRUE(matchesObjC("@interface Foo @end Foo *f;",
744*67e74705SXin Li                           varDecl(hasType(isAnyPointer()))));
745*67e74705SXin Li }
746*67e74705SXin Li 
TEST(IsAnyPointer,ReportsNoFalsePositives)747*67e74705SXin Li TEST(IsAnyPointer, ReportsNoFalsePositives) {
748*67e74705SXin Li   EXPECT_TRUE(notMatches("int i = 0;", varDecl(hasType(isAnyPointer()))));
749*67e74705SXin Li }
750*67e74705SXin Li 
TEST(IsAnyCharacter,MatchesCharacters)751*67e74705SXin Li TEST(IsAnyCharacter, MatchesCharacters) {
752*67e74705SXin Li   EXPECT_TRUE(matches("char i = 0;", varDecl(hasType(isAnyCharacter()))));
753*67e74705SXin Li }
754*67e74705SXin Li 
TEST(IsAnyCharacter,ReportsNoFalsePositives)755*67e74705SXin Li TEST(IsAnyCharacter, ReportsNoFalsePositives) {
756*67e74705SXin Li   EXPECT_TRUE(notMatches("int i;", varDecl(hasType(isAnyCharacter()))));
757*67e74705SXin Li }
758*67e74705SXin Li 
TEST(IsArrow,MatchesMemberVariablesViaArrow)759*67e74705SXin Li TEST(IsArrow, MatchesMemberVariablesViaArrow) {
760*67e74705SXin Li   EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };",
761*67e74705SXin Li                       memberExpr(isArrow())));
762*67e74705SXin Li   EXPECT_TRUE(matches("class Y { void x() { y; } int y; };",
763*67e74705SXin Li                       memberExpr(isArrow())));
764*67e74705SXin Li   EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };",
765*67e74705SXin Li                          memberExpr(isArrow())));
766*67e74705SXin Li }
767*67e74705SXin Li 
TEST(IsArrow,MatchesStaticMemberVariablesViaArrow)768*67e74705SXin Li TEST(IsArrow, MatchesStaticMemberVariablesViaArrow) {
769*67e74705SXin Li   EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
770*67e74705SXin Li                       memberExpr(isArrow())));
771*67e74705SXin Li   EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
772*67e74705SXin Li                          memberExpr(isArrow())));
773*67e74705SXin Li   EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } static int y; };",
774*67e74705SXin Li                          memberExpr(isArrow())));
775*67e74705SXin Li }
776*67e74705SXin Li 
TEST(IsArrow,MatchesMemberCallsViaArrow)777*67e74705SXin Li TEST(IsArrow, MatchesMemberCallsViaArrow) {
778*67e74705SXin Li   EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
779*67e74705SXin Li                       memberExpr(isArrow())));
780*67e74705SXin Li   EXPECT_TRUE(matches("class Y { void x() { x(); } };",
781*67e74705SXin Li                       memberExpr(isArrow())));
782*67e74705SXin Li   EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",
783*67e74705SXin Li                          memberExpr(isArrow())));
784*67e74705SXin Li }
785*67e74705SXin Li 
TEST(ConversionDeclaration,IsExplicit)786*67e74705SXin Li TEST(ConversionDeclaration, IsExplicit) {
787*67e74705SXin Li   EXPECT_TRUE(matches("struct S { explicit operator int(); };",
788*67e74705SXin Li                       cxxConversionDecl(isExplicit())));
789*67e74705SXin Li   EXPECT_TRUE(notMatches("struct S { operator int(); };",
790*67e74705SXin Li                          cxxConversionDecl(isExplicit())));
791*67e74705SXin Li }
792*67e74705SXin Li 
TEST(Matcher,ArgumentCount)793*67e74705SXin Li TEST(Matcher, ArgumentCount) {
794*67e74705SXin Li   StatementMatcher Call1Arg = callExpr(argumentCountIs(1));
795*67e74705SXin Li 
796*67e74705SXin Li   EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg));
797*67e74705SXin Li   EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg));
798*67e74705SXin Li   EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg));
799*67e74705SXin Li }
800*67e74705SXin Li 
TEST(Matcher,ParameterCount)801*67e74705SXin Li TEST(Matcher, ParameterCount) {
802*67e74705SXin Li   DeclarationMatcher Function1Arg = functionDecl(parameterCountIs(1));
803*67e74705SXin Li   EXPECT_TRUE(matches("void f(int i) {}", Function1Arg));
804*67e74705SXin Li   EXPECT_TRUE(matches("class X { void f(int i) {} };", Function1Arg));
805*67e74705SXin Li   EXPECT_TRUE(notMatches("void f() {}", Function1Arg));
806*67e74705SXin Li   EXPECT_TRUE(notMatches("void f(int i, int j, int k) {}", Function1Arg));
807*67e74705SXin Li   EXPECT_TRUE(matches("void f(int i, ...) {};", Function1Arg));
808*67e74705SXin Li }
809*67e74705SXin Li 
TEST(Matcher,References)810*67e74705SXin Li TEST(Matcher, References) {
811*67e74705SXin Li   DeclarationMatcher ReferenceClassX = varDecl(
812*67e74705SXin Li     hasType(references(recordDecl(hasName("X")))));
813*67e74705SXin Li   EXPECT_TRUE(matches("class X {}; void y(X y) { X &x = y; }",
814*67e74705SXin Li                       ReferenceClassX));
815*67e74705SXin Li   EXPECT_TRUE(
816*67e74705SXin Li     matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
817*67e74705SXin Li   // The match here is on the implicit copy constructor code for
818*67e74705SXin Li   // class X, not on code 'X x = y'.
819*67e74705SXin Li   EXPECT_TRUE(
820*67e74705SXin Li     matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
821*67e74705SXin Li   EXPECT_TRUE(
822*67e74705SXin Li     notMatches("class X {}; extern X x;", ReferenceClassX));
823*67e74705SXin Li   EXPECT_TRUE(
824*67e74705SXin Li     notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
825*67e74705SXin Li }
826*67e74705SXin Li 
TEST(QualType,hasLocalQualifiers)827*67e74705SXin Li TEST(QualType, hasLocalQualifiers) {
828*67e74705SXin Li   EXPECT_TRUE(notMatches("typedef const int const_int; const_int i = 1;",
829*67e74705SXin Li                          varDecl(hasType(hasLocalQualifiers()))));
830*67e74705SXin Li   EXPECT_TRUE(matches("int *const j = nullptr;",
831*67e74705SXin Li                       varDecl(hasType(hasLocalQualifiers()))));
832*67e74705SXin Li   EXPECT_TRUE(matches("int *volatile k;",
833*67e74705SXin Li                       varDecl(hasType(hasLocalQualifiers()))));
834*67e74705SXin Li   EXPECT_TRUE(notMatches("int m;",
835*67e74705SXin Li                          varDecl(hasType(hasLocalQualifiers()))));
836*67e74705SXin Li }
837*67e74705SXin Li 
TEST(IsExternC,MatchesExternCFunctionDeclarations)838*67e74705SXin Li TEST(IsExternC, MatchesExternCFunctionDeclarations) {
839*67e74705SXin Li   EXPECT_TRUE(matches("extern \"C\" void f() {}", functionDecl(isExternC())));
840*67e74705SXin Li   EXPECT_TRUE(matches("extern \"C\" { void f() {} }",
841*67e74705SXin Li                       functionDecl(isExternC())));
842*67e74705SXin Li   EXPECT_TRUE(notMatches("void f() {}", functionDecl(isExternC())));
843*67e74705SXin Li }
844*67e74705SXin Li 
TEST(IsDefaulted,MatchesDefaultedFunctionDeclarations)845*67e74705SXin Li TEST(IsDefaulted, MatchesDefaultedFunctionDeclarations) {
846*67e74705SXin Li   EXPECT_TRUE(notMatches("class A { ~A(); };",
847*67e74705SXin Li                          functionDecl(hasName("~A"), isDefaulted())));
848*67e74705SXin Li   EXPECT_TRUE(matches("class B { ~B() = default; };",
849*67e74705SXin Li                       functionDecl(hasName("~B"), isDefaulted())));
850*67e74705SXin Li }
851*67e74705SXin Li 
TEST(IsDeleted,MatchesDeletedFunctionDeclarations)852*67e74705SXin Li TEST(IsDeleted, MatchesDeletedFunctionDeclarations) {
853*67e74705SXin Li   EXPECT_TRUE(
854*67e74705SXin Li     notMatches("void Func();", functionDecl(hasName("Func"), isDeleted())));
855*67e74705SXin Li   EXPECT_TRUE(matches("void Func() = delete;",
856*67e74705SXin Li                       functionDecl(hasName("Func"), isDeleted())));
857*67e74705SXin Li }
858*67e74705SXin Li 
TEST(IsNoThrow,MatchesNoThrowFunctionDeclarations)859*67e74705SXin Li TEST(IsNoThrow, MatchesNoThrowFunctionDeclarations) {
860*67e74705SXin Li   EXPECT_TRUE(notMatches("void f();", functionDecl(isNoThrow())));
861*67e74705SXin Li   EXPECT_TRUE(notMatches("void f() throw(int);", functionDecl(isNoThrow())));
862*67e74705SXin Li   EXPECT_TRUE(
863*67e74705SXin Li     notMatches("void f() noexcept(false);", functionDecl(isNoThrow())));
864*67e74705SXin Li   EXPECT_TRUE(matches("void f() throw();", functionDecl(isNoThrow())));
865*67e74705SXin Li   EXPECT_TRUE(matches("void f() noexcept;", functionDecl(isNoThrow())));
866*67e74705SXin Li 
867*67e74705SXin Li   EXPECT_TRUE(notMatches("void f();", functionProtoType(isNoThrow())));
868*67e74705SXin Li   EXPECT_TRUE(notMatches("void f() throw(int);", functionProtoType(isNoThrow())));
869*67e74705SXin Li   EXPECT_TRUE(
870*67e74705SXin Li     notMatches("void f() noexcept(false);", functionProtoType(isNoThrow())));
871*67e74705SXin Li   EXPECT_TRUE(matches("void f() throw();", functionProtoType(isNoThrow())));
872*67e74705SXin Li   EXPECT_TRUE(matches("void f() noexcept;", functionProtoType(isNoThrow())));
873*67e74705SXin Li }
874*67e74705SXin Li 
TEST(isConstexpr,MatchesConstexprDeclarations)875*67e74705SXin Li TEST(isConstexpr, MatchesConstexprDeclarations) {
876*67e74705SXin Li   EXPECT_TRUE(matches("constexpr int foo = 42;",
877*67e74705SXin Li                       varDecl(hasName("foo"), isConstexpr())));
878*67e74705SXin Li   EXPECT_TRUE(matches("constexpr int bar();",
879*67e74705SXin Li                       functionDecl(hasName("bar"), isConstexpr())));
880*67e74705SXin Li }
881*67e74705SXin Li 
TEST(TemplateArgumentCountIs,Matches)882*67e74705SXin Li TEST(TemplateArgumentCountIs, Matches) {
883*67e74705SXin Li   EXPECT_TRUE(
884*67e74705SXin Li     matches("template<typename T> struct C {}; C<int> c;",
885*67e74705SXin Li             classTemplateSpecializationDecl(templateArgumentCountIs(1))));
886*67e74705SXin Li   EXPECT_TRUE(
887*67e74705SXin Li     notMatches("template<typename T> struct C {}; C<int> c;",
888*67e74705SXin Li                classTemplateSpecializationDecl(templateArgumentCountIs(2))));
889*67e74705SXin Li 
890*67e74705SXin Li   EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
891*67e74705SXin Li                       templateSpecializationType(templateArgumentCountIs(1))));
892*67e74705SXin Li   EXPECT_TRUE(
893*67e74705SXin Li     notMatches("template<typename T> struct C {}; C<int> c;",
894*67e74705SXin Li                templateSpecializationType(templateArgumentCountIs(2))));
895*67e74705SXin Li }
896*67e74705SXin Li 
TEST(IsIntegral,Matches)897*67e74705SXin Li TEST(IsIntegral, Matches) {
898*67e74705SXin Li   EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
899*67e74705SXin Li                       classTemplateSpecializationDecl(
900*67e74705SXin Li                         hasAnyTemplateArgument(isIntegral()))));
901*67e74705SXin Li   EXPECT_TRUE(notMatches("template<typename T> struct C {}; C<int> c;",
902*67e74705SXin Li                          classTemplateSpecializationDecl(hasAnyTemplateArgument(
903*67e74705SXin Li                            templateArgument(isIntegral())))));
904*67e74705SXin Li }
905*67e74705SXin Li 
TEST(EqualsIntegralValue,Matches)906*67e74705SXin Li TEST(EqualsIntegralValue, Matches) {
907*67e74705SXin Li   EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
908*67e74705SXin Li                       classTemplateSpecializationDecl(
909*67e74705SXin Li                         hasAnyTemplateArgument(equalsIntegralValue("42")))));
910*67e74705SXin Li   EXPECT_TRUE(matches("template<int T> struct C {}; C<-42> c;",
911*67e74705SXin Li                       classTemplateSpecializationDecl(
912*67e74705SXin Li                         hasAnyTemplateArgument(equalsIntegralValue("-42")))));
913*67e74705SXin Li   EXPECT_TRUE(matches("template<int T> struct C {}; C<-0042> c;",
914*67e74705SXin Li                       classTemplateSpecializationDecl(
915*67e74705SXin Li                         hasAnyTemplateArgument(equalsIntegralValue("-34")))));
916*67e74705SXin Li   EXPECT_TRUE(notMatches("template<int T> struct C {}; C<42> c;",
917*67e74705SXin Li                          classTemplateSpecializationDecl(hasAnyTemplateArgument(
918*67e74705SXin Li                            equalsIntegralValue("0042")))));
919*67e74705SXin Li }
920*67e74705SXin Li 
TEST(Matcher,MatchesAccessSpecDecls)921*67e74705SXin Li TEST(Matcher, MatchesAccessSpecDecls) {
922*67e74705SXin Li   EXPECT_TRUE(matches("class C { public: int i; };", accessSpecDecl()));
923*67e74705SXin Li   EXPECT_TRUE(
924*67e74705SXin Li       matches("class C { public: int i; };", accessSpecDecl(isPublic())));
925*67e74705SXin Li   EXPECT_TRUE(
926*67e74705SXin Li       notMatches("class C { public: int i; };", accessSpecDecl(isProtected())));
927*67e74705SXin Li   EXPECT_TRUE(
928*67e74705SXin Li       notMatches("class C { public: int i; };", accessSpecDecl(isPrivate())));
929*67e74705SXin Li 
930*67e74705SXin Li   EXPECT_TRUE(notMatches("class C { int i; };", accessSpecDecl()));
931*67e74705SXin Li }
932*67e74705SXin Li 
TEST(Matcher,MatchesFinal)933*67e74705SXin Li TEST(Matcher, MatchesFinal) {
934*67e74705SXin Li   EXPECT_TRUE(matches("class X final {};", cxxRecordDecl(isFinal())));
935*67e74705SXin Li   EXPECT_TRUE(matches("class X { virtual void f() final; };",
936*67e74705SXin Li                       cxxMethodDecl(isFinal())));
937*67e74705SXin Li   EXPECT_TRUE(notMatches("class X {};", cxxRecordDecl(isFinal())));
938*67e74705SXin Li   EXPECT_TRUE(
939*67e74705SXin Li     notMatches("class X { virtual void f(); };", cxxMethodDecl(isFinal())));
940*67e74705SXin Li }
941*67e74705SXin Li 
TEST(Matcher,MatchesVirtualMethod)942*67e74705SXin Li TEST(Matcher, MatchesVirtualMethod) {
943*67e74705SXin Li   EXPECT_TRUE(matches("class X { virtual int f(); };",
944*67e74705SXin Li                       cxxMethodDecl(isVirtual(), hasName("::X::f"))));
945*67e74705SXin Li   EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isVirtual())));
946*67e74705SXin Li }
947*67e74705SXin Li 
TEST(Matcher,MatchesVirtualAsWrittenMethod)948*67e74705SXin Li TEST(Matcher, MatchesVirtualAsWrittenMethod) {
949*67e74705SXin Li   EXPECT_TRUE(matches("class A { virtual int f(); };"
950*67e74705SXin Li                         "class B : public A { int f(); };",
951*67e74705SXin Li                       cxxMethodDecl(isVirtualAsWritten(), hasName("::A::f"))));
952*67e74705SXin Li   EXPECT_TRUE(
953*67e74705SXin Li     notMatches("class A { virtual int f(); };"
954*67e74705SXin Li                  "class B : public A { int f(); };",
955*67e74705SXin Li                cxxMethodDecl(isVirtualAsWritten(), hasName("::B::f"))));
956*67e74705SXin Li }
957*67e74705SXin Li 
TEST(Matcher,MatchesPureMethod)958*67e74705SXin Li TEST(Matcher, MatchesPureMethod) {
959*67e74705SXin Li   EXPECT_TRUE(matches("class X { virtual int f() = 0; };",
960*67e74705SXin Li                       cxxMethodDecl(isPure(), hasName("::X::f"))));
961*67e74705SXin Li   EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isPure())));
962*67e74705SXin Li }
963*67e74705SXin Li 
TEST(Matcher,MatchesCopyAssignmentOperator)964*67e74705SXin Li TEST(Matcher, MatchesCopyAssignmentOperator) {
965*67e74705SXin Li   EXPECT_TRUE(matches("class X { X &operator=(X); };",
966*67e74705SXin Li                       cxxMethodDecl(isCopyAssignmentOperator())));
967*67e74705SXin Li   EXPECT_TRUE(matches("class X { X &operator=(X &); };",
968*67e74705SXin Li                       cxxMethodDecl(isCopyAssignmentOperator())));
969*67e74705SXin Li   EXPECT_TRUE(matches("class X { X &operator=(const X &); };",
970*67e74705SXin Li                       cxxMethodDecl(isCopyAssignmentOperator())));
971*67e74705SXin Li   EXPECT_TRUE(matches("class X { X &operator=(volatile X &); };",
972*67e74705SXin Li                       cxxMethodDecl(isCopyAssignmentOperator())));
973*67e74705SXin Li   EXPECT_TRUE(matches("class X { X &operator=(const volatile X &); };",
974*67e74705SXin Li                       cxxMethodDecl(isCopyAssignmentOperator())));
975*67e74705SXin Li   EXPECT_TRUE(notMatches("class X { X &operator=(X &&); };",
976*67e74705SXin Li                          cxxMethodDecl(isCopyAssignmentOperator())));
977*67e74705SXin Li }
978*67e74705SXin Li 
TEST(Matcher,MatchesMoveAssignmentOperator)979*67e74705SXin Li TEST(Matcher, MatchesMoveAssignmentOperator) {
980*67e74705SXin Li   EXPECT_TRUE(notMatches("class X { X &operator=(X); };",
981*67e74705SXin Li                          cxxMethodDecl(isMoveAssignmentOperator())));
982*67e74705SXin Li   EXPECT_TRUE(matches("class X { X &operator=(X &&); };",
983*67e74705SXin Li                       cxxMethodDecl(isMoveAssignmentOperator())));
984*67e74705SXin Li   EXPECT_TRUE(matches("class X { X &operator=(const X &&); };",
985*67e74705SXin Li                       cxxMethodDecl(isMoveAssignmentOperator())));
986*67e74705SXin Li   EXPECT_TRUE(matches("class X { X &operator=(volatile X &&); };",
987*67e74705SXin Li                       cxxMethodDecl(isMoveAssignmentOperator())));
988*67e74705SXin Li   EXPECT_TRUE(matches("class X { X &operator=(const volatile X &&); };",
989*67e74705SXin Li                       cxxMethodDecl(isMoveAssignmentOperator())));
990*67e74705SXin Li   EXPECT_TRUE(notMatches("class X { X &operator=(X &); };",
991*67e74705SXin Li                          cxxMethodDecl(isMoveAssignmentOperator())));
992*67e74705SXin Li }
993*67e74705SXin Li 
TEST(Matcher,MatchesConstMethod)994*67e74705SXin Li TEST(Matcher, MatchesConstMethod) {
995*67e74705SXin Li   EXPECT_TRUE(
996*67e74705SXin Li     matches("struct A { void foo() const; };", cxxMethodDecl(isConst())));
997*67e74705SXin Li   EXPECT_TRUE(
998*67e74705SXin Li     notMatches("struct A { void foo(); };", cxxMethodDecl(isConst())));
999*67e74705SXin Li }
1000*67e74705SXin Li 
TEST(Matcher,MatchesOverridingMethod)1001*67e74705SXin Li TEST(Matcher, MatchesOverridingMethod) {
1002*67e74705SXin Li   EXPECT_TRUE(matches("class X { virtual int f(); }; "
1003*67e74705SXin Li                         "class Y : public X { int f(); };",
1004*67e74705SXin Li                       cxxMethodDecl(isOverride(), hasName("::Y::f"))));
1005*67e74705SXin Li   EXPECT_TRUE(notMatches("class X { virtual int f(); }; "
1006*67e74705SXin Li                            "class Y : public X { int f(); };",
1007*67e74705SXin Li                          cxxMethodDecl(isOverride(), hasName("::X::f"))));
1008*67e74705SXin Li   EXPECT_TRUE(notMatches("class X { int f(); }; "
1009*67e74705SXin Li                            "class Y : public X { int f(); };",
1010*67e74705SXin Li                          cxxMethodDecl(isOverride())));
1011*67e74705SXin Li   EXPECT_TRUE(notMatches("class X { int f(); int f(int); }; ",
1012*67e74705SXin Li                          cxxMethodDecl(isOverride())));
1013*67e74705SXin Li   EXPECT_TRUE(
1014*67e74705SXin Li     matches("template <typename Base> struct Y : Base { void f() override;};",
1015*67e74705SXin Li             cxxMethodDecl(isOverride(), hasName("::Y::f"))));
1016*67e74705SXin Li }
1017*67e74705SXin Li 
TEST(Matcher,ConstructorArgument)1018*67e74705SXin Li TEST(Matcher, ConstructorArgument) {
1019*67e74705SXin Li   StatementMatcher Constructor = cxxConstructExpr(
1020*67e74705SXin Li     hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
1021*67e74705SXin Li 
1022*67e74705SXin Li   EXPECT_TRUE(
1023*67e74705SXin Li     matches("class X { public: X(int); }; void x() { int y; X x(y); }",
1024*67e74705SXin Li             Constructor));
1025*67e74705SXin Li   EXPECT_TRUE(
1026*67e74705SXin Li     matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
1027*67e74705SXin Li             Constructor));
1028*67e74705SXin Li   EXPECT_TRUE(
1029*67e74705SXin Li     matches("class X { public: X(int); }; void x() { int y; X x = y; }",
1030*67e74705SXin Li             Constructor));
1031*67e74705SXin Li   EXPECT_TRUE(
1032*67e74705SXin Li     notMatches("class X { public: X(int); }; void x() { int z; X x(z); }",
1033*67e74705SXin Li                Constructor));
1034*67e74705SXin Li 
1035*67e74705SXin Li   StatementMatcher WrongIndex = cxxConstructExpr(
1036*67e74705SXin Li     hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
1037*67e74705SXin Li   EXPECT_TRUE(
1038*67e74705SXin Li     notMatches("class X { public: X(int); }; void x() { int y; X x(y); }",
1039*67e74705SXin Li                WrongIndex));
1040*67e74705SXin Li }
1041*67e74705SXin Li 
TEST(Matcher,ConstructorArgumentCount)1042*67e74705SXin Li TEST(Matcher, ConstructorArgumentCount) {
1043*67e74705SXin Li   StatementMatcher Constructor1Arg = cxxConstructExpr(argumentCountIs(1));
1044*67e74705SXin Li 
1045*67e74705SXin Li   EXPECT_TRUE(
1046*67e74705SXin Li     matches("class X { public: X(int); }; void x() { X x(0); }",
1047*67e74705SXin Li             Constructor1Arg));
1048*67e74705SXin Li   EXPECT_TRUE(
1049*67e74705SXin Li     matches("class X { public: X(int); }; void x() { X x = X(0); }",
1050*67e74705SXin Li             Constructor1Arg));
1051*67e74705SXin Li   EXPECT_TRUE(
1052*67e74705SXin Li     matches("class X { public: X(int); }; void x() { X x = 0; }",
1053*67e74705SXin Li             Constructor1Arg));
1054*67e74705SXin Li   EXPECT_TRUE(
1055*67e74705SXin Li     notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
1056*67e74705SXin Li                Constructor1Arg));
1057*67e74705SXin Li }
1058*67e74705SXin Li 
TEST(Matcher,ConstructorListInitialization)1059*67e74705SXin Li TEST(Matcher, ConstructorListInitialization) {
1060*67e74705SXin Li   StatementMatcher ConstructorListInit =
1061*67e74705SXin Li     cxxConstructExpr(isListInitialization());
1062*67e74705SXin Li 
1063*67e74705SXin Li   EXPECT_TRUE(
1064*67e74705SXin Li     matches("class X { public: X(int); }; void x() { X x{0}; }",
1065*67e74705SXin Li             ConstructorListInit));
1066*67e74705SXin Li   EXPECT_FALSE(
1067*67e74705SXin Li     matches("class X { public: X(int); }; void x() { X x(0); }",
1068*67e74705SXin Li             ConstructorListInit));
1069*67e74705SXin Li }
1070*67e74705SXin Li 
TEST(ConstructorDeclaration,IsImplicit)1071*67e74705SXin Li TEST(ConstructorDeclaration, IsImplicit) {
1072*67e74705SXin Li   // This one doesn't match because the constructor is not added by the
1073*67e74705SXin Li   // compiler (it is not needed).
1074*67e74705SXin Li   EXPECT_TRUE(notMatches("class Foo { };",
1075*67e74705SXin Li                          cxxConstructorDecl(isImplicit())));
1076*67e74705SXin Li   // The compiler added the implicit default constructor.
1077*67e74705SXin Li   EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
1078*67e74705SXin Li                       cxxConstructorDecl(isImplicit())));
1079*67e74705SXin Li   EXPECT_TRUE(matches("class Foo { Foo(){} };",
1080*67e74705SXin Li                       cxxConstructorDecl(unless(isImplicit()))));
1081*67e74705SXin Li   // The compiler added an implicit assignment operator.
1082*67e74705SXin Li   EXPECT_TRUE(matches("struct A { int x; } a = {0}, b = a; void f() { a = b; }",
1083*67e74705SXin Li                       cxxMethodDecl(isImplicit(), hasName("operator="))));
1084*67e74705SXin Li }
1085*67e74705SXin Li 
TEST(ConstructorDeclaration,IsExplicit)1086*67e74705SXin Li TEST(ConstructorDeclaration, IsExplicit) {
1087*67e74705SXin Li   EXPECT_TRUE(matches("struct S { explicit S(int); };",
1088*67e74705SXin Li                       cxxConstructorDecl(isExplicit())));
1089*67e74705SXin Li   EXPECT_TRUE(notMatches("struct S { S(int); };",
1090*67e74705SXin Li                          cxxConstructorDecl(isExplicit())));
1091*67e74705SXin Li }
1092*67e74705SXin Li 
TEST(ConstructorDeclaration,Kinds)1093*67e74705SXin Li TEST(ConstructorDeclaration, Kinds) {
1094*67e74705SXin Li   EXPECT_TRUE(matches("struct S { S(); };",
1095*67e74705SXin Li                       cxxConstructorDecl(isDefaultConstructor())));
1096*67e74705SXin Li   EXPECT_TRUE(notMatches("struct S { S(); };",
1097*67e74705SXin Li                          cxxConstructorDecl(isCopyConstructor())));
1098*67e74705SXin Li   EXPECT_TRUE(notMatches("struct S { S(); };",
1099*67e74705SXin Li                          cxxConstructorDecl(isMoveConstructor())));
1100*67e74705SXin Li 
1101*67e74705SXin Li   EXPECT_TRUE(notMatches("struct S { S(const S&); };",
1102*67e74705SXin Li                          cxxConstructorDecl(isDefaultConstructor())));
1103*67e74705SXin Li   EXPECT_TRUE(matches("struct S { S(const S&); };",
1104*67e74705SXin Li                       cxxConstructorDecl(isCopyConstructor())));
1105*67e74705SXin Li   EXPECT_TRUE(notMatches("struct S { S(const S&); };",
1106*67e74705SXin Li                          cxxConstructorDecl(isMoveConstructor())));
1107*67e74705SXin Li 
1108*67e74705SXin Li   EXPECT_TRUE(notMatches("struct S { S(S&&); };",
1109*67e74705SXin Li                          cxxConstructorDecl(isDefaultConstructor())));
1110*67e74705SXin Li   EXPECT_TRUE(notMatches("struct S { S(S&&); };",
1111*67e74705SXin Li                          cxxConstructorDecl(isCopyConstructor())));
1112*67e74705SXin Li   EXPECT_TRUE(matches("struct S { S(S&&); };",
1113*67e74705SXin Li                       cxxConstructorDecl(isMoveConstructor())));
1114*67e74705SXin Li }
1115*67e74705SXin Li 
TEST(ConstructorDeclaration,IsUserProvided)1116*67e74705SXin Li TEST(ConstructorDeclaration, IsUserProvided) {
1117*67e74705SXin Li   EXPECT_TRUE(notMatches("struct S { int X = 0; };",
1118*67e74705SXin Li                          cxxConstructorDecl(isUserProvided())));
1119*67e74705SXin Li   EXPECT_TRUE(notMatches("struct S { S() = default; };",
1120*67e74705SXin Li                          cxxConstructorDecl(isUserProvided())));
1121*67e74705SXin Li   EXPECT_TRUE(notMatches("struct S { S() = delete; };",
1122*67e74705SXin Li                          cxxConstructorDecl(isUserProvided())));
1123*67e74705SXin Li   EXPECT_TRUE(
1124*67e74705SXin Li     matches("struct S { S(); };", cxxConstructorDecl(isUserProvided())));
1125*67e74705SXin Li   EXPECT_TRUE(matches("struct S { S(); }; S::S(){}",
1126*67e74705SXin Li                       cxxConstructorDecl(isUserProvided())));
1127*67e74705SXin Li }
1128*67e74705SXin Li 
TEST(ConstructorDeclaration,IsDelegatingConstructor)1129*67e74705SXin Li TEST(ConstructorDeclaration, IsDelegatingConstructor) {
1130*67e74705SXin Li   EXPECT_TRUE(notMatches("struct S { S(); S(int); int X; };",
1131*67e74705SXin Li                          cxxConstructorDecl(isDelegatingConstructor())));
1132*67e74705SXin Li   EXPECT_TRUE(notMatches("struct S { S(){} S(int X) : X(X) {} int X; };",
1133*67e74705SXin Li                          cxxConstructorDecl(isDelegatingConstructor())));
1134*67e74705SXin Li   EXPECT_TRUE(matches(
1135*67e74705SXin Li     "struct S { S() : S(0) {} S(int X) : X(X) {} int X; };",
1136*67e74705SXin Li     cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(0))));
1137*67e74705SXin Li   EXPECT_TRUE(matches(
1138*67e74705SXin Li     "struct S { S(); S(int X); int X; }; S::S(int X) : S() {}",
1139*67e74705SXin Li     cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(1))));
1140*67e74705SXin Li }
1141*67e74705SXin Li 
TEST(StringLiteral,HasSize)1142*67e74705SXin Li TEST(StringLiteral, HasSize) {
1143*67e74705SXin Li   StatementMatcher Literal = stringLiteral(hasSize(4));
1144*67e74705SXin Li   EXPECT_TRUE(matches("const char *s = \"abcd\";", Literal));
1145*67e74705SXin Li   // wide string
1146*67e74705SXin Li   EXPECT_TRUE(matches("const wchar_t *s = L\"abcd\";", Literal));
1147*67e74705SXin Li   // with escaped characters
1148*67e74705SXin Li   EXPECT_TRUE(matches("const char *s = \"\x05\x06\x07\x08\";", Literal));
1149*67e74705SXin Li   // no matching, too small
1150*67e74705SXin Li   EXPECT_TRUE(notMatches("const char *s = \"ab\";", Literal));
1151*67e74705SXin Li }
1152*67e74705SXin Li 
TEST(Matcher,HasNameSupportsNamespaces)1153*67e74705SXin Li TEST(Matcher, HasNameSupportsNamespaces) {
1154*67e74705SXin Li   EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1155*67e74705SXin Li                       recordDecl(hasName("a::b::C"))));
1156*67e74705SXin Li   EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1157*67e74705SXin Li                       recordDecl(hasName("::a::b::C"))));
1158*67e74705SXin Li   EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1159*67e74705SXin Li                       recordDecl(hasName("b::C"))));
1160*67e74705SXin Li   EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1161*67e74705SXin Li                       recordDecl(hasName("C"))));
1162*67e74705SXin Li   EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1163*67e74705SXin Li                          recordDecl(hasName("c::b::C"))));
1164*67e74705SXin Li   EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1165*67e74705SXin Li                          recordDecl(hasName("a::c::C"))));
1166*67e74705SXin Li   EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1167*67e74705SXin Li                          recordDecl(hasName("a::b::A"))));
1168*67e74705SXin Li   EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1169*67e74705SXin Li                          recordDecl(hasName("::C"))));
1170*67e74705SXin Li   EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1171*67e74705SXin Li                          recordDecl(hasName("::b::C"))));
1172*67e74705SXin Li   EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1173*67e74705SXin Li                          recordDecl(hasName("z::a::b::C"))));
1174*67e74705SXin Li   EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1175*67e74705SXin Li                          recordDecl(hasName("a+b::C"))));
1176*67e74705SXin Li   EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
1177*67e74705SXin Li                          recordDecl(hasName("C"))));
1178*67e74705SXin Li }
1179*67e74705SXin Li 
TEST(Matcher,HasNameSupportsOuterClasses)1180*67e74705SXin Li TEST(Matcher, HasNameSupportsOuterClasses) {
1181*67e74705SXin Li   EXPECT_TRUE(
1182*67e74705SXin Li     matches("class A { class B { class C; }; };",
1183*67e74705SXin Li             recordDecl(hasName("A::B::C"))));
1184*67e74705SXin Li   EXPECT_TRUE(
1185*67e74705SXin Li     matches("class A { class B { class C; }; };",
1186*67e74705SXin Li             recordDecl(hasName("::A::B::C"))));
1187*67e74705SXin Li   EXPECT_TRUE(
1188*67e74705SXin Li     matches("class A { class B { class C; }; };",
1189*67e74705SXin Li             recordDecl(hasName("B::C"))));
1190*67e74705SXin Li   EXPECT_TRUE(
1191*67e74705SXin Li     matches("class A { class B { class C; }; };",
1192*67e74705SXin Li             recordDecl(hasName("C"))));
1193*67e74705SXin Li   EXPECT_TRUE(
1194*67e74705SXin Li     notMatches("class A { class B { class C; }; };",
1195*67e74705SXin Li                recordDecl(hasName("c::B::C"))));
1196*67e74705SXin Li   EXPECT_TRUE(
1197*67e74705SXin Li     notMatches("class A { class B { class C; }; };",
1198*67e74705SXin Li                recordDecl(hasName("A::c::C"))));
1199*67e74705SXin Li   EXPECT_TRUE(
1200*67e74705SXin Li     notMatches("class A { class B { class C; }; };",
1201*67e74705SXin Li                recordDecl(hasName("A::B::A"))));
1202*67e74705SXin Li   EXPECT_TRUE(
1203*67e74705SXin Li     notMatches("class A { class B { class C; }; };",
1204*67e74705SXin Li                recordDecl(hasName("::C"))));
1205*67e74705SXin Li   EXPECT_TRUE(
1206*67e74705SXin Li     notMatches("class A { class B { class C; }; };",
1207*67e74705SXin Li                recordDecl(hasName("::B::C"))));
1208*67e74705SXin Li   EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
1209*67e74705SXin Li                          recordDecl(hasName("z::A::B::C"))));
1210*67e74705SXin Li   EXPECT_TRUE(
1211*67e74705SXin Li     notMatches("class A { class B { class C; }; };",
1212*67e74705SXin Li                recordDecl(hasName("A+B::C"))));
1213*67e74705SXin Li }
1214*67e74705SXin Li 
TEST(Matcher,HasNameSupportsInlinedNamespaces)1215*67e74705SXin Li TEST(Matcher, HasNameSupportsInlinedNamespaces) {
1216*67e74705SXin Li   std::string code = "namespace a { inline namespace b { class C; } }";
1217*67e74705SXin Li   EXPECT_TRUE(matches(code, recordDecl(hasName("a::b::C"))));
1218*67e74705SXin Li   EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
1219*67e74705SXin Li   EXPECT_TRUE(matches(code, recordDecl(hasName("::a::b::C"))));
1220*67e74705SXin Li   EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
1221*67e74705SXin Li }
1222*67e74705SXin Li 
TEST(Matcher,HasNameSupportsAnonymousNamespaces)1223*67e74705SXin Li TEST(Matcher, HasNameSupportsAnonymousNamespaces) {
1224*67e74705SXin Li   std::string code = "namespace a { namespace { class C; } }";
1225*67e74705SXin Li   EXPECT_TRUE(
1226*67e74705SXin Li     matches(code, recordDecl(hasName("a::(anonymous namespace)::C"))));
1227*67e74705SXin Li   EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
1228*67e74705SXin Li   EXPECT_TRUE(
1229*67e74705SXin Li     matches(code, recordDecl(hasName("::a::(anonymous namespace)::C"))));
1230*67e74705SXin Li   EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
1231*67e74705SXin Li }
1232*67e74705SXin Li 
TEST(Matcher,HasNameSupportsAnonymousOuterClasses)1233*67e74705SXin Li TEST(Matcher, HasNameSupportsAnonymousOuterClasses) {
1234*67e74705SXin Li   EXPECT_TRUE(matches("class A { class { class C; } x; };",
1235*67e74705SXin Li                       recordDecl(hasName("A::(anonymous class)::C"))));
1236*67e74705SXin Li   EXPECT_TRUE(matches("class A { class { class C; } x; };",
1237*67e74705SXin Li                       recordDecl(hasName("::A::(anonymous class)::C"))));
1238*67e74705SXin Li   EXPECT_FALSE(matches("class A { class { class C; } x; };",
1239*67e74705SXin Li                        recordDecl(hasName("::A::C"))));
1240*67e74705SXin Li   EXPECT_TRUE(matches("class A { struct { class C; } x; };",
1241*67e74705SXin Li                       recordDecl(hasName("A::(anonymous struct)::C"))));
1242*67e74705SXin Li   EXPECT_TRUE(matches("class A { struct { class C; } x; };",
1243*67e74705SXin Li                       recordDecl(hasName("::A::(anonymous struct)::C"))));
1244*67e74705SXin Li   EXPECT_FALSE(matches("class A { struct { class C; } x; };",
1245*67e74705SXin Li                        recordDecl(hasName("::A::C"))));
1246*67e74705SXin Li }
1247*67e74705SXin Li 
TEST(Matcher,HasNameSupportsFunctionScope)1248*67e74705SXin Li TEST(Matcher, HasNameSupportsFunctionScope) {
1249*67e74705SXin Li   std::string code =
1250*67e74705SXin Li     "namespace a { void F(int a) { struct S { int m; }; int i; } }";
1251*67e74705SXin Li   EXPECT_TRUE(matches(code, varDecl(hasName("i"))));
1252*67e74705SXin Li   EXPECT_FALSE(matches(code, varDecl(hasName("F()::i"))));
1253*67e74705SXin Li 
1254*67e74705SXin Li   EXPECT_TRUE(matches(code, fieldDecl(hasName("m"))));
1255*67e74705SXin Li   EXPECT_TRUE(matches(code, fieldDecl(hasName("S::m"))));
1256*67e74705SXin Li   EXPECT_TRUE(matches(code, fieldDecl(hasName("F(int)::S::m"))));
1257*67e74705SXin Li   EXPECT_TRUE(matches(code, fieldDecl(hasName("a::F(int)::S::m"))));
1258*67e74705SXin Li   EXPECT_TRUE(matches(code, fieldDecl(hasName("::a::F(int)::S::m"))));
1259*67e74705SXin Li }
1260*67e74705SXin Li 
TEST(Matcher,HasAnyName)1261*67e74705SXin Li TEST(Matcher, HasAnyName) {
1262*67e74705SXin Li   const std::string Code = "namespace a { namespace b { class C; } }";
1263*67e74705SXin Li 
1264*67e74705SXin Li   EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "a::b::C"))));
1265*67e74705SXin Li   EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("a::b::C", "XX"))));
1266*67e74705SXin Li   EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX::C", "a::b::C"))));
1267*67e74705SXin Li   EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "C"))));
1268*67e74705SXin Li 
1269*67e74705SXin Li   EXPECT_TRUE(notMatches(Code, recordDecl(hasAnyName("::C", "::b::C"))));
1270*67e74705SXin Li   EXPECT_TRUE(
1271*67e74705SXin Li     matches(Code, recordDecl(hasAnyName("::C", "::b::C", "::a::b::C"))));
1272*67e74705SXin Li 
1273*67e74705SXin Li   std::vector<StringRef> Names = {"::C", "::b::C", "::a::b::C"};
1274*67e74705SXin Li   EXPECT_TRUE(matches(Code, recordDecl(hasAnyName(Names))));
1275*67e74705SXin Li }
1276*67e74705SXin Li 
TEST(Matcher,IsDefinition)1277*67e74705SXin Li TEST(Matcher, IsDefinition) {
1278*67e74705SXin Li   DeclarationMatcher DefinitionOfClassA =
1279*67e74705SXin Li     recordDecl(hasName("A"), isDefinition());
1280*67e74705SXin Li   EXPECT_TRUE(matches("class A {};", DefinitionOfClassA));
1281*67e74705SXin Li   EXPECT_TRUE(notMatches("class A;", DefinitionOfClassA));
1282*67e74705SXin Li 
1283*67e74705SXin Li   DeclarationMatcher DefinitionOfVariableA =
1284*67e74705SXin Li     varDecl(hasName("a"), isDefinition());
1285*67e74705SXin Li   EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));
1286*67e74705SXin Li   EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));
1287*67e74705SXin Li 
1288*67e74705SXin Li   DeclarationMatcher DefinitionOfMethodA =
1289*67e74705SXin Li     cxxMethodDecl(hasName("a"), isDefinition());
1290*67e74705SXin Li   EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));
1291*67e74705SXin Li   EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));
1292*67e74705SXin Li }
1293*67e74705SXin Li 
TEST(Matcher,HandlesNullQualTypes)1294*67e74705SXin Li TEST(Matcher, HandlesNullQualTypes) {
1295*67e74705SXin Li   // FIXME: Add a Type matcher so we can replace uses of this
1296*67e74705SXin Li   // variable with Type(True())
1297*67e74705SXin Li   const TypeMatcher AnyType = anything();
1298*67e74705SXin Li 
1299*67e74705SXin Li   // We don't really care whether this matcher succeeds; we're testing that
1300*67e74705SXin Li   // it completes without crashing.
1301*67e74705SXin Li   EXPECT_TRUE(matches(
1302*67e74705SXin Li     "struct A { };"
1303*67e74705SXin Li       "template <typename T>"
1304*67e74705SXin Li       "void f(T t) {"
1305*67e74705SXin Li       "  T local_t(t /* this becomes a null QualType in the AST */);"
1306*67e74705SXin Li       "}"
1307*67e74705SXin Li       "void g() {"
1308*67e74705SXin Li       "  f(0);"
1309*67e74705SXin Li       "}",
1310*67e74705SXin Li     expr(hasType(TypeMatcher(
1311*67e74705SXin Li       anyOf(
1312*67e74705SXin Li         TypeMatcher(hasDeclaration(anything())),
1313*67e74705SXin Li         pointsTo(AnyType),
1314*67e74705SXin Li         references(AnyType)
1315*67e74705SXin Li         // Other QualType matchers should go here.
1316*67e74705SXin Li       ))))));
1317*67e74705SXin Li }
1318*67e74705SXin Li 
1319*67e74705SXin Li 
TEST(StatementCountIs,FindsNoStatementsInAnEmptyCompoundStatement)1320*67e74705SXin Li TEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) {
1321*67e74705SXin Li   EXPECT_TRUE(matches("void f() { }",
1322*67e74705SXin Li                       compoundStmt(statementCountIs(0))));
1323*67e74705SXin Li   EXPECT_TRUE(notMatches("void f() {}",
1324*67e74705SXin Li                          compoundStmt(statementCountIs(1))));
1325*67e74705SXin Li }
1326*67e74705SXin Li 
TEST(StatementCountIs,AppearsToMatchOnlyOneCount)1327*67e74705SXin Li TEST(StatementCountIs, AppearsToMatchOnlyOneCount) {
1328*67e74705SXin Li   EXPECT_TRUE(matches("void f() { 1; }",
1329*67e74705SXin Li                       compoundStmt(statementCountIs(1))));
1330*67e74705SXin Li   EXPECT_TRUE(notMatches("void f() { 1; }",
1331*67e74705SXin Li                          compoundStmt(statementCountIs(0))));
1332*67e74705SXin Li   EXPECT_TRUE(notMatches("void f() { 1; }",
1333*67e74705SXin Li                          compoundStmt(statementCountIs(2))));
1334*67e74705SXin Li }
1335*67e74705SXin Li 
TEST(StatementCountIs,WorksWithMultipleStatements)1336*67e74705SXin Li TEST(StatementCountIs, WorksWithMultipleStatements) {
1337*67e74705SXin Li   EXPECT_TRUE(matches("void f() { 1; 2; 3; }",
1338*67e74705SXin Li                       compoundStmt(statementCountIs(3))));
1339*67e74705SXin Li }
1340*67e74705SXin Li 
TEST(StatementCountIs,WorksWithNestedCompoundStatements)1341*67e74705SXin Li TEST(StatementCountIs, WorksWithNestedCompoundStatements) {
1342*67e74705SXin Li   EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1343*67e74705SXin Li                       compoundStmt(statementCountIs(1))));
1344*67e74705SXin Li   EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1345*67e74705SXin Li                       compoundStmt(statementCountIs(2))));
1346*67e74705SXin Li   EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
1347*67e74705SXin Li                          compoundStmt(statementCountIs(3))));
1348*67e74705SXin Li   EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1349*67e74705SXin Li                       compoundStmt(statementCountIs(4))));
1350*67e74705SXin Li }
1351*67e74705SXin Li 
TEST(Member,WorksInSimplestCase)1352*67e74705SXin Li TEST(Member, WorksInSimplestCase) {
1353*67e74705SXin Li   EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
1354*67e74705SXin Li                       memberExpr(member(hasName("first")))));
1355*67e74705SXin Li }
1356*67e74705SXin Li 
TEST(Member,DoesNotMatchTheBaseExpression)1357*67e74705SXin Li TEST(Member, DoesNotMatchTheBaseExpression) {
1358*67e74705SXin Li   // Don't pick out the wrong part of the member expression, this should
1359*67e74705SXin Li   // be checking the member (name) only.
1360*67e74705SXin Li   EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
1361*67e74705SXin Li                          memberExpr(member(hasName("first")))));
1362*67e74705SXin Li }
1363*67e74705SXin Li 
TEST(Member,MatchesInMemberFunctionCall)1364*67e74705SXin Li TEST(Member, MatchesInMemberFunctionCall) {
1365*67e74705SXin Li   EXPECT_TRUE(matches("void f() {"
1366*67e74705SXin Li                         "  struct { void first() {}; } s;"
1367*67e74705SXin Li                         "  s.first();"
1368*67e74705SXin Li                         "};",
1369*67e74705SXin Li                       memberExpr(member(hasName("first")))));
1370*67e74705SXin Li }
1371*67e74705SXin Li 
TEST(Member,MatchesMember)1372*67e74705SXin Li TEST(Member, MatchesMember) {
1373*67e74705SXin Li   EXPECT_TRUE(matches(
1374*67e74705SXin Li     "struct A { int i; }; void f() { A a; a.i = 2; }",
1375*67e74705SXin Li     memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
1376*67e74705SXin Li   EXPECT_TRUE(notMatches(
1377*67e74705SXin Li     "struct A { float f; }; void f() { A a; a.f = 2.0f; }",
1378*67e74705SXin Li     memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
1379*67e74705SXin Li }
1380*67e74705SXin Li 
TEST(Member,BitFields)1381*67e74705SXin Li TEST(Member, BitFields) {
1382*67e74705SXin Li   EXPECT_TRUE(matches("class C { int a : 2; int b; };",
1383*67e74705SXin Li                       fieldDecl(isBitField(), hasName("a"))));
1384*67e74705SXin Li   EXPECT_TRUE(notMatches("class C { int a : 2; int b; };",
1385*67e74705SXin Li                          fieldDecl(isBitField(), hasName("b"))));
1386*67e74705SXin Li   EXPECT_TRUE(matches("class C { int a : 2; int b : 4; };",
1387*67e74705SXin Li                       fieldDecl(isBitField(), hasBitWidth(2), hasName("a"))));
1388*67e74705SXin Li }
1389*67e74705SXin Li 
TEST(Member,UnderstandsAccess)1390*67e74705SXin Li TEST(Member, UnderstandsAccess) {
1391*67e74705SXin Li   EXPECT_TRUE(matches(
1392*67e74705SXin Li     "struct A { int i; };", fieldDecl(isPublic(), hasName("i"))));
1393*67e74705SXin Li   EXPECT_TRUE(notMatches(
1394*67e74705SXin Li     "struct A { int i; };", fieldDecl(isProtected(), hasName("i"))));
1395*67e74705SXin Li   EXPECT_TRUE(notMatches(
1396*67e74705SXin Li     "struct A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
1397*67e74705SXin Li 
1398*67e74705SXin Li   EXPECT_TRUE(notMatches(
1399*67e74705SXin Li     "class A { int i; };", fieldDecl(isPublic(), hasName("i"))));
1400*67e74705SXin Li   EXPECT_TRUE(notMatches(
1401*67e74705SXin Li     "class A { int i; };", fieldDecl(isProtected(), hasName("i"))));
1402*67e74705SXin Li   EXPECT_TRUE(matches(
1403*67e74705SXin Li     "class A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
1404*67e74705SXin Li 
1405*67e74705SXin Li   EXPECT_TRUE(notMatches(
1406*67e74705SXin Li     "class A { protected: int i; };", fieldDecl(isPublic(), hasName("i"))));
1407*67e74705SXin Li   EXPECT_TRUE(matches("class A { protected: int i; };",
1408*67e74705SXin Li                       fieldDecl(isProtected(), hasName("i"))));
1409*67e74705SXin Li   EXPECT_TRUE(notMatches(
1410*67e74705SXin Li     "class A { protected: int i; };", fieldDecl(isPrivate(), hasName("i"))));
1411*67e74705SXin Li 
1412*67e74705SXin Li   // Non-member decls have the AccessSpecifier AS_none and thus aren't matched.
1413*67e74705SXin Li   EXPECT_TRUE(notMatches("int i;", varDecl(isPublic(), hasName("i"))));
1414*67e74705SXin Li   EXPECT_TRUE(notMatches("int i;", varDecl(isProtected(), hasName("i"))));
1415*67e74705SXin Li   EXPECT_TRUE(notMatches("int i;", varDecl(isPrivate(), hasName("i"))));
1416*67e74705SXin Li }
1417*67e74705SXin Li 
TEST(hasDynamicExceptionSpec,MatchesDynamicExceptionSpecifications)1418*67e74705SXin Li TEST(hasDynamicExceptionSpec, MatchesDynamicExceptionSpecifications) {
1419*67e74705SXin Li   EXPECT_TRUE(notMatches("void f();", functionDecl(hasDynamicExceptionSpec())));
1420*67e74705SXin Li   EXPECT_TRUE(notMatches("void g() noexcept;",
1421*67e74705SXin Li                          functionDecl(hasDynamicExceptionSpec())));
1422*67e74705SXin Li   EXPECT_TRUE(notMatches("void h() noexcept(true);",
1423*67e74705SXin Li                          functionDecl(hasDynamicExceptionSpec())));
1424*67e74705SXin Li   EXPECT_TRUE(notMatches("void i() noexcept(false);",
1425*67e74705SXin Li                          functionDecl(hasDynamicExceptionSpec())));
1426*67e74705SXin Li   EXPECT_TRUE(
1427*67e74705SXin Li       matches("void j() throw();", functionDecl(hasDynamicExceptionSpec())));
1428*67e74705SXin Li   EXPECT_TRUE(
1429*67e74705SXin Li       matches("void k() throw(int);", functionDecl(hasDynamicExceptionSpec())));
1430*67e74705SXin Li   EXPECT_TRUE(
1431*67e74705SXin Li       matches("void l() throw(...);", functionDecl(hasDynamicExceptionSpec())));
1432*67e74705SXin Li 
1433*67e74705SXin Li   EXPECT_TRUE(notMatches("void f();", functionProtoType(hasDynamicExceptionSpec())));
1434*67e74705SXin Li   EXPECT_TRUE(notMatches("void g() noexcept;",
1435*67e74705SXin Li                          functionProtoType(hasDynamicExceptionSpec())));
1436*67e74705SXin Li   EXPECT_TRUE(notMatches("void h() noexcept(true);",
1437*67e74705SXin Li                          functionProtoType(hasDynamicExceptionSpec())));
1438*67e74705SXin Li   EXPECT_TRUE(notMatches("void i() noexcept(false);",
1439*67e74705SXin Li                          functionProtoType(hasDynamicExceptionSpec())));
1440*67e74705SXin Li   EXPECT_TRUE(
1441*67e74705SXin Li       matches("void j() throw();", functionProtoType(hasDynamicExceptionSpec())));
1442*67e74705SXin Li   EXPECT_TRUE(
1443*67e74705SXin Li       matches("void k() throw(int);", functionProtoType(hasDynamicExceptionSpec())));
1444*67e74705SXin Li   EXPECT_TRUE(
1445*67e74705SXin Li       matches("void l() throw(...);", functionProtoType(hasDynamicExceptionSpec())));
1446*67e74705SXin Li }
1447*67e74705SXin Li 
TEST(HasObjectExpression,DoesNotMatchMember)1448*67e74705SXin Li TEST(HasObjectExpression, DoesNotMatchMember) {
1449*67e74705SXin Li   EXPECT_TRUE(notMatches(
1450*67e74705SXin Li     "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
1451*67e74705SXin Li     memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
1452*67e74705SXin Li }
1453*67e74705SXin Li 
TEST(HasObjectExpression,MatchesBaseOfVariable)1454*67e74705SXin Li TEST(HasObjectExpression, MatchesBaseOfVariable) {
1455*67e74705SXin Li   EXPECT_TRUE(matches(
1456*67e74705SXin Li     "struct X { int m; }; void f(X x) { x.m; }",
1457*67e74705SXin Li     memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
1458*67e74705SXin Li   EXPECT_TRUE(matches(
1459*67e74705SXin Li     "struct X { int m; }; void f(X* x) { x->m; }",
1460*67e74705SXin Li     memberExpr(hasObjectExpression(
1461*67e74705SXin Li       hasType(pointsTo(recordDecl(hasName("X"))))))));
1462*67e74705SXin Li }
1463*67e74705SXin Li 
TEST(HasObjectExpression,MatchesObjectExpressionOfImplicitlyFormedMemberExpression)1464*67e74705SXin Li TEST(HasObjectExpression,
1465*67e74705SXin Li      MatchesObjectExpressionOfImplicitlyFormedMemberExpression) {
1466*67e74705SXin Li   EXPECT_TRUE(matches(
1467*67e74705SXin Li     "class X {}; struct S { X m; void f() { this->m; } };",
1468*67e74705SXin Li     memberExpr(hasObjectExpression(
1469*67e74705SXin Li       hasType(pointsTo(recordDecl(hasName("S"))))))));
1470*67e74705SXin Li   EXPECT_TRUE(matches(
1471*67e74705SXin Li     "class X {}; struct S { X m; void f() { m; } };",
1472*67e74705SXin Li     memberExpr(hasObjectExpression(
1473*67e74705SXin Li       hasType(pointsTo(recordDecl(hasName("S"))))))));
1474*67e74705SXin Li }
1475*67e74705SXin Li 
TEST(Field,DoesNotMatchNonFieldMembers)1476*67e74705SXin Li TEST(Field, DoesNotMatchNonFieldMembers) {
1477*67e74705SXin Li   EXPECT_TRUE(notMatches("class X { void m(); };", fieldDecl(hasName("m"))));
1478*67e74705SXin Li   EXPECT_TRUE(notMatches("class X { class m {}; };", fieldDecl(hasName("m"))));
1479*67e74705SXin Li   EXPECT_TRUE(notMatches("class X { enum { m }; };", fieldDecl(hasName("m"))));
1480*67e74705SXin Li   EXPECT_TRUE(notMatches("class X { enum m {}; };", fieldDecl(hasName("m"))));
1481*67e74705SXin Li }
1482*67e74705SXin Li 
TEST(Field,MatchesField)1483*67e74705SXin Li TEST(Field, MatchesField) {
1484*67e74705SXin Li   EXPECT_TRUE(matches("class X { int m; };", fieldDecl(hasName("m"))));
1485*67e74705SXin Li }
1486*67e74705SXin Li 
TEST(IsVolatileQualified,QualifiersMatch)1487*67e74705SXin Li TEST(IsVolatileQualified, QualifiersMatch) {
1488*67e74705SXin Li   EXPECT_TRUE(matches("volatile int i = 42;",
1489*67e74705SXin Li                       varDecl(hasType(isVolatileQualified()))));
1490*67e74705SXin Li   EXPECT_TRUE(notMatches("volatile int *i;",
1491*67e74705SXin Li                          varDecl(hasType(isVolatileQualified()))));
1492*67e74705SXin Li   EXPECT_TRUE(matches("typedef volatile int v_int; v_int i = 42;",
1493*67e74705SXin Li                       varDecl(hasType(isVolatileQualified()))));
1494*67e74705SXin Li }
1495*67e74705SXin Li 
TEST(IsConstQualified,MatchesConstInt)1496*67e74705SXin Li TEST(IsConstQualified, MatchesConstInt) {
1497*67e74705SXin Li   EXPECT_TRUE(matches("const int i = 42;",
1498*67e74705SXin Li                       varDecl(hasType(isConstQualified()))));
1499*67e74705SXin Li }
1500*67e74705SXin Li 
TEST(IsConstQualified,MatchesConstPointer)1501*67e74705SXin Li TEST(IsConstQualified, MatchesConstPointer) {
1502*67e74705SXin Li   EXPECT_TRUE(matches("int i = 42; int* const p(&i);",
1503*67e74705SXin Li                       varDecl(hasType(isConstQualified()))));
1504*67e74705SXin Li }
1505*67e74705SXin Li 
TEST(IsConstQualified,MatchesThroughTypedef)1506*67e74705SXin Li TEST(IsConstQualified, MatchesThroughTypedef) {
1507*67e74705SXin Li   EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
1508*67e74705SXin Li                       varDecl(hasType(isConstQualified()))));
1509*67e74705SXin Li   EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p(0);",
1510*67e74705SXin Li                       varDecl(hasType(isConstQualified()))));
1511*67e74705SXin Li }
1512*67e74705SXin Li 
TEST(IsConstQualified,DoesNotMatchInappropriately)1513*67e74705SXin Li TEST(IsConstQualified, DoesNotMatchInappropriately) {
1514*67e74705SXin Li   EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
1515*67e74705SXin Li                          varDecl(hasType(isConstQualified()))));
1516*67e74705SXin Li   EXPECT_TRUE(notMatches("int const* p;",
1517*67e74705SXin Li                          varDecl(hasType(isConstQualified()))));
1518*67e74705SXin Li }
1519*67e74705SXin Li 
TEST(DeclCount,DeclCountIsCorrect)1520*67e74705SXin Li TEST(DeclCount, DeclCountIsCorrect) {
1521*67e74705SXin Li   EXPECT_TRUE(matches("void f() {int i,j;}",
1522*67e74705SXin Li                       declStmt(declCountIs(2))));
1523*67e74705SXin Li   EXPECT_TRUE(notMatches("void f() {int i,j; int k;}",
1524*67e74705SXin Li                          declStmt(declCountIs(3))));
1525*67e74705SXin Li   EXPECT_TRUE(notMatches("void f() {int i,j, k, l;}",
1526*67e74705SXin Li                          declStmt(declCountIs(3))));
1527*67e74705SXin Li }
1528*67e74705SXin Li 
1529*67e74705SXin Li 
TEST(EachOf,TriggersForEachMatch)1530*67e74705SXin Li TEST(EachOf, TriggersForEachMatch) {
1531*67e74705SXin Li   EXPECT_TRUE(matchAndVerifyResultTrue(
1532*67e74705SXin Li     "class A { int a; int b; };",
1533*67e74705SXin Li     recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
1534*67e74705SXin Li                       has(fieldDecl(hasName("b")).bind("v")))),
1535*67e74705SXin Li     llvm::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 2)));
1536*67e74705SXin Li }
1537*67e74705SXin Li 
TEST(EachOf,BehavesLikeAnyOfUnlessBothMatch)1538*67e74705SXin Li TEST(EachOf, BehavesLikeAnyOfUnlessBothMatch) {
1539*67e74705SXin Li   EXPECT_TRUE(matchAndVerifyResultTrue(
1540*67e74705SXin Li     "class A { int a; int c; };",
1541*67e74705SXin Li     recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
1542*67e74705SXin Li                       has(fieldDecl(hasName("b")).bind("v")))),
1543*67e74705SXin Li     llvm::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 1)));
1544*67e74705SXin Li   EXPECT_TRUE(matchAndVerifyResultTrue(
1545*67e74705SXin Li     "class A { int c; int b; };",
1546*67e74705SXin Li     recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
1547*67e74705SXin Li                       has(fieldDecl(hasName("b")).bind("v")))),
1548*67e74705SXin Li     llvm::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 1)));
1549*67e74705SXin Li   EXPECT_TRUE(notMatches(
1550*67e74705SXin Li     "class A { int c; int d; };",
1551*67e74705SXin Li     recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
1552*67e74705SXin Li                       has(fieldDecl(hasName("b")).bind("v"))))));
1553*67e74705SXin Li }
1554*67e74705SXin Li 
TEST(IsTemplateInstantiation,MatchesImplicitClassTemplateInstantiation)1555*67e74705SXin Li TEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) {
1556*67e74705SXin Li   // Make sure that we can both match the class by name (::X) and by the type
1557*67e74705SXin Li   // the template was instantiated with (via a field).
1558*67e74705SXin Li 
1559*67e74705SXin Li   EXPECT_TRUE(matches(
1560*67e74705SXin Li     "template <typename T> class X {}; class A {}; X<A> x;",
1561*67e74705SXin Li     cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
1562*67e74705SXin Li 
1563*67e74705SXin Li   EXPECT_TRUE(matches(
1564*67e74705SXin Li     "template <typename T> class X { T t; }; class A {}; X<A> x;",
1565*67e74705SXin Li     cxxRecordDecl(isTemplateInstantiation(), hasDescendant(
1566*67e74705SXin Li       fieldDecl(hasType(recordDecl(hasName("A"))))))));
1567*67e74705SXin Li }
1568*67e74705SXin Li 
TEST(IsTemplateInstantiation,MatchesImplicitFunctionTemplateInstantiation)1569*67e74705SXin Li TEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) {
1570*67e74705SXin Li   EXPECT_TRUE(matches(
1571*67e74705SXin Li     "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
1572*67e74705SXin Li     functionDecl(hasParameter(0, hasType(recordDecl(hasName("A")))),
1573*67e74705SXin Li                  isTemplateInstantiation())));
1574*67e74705SXin Li }
1575*67e74705SXin Li 
TEST(IsTemplateInstantiation,MatchesExplicitClassTemplateInstantiation)1576*67e74705SXin Li TEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) {
1577*67e74705SXin Li   EXPECT_TRUE(matches(
1578*67e74705SXin Li     "template <typename T> class X { T t; }; class A {};"
1579*67e74705SXin Li       "template class X<A>;",
1580*67e74705SXin Li     cxxRecordDecl(isTemplateInstantiation(), hasDescendant(
1581*67e74705SXin Li       fieldDecl(hasType(recordDecl(hasName("A"))))))));
1582*67e74705SXin Li }
1583*67e74705SXin Li 
TEST(IsTemplateInstantiation,MatchesInstantiationOfPartiallySpecializedClassTemplate)1584*67e74705SXin Li TEST(IsTemplateInstantiation,
1585*67e74705SXin Li      MatchesInstantiationOfPartiallySpecializedClassTemplate) {
1586*67e74705SXin Li   EXPECT_TRUE(matches(
1587*67e74705SXin Li     "template <typename T> class X {};"
1588*67e74705SXin Li       "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
1589*67e74705SXin Li     cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
1590*67e74705SXin Li }
1591*67e74705SXin Li 
TEST(IsTemplateInstantiation,MatchesInstantiationOfClassTemplateNestedInNonTemplate)1592*67e74705SXin Li TEST(IsTemplateInstantiation,
1593*67e74705SXin Li      MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
1594*67e74705SXin Li   EXPECT_TRUE(matches(
1595*67e74705SXin Li     "class A {};"
1596*67e74705SXin Li       "class X {"
1597*67e74705SXin Li       "  template <typename U> class Y { U u; };"
1598*67e74705SXin Li       "  Y<A> y;"
1599*67e74705SXin Li       "};",
1600*67e74705SXin Li     cxxRecordDecl(hasName("::X::Y"), isTemplateInstantiation())));
1601*67e74705SXin Li }
1602*67e74705SXin Li 
TEST(IsTemplateInstantiation,DoesNotMatchInstantiationsInsideOfInstantiation)1603*67e74705SXin Li TEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) {
1604*67e74705SXin Li   // FIXME: Figure out whether this makes sense. It doesn't affect the
1605*67e74705SXin Li   // normal use case as long as the uppermost instantiation always is marked
1606*67e74705SXin Li   // as template instantiation, but it might be confusing as a predicate.
1607*67e74705SXin Li   EXPECT_TRUE(matches(
1608*67e74705SXin Li     "class A {};"
1609*67e74705SXin Li       "template <typename T> class X {"
1610*67e74705SXin Li       "  template <typename U> class Y { U u; };"
1611*67e74705SXin Li       "  Y<T> y;"
1612*67e74705SXin Li       "}; X<A> x;",
1613*67e74705SXin Li     cxxRecordDecl(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
1614*67e74705SXin Li }
1615*67e74705SXin Li 
TEST(IsTemplateInstantiation,DoesNotMatchExplicitClassTemplateSpecialization)1616*67e74705SXin Li TEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) {
1617*67e74705SXin Li   EXPECT_TRUE(notMatches(
1618*67e74705SXin Li     "template <typename T> class X {}; class A {};"
1619*67e74705SXin Li       "template <> class X<A> {}; X<A> x;",
1620*67e74705SXin Li     cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
1621*67e74705SXin Li }
1622*67e74705SXin Li 
TEST(IsTemplateInstantiation,DoesNotMatchNonTemplate)1623*67e74705SXin Li TEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) {
1624*67e74705SXin Li   EXPECT_TRUE(notMatches(
1625*67e74705SXin Li     "class A {}; class Y { A a; };",
1626*67e74705SXin Li     cxxRecordDecl(isTemplateInstantiation())));
1627*67e74705SXin Li }
1628*67e74705SXin Li 
TEST(IsInstantiated,MatchesInstantiation)1629*67e74705SXin Li TEST(IsInstantiated, MatchesInstantiation) {
1630*67e74705SXin Li   EXPECT_TRUE(
1631*67e74705SXin Li     matches("template<typename T> class A { T i; }; class Y { A<int> a; };",
1632*67e74705SXin Li             cxxRecordDecl(isInstantiated())));
1633*67e74705SXin Li }
1634*67e74705SXin Li 
TEST(IsInstantiated,NotMatchesDefinition)1635*67e74705SXin Li TEST(IsInstantiated, NotMatchesDefinition) {
1636*67e74705SXin Li   EXPECT_TRUE(notMatches("template<typename T> class A { T i; };",
1637*67e74705SXin Li                          cxxRecordDecl(isInstantiated())));
1638*67e74705SXin Li }
1639*67e74705SXin Li 
TEST(IsInTemplateInstantiation,MatchesInstantiationStmt)1640*67e74705SXin Li TEST(IsInTemplateInstantiation, MatchesInstantiationStmt) {
1641*67e74705SXin Li   EXPECT_TRUE(matches("template<typename T> struct A { A() { T i; } };"
1642*67e74705SXin Li                         "class Y { A<int> a; }; Y y;",
1643*67e74705SXin Li                       declStmt(isInTemplateInstantiation())));
1644*67e74705SXin Li }
1645*67e74705SXin Li 
TEST(IsInTemplateInstantiation,NotMatchesDefinitionStmt)1646*67e74705SXin Li TEST(IsInTemplateInstantiation, NotMatchesDefinitionStmt) {
1647*67e74705SXin Li   EXPECT_TRUE(notMatches("template<typename T> struct A { void x() { T i; } };",
1648*67e74705SXin Li                          declStmt(isInTemplateInstantiation())));
1649*67e74705SXin Li }
1650*67e74705SXin Li 
TEST(IsInstantiated,MatchesFunctionInstantiation)1651*67e74705SXin Li TEST(IsInstantiated, MatchesFunctionInstantiation) {
1652*67e74705SXin Li   EXPECT_TRUE(
1653*67e74705SXin Li     matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
1654*67e74705SXin Li             functionDecl(isInstantiated())));
1655*67e74705SXin Li }
1656*67e74705SXin Li 
TEST(IsInstantiated,NotMatchesFunctionDefinition)1657*67e74705SXin Li TEST(IsInstantiated, NotMatchesFunctionDefinition) {
1658*67e74705SXin Li   EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
1659*67e74705SXin Li                          varDecl(isInstantiated())));
1660*67e74705SXin Li }
1661*67e74705SXin Li 
TEST(IsInTemplateInstantiation,MatchesFunctionInstantiationStmt)1662*67e74705SXin Li TEST(IsInTemplateInstantiation, MatchesFunctionInstantiationStmt) {
1663*67e74705SXin Li   EXPECT_TRUE(
1664*67e74705SXin Li     matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
1665*67e74705SXin Li             declStmt(isInTemplateInstantiation())));
1666*67e74705SXin Li }
1667*67e74705SXin Li 
TEST(IsInTemplateInstantiation,NotMatchesFunctionDefinitionStmt)1668*67e74705SXin Li TEST(IsInTemplateInstantiation, NotMatchesFunctionDefinitionStmt) {
1669*67e74705SXin Li   EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
1670*67e74705SXin Li                          declStmt(isInTemplateInstantiation())));
1671*67e74705SXin Li }
1672*67e74705SXin Li 
TEST(IsInTemplateInstantiation,Sharing)1673*67e74705SXin Li TEST(IsInTemplateInstantiation, Sharing) {
1674*67e74705SXin Li   auto Matcher = binaryOperator(unless(isInTemplateInstantiation()));
1675*67e74705SXin Li   // FIXME: Node sharing is an implementation detail, exposing it is ugly
1676*67e74705SXin Li   // and makes the matcher behave in non-obvious ways.
1677*67e74705SXin Li   EXPECT_TRUE(notMatches(
1678*67e74705SXin Li     "int j; template<typename T> void A(T t) { j += 42; } void x() { A(0); }",
1679*67e74705SXin Li     Matcher));
1680*67e74705SXin Li   EXPECT_TRUE(matches(
1681*67e74705SXin Li     "int j; template<typename T> void A(T t) { j += t; } void x() { A(0); }",
1682*67e74705SXin Li     Matcher));
1683*67e74705SXin Li }
1684*67e74705SXin Li 
TEST(IsExplicitTemplateSpecialization,DoesNotMatchPrimaryTemplate)1685*67e74705SXin Li TEST(IsExplicitTemplateSpecialization,
1686*67e74705SXin Li      DoesNotMatchPrimaryTemplate) {
1687*67e74705SXin Li   EXPECT_TRUE(notMatches(
1688*67e74705SXin Li     "template <typename T> class X {};",
1689*67e74705SXin Li     cxxRecordDecl(isExplicitTemplateSpecialization())));
1690*67e74705SXin Li   EXPECT_TRUE(notMatches(
1691*67e74705SXin Li     "template <typename T> void f(T t);",
1692*67e74705SXin Li     functionDecl(isExplicitTemplateSpecialization())));
1693*67e74705SXin Li }
1694*67e74705SXin Li 
TEST(IsExplicitTemplateSpecialization,DoesNotMatchExplicitTemplateInstantiations)1695*67e74705SXin Li TEST(IsExplicitTemplateSpecialization,
1696*67e74705SXin Li      DoesNotMatchExplicitTemplateInstantiations) {
1697*67e74705SXin Li   EXPECT_TRUE(notMatches(
1698*67e74705SXin Li     "template <typename T> class X {};"
1699*67e74705SXin Li       "template class X<int>; extern template class X<long>;",
1700*67e74705SXin Li     cxxRecordDecl(isExplicitTemplateSpecialization())));
1701*67e74705SXin Li   EXPECT_TRUE(notMatches(
1702*67e74705SXin Li     "template <typename T> void f(T t) {}"
1703*67e74705SXin Li       "template void f(int t); extern template void f(long t);",
1704*67e74705SXin Li     functionDecl(isExplicitTemplateSpecialization())));
1705*67e74705SXin Li }
1706*67e74705SXin Li 
TEST(IsExplicitTemplateSpecialization,DoesNotMatchImplicitTemplateInstantiations)1707*67e74705SXin Li TEST(IsExplicitTemplateSpecialization,
1708*67e74705SXin Li      DoesNotMatchImplicitTemplateInstantiations) {
1709*67e74705SXin Li   EXPECT_TRUE(notMatches(
1710*67e74705SXin Li     "template <typename T> class X {}; X<int> x;",
1711*67e74705SXin Li     cxxRecordDecl(isExplicitTemplateSpecialization())));
1712*67e74705SXin Li   EXPECT_TRUE(notMatches(
1713*67e74705SXin Li     "template <typename T> void f(T t); void g() { f(10); }",
1714*67e74705SXin Li     functionDecl(isExplicitTemplateSpecialization())));
1715*67e74705SXin Li }
1716*67e74705SXin Li 
TEST(IsExplicitTemplateSpecialization,MatchesExplicitTemplateSpecializations)1717*67e74705SXin Li TEST(IsExplicitTemplateSpecialization,
1718*67e74705SXin Li      MatchesExplicitTemplateSpecializations) {
1719*67e74705SXin Li   EXPECT_TRUE(matches(
1720*67e74705SXin Li     "template <typename T> class X {};"
1721*67e74705SXin Li       "template<> class X<int> {};",
1722*67e74705SXin Li     cxxRecordDecl(isExplicitTemplateSpecialization())));
1723*67e74705SXin Li   EXPECT_TRUE(matches(
1724*67e74705SXin Li     "template <typename T> void f(T t) {}"
1725*67e74705SXin Li       "template<> void f(int t) {}",
1726*67e74705SXin Li     functionDecl(isExplicitTemplateSpecialization())));
1727*67e74705SXin Li }
1728*67e74705SXin Li 
TEST(TypeMatching,MatchesBool)1729*67e74705SXin Li TEST(TypeMatching, MatchesBool) {
1730*67e74705SXin Li   EXPECT_TRUE(matches("struct S { bool func(); };",
1731*67e74705SXin Li                       cxxMethodDecl(returns(booleanType()))));
1732*67e74705SXin Li   EXPECT_TRUE(notMatches("struct S { void func(); };",
1733*67e74705SXin Li                          cxxMethodDecl(returns(booleanType()))));
1734*67e74705SXin Li }
1735*67e74705SXin Li 
TEST(TypeMatching,MatchesVoid)1736*67e74705SXin Li TEST(TypeMatching, MatchesVoid) {
1737*67e74705SXin Li   EXPECT_TRUE(matches("struct S { void func(); };",
1738*67e74705SXin Li                       cxxMethodDecl(returns(voidType()))));
1739*67e74705SXin Li }
1740*67e74705SXin Li 
TEST(TypeMatching,MatchesRealFloats)1741*67e74705SXin Li TEST(TypeMatching, MatchesRealFloats) {
1742*67e74705SXin Li   EXPECT_TRUE(matches("struct S { float func(); };",
1743*67e74705SXin Li                       cxxMethodDecl(returns(realFloatingPointType()))));
1744*67e74705SXin Li   EXPECT_TRUE(notMatches("struct S { int func(); };",
1745*67e74705SXin Li                          cxxMethodDecl(returns(realFloatingPointType()))));
1746*67e74705SXin Li   EXPECT_TRUE(matches("struct S { long double func(); };",
1747*67e74705SXin Li                       cxxMethodDecl(returns(realFloatingPointType()))));
1748*67e74705SXin Li }
1749*67e74705SXin Li 
TEST(TypeMatching,MatchesArrayTypes)1750*67e74705SXin Li TEST(TypeMatching, MatchesArrayTypes) {
1751*67e74705SXin Li   EXPECT_TRUE(matches("int a[] = {2,3};", arrayType()));
1752*67e74705SXin Li   EXPECT_TRUE(matches("int a[42];", arrayType()));
1753*67e74705SXin Li   EXPECT_TRUE(matches("void f(int b) { int a[b]; }", arrayType()));
1754*67e74705SXin Li 
1755*67e74705SXin Li   EXPECT_TRUE(notMatches("struct A {}; A a[7];",
1756*67e74705SXin Li                          arrayType(hasElementType(builtinType()))));
1757*67e74705SXin Li 
1758*67e74705SXin Li   EXPECT_TRUE(matches(
1759*67e74705SXin Li     "int const a[] = { 2, 3 };",
1760*67e74705SXin Li     qualType(arrayType(hasElementType(builtinType())))));
1761*67e74705SXin Li   EXPECT_TRUE(matches(
1762*67e74705SXin Li     "int const a[] = { 2, 3 };",
1763*67e74705SXin Li     qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
1764*67e74705SXin Li   EXPECT_TRUE(matches(
1765*67e74705SXin Li     "typedef const int T; T x[] = { 1, 2 };",
1766*67e74705SXin Li     qualType(isConstQualified(), arrayType())));
1767*67e74705SXin Li 
1768*67e74705SXin Li   EXPECT_TRUE(notMatches(
1769*67e74705SXin Li     "int a[] = { 2, 3 };",
1770*67e74705SXin Li     qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
1771*67e74705SXin Li   EXPECT_TRUE(notMatches(
1772*67e74705SXin Li     "int a[] = { 2, 3 };",
1773*67e74705SXin Li     qualType(arrayType(hasElementType(isConstQualified(), builtinType())))));
1774*67e74705SXin Li   EXPECT_TRUE(notMatches(
1775*67e74705SXin Li     "int const a[] = { 2, 3 };",
1776*67e74705SXin Li     qualType(arrayType(hasElementType(builtinType())),
1777*67e74705SXin Li              unless(isConstQualified()))));
1778*67e74705SXin Li 
1779*67e74705SXin Li   EXPECT_TRUE(matches("int a[2];",
1780*67e74705SXin Li                       constantArrayType(hasElementType(builtinType()))));
1781*67e74705SXin Li   EXPECT_TRUE(matches("const int a = 0;", qualType(isInteger())));
1782*67e74705SXin Li }
1783*67e74705SXin Li 
TEST(TypeMatching,DecayedType)1784*67e74705SXin Li TEST(TypeMatching, DecayedType) {
1785*67e74705SXin Li   EXPECT_TRUE(matches("void f(int i[]);", valueDecl(hasType(decayedType(hasDecayedType(pointerType()))))));
1786*67e74705SXin Li   EXPECT_TRUE(notMatches("int i[7];", decayedType()));
1787*67e74705SXin Li }
1788*67e74705SXin Li 
TEST(TypeMatching,MatchesComplexTypes)1789*67e74705SXin Li TEST(TypeMatching, MatchesComplexTypes) {
1790*67e74705SXin Li   EXPECT_TRUE(matches("_Complex float f;", complexType()));
1791*67e74705SXin Li   EXPECT_TRUE(matches(
1792*67e74705SXin Li     "_Complex float f;",
1793*67e74705SXin Li     complexType(hasElementType(builtinType()))));
1794*67e74705SXin Li   EXPECT_TRUE(notMatches(
1795*67e74705SXin Li     "_Complex float f;",
1796*67e74705SXin Li     complexType(hasElementType(isInteger()))));
1797*67e74705SXin Li }
1798*67e74705SXin Li 
TEST(NS,Anonymous)1799*67e74705SXin Li TEST(NS, Anonymous) {
1800*67e74705SXin Li   EXPECT_TRUE(notMatches("namespace N {}", namespaceDecl(isAnonymous())));
1801*67e74705SXin Li   EXPECT_TRUE(matches("namespace {}", namespaceDecl(isAnonymous())));
1802*67e74705SXin Li }
1803*67e74705SXin Li 
TEST(EqualsBoundNodeMatcher,QualType)1804*67e74705SXin Li TEST(EqualsBoundNodeMatcher, QualType) {
1805*67e74705SXin Li   EXPECT_TRUE(matches(
1806*67e74705SXin Li     "int i = 1;", varDecl(hasType(qualType().bind("type")),
1807*67e74705SXin Li                           hasInitializer(ignoringParenImpCasts(
1808*67e74705SXin Li                             hasType(qualType(equalsBoundNode("type"))))))));
1809*67e74705SXin Li   EXPECT_TRUE(notMatches("int i = 1.f;",
1810*67e74705SXin Li                          varDecl(hasType(qualType().bind("type")),
1811*67e74705SXin Li                                  hasInitializer(ignoringParenImpCasts(hasType(
1812*67e74705SXin Li                                    qualType(equalsBoundNode("type"))))))));
1813*67e74705SXin Li }
1814*67e74705SXin Li 
TEST(EqualsBoundNodeMatcher,NonMatchingTypes)1815*67e74705SXin Li TEST(EqualsBoundNodeMatcher, NonMatchingTypes) {
1816*67e74705SXin Li   EXPECT_TRUE(notMatches(
1817*67e74705SXin Li     "int i = 1;", varDecl(namedDecl(hasName("i")).bind("name"),
1818*67e74705SXin Li                           hasInitializer(ignoringParenImpCasts(
1819*67e74705SXin Li                             hasType(qualType(equalsBoundNode("type"))))))));
1820*67e74705SXin Li }
1821*67e74705SXin Li 
TEST(EqualsBoundNodeMatcher,Stmt)1822*67e74705SXin Li TEST(EqualsBoundNodeMatcher, Stmt) {
1823*67e74705SXin Li   EXPECT_TRUE(
1824*67e74705SXin Li     matches("void f() { if(true) {} }",
1825*67e74705SXin Li             stmt(allOf(ifStmt().bind("if"),
1826*67e74705SXin Li                        hasParent(stmt(has(stmt(equalsBoundNode("if")))))))));
1827*67e74705SXin Li 
1828*67e74705SXin Li   EXPECT_TRUE(notMatches(
1829*67e74705SXin Li     "void f() { if(true) { if (true) {} } }",
1830*67e74705SXin Li     stmt(allOf(ifStmt().bind("if"), has(stmt(equalsBoundNode("if")))))));
1831*67e74705SXin Li }
1832*67e74705SXin Li 
TEST(EqualsBoundNodeMatcher,Decl)1833*67e74705SXin Li TEST(EqualsBoundNodeMatcher, Decl) {
1834*67e74705SXin Li   EXPECT_TRUE(matches(
1835*67e74705SXin Li     "class X { class Y {}; };",
1836*67e74705SXin Li     decl(allOf(recordDecl(hasName("::X::Y")).bind("record"),
1837*67e74705SXin Li                hasParent(decl(has(decl(equalsBoundNode("record")))))))));
1838*67e74705SXin Li 
1839*67e74705SXin Li   EXPECT_TRUE(notMatches("class X { class Y {}; };",
1840*67e74705SXin Li                          decl(allOf(recordDecl(hasName("::X")).bind("record"),
1841*67e74705SXin Li                                     has(decl(equalsBoundNode("record")))))));
1842*67e74705SXin Li }
1843*67e74705SXin Li 
TEST(EqualsBoundNodeMatcher,Type)1844*67e74705SXin Li TEST(EqualsBoundNodeMatcher, Type) {
1845*67e74705SXin Li   EXPECT_TRUE(matches(
1846*67e74705SXin Li     "class X { int a; int b; };",
1847*67e74705SXin Li     recordDecl(
1848*67e74705SXin Li       has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
1849*67e74705SXin Li       has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
1850*67e74705SXin Li 
1851*67e74705SXin Li   EXPECT_TRUE(notMatches(
1852*67e74705SXin Li     "class X { int a; double b; };",
1853*67e74705SXin Li     recordDecl(
1854*67e74705SXin Li       has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
1855*67e74705SXin Li       has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
1856*67e74705SXin Li }
1857*67e74705SXin Li 
TEST(EqualsBoundNodeMatcher,UsingForEachDescendant)1858*67e74705SXin Li TEST(EqualsBoundNodeMatcher, UsingForEachDescendant) {
1859*67e74705SXin Li   EXPECT_TRUE(matchAndVerifyResultTrue(
1860*67e74705SXin Li     "int f() {"
1861*67e74705SXin Li       "  if (1) {"
1862*67e74705SXin Li       "    int i = 9;"
1863*67e74705SXin Li       "  }"
1864*67e74705SXin Li       "  int j = 10;"
1865*67e74705SXin Li       "  {"
1866*67e74705SXin Li       "    float k = 9.0;"
1867*67e74705SXin Li       "  }"
1868*67e74705SXin Li       "  return 0;"
1869*67e74705SXin Li       "}",
1870*67e74705SXin Li     // Look for variable declarations within functions whose type is the same
1871*67e74705SXin Li     // as the function return type.
1872*67e74705SXin Li     functionDecl(returns(qualType().bind("type")),
1873*67e74705SXin Li                  forEachDescendant(varDecl(hasType(
1874*67e74705SXin Li                    qualType(equalsBoundNode("type")))).bind("decl"))),
1875*67e74705SXin Li     // Only i and j should match, not k.
1876*67e74705SXin Li     llvm::make_unique<VerifyIdIsBoundTo<VarDecl>>("decl", 2)));
1877*67e74705SXin Li }
1878*67e74705SXin Li 
TEST(EqualsBoundNodeMatcher,FiltersMatchedCombinations)1879*67e74705SXin Li TEST(EqualsBoundNodeMatcher, FiltersMatchedCombinations) {
1880*67e74705SXin Li   EXPECT_TRUE(matchAndVerifyResultTrue(
1881*67e74705SXin Li     "void f() {"
1882*67e74705SXin Li       "  int x;"
1883*67e74705SXin Li       "  double d;"
1884*67e74705SXin Li       "  x = d + x - d + x;"
1885*67e74705SXin Li       "}",
1886*67e74705SXin Li     functionDecl(
1887*67e74705SXin Li       hasName("f"), forEachDescendant(varDecl().bind("d")),
1888*67e74705SXin Li       forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d")))))),
1889*67e74705SXin Li     llvm::make_unique<VerifyIdIsBoundTo<VarDecl>>("d", 5)));
1890*67e74705SXin Li }
1891*67e74705SXin Li 
TEST(EqualsBoundNodeMatcher,UnlessDescendantsOfAncestorsMatch)1892*67e74705SXin Li TEST(EqualsBoundNodeMatcher, UnlessDescendantsOfAncestorsMatch) {
1893*67e74705SXin Li   EXPECT_TRUE(matchAndVerifyResultTrue(
1894*67e74705SXin Li     "struct StringRef { int size() const; const char* data() const; };"
1895*67e74705SXin Li       "void f(StringRef v) {"
1896*67e74705SXin Li       "  v.data();"
1897*67e74705SXin Li       "}",
1898*67e74705SXin Li     cxxMemberCallExpr(
1899*67e74705SXin Li       callee(cxxMethodDecl(hasName("data"))),
1900*67e74705SXin Li       on(declRefExpr(to(
1901*67e74705SXin Li         varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
1902*67e74705SXin Li       unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
1903*67e74705SXin Li         callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
1904*67e74705SXin Li         on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
1905*67e74705SXin Li       .bind("data"),
1906*67e74705SXin Li     llvm::make_unique<VerifyIdIsBoundTo<Expr>>("data", 1)));
1907*67e74705SXin Li 
1908*67e74705SXin Li   EXPECT_FALSE(matches(
1909*67e74705SXin Li     "struct StringRef { int size() const; const char* data() const; };"
1910*67e74705SXin Li       "void f(StringRef v) {"
1911*67e74705SXin Li       "  v.data();"
1912*67e74705SXin Li       "  v.size();"
1913*67e74705SXin Li       "}",
1914*67e74705SXin Li     cxxMemberCallExpr(
1915*67e74705SXin Li       callee(cxxMethodDecl(hasName("data"))),
1916*67e74705SXin Li       on(declRefExpr(to(
1917*67e74705SXin Li         varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
1918*67e74705SXin Li       unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
1919*67e74705SXin Li         callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
1920*67e74705SXin Li         on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
1921*67e74705SXin Li       .bind("data")));
1922*67e74705SXin Li }
1923*67e74705SXin Li 
TEST(NullPointerConstants,Basic)1924*67e74705SXin Li TEST(NullPointerConstants, Basic) {
1925*67e74705SXin Li   EXPECT_TRUE(matches("#define NULL ((void *)0)\n"
1926*67e74705SXin Li                         "void *v1 = NULL;", expr(nullPointerConstant())));
1927*67e74705SXin Li   EXPECT_TRUE(matches("void *v2 = nullptr;", expr(nullPointerConstant())));
1928*67e74705SXin Li   EXPECT_TRUE(matches("void *v3 = __null;", expr(nullPointerConstant())));
1929*67e74705SXin Li   EXPECT_TRUE(matches("char *cp = (char *)0;", expr(nullPointerConstant())));
1930*67e74705SXin Li   EXPECT_TRUE(matches("int *ip = 0;", expr(nullPointerConstant())));
1931*67e74705SXin Li   EXPECT_TRUE(notMatches("int i = 0;", expr(nullPointerConstant())));
1932*67e74705SXin Li }
1933*67e74705SXin Li 
1934*67e74705SXin Li } // namespace ast_matchers
1935*67e74705SXin Li } // namespace clang
1936