1 //= unittests/ASTMatchers/ASTMatchersTraversalTest.cpp - matchers unit tests =//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "ASTMatchersTest.h"
10 #include "clang/AST/Attrs.inc"
11 #include "clang/AST/PrettyPrinter.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
13 #include "clang/ASTMatchers/ASTMatchers.h"
14 #include "clang/Tooling/Tooling.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/ADT/Triple.h"
17 #include "llvm/Support/Host.h"
18 #include "gtest/gtest.h"
19 
20 namespace clang {
21 namespace ast_matchers {
22 
TEST(DeclarationMatcher,hasMethod)23 TEST(DeclarationMatcher, hasMethod) {
24   EXPECT_TRUE(matches("class A { void func(); };",
25                       cxxRecordDecl(hasMethod(hasName("func")))));
26   EXPECT_TRUE(notMatches("class A { void func(); };",
27                          cxxRecordDecl(hasMethod(isPublic()))));
28 }
29 
TEST(DeclarationMatcher,ClassDerivedFromDependentTemplateSpecialization)30 TEST(DeclarationMatcher, ClassDerivedFromDependentTemplateSpecialization) {
31   EXPECT_TRUE(matches(
32     "template <typename T> struct A {"
33       "  template <typename T2> struct F {};"
34       "};"
35       "template <typename T> struct B : A<T>::template F<T> {};"
36       "B<int> b;",
37     cxxRecordDecl(hasName("B"), isDerivedFrom(recordDecl()))));
38 }
39 
TEST(DeclarationMatcher,hasDeclContext)40 TEST(DeclarationMatcher, hasDeclContext) {
41   EXPECT_TRUE(matches(
42     "namespace N {"
43       "  namespace M {"
44       "    class D {};"
45       "  }"
46       "}",
47     recordDecl(hasDeclContext(namespaceDecl(hasName("M"))))));
48   EXPECT_TRUE(notMatches(
49     "namespace N {"
50       "  namespace M {"
51       "    class D {};"
52       "  }"
53       "}",
54     recordDecl(hasDeclContext(namespaceDecl(hasName("N"))))));
55 
56   EXPECT_TRUE(matches("namespace {"
57                         "  namespace M {"
58                         "    class D {};"
59                         "  }"
60                         "}",
61                       recordDecl(hasDeclContext(namespaceDecl(
62                         hasName("M"), hasDeclContext(namespaceDecl()))))));
63 
64   EXPECT_TRUE(matches("class D{};", decl(hasDeclContext(decl()))));
65 }
66 
TEST(HasDescendant,MatchesDescendantTypes)67 TEST(HasDescendant, MatchesDescendantTypes) {
68   EXPECT_TRUE(matches("void f() { int i = 3; }",
69                       decl(hasDescendant(loc(builtinType())))));
70   EXPECT_TRUE(matches("void f() { int i = 3; }",
71                       stmt(hasDescendant(builtinType()))));
72 
73   EXPECT_TRUE(matches("void f() { int i = 3; }",
74                       stmt(hasDescendant(loc(builtinType())))));
75   EXPECT_TRUE(matches("void f() { int i = 3; }",
76                       stmt(hasDescendant(qualType(builtinType())))));
77 
78   EXPECT_TRUE(notMatches("void f() { float f = 2.0f; }",
79                          stmt(hasDescendant(isInteger()))));
80 
81   EXPECT_TRUE(matchAndVerifyResultTrue(
82     "void f() { int a; float c; int d; int e; }",
83     functionDecl(forEachDescendant(
84       varDecl(hasDescendant(isInteger())).bind("x"))),
85     std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 3)));
86 }
87 
TEST(HasDescendant,MatchesDescendantsOfTypes)88 TEST(HasDescendant, MatchesDescendantsOfTypes) {
89   EXPECT_TRUE(matches("void f() { int*** i; }",
90                       qualType(hasDescendant(builtinType()))));
91   EXPECT_TRUE(matches("void f() { int*** i; }",
92                       qualType(hasDescendant(
93                         pointerType(pointee(builtinType()))))));
94   EXPECT_TRUE(matches("void f() { int*** i; }",
95                       typeLoc(hasDescendant(loc(builtinType())))));
96 
97   EXPECT_TRUE(matchAndVerifyResultTrue(
98     "void f() { int*** i; }",
99     qualType(asString("int ***"), forEachDescendant(pointerType().bind("x"))),
100     std::make_unique<VerifyIdIsBoundTo<Type>>("x", 2)));
101 }
102 
103 
TEST(Has,MatchesChildrenOfTypes)104 TEST(Has, MatchesChildrenOfTypes) {
105   EXPECT_TRUE(matches("int i;",
106                       varDecl(hasName("i"), has(isInteger()))));
107   EXPECT_TRUE(notMatches("int** i;",
108                          varDecl(hasName("i"), has(isInteger()))));
109   EXPECT_TRUE(matchAndVerifyResultTrue(
110     "int (*f)(float, int);",
111     qualType(functionType(), forEach(qualType(isInteger()).bind("x"))),
112     std::make_unique<VerifyIdIsBoundTo<QualType>>("x", 2)));
113 }
114 
TEST(Has,MatchesChildTypes)115 TEST(Has, MatchesChildTypes) {
116   EXPECT_TRUE(matches(
117     "int* i;",
118     varDecl(hasName("i"), hasType(qualType(has(builtinType()))))));
119   EXPECT_TRUE(notMatches(
120     "int* i;",
121     varDecl(hasName("i"), hasType(qualType(has(pointerType()))))));
122 }
123 
TEST(StatementMatcher,Has)124 TEST(StatementMatcher, Has) {
125   StatementMatcher HasVariableI =
126       expr(hasType(pointsTo(recordDecl(hasName("X")))),
127            has(ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("i")))))));
128 
129   EXPECT_TRUE(matches(
130     "class X; X *x(int); void c() { int i; x(i); }", HasVariableI));
131   EXPECT_TRUE(notMatches(
132     "class X; X *x(int); void c() { int i; x(42); }", HasVariableI));
133 }
134 
TEST(StatementMatcher,HasDescendant)135 TEST(StatementMatcher, HasDescendant) {
136   StatementMatcher HasDescendantVariableI =
137     expr(hasType(pointsTo(recordDecl(hasName("X")))),
138          hasDescendant(declRefExpr(to(varDecl(hasName("i"))))));
139 
140   EXPECT_TRUE(matches(
141     "class X; X *x(bool); bool b(int); void c() { int i; x(b(i)); }",
142     HasDescendantVariableI));
143   EXPECT_TRUE(notMatches(
144     "class X; X *x(bool); bool b(int); void c() { int i; x(b(42)); }",
145     HasDescendantVariableI));
146 }
147 
TEST(TypeMatcher,MatchesClassType)148 TEST(TypeMatcher, MatchesClassType) {
149   TypeMatcher TypeA = hasDeclaration(recordDecl(hasName("A")));
150 
151   EXPECT_TRUE(matches("class A { public: A *a; };", TypeA));
152   EXPECT_TRUE(notMatches("class A {};", TypeA));
153 
154   TypeMatcher TypeDerivedFromA =
155     hasDeclaration(cxxRecordDecl(isDerivedFrom("A")));
156 
157   EXPECT_TRUE(matches("class A {}; class B : public A { public: B *b; };",
158                       TypeDerivedFromA));
159   EXPECT_TRUE(notMatches("class A {};", TypeA));
160 
161   TypeMatcher TypeAHasClassB = hasDeclaration(
162     recordDecl(hasName("A"), has(recordDecl(hasName("B")))));
163 
164   EXPECT_TRUE(
165     matches("class A { public: A *a; class B {}; };", TypeAHasClassB));
166 
167   EXPECT_TRUE(matchesC("struct S {}; void f(void) { struct S s; }",
168                        varDecl(hasType(namedDecl(hasName("S"))))));
169 }
170 
TEST(TypeMatcher,MatchesDeclTypes)171 TEST(TypeMatcher, MatchesDeclTypes) {
172   // TypedefType -> TypedefNameDecl
173   EXPECT_TRUE(matches("typedef int I; void f(I i);",
174                       parmVarDecl(hasType(namedDecl(hasName("I"))))));
175   // ObjCObjectPointerType
176   EXPECT_TRUE(matchesObjC("@interface Foo @end void f(Foo *f);",
177                           parmVarDecl(hasType(objcObjectPointerType()))));
178   // ObjCObjectPointerType -> ObjCInterfaceType -> ObjCInterfaceDecl
179   EXPECT_TRUE(matchesObjC(
180     "@interface Foo @end void f(Foo *f);",
181     parmVarDecl(hasType(pointsTo(objcInterfaceDecl(hasName("Foo")))))));
182   // TemplateTypeParmType
183   EXPECT_TRUE(matches("template <typename T> void f(T t);",
184                       parmVarDecl(hasType(templateTypeParmType()))));
185   // TemplateTypeParmType -> TemplateTypeParmDecl
186   EXPECT_TRUE(matches("template <typename T> void f(T t);",
187                       parmVarDecl(hasType(namedDecl(hasName("T"))))));
188   // InjectedClassNameType
189   EXPECT_TRUE(matches("template <typename T> struct S {"
190                         "  void f(S s);"
191                         "};",
192                       parmVarDecl(hasType(injectedClassNameType()))));
193   EXPECT_TRUE(notMatches("template <typename T> struct S {"
194                            "  void g(S<T> s);"
195                            "};",
196                          parmVarDecl(hasType(injectedClassNameType()))));
197   // InjectedClassNameType -> CXXRecordDecl
198   EXPECT_TRUE(matches("template <typename T> struct S {"
199                         "  void f(S s);"
200                         "};",
201                       parmVarDecl(hasType(namedDecl(hasName("S"))))));
202 
203   static const char Using[] = "template <typename T>"
204     "struct Base {"
205     "  typedef T Foo;"
206     "};"
207     ""
208     "template <typename T>"
209     "struct S : private Base<T> {"
210     "  using typename Base<T>::Foo;"
211     "  void f(Foo);"
212     "};";
213   // UnresolvedUsingTypenameDecl
214   EXPECT_TRUE(matches(Using, unresolvedUsingTypenameDecl(hasName("Foo"))));
215   // UnresolvedUsingTypenameType -> UnresolvedUsingTypenameDecl
216   EXPECT_TRUE(matches(Using, parmVarDecl(hasType(namedDecl(hasName("Foo"))))));
217 }
218 
TEST(HasDeclaration,HasDeclarationOfEnumType)219 TEST(HasDeclaration, HasDeclarationOfEnumType) {
220   EXPECT_TRUE(matches("enum X {}; void y(X *x) { x; }",
221                       expr(hasType(pointsTo(
222                         qualType(hasDeclaration(enumDecl(hasName("X")))))))));
223 }
224 
TEST(HasDeclaration,HasGetDeclTraitTest)225 TEST(HasDeclaration, HasGetDeclTraitTest) {
226   static_assert(internal::has_getDecl<TypedefType>::value,
227                 "Expected TypedefType to have a getDecl.");
228   static_assert(internal::has_getDecl<RecordType>::value,
229                 "Expected RecordType to have a getDecl.");
230   static_assert(!internal::has_getDecl<TemplateSpecializationType>::value,
231                 "Expected TemplateSpecializationType to *not* have a getDecl.");
232 }
233 
TEST(HasDeclaration,ElaboratedType)234 TEST(HasDeclaration, ElaboratedType) {
235   EXPECT_TRUE(matches(
236       "namespace n { template <typename T> struct X {}; }"
237       "void f(n::X<int>);",
238       parmVarDecl(hasType(qualType(hasDeclaration(cxxRecordDecl()))))));
239   EXPECT_TRUE(matches(
240       "namespace n { template <typename T> struct X {}; }"
241       "void f(n::X<int>);",
242       parmVarDecl(hasType(elaboratedType(hasDeclaration(cxxRecordDecl()))))));
243 }
244 
TEST(HasDeclaration,HasDeclarationOfTypeWithDecl)245 TEST(HasDeclaration, HasDeclarationOfTypeWithDecl) {
246   EXPECT_TRUE(matches("typedef int X; X a;",
247                       varDecl(hasName("a"),
248                               hasType(typedefType(hasDeclaration(decl()))))));
249 
250   // FIXME: Add tests for other types with getDecl() (e.g. RecordType)
251 }
252 
TEST(HasDeclaration,HasDeclarationOfTemplateSpecializationType)253 TEST(HasDeclaration, HasDeclarationOfTemplateSpecializationType) {
254   EXPECT_TRUE(matches("template <typename T> class A {}; A<int> a;",
255                       varDecl(hasType(templateSpecializationType(
256                         hasDeclaration(namedDecl(hasName("A"))))))));
257   EXPECT_TRUE(matches("template <typename T> class A {};"
258                       "template <typename T> class B { A<T> a; };",
259                       fieldDecl(hasType(templateSpecializationType(
260                         hasDeclaration(namedDecl(hasName("A"))))))));
261   EXPECT_TRUE(matches("template <typename T> class A {}; A<int> a;",
262                       varDecl(hasType(templateSpecializationType(
263                           hasDeclaration(cxxRecordDecl()))))));
264 }
265 
TEST(HasDeclaration,HasDeclarationOfCXXNewExpr)266 TEST(HasDeclaration, HasDeclarationOfCXXNewExpr) {
267   EXPECT_TRUE(
268       matches("int *A = new int();",
269               cxxNewExpr(hasDeclaration(functionDecl(parameterCountIs(1))))));
270 }
271 
TEST(HasDeclaration,HasDeclarationOfTypeAlias)272 TEST(HasDeclaration, HasDeclarationOfTypeAlias) {
273   EXPECT_TRUE(matches("template <typename T> using C = T; C<int> c;",
274                       varDecl(hasType(templateSpecializationType(
275                           hasDeclaration(typeAliasTemplateDecl()))))));
276 }
277 
TEST(HasUnqualifiedDesugaredType,DesugarsUsing)278 TEST(HasUnqualifiedDesugaredType, DesugarsUsing) {
279   EXPECT_TRUE(
280       matches("struct A {}; using B = A; B b;",
281               varDecl(hasType(hasUnqualifiedDesugaredType(recordType())))));
282   EXPECT_TRUE(
283       matches("struct A {}; using B = A; using C = B; C b;",
284               varDecl(hasType(hasUnqualifiedDesugaredType(recordType())))));
285 }
286 
TEST(HasUnderlyingDecl,Matches)287 TEST(HasUnderlyingDecl, Matches) {
288   EXPECT_TRUE(matches("namespace N { template <class T> void f(T t); }"
289                       "template <class T> void g() { using N::f; f(T()); }",
290                       unresolvedLookupExpr(hasAnyDeclaration(
291                           namedDecl(hasUnderlyingDecl(hasName("::N::f")))))));
292   EXPECT_TRUE(matches(
293       "namespace N { template <class T> void f(T t); }"
294       "template <class T> void g() { N::f(T()); }",
295       unresolvedLookupExpr(hasAnyDeclaration(namedDecl(hasName("::N::f"))))));
296   EXPECT_TRUE(notMatches(
297       "namespace N { template <class T> void f(T t); }"
298       "template <class T> void g() { using N::f; f(T()); }",
299       unresolvedLookupExpr(hasAnyDeclaration(namedDecl(hasName("::N::f"))))));
300 }
301 
TEST(HasType,TakesQualTypeMatcherAndMatchesExpr)302 TEST(HasType, TakesQualTypeMatcherAndMatchesExpr) {
303   TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
304   EXPECT_TRUE(
305     matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX))));
306   EXPECT_TRUE(
307     notMatches("class X {}; void y(X *x) { x; }",
308                expr(hasType(ClassX))));
309   EXPECT_TRUE(
310     matches("class X {}; void y(X *x) { x; }",
311             expr(hasType(pointsTo(ClassX)))));
312 }
313 
TEST(HasType,TakesQualTypeMatcherAndMatchesValueDecl)314 TEST(HasType, TakesQualTypeMatcherAndMatchesValueDecl) {
315   TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
316   EXPECT_TRUE(
317     matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX))));
318   EXPECT_TRUE(
319     notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX))));
320   EXPECT_TRUE(
321     matches("class X {}; void y() { X *x; }",
322             varDecl(hasType(pointsTo(ClassX)))));
323 }
324 
TEST(HasType,TakesQualTypeMatcherAndMatchesCXXBaseSpecifier)325 TEST(HasType, TakesQualTypeMatcherAndMatchesCXXBaseSpecifier) {
326   TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
327   CXXBaseSpecifierMatcher BaseClassX = cxxBaseSpecifier(hasType(ClassX));
328   DeclarationMatcher ClassHasBaseClassX =
329       cxxRecordDecl(hasDirectBase(BaseClassX));
330   EXPECT_TRUE(matches("class X {}; class Y : X {};", ClassHasBaseClassX));
331   EXPECT_TRUE(notMatches("class Z {}; class Y : Z {};", ClassHasBaseClassX));
332 }
333 
TEST(HasType,TakesDeclMatcherAndMatchesExpr)334 TEST(HasType, TakesDeclMatcherAndMatchesExpr) {
335   DeclarationMatcher ClassX = recordDecl(hasName("X"));
336   EXPECT_TRUE(
337     matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX))));
338   EXPECT_TRUE(
339     notMatches("class X {}; void y(X *x) { x; }",
340                expr(hasType(ClassX))));
341 }
342 
TEST(HasType,TakesDeclMatcherAndMatchesValueDecl)343 TEST(HasType, TakesDeclMatcherAndMatchesValueDecl) {
344   DeclarationMatcher ClassX = recordDecl(hasName("X"));
345   EXPECT_TRUE(
346     matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX))));
347   EXPECT_TRUE(
348     notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX))));
349 }
350 
TEST(HasType,TakesDeclMatcherAndMatchesCXXBaseSpecifier)351 TEST(HasType, TakesDeclMatcherAndMatchesCXXBaseSpecifier) {
352   DeclarationMatcher ClassX = recordDecl(hasName("X"));
353   CXXBaseSpecifierMatcher BaseClassX = cxxBaseSpecifier(hasType(ClassX));
354   DeclarationMatcher ClassHasBaseClassX =
355       cxxRecordDecl(hasDirectBase(BaseClassX));
356   EXPECT_TRUE(matches("class X {}; class Y : X {};", ClassHasBaseClassX));
357   EXPECT_TRUE(notMatches("class Z {}; class Y : Z {};", ClassHasBaseClassX));
358 }
359 
TEST(HasType,MatchesTypedefDecl)360 TEST(HasType, MatchesTypedefDecl) {
361   EXPECT_TRUE(matches("typedef int X;", typedefDecl(hasType(asString("int")))));
362   EXPECT_TRUE(matches("typedef const int T;",
363                       typedefDecl(hasType(asString("const int")))));
364   EXPECT_TRUE(notMatches("typedef const int T;",
365                          typedefDecl(hasType(asString("int")))));
366   EXPECT_TRUE(matches("typedef int foo; typedef foo bar;",
367                       typedefDecl(hasType(asString("foo")), hasName("bar"))));
368 }
369 
TEST(HasType,MatchesTypedefNameDecl)370 TEST(HasType, MatchesTypedefNameDecl) {
371   EXPECT_TRUE(matches("using X = int;", typedefNameDecl(hasType(asString("int")))));
372   EXPECT_TRUE(matches("using T = const int;",
373                       typedefNameDecl(hasType(asString("const int")))));
374   EXPECT_TRUE(notMatches("using T = const int;",
375                          typedefNameDecl(hasType(asString("int")))));
376   EXPECT_TRUE(matches("using foo = int; using bar = foo;",
377                       typedefNameDecl(hasType(asString("foo")), hasName("bar"))));
378 }
379 
TEST(HasTypeLoc,MatchesBlockDecl)380 TEST(HasTypeLoc, MatchesBlockDecl) {
381   EXPECT_TRUE(matchesConditionally(
382       "auto x = ^int (int a, int b) { return a + b; };",
383       blockDecl(hasTypeLoc(loc(asString("int (int, int)")))), true,
384       {"-fblocks"}));
385 }
386 
TEST(HasTypeLoc,MatchesCXXBaseSpecifierAndCtorInitializer)387 TEST(HasTypeLoc, MatchesCXXBaseSpecifierAndCtorInitializer) {
388   llvm::StringRef code = R"cpp(
389   class Foo {};
390   class Bar : public Foo {
391     Bar() : Foo() {}
392   };
393   )cpp";
394 
395   EXPECT_TRUE(matches(
396       code, cxxRecordDecl(hasAnyBase(hasTypeLoc(loc(asString("class Foo")))))));
397   EXPECT_TRUE(matches(
398       code, cxxCtorInitializer(hasTypeLoc(loc(asString("class Foo"))))));
399 }
400 
TEST(HasTypeLoc,MatchesCXXFunctionalCastExpr)401 TEST(HasTypeLoc, MatchesCXXFunctionalCastExpr) {
402   EXPECT_TRUE(matches("auto x = int(3);",
403                       cxxFunctionalCastExpr(hasTypeLoc(loc(asString("int"))))));
404 }
405 
TEST(HasTypeLoc,MatchesCXXNewExpr)406 TEST(HasTypeLoc, MatchesCXXNewExpr) {
407   EXPECT_TRUE(matches("auto* x = new int(3);",
408                       cxxNewExpr(hasTypeLoc(loc(asString("int"))))));
409   EXPECT_TRUE(matches("class Foo{}; auto* x = new Foo();",
410                       cxxNewExpr(hasTypeLoc(loc(asString("class Foo"))))));
411 }
412 
TEST(HasTypeLoc,MatchesCXXTemporaryObjectExpr)413 TEST(HasTypeLoc, MatchesCXXTemporaryObjectExpr) {
414   EXPECT_TRUE(
415       matches("struct Foo { Foo(int, int); }; auto x = Foo(1, 2);",
416               cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("struct Foo"))))));
417 }
418 
TEST(HasTypeLoc,MatchesCXXUnresolvedConstructExpr)419 TEST(HasTypeLoc, MatchesCXXUnresolvedConstructExpr) {
420   EXPECT_TRUE(
421       matches("template <typename T> T make() { return T(); }",
422               cxxUnresolvedConstructExpr(hasTypeLoc(loc(asString("T"))))));
423 }
424 
TEST(HasTypeLoc,MatchesClassTemplateSpecializationDecl)425 TEST(HasTypeLoc, MatchesClassTemplateSpecializationDecl) {
426   EXPECT_TRUE(matches(
427       "template <typename T> class Foo; template <> class Foo<int> {};",
428       classTemplateSpecializationDecl(hasTypeLoc(loc(asString("Foo<int>"))))));
429 }
430 
TEST(HasTypeLoc,MatchesCompoundLiteralExpr)431 TEST(HasTypeLoc, MatchesCompoundLiteralExpr) {
432   EXPECT_TRUE(
433       matches("int* x = (int[2]) { 0, 1 };",
434               compoundLiteralExpr(hasTypeLoc(loc(asString("int[2]"))))));
435 }
436 
TEST(HasTypeLoc,MatchesDeclaratorDecl)437 TEST(HasTypeLoc, MatchesDeclaratorDecl) {
438   EXPECT_TRUE(matches("int x;",
439                       varDecl(hasName("x"), hasTypeLoc(loc(asString("int"))))));
440   EXPECT_TRUE(matches("int x(3);",
441                       varDecl(hasName("x"), hasTypeLoc(loc(asString("int"))))));
442   EXPECT_TRUE(
443       matches("struct Foo { Foo(int, int); }; Foo x(1, 2);",
444               varDecl(hasName("x"), hasTypeLoc(loc(asString("struct Foo"))))));
445 
446   // Make sure we don't crash on implicit constructors.
447   EXPECT_TRUE(notMatches("class X {}; X x;",
448                          declaratorDecl(hasTypeLoc(loc(asString("int"))))));
449 }
450 
TEST(HasTypeLoc,MatchesExplicitCastExpr)451 TEST(HasTypeLoc, MatchesExplicitCastExpr) {
452   EXPECT_TRUE(matches("auto x = (int) 3;",
453                       explicitCastExpr(hasTypeLoc(loc(asString("int"))))));
454   EXPECT_TRUE(matches("auto x = static_cast<int>(3);",
455                       explicitCastExpr(hasTypeLoc(loc(asString("int"))))));
456 }
457 
TEST(HasTypeLoc,MatchesObjCPropertyDecl)458 TEST(HasTypeLoc, MatchesObjCPropertyDecl) {
459   EXPECT_TRUE(matchesObjC(R"objc(
460       @interface Foo
461       @property int enabled;
462       @end
463     )objc",
464                           objcPropertyDecl(hasTypeLoc(loc(asString("int"))))));
465 }
466 
TEST(HasTypeLoc,MatchesTemplateArgumentLoc)467 TEST(HasTypeLoc, MatchesTemplateArgumentLoc) {
468   EXPECT_TRUE(matches("template <typename T> class Foo {}; Foo<int> x;",
469                       templateArgumentLoc(hasTypeLoc(loc(asString("int"))))));
470 }
471 
TEST(HasTypeLoc,MatchesTypedefNameDecl)472 TEST(HasTypeLoc, MatchesTypedefNameDecl) {
473   EXPECT_TRUE(matches("typedef int X;",
474                       typedefNameDecl(hasTypeLoc(loc(asString("int"))))));
475   EXPECT_TRUE(matches("using X = int;",
476                       typedefNameDecl(hasTypeLoc(loc(asString("int"))))));
477 }
478 
TEST(Callee,MatchesDeclarations)479 TEST(Callee, MatchesDeclarations) {
480   StatementMatcher CallMethodX = callExpr(callee(cxxMethodDecl(hasName("x"))));
481 
482   EXPECT_TRUE(matches("class Y { void x() { x(); } };", CallMethodX));
483   EXPECT_TRUE(notMatches("class Y { void x() {} };", CallMethodX));
484 
485   CallMethodX = traverse(TK_AsIs, callExpr(callee(cxxConversionDecl())));
486   EXPECT_TRUE(
487     matches("struct Y { operator int() const; }; int i = Y();", CallMethodX));
488   EXPECT_TRUE(notMatches("struct Y { operator int() const; }; Y y = Y();",
489                          CallMethodX));
490 }
491 
TEST(Callee,MatchesMemberExpressions)492 TEST(Callee, MatchesMemberExpressions) {
493   EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
494                       callExpr(callee(memberExpr()))));
495   EXPECT_TRUE(
496     notMatches("class Y { void x() { this->x(); } };", callExpr(callee(callExpr()))));
497 }
498 
TEST(Matcher,Argument)499 TEST(Matcher, Argument) {
500   StatementMatcher CallArgumentY = callExpr(
501     hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
502 
503   EXPECT_TRUE(matches("void x(int) { int y; x(y); }", CallArgumentY));
504   EXPECT_TRUE(
505     matches("class X { void x(int) { int y; x(y); } };", CallArgumentY));
506   EXPECT_TRUE(notMatches("void x(int) { int z; x(z); }", CallArgumentY));
507 
508   StatementMatcher WrongIndex = callExpr(
509     hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
510   EXPECT_TRUE(notMatches("void x(int) { int y; x(y); }", WrongIndex));
511 }
512 
TEST(Matcher,AnyArgument)513 TEST(Matcher, AnyArgument) {
514   auto HasArgumentY = hasAnyArgument(
515       ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("y"))))));
516   StatementMatcher CallArgumentY = callExpr(HasArgumentY);
517   StatementMatcher CtorArgumentY = cxxConstructExpr(HasArgumentY);
518   StatementMatcher UnresolvedCtorArgumentY =
519       cxxUnresolvedConstructExpr(HasArgumentY);
520   StatementMatcher ObjCCallArgumentY = objcMessageExpr(HasArgumentY);
521   EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
522   EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
523   EXPECT_TRUE(matches("struct Y { Y(int, int); };"
524                       "void x() { int y; (void)Y(1, y); }",
525                       CtorArgumentY));
526   EXPECT_TRUE(matches("struct Y { Y(int, int); };"
527                       "void x() { int y; (void)Y(y, 42); }",
528                       CtorArgumentY));
529   EXPECT_TRUE(matches("template <class Y> void x() { int y; (void)Y(1, y); }",
530                       UnresolvedCtorArgumentY));
531   EXPECT_TRUE(matches("template <class Y> void x() { int y; (void)Y(y, 42); }",
532                       UnresolvedCtorArgumentY));
533   EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) y; @end "
534                           "void x(I* i) { int y; [i f:y]; }",
535                           ObjCCallArgumentY));
536   EXPECT_FALSE(matchesObjC("@interface I -(void)f:(int) z; @end "
537                            "void x(I* i) { int z; [i f:z]; }",
538                            ObjCCallArgumentY));
539   EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
540   EXPECT_TRUE(notMatches("struct Y { Y(int, int); };"
541                          "void x() { int y; (void)Y(1, 2); }",
542                          CtorArgumentY));
543   EXPECT_TRUE(notMatches("template <class Y>"
544                          "void x() { int y; (void)Y(1, 2); }",
545                          UnresolvedCtorArgumentY));
546 
547   StatementMatcher ImplicitCastedArgument =
548       traverse(TK_AsIs, callExpr(hasAnyArgument(implicitCastExpr())));
549   EXPECT_TRUE(matches("void x(long) { int y; x(y); }", ImplicitCastedArgument));
550 }
551 
TEST(Matcher,HasReceiver)552 TEST(Matcher, HasReceiver) {
553   EXPECT_TRUE(matchesObjC(
554       "@interface NSString @end "
555       "void f(NSString *x) {"
556       "[x containsString];"
557       "}",
558       objcMessageExpr(hasReceiver(declRefExpr(to(varDecl(hasName("x"))))))));
559 
560   EXPECT_FALSE(matchesObjC(
561       "@interface NSString +(NSString *) stringWithFormat; @end "
562       "void f() { [NSString stringWithFormat]; }",
563       objcMessageExpr(hasReceiver(declRefExpr(to(varDecl(hasName("x"))))))));
564 }
565 
TEST(Matcher,MatchesMethodsOnLambda)566 TEST(Matcher, MatchesMethodsOnLambda) {
567   StringRef Code = R"cpp(
568 struct A {
569   ~A() {}
570 };
571 void foo()
572 {
573   A a;
574   auto l = [a] { };
575   auto lCopy = l;
576   auto lPtrDecay = +[] { };
577   (void)lPtrDecay;
578 }
579 )cpp";
580 
581   EXPECT_TRUE(matches(
582       Code, cxxConstructorDecl(
583                 hasBody(compoundStmt()),
584                 hasAncestor(lambdaExpr(hasAncestor(varDecl(hasName("l"))))),
585                 isCopyConstructor())));
586   EXPECT_TRUE(matches(
587       Code, cxxConstructorDecl(
588                 hasBody(compoundStmt()),
589                 hasAncestor(lambdaExpr(hasAncestor(varDecl(hasName("l"))))),
590                 isMoveConstructor())));
591   EXPECT_TRUE(matches(
592       Code, cxxDestructorDecl(
593                 hasBody(compoundStmt()),
594                 hasAncestor(lambdaExpr(hasAncestor(varDecl(hasName("l"))))))));
595   EXPECT_TRUE(matches(
596       Code, cxxConversionDecl(hasBody(compoundStmt(has(returnStmt(
597                                   hasReturnValue(implicitCastExpr()))))),
598                               hasAncestor(lambdaExpr(hasAncestor(
599                                   varDecl(hasName("lPtrDecay"))))))));
600 }
601 
TEST(Matcher,MatchesCoroutine)602 TEST(Matcher, MatchesCoroutine) {
603   FileContentMappings M;
604   M.push_back(std::make_pair("/coro_header", R"cpp(
605 namespace std {
606 
607 template <class... Args>
608 struct void_t_imp {
609   using type = void;
610 };
611 template <class... Args>
612 using void_t = typename void_t_imp<Args...>::type;
613 
614 template <class T, class = void>
615 struct traits_sfinae_base {};
616 
617 template <class T>
618 struct traits_sfinae_base<T, void_t<typename T::promise_type>> {
619   using promise_type = typename T::promise_type;
620 };
621 
622 template <class Ret, class... Args>
623 struct coroutine_traits : public traits_sfinae_base<Ret> {};
624 }  // namespace std
625 struct awaitable {
626   bool await_ready() noexcept;
627   template <typename F>
628   void await_suspend(F) noexcept;
629   void await_resume() noexcept;
630 } a;
631 struct promise {
632   void get_return_object();
633   awaitable initial_suspend();
634   awaitable final_suspend() noexcept;
635   awaitable yield_value(int); // expected-note 2{{candidate}}
636   void return_value(int); // expected-note 2{{here}}
637   void unhandled_exception();
638 };
639 template <typename... T>
640 struct std::coroutine_traits<void, T...> { using promise_type = promise; };
641 namespace std {
642 template <class PromiseType = void>
643 struct coroutine_handle {
644   static coroutine_handle from_address(void *) noexcept;
645 };
646 } // namespace std
647 )cpp"));
648   StringRef CoReturnCode = R"cpp(
649 #include <coro_header>
650 void check_match_co_return() {
651   co_return 1;
652 }
653 )cpp";
654   EXPECT_TRUE(matchesConditionally(CoReturnCode,
655                                    coreturnStmt(isExpansionInMainFile()),
656                                    true, {"-std=c++20", "-I/"}, M));
657   StringRef CoAwaitCode = R"cpp(
658 #include <coro_header>
659 void check_match_co_await() {
660   co_await a;
661 }
662 )cpp";
663   EXPECT_TRUE(matchesConditionally(CoAwaitCode,
664                                    coawaitExpr(isExpansionInMainFile()),
665                                    true, {"-std=c++20", "-I/"}, M));
666   StringRef CoYieldCode = R"cpp(
667 #include <coro_header>
668 void check_match_co_yield() {
669   co_yield 1.0;
670 }
671 )cpp";
672   EXPECT_TRUE(matchesConditionally(CoYieldCode,
673                                    coyieldExpr(isExpansionInMainFile()),
674                                    true, {"-std=c++20", "-I/"}, M));
675 }
676 
TEST(Matcher,isClassMessage)677 TEST(Matcher, isClassMessage) {
678   EXPECT_TRUE(matchesObjC(
679       "@interface NSString +(NSString *) stringWithFormat; @end "
680       "void f() { [NSString stringWithFormat]; }",
681       objcMessageExpr(isClassMessage())));
682 
683   EXPECT_FALSE(matchesObjC(
684       "@interface NSString @end "
685       "void f(NSString *x) {"
686       "[x containsString];"
687       "}",
688       objcMessageExpr(isClassMessage())));
689 }
690 
TEST(Matcher,isInstanceMessage)691 TEST(Matcher, isInstanceMessage) {
692   EXPECT_TRUE(matchesObjC(
693       "@interface NSString @end "
694       "void f(NSString *x) {"
695       "[x containsString];"
696       "}",
697       objcMessageExpr(isInstanceMessage())));
698 
699   EXPECT_FALSE(matchesObjC(
700       "@interface NSString +(NSString *) stringWithFormat; @end "
701       "void f() { [NSString stringWithFormat]; }",
702       objcMessageExpr(isInstanceMessage())));
703 
704 }
705 
TEST(Matcher,isClassMethod)706 TEST(Matcher, isClassMethod) {
707   EXPECT_TRUE(matchesObjC(
708     "@interface Bar + (void)bar; @end",
709     objcMethodDecl(isClassMethod())));
710 
711   EXPECT_TRUE(matchesObjC(
712     "@interface Bar @end"
713     "@implementation Bar + (void)bar {} @end",
714     objcMethodDecl(isClassMethod())));
715 
716   EXPECT_FALSE(matchesObjC(
717     "@interface Foo - (void)foo; @end",
718     objcMethodDecl(isClassMethod())));
719 
720   EXPECT_FALSE(matchesObjC(
721     "@interface Foo @end "
722     "@implementation Foo - (void)foo {} @end",
723     objcMethodDecl(isClassMethod())));
724 }
725 
TEST(Matcher,isInstanceMethod)726 TEST(Matcher, isInstanceMethod) {
727   EXPECT_TRUE(matchesObjC(
728     "@interface Foo - (void)foo; @end",
729     objcMethodDecl(isInstanceMethod())));
730 
731   EXPECT_TRUE(matchesObjC(
732     "@interface Foo @end "
733     "@implementation Foo - (void)foo {} @end",
734     objcMethodDecl(isInstanceMethod())));
735 
736   EXPECT_FALSE(matchesObjC(
737     "@interface Bar + (void)bar; @end",
738     objcMethodDecl(isInstanceMethod())));
739 
740   EXPECT_FALSE(matchesObjC(
741     "@interface Bar @end"
742     "@implementation Bar + (void)bar {} @end",
743     objcMethodDecl(isInstanceMethod())));
744 }
745 
TEST(MatcherCXXMemberCallExpr,On)746 TEST(MatcherCXXMemberCallExpr, On) {
747   StringRef Snippet1 = R"cc(
748         struct Y {
749           void m();
750         };
751         void z(Y y) { y.m(); }
752       )cc";
753   StringRef Snippet2 = R"cc(
754         struct Y {
755           void m();
756         };
757         struct X : public Y {};
758         void z(X x) { x.m(); }
759       )cc";
760   auto MatchesY = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y")))));
761   EXPECT_TRUE(matches(Snippet1, MatchesY));
762   EXPECT_TRUE(notMatches(Snippet2, MatchesY));
763 
764   auto MatchesX = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("X")))));
765   EXPECT_TRUE(matches(Snippet2, MatchesX));
766 
767   // Parens are ignored.
768   StringRef Snippet3 = R"cc(
769     struct Y {
770       void m();
771     };
772     Y g();
773     void z(Y y) { (g()).m(); }
774   )cc";
775   auto MatchesCall = cxxMemberCallExpr(on(callExpr()));
776   EXPECT_TRUE(matches(Snippet3, MatchesCall));
777 }
778 
TEST(MatcherCXXMemberCallExpr,OnImplicitObjectArgument)779 TEST(MatcherCXXMemberCallExpr, OnImplicitObjectArgument) {
780   StringRef Snippet1 = R"cc(
781     struct Y {
782       void m();
783     };
784     void z(Y y) { y.m(); }
785   )cc";
786   StringRef Snippet2 = R"cc(
787     struct Y {
788       void m();
789     };
790     struct X : public Y {};
791     void z(X x) { x.m(); }
792   )cc";
793   auto MatchesY = traverse(TK_AsIs, cxxMemberCallExpr(onImplicitObjectArgument(
794                                         hasType(cxxRecordDecl(hasName("Y"))))));
795   EXPECT_TRUE(matches(Snippet1, MatchesY));
796   EXPECT_TRUE(matches(Snippet2, MatchesY));
797 
798   auto MatchesX = traverse(TK_AsIs, cxxMemberCallExpr(onImplicitObjectArgument(
799                                         hasType(cxxRecordDecl(hasName("X"))))));
800   EXPECT_TRUE(notMatches(Snippet2, MatchesX));
801 
802   // Parens are not ignored.
803   StringRef Snippet3 = R"cc(
804     struct Y {
805       void m();
806     };
807     Y g();
808     void z(Y y) { (g()).m(); }
809   )cc";
810   auto MatchesCall = traverse(
811       TK_AsIs, cxxMemberCallExpr(onImplicitObjectArgument(callExpr())));
812   EXPECT_TRUE(notMatches(Snippet3, MatchesCall));
813 }
814 
TEST(Matcher,HasObjectExpr)815 TEST(Matcher, HasObjectExpr) {
816   StringRef Snippet1 = R"cc(
817         struct X {
818           int m;
819           int f(X x) { return x.m; }
820         };
821       )cc";
822   StringRef Snippet2 = R"cc(
823         struct X {
824           int m;
825           int f(X x) { return m; }
826         };
827       )cc";
828   auto MatchesX =
829       memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))));
830   EXPECT_TRUE(matches(Snippet1, MatchesX));
831   EXPECT_TRUE(notMatches(Snippet2, MatchesX));
832 
833   auto MatchesXPointer = memberExpr(
834       hasObjectExpression(hasType(pointsTo(cxxRecordDecl(hasName("X"))))));
835   EXPECT_TRUE(notMatches(Snippet1, MatchesXPointer));
836   EXPECT_TRUE(matches(Snippet2, MatchesXPointer));
837 }
838 
TEST(ForEachArgumentWithParam,ReportsNoFalsePositives)839 TEST(ForEachArgumentWithParam, ReportsNoFalsePositives) {
840   StatementMatcher ArgumentY =
841     declRefExpr(to(varDecl(hasName("y")))).bind("arg");
842   DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
843   StatementMatcher CallExpr =
844     callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
845 
846   // IntParam does not match.
847   EXPECT_TRUE(notMatches("void f(int* i) { int* y; f(y); }", CallExpr));
848   // ArgumentY does not match.
849   EXPECT_TRUE(notMatches("void f(int i) { int x; f(x); }", CallExpr));
850 }
851 
TEST(ForEachArgumentWithParam,MatchesCXXMemberCallExpr)852 TEST(ForEachArgumentWithParam, MatchesCXXMemberCallExpr) {
853   StatementMatcher ArgumentY =
854     declRefExpr(to(varDecl(hasName("y")))).bind("arg");
855   DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
856   StatementMatcher CallExpr =
857     callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
858   EXPECT_TRUE(matchAndVerifyResultTrue(
859     "struct S {"
860       "  const S& operator[](int i) { return *this; }"
861       "};"
862       "void f(S S1) {"
863       "  int y = 1;"
864       "  S1[y];"
865       "}",
866     CallExpr, std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param", 1)));
867 
868   StatementMatcher CallExpr2 =
869     callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
870   EXPECT_TRUE(matchAndVerifyResultTrue(
871     "struct S {"
872       "  static void g(int i);"
873       "};"
874       "void f() {"
875       "  int y = 1;"
876       "  S::g(y);"
877       "}",
878     CallExpr2, std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param", 1)));
879 }
880 
TEST(ForEachArgumentWithParam,MatchesCallExpr)881 TEST(ForEachArgumentWithParam, MatchesCallExpr) {
882   StatementMatcher ArgumentY =
883     declRefExpr(to(varDecl(hasName("y")))).bind("arg");
884   DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
885   StatementMatcher CallExpr =
886     callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
887 
888   EXPECT_TRUE(
889     matchAndVerifyResultTrue("void f(int i) { int y; f(y); }", CallExpr,
890                              std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>(
891                                "param")));
892   EXPECT_TRUE(
893     matchAndVerifyResultTrue("void f(int i) { int y; f(y); }", CallExpr,
894                              std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>(
895                                "arg")));
896 
897   EXPECT_TRUE(matchAndVerifyResultTrue(
898     "void f(int i, int j) { int y; f(y, y); }", CallExpr,
899     std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param", 2)));
900   EXPECT_TRUE(matchAndVerifyResultTrue(
901     "void f(int i, int j) { int y; f(y, y); }", CallExpr,
902     std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg", 2)));
903 }
904 
TEST(ForEachArgumentWithParam,MatchesConstructExpr)905 TEST(ForEachArgumentWithParam, MatchesConstructExpr) {
906   StatementMatcher ArgumentY =
907     declRefExpr(to(varDecl(hasName("y")))).bind("arg");
908   DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
909   StatementMatcher ConstructExpr = traverse(
910       TK_AsIs, cxxConstructExpr(forEachArgumentWithParam(ArgumentY, IntParam)));
911 
912   EXPECT_TRUE(matchAndVerifyResultTrue(
913     "struct C {"
914       "  C(int i) {}"
915       "};"
916       "int y = 0;"
917       "C Obj(y);",
918     ConstructExpr,
919     std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param")));
920 }
921 
TEST(ForEachArgumentWithParam,HandlesBoundNodesForNonMatches)922 TEST(ForEachArgumentWithParam, HandlesBoundNodesForNonMatches) {
923   EXPECT_TRUE(matchAndVerifyResultTrue(
924     "void g(int i, int j) {"
925       "  int a;"
926       "  int b;"
927       "  int c;"
928       "  g(a, 0);"
929       "  g(a, b);"
930       "  g(0, b);"
931       "}",
932     functionDecl(
933       forEachDescendant(varDecl().bind("v")),
934       forEachDescendant(callExpr(forEachArgumentWithParam(
935         declRefExpr(to(decl(equalsBoundNode("v")))), parmVarDecl())))),
936     std::make_unique<VerifyIdIsBoundTo<VarDecl>>("v", 4)));
937 }
938 
TEST(ForEachArgumentWithParamType,ReportsNoFalsePositives)939 TEST(ForEachArgumentWithParamType, ReportsNoFalsePositives) {
940   StatementMatcher ArgumentY =
941       declRefExpr(to(varDecl(hasName("y")))).bind("arg");
942   TypeMatcher IntType = qualType(isInteger()).bind("type");
943   StatementMatcher CallExpr =
944       callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
945 
946   // IntParam does not match.
947   EXPECT_TRUE(notMatches("void f(int* i) { int* y; f(y); }", CallExpr));
948   // ArgumentY does not match.
949   EXPECT_TRUE(notMatches("void f(int i) { int x; f(x); }", CallExpr));
950 }
951 
TEST(ForEachArgumentWithParamType,MatchesCXXMemberCallExpr)952 TEST(ForEachArgumentWithParamType, MatchesCXXMemberCallExpr) {
953   StatementMatcher ArgumentY =
954       declRefExpr(to(varDecl(hasName("y")))).bind("arg");
955   TypeMatcher IntType = qualType(isInteger()).bind("type");
956   StatementMatcher CallExpr =
957       callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
958   EXPECT_TRUE(matchAndVerifyResultTrue(
959       "struct S {"
960       "  const S& operator[](int i) { return *this; }"
961       "};"
962       "void f(S S1) {"
963       "  int y = 1;"
964       "  S1[y];"
965       "}",
966       CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type", 1)));
967 
968   StatementMatcher CallExpr2 =
969       callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
970   EXPECT_TRUE(matchAndVerifyResultTrue(
971       "struct S {"
972       "  static void g(int i);"
973       "};"
974       "void f() {"
975       "  int y = 1;"
976       "  S::g(y);"
977       "}",
978       CallExpr2, std::make_unique<VerifyIdIsBoundTo<QualType>>("type", 1)));
979 }
980 
TEST(ForEachArgumentWithParamType,MatchesCallExpr)981 TEST(ForEachArgumentWithParamType, MatchesCallExpr) {
982   StatementMatcher ArgumentY =
983       declRefExpr(to(varDecl(hasName("y")))).bind("arg");
984   TypeMatcher IntType = qualType(isInteger()).bind("type");
985   StatementMatcher CallExpr =
986       callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
987 
988   EXPECT_TRUE(matchAndVerifyResultTrue(
989       "void f(int i) { int y; f(y); }", CallExpr,
990       std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
991   EXPECT_TRUE(matchAndVerifyResultTrue(
992       "void f(int i) { int y; f(y); }", CallExpr,
993       std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
994 
995   EXPECT_TRUE(matchAndVerifyResultTrue(
996       "void f(int i, int j) { int y; f(y, y); }", CallExpr,
997       std::make_unique<VerifyIdIsBoundTo<QualType>>("type", 2)));
998   EXPECT_TRUE(matchAndVerifyResultTrue(
999       "void f(int i, int j) { int y; f(y, y); }", CallExpr,
1000       std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg", 2)));
1001 }
1002 
TEST(ForEachArgumentWithParamType,MatchesConstructExpr)1003 TEST(ForEachArgumentWithParamType, MatchesConstructExpr) {
1004   StatementMatcher ArgumentY =
1005       declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1006   TypeMatcher IntType = qualType(isInteger()).bind("type");
1007   StatementMatcher ConstructExpr =
1008       cxxConstructExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1009 
1010   EXPECT_TRUE(matchAndVerifyResultTrue(
1011       "struct C {"
1012       "  C(int i) {}"
1013       "};"
1014       "int y = 0;"
1015       "C Obj(y);",
1016       ConstructExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
1017   EXPECT_TRUE(matchAndVerifyResultTrue(
1018       "struct C {"
1019       "  C(int i) {}"
1020       "};"
1021       "int y = 0;"
1022       "C Obj(y);",
1023       ConstructExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
1024 }
1025 
TEST(ForEachArgumentWithParamType,HandlesKandRFunctions)1026 TEST(ForEachArgumentWithParamType, HandlesKandRFunctions) {
1027   StatementMatcher ArgumentY =
1028       declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1029   TypeMatcher IntType = qualType(isInteger()).bind("type");
1030   StatementMatcher CallExpr =
1031       callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1032 
1033   EXPECT_TRUE(matchesC("void f();\n"
1034                        "void call_it(void) { int x, y; f(x, y); }\n"
1035                        "void f(a, b) int a, b; {}\n"
1036                        "void call_it2(void) { int x, y; f(x, y); }",
1037                        CallExpr));
1038 }
1039 
TEST(ForEachArgumentWithParamType,HandlesBoundNodesForNonMatches)1040 TEST(ForEachArgumentWithParamType, HandlesBoundNodesForNonMatches) {
1041   EXPECT_TRUE(matchAndVerifyResultTrue(
1042       "void g(int i, int j) {"
1043       "  int a;"
1044       "  int b;"
1045       "  int c;"
1046       "  g(a, 0);"
1047       "  g(a, b);"
1048       "  g(0, b);"
1049       "}",
1050       functionDecl(
1051           forEachDescendant(varDecl().bind("v")),
1052           forEachDescendant(callExpr(forEachArgumentWithParamType(
1053               declRefExpr(to(decl(equalsBoundNode("v")))), qualType())))),
1054       std::make_unique<VerifyIdIsBoundTo<VarDecl>>("v", 4)));
1055 }
1056 
TEST(ForEachArgumentWithParamType,MatchesFunctionPtrCalls)1057 TEST(ForEachArgumentWithParamType, MatchesFunctionPtrCalls) {
1058   StatementMatcher ArgumentY =
1059       declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1060   TypeMatcher IntType = qualType(builtinType()).bind("type");
1061   StatementMatcher CallExpr =
1062       callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1063 
1064   EXPECT_TRUE(matchAndVerifyResultTrue(
1065       "void f(int i) {"
1066       "void (*f_ptr)(int) = f; int y; f_ptr(y); }",
1067       CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
1068   EXPECT_TRUE(matchAndVerifyResultTrue(
1069       "void f(int i) {"
1070       "void (*f_ptr)(int) = f; int y; f_ptr(y); }",
1071       CallExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
1072 }
1073 
TEST(ForEachArgumentWithParamType,MatchesMemberFunctionPtrCalls)1074 TEST(ForEachArgumentWithParamType, MatchesMemberFunctionPtrCalls) {
1075   StatementMatcher ArgumentY =
1076       declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1077   TypeMatcher IntType = qualType(builtinType()).bind("type");
1078   StatementMatcher CallExpr =
1079       callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1080 
1081   StringRef S = "struct A {\n"
1082                 "  int f(int i) { return i + 1; }\n"
1083                 "  int (A::*x)(int);\n"
1084                 "};\n"
1085                 "void f() {\n"
1086                 "  int y = 42;\n"
1087                 "  A a;\n"
1088                 "  a.x = &A::f;\n"
1089                 "  (a.*(a.x))(y);\n"
1090                 "}";
1091   EXPECT_TRUE(matchAndVerifyResultTrue(
1092       S, CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
1093   EXPECT_TRUE(matchAndVerifyResultTrue(
1094       S, CallExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
1095 }
1096 
TEST(ForEachArgumentWithParamType,MatchesVariadicFunctionPtrCalls)1097 TEST(ForEachArgumentWithParamType, MatchesVariadicFunctionPtrCalls) {
1098   StatementMatcher ArgumentY =
1099       declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1100   TypeMatcher IntType = qualType(builtinType()).bind("type");
1101   StatementMatcher CallExpr =
1102       callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1103 
1104   StringRef S = R"cpp(
1105     void fcntl(int fd, int cmd, ...) {}
1106 
1107     template <typename Func>
1108     void f(Func F) {
1109       int y = 42;
1110       F(y, 1, 3);
1111     }
1112 
1113     void g() { f(fcntl); }
1114   )cpp";
1115 
1116   EXPECT_TRUE(matchAndVerifyResultTrue(
1117       S, CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
1118   EXPECT_TRUE(matchAndVerifyResultTrue(
1119       S, CallExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
1120 }
1121 
TEST(QualType,hasCanonicalType)1122 TEST(QualType, hasCanonicalType) {
1123   EXPECT_TRUE(notMatches("typedef int &int_ref;"
1124                            "int a;"
1125                            "int_ref b = a;",
1126                          varDecl(hasType(qualType(referenceType())))));
1127   EXPECT_TRUE(
1128     matches("typedef int &int_ref;"
1129               "int a;"
1130               "int_ref b = a;",
1131             varDecl(hasType(qualType(hasCanonicalType(referenceType()))))));
1132 }
1133 
TEST(HasParameter,CallsInnerMatcher)1134 TEST(HasParameter, CallsInnerMatcher) {
1135   EXPECT_TRUE(matches("class X { void x(int) {} };",
1136                       cxxMethodDecl(hasParameter(0, varDecl()))));
1137   EXPECT_TRUE(notMatches("class X { void x(int) {} };",
1138                          cxxMethodDecl(hasParameter(0, hasName("x")))));
1139   EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) x; @end",
1140                           objcMethodDecl(hasParameter(0, hasName("x")))));
1141   EXPECT_TRUE(matchesObjC("int main() { void (^b)(int) = ^(int p) {}; }",
1142                           blockDecl(hasParameter(0, hasName("p")))));
1143 }
1144 
TEST(HasParameter,DoesNotMatchIfIndexOutOfBounds)1145 TEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) {
1146   EXPECT_TRUE(notMatches("class X { void x(int) {} };",
1147                          cxxMethodDecl(hasParameter(42, varDecl()))));
1148 }
1149 
TEST(HasType,MatchesParameterVariableTypesStrictly)1150 TEST(HasType, MatchesParameterVariableTypesStrictly) {
1151   EXPECT_TRUE(matches(
1152     "class X { void x(X x) {} };",
1153     cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
1154   EXPECT_TRUE(notMatches(
1155     "class X { void x(const X &x) {} };",
1156     cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
1157   EXPECT_TRUE(matches("class X { void x(const X *x) {} };",
1158                       cxxMethodDecl(hasParameter(
1159                         0, hasType(pointsTo(recordDecl(hasName("X"))))))));
1160   EXPECT_TRUE(matches("class X { void x(const X &x) {} };",
1161                       cxxMethodDecl(hasParameter(
1162                         0, hasType(references(recordDecl(hasName("X"))))))));
1163 }
1164 
TEST(HasAnyParameter,MatchesIndependentlyOfPosition)1165 TEST(HasAnyParameter, MatchesIndependentlyOfPosition) {
1166   EXPECT_TRUE(matches(
1167     "class Y {}; class X { void x(X x, Y y) {} };",
1168     cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
1169   EXPECT_TRUE(matches(
1170     "class Y {}; class X { void x(Y y, X x) {} };",
1171     cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
1172   EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) x; @end",
1173                           objcMethodDecl(hasAnyParameter(hasName("x")))));
1174   EXPECT_TRUE(matchesObjC("int main() { void (^b)(int) = ^(int p) {}; }",
1175                           blockDecl(hasAnyParameter(hasName("p")))));
1176 }
1177 
TEST(Returns,MatchesReturnTypes)1178 TEST(Returns, MatchesReturnTypes) {
1179   EXPECT_TRUE(matches("class Y { int f() { return 1; } };",
1180                       functionDecl(returns(asString("int")))));
1181   EXPECT_TRUE(notMatches("class Y { int f() { return 1; } };",
1182                          functionDecl(returns(asString("float")))));
1183   EXPECT_TRUE(matches("class Y { Y getMe() { return *this; } };",
1184                       functionDecl(returns(hasDeclaration(
1185                         recordDecl(hasName("Y")))))));
1186 }
1187 
TEST(HasAnyParameter,DoesntMatchIfInnerMatcherDoesntMatch)1188 TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
1189   EXPECT_TRUE(notMatches(
1190     "class Y {}; class X { void x(int) {} };",
1191     cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
1192 }
1193 
TEST(HasAnyParameter,DoesNotMatchThisPointer)1194 TEST(HasAnyParameter, DoesNotMatchThisPointer) {
1195   EXPECT_TRUE(notMatches("class Y {}; class X { void x() {} };",
1196                          cxxMethodDecl(hasAnyParameter(
1197                            hasType(pointsTo(recordDecl(hasName("X"))))))));
1198 }
1199 
TEST(HasName,MatchesParameterVariableDeclarations)1200 TEST(HasName, MatchesParameterVariableDeclarations) {
1201   EXPECT_TRUE(matches("class Y {}; class X { void x(int x) {} };",
1202                       cxxMethodDecl(hasAnyParameter(hasName("x")))));
1203   EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
1204                          cxxMethodDecl(hasAnyParameter(hasName("x")))));
1205 }
1206 
TEST(Matcher,MatchesTypeTemplateArgument)1207 TEST(Matcher, MatchesTypeTemplateArgument) {
1208   EXPECT_TRUE(matches(
1209     "template<typename T> struct B {};"
1210       "B<int> b;",
1211     classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToType(
1212       asString("int"))))));
1213 }
1214 
TEST(Matcher,MatchesTemplateTemplateArgument)1215 TEST(Matcher, MatchesTemplateTemplateArgument) {
1216   EXPECT_TRUE(matches("template<template <typename> class S> class X {};"
1217                       "template<typename T> class Y {};"
1218                       "X<Y> xi;",
1219                       classTemplateSpecializationDecl(hasAnyTemplateArgument(
1220                           refersToTemplate(templateName())))));
1221 }
1222 
TEST(Matcher,MatchesDeclarationReferenceTemplateArgument)1223 TEST(Matcher, MatchesDeclarationReferenceTemplateArgument) {
1224   EXPECT_TRUE(matches(
1225     "struct B { int next; };"
1226       "template<int(B::*next_ptr)> struct A {};"
1227       "A<&B::next> a;",
1228     classTemplateSpecializationDecl(hasAnyTemplateArgument(
1229       refersToDeclaration(fieldDecl(hasName("next")))))));
1230 
1231   EXPECT_TRUE(notMatches(
1232     "template <typename T> struct A {};"
1233       "A<int> a;",
1234     classTemplateSpecializationDecl(hasAnyTemplateArgument(
1235       refersToDeclaration(decl())))));
1236 
1237   EXPECT_TRUE(matches(
1238     "struct B { int next; };"
1239       "template<int(B::*next_ptr)> struct A {};"
1240       "A<&B::next> a;",
1241     templateSpecializationType(hasAnyTemplateArgument(isExpr(
1242       hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))));
1243 
1244   EXPECT_TRUE(notMatches(
1245     "template <typename T> struct A {};"
1246       "A<int> a;",
1247     templateSpecializationType(hasAnyTemplateArgument(
1248       refersToDeclaration(decl())))));
1249 }
1250 
1251 
TEST(Matcher,MatchesSpecificArgument)1252 TEST(Matcher, MatchesSpecificArgument) {
1253   EXPECT_TRUE(matches(
1254     "template<typename T, typename U> class A {};"
1255       "A<bool, int> a;",
1256     classTemplateSpecializationDecl(hasTemplateArgument(
1257       1, refersToType(asString("int"))))));
1258   EXPECT_TRUE(notMatches(
1259     "template<typename T, typename U> class A {};"
1260       "A<int, bool> a;",
1261     classTemplateSpecializationDecl(hasTemplateArgument(
1262       1, refersToType(asString("int"))))));
1263 
1264   EXPECT_TRUE(matches(
1265     "template<typename T, typename U> class A {};"
1266       "A<bool, int> a;",
1267     templateSpecializationType(hasTemplateArgument(
1268       1, refersToType(asString("int"))))));
1269   EXPECT_TRUE(notMatches(
1270     "template<typename T, typename U> class A {};"
1271       "A<int, bool> a;",
1272     templateSpecializationType(hasTemplateArgument(
1273       1, refersToType(asString("int"))))));
1274 
1275   EXPECT_TRUE(matches(
1276     "template<typename T> void f() {};"
1277       "void func() { f<int>(); }",
1278     functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))));
1279   EXPECT_TRUE(notMatches(
1280     "template<typename T> void f() {};",
1281     functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))));
1282 }
1283 
TEST(TemplateArgument,Matches)1284 TEST(TemplateArgument, Matches) {
1285   EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
1286                       classTemplateSpecializationDecl(
1287                         hasAnyTemplateArgument(templateArgument()))));
1288   EXPECT_TRUE(matches(
1289     "template<typename T> struct C {}; C<int> c;",
1290     templateSpecializationType(hasAnyTemplateArgument(templateArgument()))));
1291 
1292   EXPECT_TRUE(matches(
1293     "template<typename T> void f() {};"
1294       "void func() { f<int>(); }",
1295     functionDecl(hasAnyTemplateArgument(templateArgument()))));
1296 }
1297 
TEST(TemplateTypeParmDecl,CXXMethodDecl)1298 TEST(TemplateTypeParmDecl, CXXMethodDecl) {
1299   const char input[] =
1300       "template<typename T>\n"
1301       "class Class {\n"
1302       "  void method();\n"
1303       "};\n"
1304       "template<typename U>\n"
1305       "void Class<U>::method() {}\n";
1306   EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1307   EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1308 }
1309 
TEST(TemplateTypeParmDecl,VarDecl)1310 TEST(TemplateTypeParmDecl, VarDecl) {
1311   const char input[] =
1312       "template<typename T>\n"
1313       "class Class {\n"
1314       "  static T pi;\n"
1315       "};\n"
1316       "template<typename U>\n"
1317       "U Class<U>::pi = U(3.1415926535897932385);\n";
1318   EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1319   EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1320 }
1321 
TEST(TemplateTypeParmDecl,VarTemplatePartialSpecializationDecl)1322 TEST(TemplateTypeParmDecl, VarTemplatePartialSpecializationDecl) {
1323   const char input[] =
1324       "template<typename T>\n"
1325       "struct Struct {\n"
1326       "  template<typename T2> static int field;\n"
1327       "};\n"
1328       "template<typename U>\n"
1329       "template<typename U2>\n"
1330       "int Struct<U>::field<U2*> = 123;\n";
1331   EXPECT_TRUE(
1332       matches(input, templateTypeParmDecl(hasName("T")), langCxx14OrLater()));
1333   EXPECT_TRUE(
1334       matches(input, templateTypeParmDecl(hasName("T2")), langCxx14OrLater()));
1335   EXPECT_TRUE(
1336       matches(input, templateTypeParmDecl(hasName("U")), langCxx14OrLater()));
1337   EXPECT_TRUE(
1338       matches(input, templateTypeParmDecl(hasName("U2")), langCxx14OrLater()));
1339 }
1340 
TEST(TemplateTypeParmDecl,ClassTemplatePartialSpecializationDecl)1341 TEST(TemplateTypeParmDecl, ClassTemplatePartialSpecializationDecl) {
1342   const char input[] =
1343       "template<typename T>\n"
1344       "class Class {\n"
1345       "  template<typename T2> struct Struct;\n"
1346       "};\n"
1347       "template<typename U>\n"
1348       "template<typename U2>\n"
1349       "struct Class<U>::Struct<U2*> {};\n";
1350   EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1351   EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T2"))));
1352   EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1353   EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U2"))));
1354 }
1355 
TEST(TemplateTypeParmDecl,EnumDecl)1356 TEST(TemplateTypeParmDecl, EnumDecl) {
1357   const char input[] =
1358       "template<typename T>\n"
1359       "struct Struct {\n"
1360       "  enum class Enum : T;\n"
1361       "};\n"
1362       "template<typename U>\n"
1363       "enum class Struct<U>::Enum : U {\n"
1364       "  e1,\n"
1365       "  e2\n"
1366       "};\n";
1367   EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1368   EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1369 }
1370 
TEST(TemplateTypeParmDecl,RecordDecl)1371 TEST(TemplateTypeParmDecl, RecordDecl) {
1372   const char input[] =
1373       "template<typename T>\n"
1374       "class Class {\n"
1375       "  struct Struct;\n"
1376       "};\n"
1377       "template<typename U>\n"
1378       "struct Class<U>::Struct {\n"
1379       "  U field;\n"
1380       "};\n";
1381   EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1382   EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1383 }
1384 
TEST(RefersToIntegralType,Matches)1385 TEST(RefersToIntegralType, Matches) {
1386   EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
1387                       classTemplateSpecializationDecl(
1388                         hasAnyTemplateArgument(refersToIntegralType(
1389                           asString("int"))))));
1390   EXPECT_TRUE(notMatches("template<unsigned T> struct C {}; C<42> c;",
1391                          classTemplateSpecializationDecl(hasAnyTemplateArgument(
1392                            refersToIntegralType(asString("int"))))));
1393 }
1394 
TEST(ConstructorDeclaration,SimpleCase)1395 TEST(ConstructorDeclaration, SimpleCase) {
1396   EXPECT_TRUE(matches("class Foo { Foo(int i); };",
1397                       cxxConstructorDecl(ofClass(hasName("Foo")))));
1398   EXPECT_TRUE(notMatches("class Foo { Foo(int i); };",
1399                          cxxConstructorDecl(ofClass(hasName("Bar")))));
1400 }
1401 
TEST(DestructorDeclaration,MatchesVirtualDestructor)1402 TEST(DestructorDeclaration, MatchesVirtualDestructor) {
1403   EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };",
1404                       cxxDestructorDecl(ofClass(hasName("Foo")))));
1405 }
1406 
TEST(DestructorDeclaration,DoesNotMatchImplicitDestructor)1407 TEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) {
1408   EXPECT_TRUE(notMatches("class Foo {};",
1409                          cxxDestructorDecl(ofClass(hasName("Foo")))));
1410 }
1411 
TEST(HasAnyConstructorInitializer,SimpleCase)1412 TEST(HasAnyConstructorInitializer, SimpleCase) {
1413   EXPECT_TRUE(
1414     notMatches("class Foo { Foo() { } };",
1415                cxxConstructorDecl(hasAnyConstructorInitializer(anything()))));
1416   EXPECT_TRUE(
1417     matches("class Foo {"
1418               "  Foo() : foo_() { }"
1419               "  int foo_;"
1420               "};",
1421             cxxConstructorDecl(hasAnyConstructorInitializer(anything()))));
1422 }
1423 
TEST(HasAnyConstructorInitializer,ForField)1424 TEST(HasAnyConstructorInitializer, ForField) {
1425   static const char Code[] =
1426     "class Baz { };"
1427       "class Foo {"
1428       "  Foo() : foo_(), bar_() { }"
1429       "  Baz foo_;"
1430       "  struct {"
1431       "    Baz bar_;"
1432       "  };"
1433       "};";
1434   EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1435     forField(hasType(recordDecl(hasName("Baz"))))))));
1436   EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1437     forField(hasName("foo_"))))));
1438   EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1439     forField(hasName("bar_"))))));
1440   EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1441     forField(hasType(recordDecl(hasName("Bar"))))))));
1442 }
1443 
TEST(HasAnyConstructorInitializer,WithInitializer)1444 TEST(HasAnyConstructorInitializer, WithInitializer) {
1445   static const char Code[] =
1446     "class Foo {"
1447       "  Foo() : foo_(0) { }"
1448       "  int foo_;"
1449       "};";
1450   EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1451     withInitializer(integerLiteral(equals(0)))))));
1452   EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1453     withInitializer(integerLiteral(equals(1)))))));
1454 }
1455 
TEST(HasAnyConstructorInitializer,IsWritten)1456 TEST(HasAnyConstructorInitializer, IsWritten) {
1457   static const char Code[] =
1458     "struct Bar { Bar(){} };"
1459       "class Foo {"
1460       "  Foo() : foo_() { }"
1461       "  Bar foo_;"
1462       "  Bar bar_;"
1463       "};";
1464   EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1465     allOf(forField(hasName("foo_")), isWritten())))));
1466   EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1467     allOf(forField(hasName("bar_")), isWritten())))));
1468   EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1469     allOf(forField(hasName("bar_")), unless(isWritten()))))));
1470 }
1471 
TEST(HasAnyConstructorInitializer,IsBaseInitializer)1472 TEST(HasAnyConstructorInitializer, IsBaseInitializer) {
1473   static const char Code[] =
1474     "struct B {};"
1475       "struct D : B {"
1476       "  int I;"
1477       "  D(int i) : I(i) {}"
1478       "};"
1479       "struct E : B {"
1480       "  E() : B() {}"
1481       "};";
1482   EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf(
1483     hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())),
1484     hasName("E")))));
1485   EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf(
1486     hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())),
1487     hasName("D")))));
1488   EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf(
1489     hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())),
1490     hasName("D")))));
1491   EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf(
1492     hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())),
1493     hasName("E")))));
1494 }
1495 
TEST(IfStmt,ChildTraversalMatchers)1496 TEST(IfStmt, ChildTraversalMatchers) {
1497   EXPECT_TRUE(matches("void f() { if (false) true; else false; }",
1498                       ifStmt(hasThen(cxxBoolLiteral(equals(true))))));
1499   EXPECT_TRUE(notMatches("void f() { if (false) false; else true; }",
1500                          ifStmt(hasThen(cxxBoolLiteral(equals(true))))));
1501   EXPECT_TRUE(matches("void f() { if (false) false; else true; }",
1502                       ifStmt(hasElse(cxxBoolLiteral(equals(true))))));
1503   EXPECT_TRUE(notMatches("void f() { if (false) true; else false; }",
1504                          ifStmt(hasElse(cxxBoolLiteral(equals(true))))));
1505 }
1506 
TEST(MatchBinaryOperator,HasOperatorName)1507 TEST(MatchBinaryOperator, HasOperatorName) {
1508   StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
1509 
1510   EXPECT_TRUE(matches("void x() { true || false; }", OperatorOr));
1511   EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
1512 }
1513 
TEST(MatchBinaryOperator,HasAnyOperatorName)1514 TEST(MatchBinaryOperator, HasAnyOperatorName) {
1515   StatementMatcher Matcher =
1516       binaryOperator(hasAnyOperatorName("+", "-", "*", "/"));
1517 
1518   EXPECT_TRUE(matches("int x(int I) { return I + 2; }", Matcher));
1519   EXPECT_TRUE(matches("int x(int I) { return I - 2; }", Matcher));
1520   EXPECT_TRUE(matches("int x(int I) { return I * 2; }", Matcher));
1521   EXPECT_TRUE(matches("int x(int I) { return I / 2; }", Matcher));
1522   EXPECT_TRUE(notMatches("int x(int I) { return I % 2; }", Matcher));
1523   // Ensure '+= isn't mistaken.
1524   EXPECT_TRUE(notMatches("void x(int &I) { I += 1; }", Matcher));
1525 }
1526 
TEST(MatchBinaryOperator,HasLHSAndHasRHS)1527 TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
1528   StatementMatcher OperatorTrueFalse =
1529     binaryOperator(hasLHS(cxxBoolLiteral(equals(true))),
1530                    hasRHS(cxxBoolLiteral(equals(false))));
1531 
1532   EXPECT_TRUE(matches("void x() { true || false; }", OperatorTrueFalse));
1533   EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse));
1534   EXPECT_TRUE(notMatches("void x() { false || true; }", OperatorTrueFalse));
1535 
1536   StatementMatcher OperatorIntPointer = arraySubscriptExpr(
1537       hasLHS(hasType(isInteger())),
1538       traverse(TK_AsIs, hasRHS(hasType(pointsTo(qualType())))));
1539   EXPECT_TRUE(matches("void x() { 1[\"abc\"]; }", OperatorIntPointer));
1540   EXPECT_TRUE(notMatches("void x() { \"abc\"[1]; }", OperatorIntPointer));
1541 
1542   StringRef Code = R"cpp(
1543 struct HasOpEqMem
1544 {
1545     bool operator==(const HasOpEqMem& other) const
1546     {
1547         return true;
1548     }
1549 };
1550 
1551 struct HasOpFree
1552 {
1553 };
1554 bool operator==(const HasOpFree& lhs, const HasOpFree& rhs)
1555 {
1556     return true;
1557 }
1558 
1559 void opMem()
1560 {
1561     HasOpEqMem s1;
1562     HasOpEqMem s2;
1563     if (s1 == s2)
1564         return;
1565 }
1566 
1567 void opFree()
1568 {
1569     HasOpFree s1;
1570     HasOpFree s2;
1571     if (s1 == s2)
1572         return;
1573 }
1574 )cpp";
1575   auto s1Expr = declRefExpr(to(varDecl(hasName("s1"))));
1576   auto s2Expr = declRefExpr(to(varDecl(hasName("s2"))));
1577   EXPECT_TRUE(matches(
1578       Code,
1579       traverse(TK_IgnoreUnlessSpelledInSource,
1580                cxxOperatorCallExpr(forFunction(functionDecl(hasName("opMem"))),
1581                                    hasOperatorName("=="), hasLHS(s1Expr),
1582                                    hasRHS(s2Expr)))));
1583   EXPECT_TRUE(matches(
1584       Code, traverse(TK_IgnoreUnlessSpelledInSource,
1585                      cxxOperatorCallExpr(
1586                          forFunction(functionDecl(hasName("opMem"))),
1587                          hasAnyOperatorName("!=", "=="), hasLHS(s1Expr)))));
1588   EXPECT_TRUE(matches(
1589       Code, traverse(TK_IgnoreUnlessSpelledInSource,
1590                      cxxOperatorCallExpr(
1591                          forFunction(functionDecl(hasName("opMem"))),
1592                          hasOperatorName("=="), hasOperands(s1Expr, s2Expr)))));
1593   EXPECT_TRUE(matches(
1594       Code, traverse(TK_IgnoreUnlessSpelledInSource,
1595                      cxxOperatorCallExpr(
1596                          forFunction(functionDecl(hasName("opMem"))),
1597                          hasOperatorName("=="), hasEitherOperand(s2Expr)))));
1598 
1599   EXPECT_TRUE(matches(
1600       Code,
1601       traverse(TK_IgnoreUnlessSpelledInSource,
1602                cxxOperatorCallExpr(forFunction(functionDecl(hasName("opFree"))),
1603                                    hasOperatorName("=="), hasLHS(s1Expr),
1604                                    hasRHS(s2Expr)))));
1605   EXPECT_TRUE(matches(
1606       Code, traverse(TK_IgnoreUnlessSpelledInSource,
1607                      cxxOperatorCallExpr(
1608                          forFunction(functionDecl(hasName("opFree"))),
1609                          hasAnyOperatorName("!=", "=="), hasLHS(s1Expr)))));
1610   EXPECT_TRUE(matches(
1611       Code, traverse(TK_IgnoreUnlessSpelledInSource,
1612                      cxxOperatorCallExpr(
1613                          forFunction(functionDecl(hasName("opFree"))),
1614                          hasOperatorName("=="), hasOperands(s1Expr, s2Expr)))));
1615   EXPECT_TRUE(matches(
1616       Code, traverse(TK_IgnoreUnlessSpelledInSource,
1617                      cxxOperatorCallExpr(
1618                          forFunction(functionDecl(hasName("opFree"))),
1619                          hasOperatorName("=="), hasEitherOperand(s2Expr)))));
1620 }
1621 
TEST(MatchBinaryOperator,HasEitherOperand)1622 TEST(MatchBinaryOperator, HasEitherOperand) {
1623   StatementMatcher HasOperand =
1624     binaryOperator(hasEitherOperand(cxxBoolLiteral(equals(false))));
1625 
1626   EXPECT_TRUE(matches("void x() { true || false; }", HasOperand));
1627   EXPECT_TRUE(matches("void x() { false && true; }", HasOperand));
1628   EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand));
1629 }
1630 
TEST(MatchBinaryOperator,HasOperands)1631 TEST(MatchBinaryOperator, HasOperands) {
1632   StatementMatcher HasOperands = binaryOperator(
1633       hasOperands(integerLiteral(equals(1)), integerLiteral(equals(2))));
1634   EXPECT_TRUE(matches("void x() { 1 + 2; }", HasOperands));
1635   EXPECT_TRUE(matches("void x() { 2 + 1; }", HasOperands));
1636   EXPECT_TRUE(notMatches("void x() { 1 + 1; }", HasOperands));
1637   EXPECT_TRUE(notMatches("void x() { 2 + 2; }", HasOperands));
1638   EXPECT_TRUE(notMatches("void x() { 0 + 0; }", HasOperands));
1639   EXPECT_TRUE(notMatches("void x() { 0 + 1; }", HasOperands));
1640 }
1641 
TEST(Matcher,BinaryOperatorTypes)1642 TEST(Matcher, BinaryOperatorTypes) {
1643   // Integration test that verifies the AST provides all binary operators in
1644   // a way we expect.
1645   // FIXME: Operator ','
1646   EXPECT_TRUE(
1647     matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(","))));
1648   EXPECT_TRUE(
1649     matches("bool b; bool c = (b = true);",
1650             binaryOperator(hasOperatorName("="))));
1651   EXPECT_TRUE(
1652     matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!="))));
1653   EXPECT_TRUE(
1654     matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("=="))));
1655   EXPECT_TRUE(matches("bool b = 1 < 2;", binaryOperator(hasOperatorName("<"))));
1656   EXPECT_TRUE(
1657     matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<="))));
1658   EXPECT_TRUE(
1659     matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<"))));
1660   EXPECT_TRUE(
1661     matches("int i = 1; int j = (i <<= 2);",
1662             binaryOperator(hasOperatorName("<<="))));
1663   EXPECT_TRUE(matches("bool b = 1 > 2;", binaryOperator(hasOperatorName(">"))));
1664   EXPECT_TRUE(
1665     matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">="))));
1666   EXPECT_TRUE(
1667     matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>"))));
1668   EXPECT_TRUE(
1669     matches("int i = 1; int j = (i >>= 2);",
1670             binaryOperator(hasOperatorName(">>="))));
1671   EXPECT_TRUE(
1672     matches("int i = 42 ^ 23;", binaryOperator(hasOperatorName("^"))));
1673   EXPECT_TRUE(
1674     matches("int i = 42; int j = (i ^= 42);",
1675             binaryOperator(hasOperatorName("^="))));
1676   EXPECT_TRUE(
1677     matches("int i = 42 % 23;", binaryOperator(hasOperatorName("%"))));
1678   EXPECT_TRUE(
1679     matches("int i = 42; int j = (i %= 42);",
1680             binaryOperator(hasOperatorName("%="))));
1681   EXPECT_TRUE(
1682     matches("bool b = 42  &23;", binaryOperator(hasOperatorName("&"))));
1683   EXPECT_TRUE(
1684     matches("bool b = true && false;",
1685             binaryOperator(hasOperatorName("&&"))));
1686   EXPECT_TRUE(
1687     matches("bool b = true; bool c = (b &= false);",
1688             binaryOperator(hasOperatorName("&="))));
1689   EXPECT_TRUE(
1690     matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|"))));
1691   EXPECT_TRUE(
1692     matches("bool b = true || false;",
1693             binaryOperator(hasOperatorName("||"))));
1694   EXPECT_TRUE(
1695     matches("bool b = true; bool c = (b |= false);",
1696             binaryOperator(hasOperatorName("|="))));
1697   EXPECT_TRUE(
1698     matches("int i = 42  *23;", binaryOperator(hasOperatorName("*"))));
1699   EXPECT_TRUE(
1700     matches("int i = 42; int j = (i *= 23);",
1701             binaryOperator(hasOperatorName("*="))));
1702   EXPECT_TRUE(
1703     matches("int i = 42 / 23;", binaryOperator(hasOperatorName("/"))));
1704   EXPECT_TRUE(
1705     matches("int i = 42; int j = (i /= 23);",
1706             binaryOperator(hasOperatorName("/="))));
1707   EXPECT_TRUE(
1708     matches("int i = 42 + 23;", binaryOperator(hasOperatorName("+"))));
1709   EXPECT_TRUE(
1710     matches("int i = 42; int j = (i += 23);",
1711             binaryOperator(hasOperatorName("+="))));
1712   EXPECT_TRUE(
1713     matches("int i = 42 - 23;", binaryOperator(hasOperatorName("-"))));
1714   EXPECT_TRUE(
1715     matches("int i = 42; int j = (i -= 23);",
1716             binaryOperator(hasOperatorName("-="))));
1717   EXPECT_TRUE(
1718     matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };",
1719             binaryOperator(hasOperatorName("->*"))));
1720   EXPECT_TRUE(
1721     matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };",
1722             binaryOperator(hasOperatorName(".*"))));
1723 
1724   // Member expressions as operators are not supported in matches.
1725   EXPECT_TRUE(
1726     notMatches("struct A { void x(A *a) { a->x(this); } };",
1727                binaryOperator(hasOperatorName("->"))));
1728 
1729   // Initializer assignments are not represented as operator equals.
1730   EXPECT_TRUE(
1731     notMatches("bool b = true;", binaryOperator(hasOperatorName("="))));
1732 
1733   // Array indexing is not represented as operator.
1734   EXPECT_TRUE(notMatches("int a[42]; void x() { a[23]; }", unaryOperator()));
1735 
1736   // Overloaded operators do not match at all.
1737   EXPECT_TRUE(notMatches(
1738     "struct A { bool operator&&(const A &a) const { return false; } };"
1739       "void x() { A a, b; a && b; }",
1740     binaryOperator()));
1741 }
1742 
TEST(MatchUnaryOperator,HasOperatorName)1743 TEST(MatchUnaryOperator, HasOperatorName) {
1744   StatementMatcher OperatorNot = unaryOperator(hasOperatorName("!"));
1745 
1746   EXPECT_TRUE(matches("void x() { !true; } ", OperatorNot));
1747   EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
1748 }
1749 
TEST(MatchUnaryOperator,HasAnyOperatorName)1750 TEST(MatchUnaryOperator, HasAnyOperatorName) {
1751   StatementMatcher Matcher = unaryOperator(hasAnyOperatorName("-", "*", "++"));
1752 
1753   EXPECT_TRUE(matches("int x(int *I) { return *I; }", Matcher));
1754   EXPECT_TRUE(matches("int x(int I) { return -I; }", Matcher));
1755   EXPECT_TRUE(matches("void x(int &I) { I++; }", Matcher));
1756   EXPECT_TRUE(matches("void x(int &I) { ++I; }", Matcher));
1757   EXPECT_TRUE(notMatches("void x(int &I) { I--; }", Matcher));
1758   EXPECT_TRUE(notMatches("void x(int &I) { --I; }", Matcher));
1759   EXPECT_TRUE(notMatches("int *x(int &I) { return &I; }", Matcher));
1760 }
1761 
TEST(MatchUnaryOperator,HasUnaryOperand)1762 TEST(MatchUnaryOperator, HasUnaryOperand) {
1763   StatementMatcher OperatorOnFalse =
1764     unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false))));
1765 
1766   EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse));
1767   EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse));
1768 
1769   StringRef Code = R"cpp(
1770 struct HasOpBangMem
1771 {
1772     bool operator!() const
1773     {
1774         return false;
1775     }
1776 };
1777 struct HasOpBangFree
1778 {
1779 };
1780 bool operator!(HasOpBangFree const&)
1781 {
1782     return false;
1783 }
1784 
1785 void opMem()
1786 {
1787     HasOpBangMem s1;
1788     if (!s1)
1789         return;
1790 }
1791 void opFree()
1792 {
1793     HasOpBangFree s1;
1794     if (!s1)
1795         return;
1796 }
1797 )cpp";
1798   auto s1Expr = declRefExpr(to(varDecl(hasName("s1"))));
1799   EXPECT_TRUE(matches(
1800       Code, traverse(TK_IgnoreUnlessSpelledInSource,
1801                      cxxOperatorCallExpr(
1802                          forFunction(functionDecl(hasName("opMem"))),
1803                          hasOperatorName("!"), hasUnaryOperand(s1Expr)))));
1804   EXPECT_TRUE(matches(
1805       Code,
1806       traverse(TK_IgnoreUnlessSpelledInSource,
1807                cxxOperatorCallExpr(forFunction(functionDecl(hasName("opMem"))),
1808                                    hasAnyOperatorName("+", "!"),
1809                                    hasUnaryOperand(s1Expr)))));
1810 
1811   EXPECT_TRUE(matches(
1812       Code, traverse(TK_IgnoreUnlessSpelledInSource,
1813                      cxxOperatorCallExpr(
1814                          forFunction(functionDecl(hasName("opFree"))),
1815                          hasOperatorName("!"), hasUnaryOperand(s1Expr)))));
1816   EXPECT_TRUE(matches(
1817       Code,
1818       traverse(TK_IgnoreUnlessSpelledInSource,
1819                cxxOperatorCallExpr(forFunction(functionDecl(hasName("opFree"))),
1820                                    hasAnyOperatorName("+", "!"),
1821                                    hasUnaryOperand(s1Expr)))));
1822 
1823   Code = R"cpp(
1824 struct HasIncOperatorsMem
1825 {
1826     HasIncOperatorsMem& operator++();
1827     HasIncOperatorsMem operator++(int);
1828 };
1829 struct HasIncOperatorsFree
1830 {
1831 };
1832 HasIncOperatorsFree& operator++(HasIncOperatorsFree&);
1833 HasIncOperatorsFree operator++(HasIncOperatorsFree&, int);
1834 
1835 void prefixIncOperatorMem()
1836 {
1837     HasIncOperatorsMem s1;
1838     ++s1;
1839 }
1840 void prefixIncOperatorFree()
1841 {
1842     HasIncOperatorsFree s1;
1843     ++s1;
1844 }
1845 void postfixIncOperatorMem()
1846 {
1847     HasIncOperatorsMem s1;
1848     s1++;
1849 }
1850 void postfixIncOperatorFree()
1851 {
1852     HasIncOperatorsFree s1;
1853     s1++;
1854 }
1855 
1856 struct HasOpPlusInt
1857 {
1858     HasOpPlusInt& operator+(int);
1859 };
1860 void plusIntOperator()
1861 {
1862     HasOpPlusInt s1;
1863     s1+1;
1864 }
1865 )cpp";
1866 
1867   EXPECT_TRUE(matches(
1868       Code,
1869       traverse(TK_IgnoreUnlessSpelledInSource,
1870                cxxOperatorCallExpr(
1871                    forFunction(functionDecl(hasName("prefixIncOperatorMem"))),
1872                    hasOperatorName("++"), hasUnaryOperand(declRefExpr())))));
1873 
1874   EXPECT_TRUE(matches(
1875       Code,
1876       traverse(TK_IgnoreUnlessSpelledInSource,
1877                cxxOperatorCallExpr(
1878                    forFunction(functionDecl(hasName("prefixIncOperatorFree"))),
1879                    hasOperatorName("++"), hasUnaryOperand(declRefExpr())))));
1880 
1881   EXPECT_TRUE(matches(
1882       Code,
1883       traverse(TK_IgnoreUnlessSpelledInSource,
1884                cxxOperatorCallExpr(
1885                    forFunction(functionDecl(hasName("postfixIncOperatorMem"))),
1886                    hasOperatorName("++"), hasUnaryOperand(declRefExpr())))));
1887 
1888   EXPECT_TRUE(matches(
1889       Code,
1890       traverse(TK_IgnoreUnlessSpelledInSource,
1891                cxxOperatorCallExpr(
1892                    forFunction(functionDecl(hasName("postfixIncOperatorFree"))),
1893                    hasOperatorName("++"), hasUnaryOperand(declRefExpr())))));
1894 
1895   EXPECT_FALSE(matches(
1896       Code, traverse(TK_IgnoreUnlessSpelledInSource,
1897                      cxxOperatorCallExpr(
1898                          forFunction(functionDecl(hasName("plusIntOperator"))),
1899                          hasOperatorName("+"), hasUnaryOperand(expr())))));
1900 
1901   Code = R"cpp(
1902 struct HasOpArrow
1903 {
1904     int& operator*();
1905 };
1906 void foo()
1907 {
1908     HasOpArrow s1;
1909     *s1;
1910 }
1911 )cpp";
1912 
1913   EXPECT_TRUE(
1914       matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
1915                              cxxOperatorCallExpr(hasOperatorName("*"),
1916                                                  hasUnaryOperand(expr())))));
1917 }
1918 
TEST(Matcher,UnaryOperatorTypes)1919 TEST(Matcher, UnaryOperatorTypes) {
1920   // Integration test that verifies the AST provides all unary operators in
1921   // a way we expect.
1922   EXPECT_TRUE(matches("bool b = !true;", unaryOperator(hasOperatorName("!"))));
1923   EXPECT_TRUE(
1924     matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&"))));
1925   EXPECT_TRUE(matches("int i = ~ 1;", unaryOperator(hasOperatorName("~"))));
1926   EXPECT_TRUE(
1927     matches("bool *p; bool b = *p;", unaryOperator(hasOperatorName("*"))));
1928   EXPECT_TRUE(
1929     matches("int i; int j = +i;", unaryOperator(hasOperatorName("+"))));
1930   EXPECT_TRUE(
1931     matches("int i; int j = -i;", unaryOperator(hasOperatorName("-"))));
1932   EXPECT_TRUE(
1933     matches("int i; int j = ++i;", unaryOperator(hasOperatorName("++"))));
1934   EXPECT_TRUE(
1935     matches("int i; int j = i++;", unaryOperator(hasOperatorName("++"))));
1936   EXPECT_TRUE(
1937     matches("int i; int j = --i;", unaryOperator(hasOperatorName("--"))));
1938   EXPECT_TRUE(
1939     matches("int i; int j = i--;", unaryOperator(hasOperatorName("--"))));
1940 
1941   // We don't match conversion operators.
1942   EXPECT_TRUE(notMatches("int i; double d = (double)i;", unaryOperator()));
1943 
1944   // Function calls are not represented as operator.
1945   EXPECT_TRUE(notMatches("void f(); void x() { f(); }", unaryOperator()));
1946 
1947   // Overloaded operators do not match at all.
1948   // FIXME: We probably want to add that.
1949   EXPECT_TRUE(notMatches(
1950     "struct A { bool operator!() const { return false; } };"
1951       "void x() { A a; !a; }", unaryOperator(hasOperatorName("!"))));
1952 }
1953 
TEST(ArraySubscriptMatchers,ArrayIndex)1954 TEST(ArraySubscriptMatchers, ArrayIndex) {
1955   EXPECT_TRUE(matches(
1956     "int i[2]; void f() { i[1] = 1; }",
1957     arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
1958   EXPECT_TRUE(matches(
1959     "int i[2]; void f() { 1[i] = 1; }",
1960     arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
1961   EXPECT_TRUE(notMatches(
1962     "int i[2]; void f() { i[1] = 1; }",
1963     arraySubscriptExpr(hasIndex(integerLiteral(equals(0))))));
1964 }
1965 
TEST(ArraySubscriptMatchers,MatchesArrayBase)1966 TEST(ArraySubscriptMatchers, MatchesArrayBase) {
1967   EXPECT_TRUE(
1968       matches("int i[2]; void f() { i[1] = 2; }",
1969               traverse(TK_AsIs, arraySubscriptExpr(hasBase(implicitCastExpr(
1970                                     hasSourceExpression(declRefExpr())))))));
1971 }
1972 
TEST(Matcher,OfClass)1973 TEST(Matcher, OfClass) {
1974   StatementMatcher Constructor = cxxConstructExpr(hasDeclaration(cxxMethodDecl(
1975     ofClass(hasName("X")))));
1976 
1977   EXPECT_TRUE(
1978     matches("class X { public: X(); }; void x(int) { X x; }", Constructor));
1979   EXPECT_TRUE(
1980     matches("class X { public: X(); }; void x(int) { X x = X(); }",
1981             Constructor));
1982   EXPECT_TRUE(
1983     notMatches("class Y { public: Y(); }; void x(int) { Y y; }",
1984                Constructor));
1985 }
1986 
TEST(Matcher,VisitsTemplateInstantiations)1987 TEST(Matcher, VisitsTemplateInstantiations) {
1988   EXPECT_TRUE(matches(
1989     "class A { public: void x(); };"
1990       "template <typename T> class B { public: void y() { T t; t.x(); } };"
1991       "void f() { B<A> b; b.y(); }",
1992     callExpr(callee(cxxMethodDecl(hasName("x"))))));
1993 
1994   EXPECT_TRUE(matches(
1995     "class A { public: void x(); };"
1996       "class C {"
1997       " public:"
1998       "  template <typename T> class B { public: void y() { T t; t.x(); } };"
1999       "};"
2000       "void f() {"
2001       "  C::B<A> b; b.y();"
2002       "}",
2003     recordDecl(hasName("C"), hasDescendant(callExpr(
2004       callee(cxxMethodDecl(hasName("x"))))))));
2005 }
2006 
TEST(Matcher,HasCondition)2007 TEST(Matcher, HasCondition) {
2008   StatementMatcher IfStmt =
2009     ifStmt(hasCondition(cxxBoolLiteral(equals(true))));
2010   EXPECT_TRUE(matches("void x() { if (true) {} }", IfStmt));
2011   EXPECT_TRUE(notMatches("void x() { if (false) {} }", IfStmt));
2012 
2013   StatementMatcher ForStmt =
2014     forStmt(hasCondition(cxxBoolLiteral(equals(true))));
2015   EXPECT_TRUE(matches("void x() { for (;true;) {} }", ForStmt));
2016   EXPECT_TRUE(notMatches("void x() { for (;false;) {} }", ForStmt));
2017 
2018   StatementMatcher WhileStmt =
2019     whileStmt(hasCondition(cxxBoolLiteral(equals(true))));
2020   EXPECT_TRUE(matches("void x() { while (true) {} }", WhileStmt));
2021   EXPECT_TRUE(notMatches("void x() { while (false) {} }", WhileStmt));
2022 
2023   StatementMatcher SwitchStmt =
2024     switchStmt(hasCondition(integerLiteral(equals(42))));
2025   EXPECT_TRUE(matches("void x() { switch (42) {case 42:;} }", SwitchStmt));
2026   EXPECT_TRUE(notMatches("void x() { switch (43) {case 43:;} }", SwitchStmt));
2027 }
2028 
TEST(For,ForLoopInternals)2029 TEST(For, ForLoopInternals) {
2030   EXPECT_TRUE(matches("void f(){ int i; for (; i < 3 ; ); }",
2031                       forStmt(hasCondition(anything()))));
2032   EXPECT_TRUE(matches("void f() { for (int i = 0; ;); }",
2033                       forStmt(hasLoopInit(anything()))));
2034 }
2035 
TEST(For,ForRangeLoopInternals)2036 TEST(For, ForRangeLoopInternals) {
2037   EXPECT_TRUE(matches("void f(){ int a[] {1, 2}; for (int i : a); }",
2038                       cxxForRangeStmt(hasLoopVariable(anything()))));
2039   EXPECT_TRUE(matches(
2040     "void f(){ int a[] {1, 2}; for (int i : a); }",
2041     cxxForRangeStmt(hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))))));
2042 }
2043 
TEST(For,NegativeForLoopInternals)2044 TEST(For, NegativeForLoopInternals) {
2045   EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }",
2046                          forStmt(hasCondition(expr()))));
2047   EXPECT_TRUE(notMatches("void f() {int i; for (; i < 4; ++i) {} }",
2048                          forStmt(hasLoopInit(anything()))));
2049 }
2050 
TEST(HasBody,FindsBodyOfForWhileDoLoops)2051 TEST(HasBody, FindsBodyOfForWhileDoLoops) {
2052   EXPECT_TRUE(matches("void f() { for(;;) {} }",
2053                       forStmt(hasBody(compoundStmt()))));
2054   EXPECT_TRUE(notMatches("void f() { for(;;); }",
2055                          forStmt(hasBody(compoundStmt()))));
2056   EXPECT_TRUE(matches("void f() { while(true) {} }",
2057                       whileStmt(hasBody(compoundStmt()))));
2058   EXPECT_TRUE(matches("void f() { do {} while(true); }",
2059                       doStmt(hasBody(compoundStmt()))));
2060   EXPECT_TRUE(matches("void f() { int p[2]; for (auto x : p) {} }",
2061                       cxxForRangeStmt(hasBody(compoundStmt()))));
2062 }
2063 
TEST(HasBody,FindsBodyOfFunctions)2064 TEST(HasBody, FindsBodyOfFunctions) {
2065   EXPECT_TRUE(matches("void f() {}", functionDecl(hasBody(compoundStmt()))));
2066   EXPECT_TRUE(notMatches("void f();", functionDecl(hasBody(compoundStmt()))));
2067   EXPECT_TRUE(matchAndVerifyResultTrue(
2068       "void f(); void f() {}",
2069       functionDecl(hasBody(compoundStmt())).bind("func"),
2070       std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("func", 1)));
2071   EXPECT_TRUE(matchAndVerifyResultTrue(
2072       "class C { void f(); }; void C::f() {}",
2073       cxxMethodDecl(hasBody(compoundStmt())).bind("met"),
2074       std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("met", 1)));
2075   EXPECT_TRUE(matchAndVerifyResultTrue(
2076       "class C { C(); }; C::C() {}",
2077       cxxConstructorDecl(hasBody(compoundStmt())).bind("ctr"),
2078       std::make_unique<VerifyIdIsBoundTo<CXXConstructorDecl>>("ctr", 1)));
2079   EXPECT_TRUE(matchAndVerifyResultTrue(
2080       "class C { ~C(); }; C::~C() {}",
2081       cxxDestructorDecl(hasBody(compoundStmt())).bind("dtr"),
2082       std::make_unique<VerifyIdIsBoundTo<CXXDestructorDecl>>("dtr", 1)));
2083 }
2084 
TEST(HasAnyBody,FindsAnyBodyOfFunctions)2085 TEST(HasAnyBody, FindsAnyBodyOfFunctions) {
2086   EXPECT_TRUE(matches("void f() {}", functionDecl(hasAnyBody(compoundStmt()))));
2087   EXPECT_TRUE(notMatches("void f();",
2088                          functionDecl(hasAnyBody(compoundStmt()))));
2089   EXPECT_TRUE(matchAndVerifyResultTrue(
2090       "void f(); void f() {}",
2091       functionDecl(hasAnyBody(compoundStmt())).bind("func"),
2092       std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("func", 2)));
2093   EXPECT_TRUE(matchAndVerifyResultTrue(
2094       "class C { void f(); }; void C::f() {}",
2095       cxxMethodDecl(hasAnyBody(compoundStmt())).bind("met"),
2096       std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("met", 2)));
2097   EXPECT_TRUE(matchAndVerifyResultTrue(
2098       "class C { C(); }; C::C() {}",
2099       cxxConstructorDecl(hasAnyBody(compoundStmt())).bind("ctr"),
2100       std::make_unique<VerifyIdIsBoundTo<CXXConstructorDecl>>("ctr", 2)));
2101   EXPECT_TRUE(matchAndVerifyResultTrue(
2102       "class C { ~C(); }; C::~C() {}",
2103       cxxDestructorDecl(hasAnyBody(compoundStmt())).bind("dtr"),
2104       std::make_unique<VerifyIdIsBoundTo<CXXDestructorDecl>>("dtr", 2)));
2105 }
2106 
TEST(HasAnySubstatement,MatchesForTopLevelCompoundStatement)2107 TEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
2108   // The simplest case: every compound statement is in a function
2109   // definition, and the function body itself must be a compound
2110   // statement.
2111   EXPECT_TRUE(matches("void f() { for (;;); }",
2112                       compoundStmt(hasAnySubstatement(forStmt()))));
2113 }
2114 
TEST(HasAnySubstatement,IsNotRecursive)2115 TEST(HasAnySubstatement, IsNotRecursive) {
2116   // It's really "has any immediate substatement".
2117   EXPECT_TRUE(notMatches("void f() { if (true) for (;;); }",
2118                          compoundStmt(hasAnySubstatement(forStmt()))));
2119 }
2120 
TEST(HasAnySubstatement,MatchesInNestedCompoundStatements)2121 TEST(HasAnySubstatement, MatchesInNestedCompoundStatements) {
2122   EXPECT_TRUE(matches("void f() { if (true) { for (;;); } }",
2123                       compoundStmt(hasAnySubstatement(forStmt()))));
2124 }
2125 
TEST(HasAnySubstatement,FindsSubstatementBetweenOthers)2126 TEST(HasAnySubstatement, FindsSubstatementBetweenOthers) {
2127   EXPECT_TRUE(matches("void f() { 1; 2; 3; for (;;); 4; 5; 6; }",
2128                       compoundStmt(hasAnySubstatement(forStmt()))));
2129 }
2130 
TEST(Member,MatchesMemberAllocationFunction)2131 TEST(Member, MatchesMemberAllocationFunction) {
2132   // Fails in C++11 mode
2133   EXPECT_TRUE(matchesConditionally(
2134       "namespace std { typedef typeof(sizeof(int)) size_t; }"
2135       "class X { void *operator new(std::size_t); };",
2136       cxxMethodDecl(ofClass(hasName("X"))), true, {"-std=gnu++03"}));
2137 
2138   EXPECT_TRUE(matches("class X { void operator delete(void*); };",
2139                       cxxMethodDecl(ofClass(hasName("X")))));
2140 
2141   // Fails in C++11 mode
2142   EXPECT_TRUE(matchesConditionally(
2143       "namespace std { typedef typeof(sizeof(int)) size_t; }"
2144       "class X { void operator delete[](void*, std::size_t); };",
2145       cxxMethodDecl(ofClass(hasName("X"))), true, {"-std=gnu++03"}));
2146 }
2147 
TEST(HasDestinationType,MatchesSimpleCase)2148 TEST(HasDestinationType, MatchesSimpleCase) {
2149   EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
2150                       cxxStaticCastExpr(hasDestinationType(
2151                         pointsTo(TypeMatcher(anything()))))));
2152 }
2153 
TEST(HasImplicitDestinationType,MatchesSimpleCase)2154 TEST(HasImplicitDestinationType, MatchesSimpleCase) {
2155   // This test creates an implicit const cast.
2156   EXPECT_TRUE(matches(
2157       "int x; const int i = x;",
2158       traverse(TK_AsIs,
2159                implicitCastExpr(hasImplicitDestinationType(isInteger())))));
2160   // This test creates an implicit array-to-pointer cast.
2161   EXPECT_TRUE(
2162       matches("int arr[3]; int *p = arr;",
2163               traverse(TK_AsIs, implicitCastExpr(hasImplicitDestinationType(
2164                                     pointsTo(TypeMatcher(anything())))))));
2165 }
2166 
TEST(HasImplicitDestinationType,DoesNotMatchIncorrectly)2167 TEST(HasImplicitDestinationType, DoesNotMatchIncorrectly) {
2168   // This test creates an implicit cast from int to char.
2169   EXPECT_TRUE(notMatches("char c = 0;",
2170                          implicitCastExpr(hasImplicitDestinationType(
2171                            unless(anything())))));
2172   // This test creates an implicit array-to-pointer cast.
2173   EXPECT_TRUE(notMatches("int arr[3]; int *p = arr;",
2174                          implicitCastExpr(hasImplicitDestinationType(
2175                            unless(anything())))));
2176 }
2177 
TEST(Matcher,IgnoresElidableConstructors)2178 TEST(Matcher, IgnoresElidableConstructors) {
2179   EXPECT_TRUE(
2180       matches("struct H {};"
2181               "template<typename T> H B(T A);"
2182               "void f() {"
2183               "  H D1;"
2184               "  D1 = B(B(1));"
2185               "}",
2186               cxxOperatorCallExpr(hasArgument(
2187                   1, callExpr(hasArgument(
2188                          0, ignoringElidableConstructorCall(callExpr()))))),
2189               langCxx11OrLater()));
2190   EXPECT_TRUE(
2191       matches("struct H {};"
2192               "template<typename T> H B(T A);"
2193               "void f() {"
2194               "  H D1;"
2195               "  D1 = B(1);"
2196               "}",
2197               cxxOperatorCallExpr(hasArgument(
2198                   1, callExpr(hasArgument(0, ignoringElidableConstructorCall(
2199                                                  integerLiteral()))))),
2200               langCxx11OrLater()));
2201   EXPECT_TRUE(matches(
2202       "struct H {};"
2203       "H G();"
2204       "void f() {"
2205       "  H D = G();"
2206       "}",
2207       varDecl(hasInitializer(anyOf(
2208           ignoringElidableConstructorCall(callExpr()),
2209           exprWithCleanups(has(ignoringElidableConstructorCall(callExpr())))))),
2210       langCxx11OrLater()));
2211 }
2212 
TEST(Matcher,IgnoresElidableInReturn)2213 TEST(Matcher, IgnoresElidableInReturn) {
2214   auto matcher = expr(ignoringElidableConstructorCall(declRefExpr()));
2215   EXPECT_TRUE(matches("struct H {};"
2216                       "H f() {"
2217                       "  H g;"
2218                       "  return g;"
2219                       "}",
2220                       matcher, langCxx11OrLater()));
2221   EXPECT_TRUE(notMatches("struct H {};"
2222                          "H f() {"
2223                          "  return H();"
2224                          "}",
2225                          matcher, langCxx11OrLater()));
2226 }
2227 
TEST(Matcher,IgnoreElidableConstructorDoesNotMatchConstructors)2228 TEST(Matcher, IgnoreElidableConstructorDoesNotMatchConstructors) {
2229   EXPECT_TRUE(matches("struct H {};"
2230                       "void f() {"
2231                       "  H D;"
2232                       "}",
2233                       varDecl(hasInitializer(
2234                           ignoringElidableConstructorCall(cxxConstructExpr()))),
2235                       langCxx11OrLater()));
2236 }
2237 
TEST(Matcher,IgnoresElidableDoesNotPreventMatches)2238 TEST(Matcher, IgnoresElidableDoesNotPreventMatches) {
2239   EXPECT_TRUE(matches("void f() {"
2240                       "  int D = 10;"
2241                       "}",
2242                       expr(ignoringElidableConstructorCall(integerLiteral())),
2243                       langCxx11OrLater()));
2244 }
2245 
TEST(Matcher,IgnoresElidableInVarInit)2246 TEST(Matcher, IgnoresElidableInVarInit) {
2247   auto matcher =
2248       varDecl(hasInitializer(ignoringElidableConstructorCall(callExpr())));
2249   EXPECT_TRUE(matches("struct H {};"
2250                       "H G();"
2251                       "void f(H D = G()) {"
2252                       "  return;"
2253                       "}",
2254                       matcher, langCxx11OrLater()));
2255   EXPECT_TRUE(matches("struct H {};"
2256                       "H G();"
2257                       "void f() {"
2258                       "  H D = G();"
2259                       "}",
2260                       matcher, langCxx11OrLater()));
2261 }
2262 
TEST(IgnoringImplicit,MatchesImplicit)2263 TEST(IgnoringImplicit, MatchesImplicit) {
2264   EXPECT_TRUE(matches("class C {}; C a = C();",
2265                       varDecl(has(ignoringImplicit(cxxConstructExpr())))));
2266 }
2267 
TEST(IgnoringImplicit,MatchesNestedImplicit)2268 TEST(IgnoringImplicit, MatchesNestedImplicit) {
2269   StringRef Code = R"(
2270 
2271 struct OtherType;
2272 
2273 struct SomeType
2274 {
2275     SomeType() {}
2276     SomeType(const OtherType&) {}
2277     SomeType& operator=(OtherType const&) { return *this; }
2278 };
2279 
2280 struct OtherType
2281 {
2282     OtherType() {}
2283     ~OtherType() {}
2284 };
2285 
2286 OtherType something()
2287 {
2288     return {};
2289 }
2290 
2291 int main()
2292 {
2293     SomeType i = something();
2294 }
2295 )";
2296   EXPECT_TRUE(matches(
2297       Code,
2298       traverse(TK_AsIs,
2299                varDecl(hasName("i"),
2300                        hasInitializer(exprWithCleanups(has(cxxConstructExpr(
2301                            has(expr(ignoringImplicit(cxxConstructExpr(has(
2302                                expr(ignoringImplicit(callExpr())))))))))))))));
2303 }
2304 
TEST(IgnoringImplicit,DoesNotMatchIncorrectly)2305 TEST(IgnoringImplicit, DoesNotMatchIncorrectly) {
2306   EXPECT_TRUE(notMatches("class C {}; C a = C();",
2307                          traverse(TK_AsIs, varDecl(has(cxxConstructExpr())))));
2308 }
2309 
TEST(Traversal,traverseMatcher)2310 TEST(Traversal, traverseMatcher) {
2311 
2312   StringRef VarDeclCode = R"cpp(
2313 void foo()
2314 {
2315   int i = 3.0;
2316 }
2317 )cpp";
2318 
2319   auto Matcher = varDecl(hasInitializer(floatLiteral()));
2320 
2321   EXPECT_TRUE(notMatches(VarDeclCode, traverse(TK_AsIs, Matcher)));
2322   EXPECT_TRUE(
2323       matches(VarDeclCode, traverse(TK_IgnoreUnlessSpelledInSource, Matcher)));
2324 
2325   auto ParentMatcher = floatLiteral(hasParent(varDecl(hasName("i"))));
2326 
2327   EXPECT_TRUE(notMatches(VarDeclCode, traverse(TK_AsIs, ParentMatcher)));
2328   EXPECT_TRUE(matches(VarDeclCode,
2329                       traverse(TK_IgnoreUnlessSpelledInSource, ParentMatcher)));
2330 
2331   EXPECT_TRUE(matches(
2332       VarDeclCode, decl(traverse(TK_AsIs, anyOf(cxxRecordDecl(), varDecl())))));
2333 
2334   EXPECT_TRUE(
2335       matches(VarDeclCode,
2336               floatLiteral(traverse(TK_AsIs, hasParent(implicitCastExpr())))));
2337 
2338   EXPECT_TRUE(
2339       matches(VarDeclCode, floatLiteral(traverse(TK_IgnoreUnlessSpelledInSource,
2340                                                  hasParent(varDecl())))));
2341 
2342   EXPECT_TRUE(
2343       matches(VarDeclCode, varDecl(traverse(TK_IgnoreUnlessSpelledInSource,
2344                                             unless(parmVarDecl())))));
2345 
2346   EXPECT_TRUE(
2347       notMatches(VarDeclCode, varDecl(traverse(TK_IgnoreUnlessSpelledInSource,
2348                                                has(implicitCastExpr())))));
2349 
2350   EXPECT_TRUE(matches(VarDeclCode,
2351                       varDecl(traverse(TK_AsIs, has(implicitCastExpr())))));
2352 
2353   EXPECT_TRUE(matches(
2354       VarDeclCode, traverse(TK_IgnoreUnlessSpelledInSource,
2355                             // The has() below strips away the ImplicitCastExpr
2356                             // before the traverse(AsIs) gets to process it.
2357                             varDecl(has(traverse(TK_AsIs, floatLiteral()))))));
2358 
2359   EXPECT_TRUE(
2360       matches(VarDeclCode, functionDecl(traverse(TK_AsIs, hasName("foo")))));
2361 
2362   EXPECT_TRUE(matches(
2363       VarDeclCode,
2364       functionDecl(traverse(TK_IgnoreUnlessSpelledInSource, hasName("foo")))));
2365 
2366   EXPECT_TRUE(matches(
2367       VarDeclCode, functionDecl(traverse(TK_AsIs, hasAnyName("foo", "bar")))));
2368 
2369   EXPECT_TRUE(
2370       matches(VarDeclCode, functionDecl(traverse(TK_IgnoreUnlessSpelledInSource,
2371                                                  hasAnyName("foo", "bar")))));
2372 
2373   StringRef Code = R"cpp(
2374 void foo(int a)
2375 {
2376   int i = 3.0 + a;
2377 }
2378 void bar()
2379 {
2380   foo(7.0);
2381 }
2382 )cpp";
2383   EXPECT_TRUE(
2384       matches(Code, callExpr(traverse(TK_IgnoreUnlessSpelledInSource,
2385                                       hasArgument(0, floatLiteral())))));
2386 
2387   EXPECT_TRUE(
2388       matches(Code, callExpr(traverse(TK_IgnoreUnlessSpelledInSource,
2389                                       hasAnyArgument(floatLiteral())))));
2390 
2391   EXPECT_TRUE(matches(
2392       R"cpp(
2393 void takesBool(bool){}
2394 
2395 template <typename T>
2396 void neverInstantiatedTemplate() {
2397   takesBool(T{});
2398 }
2399 )cpp",
2400       traverse(TK_IgnoreUnlessSpelledInSource,
2401                callExpr(unless(callExpr(hasDeclaration(functionDecl())))))));
2402 
2403   EXPECT_TRUE(
2404       matches(VarDeclCode, varDecl(traverse(TK_IgnoreUnlessSpelledInSource,
2405                                             hasType(builtinType())))));
2406 
2407   EXPECT_TRUE(
2408       matches(VarDeclCode,
2409               functionDecl(hasName("foo"),
2410                            traverse(TK_AsIs, hasDescendant(floatLiteral())))));
2411 
2412   EXPECT_TRUE(notMatches(
2413       Code, traverse(TK_AsIs, floatLiteral(hasParent(callExpr(
2414                                   callee(functionDecl(hasName("foo")))))))));
2415   EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
2416                                      floatLiteral(hasParent(callExpr(callee(
2417                                          functionDecl(hasName("foo")))))))));
2418 
2419   Code = R"cpp(
2420 void foo()
2421 {
2422   int i = (3);
2423 }
2424 )cpp";
2425   EXPECT_TRUE(matches(
2426       Code, traverse(TK_IgnoreUnlessSpelledInSource,
2427                      varDecl(hasInitializer(integerLiteral(equals(3)))))));
2428   EXPECT_TRUE(matches(
2429       Code,
2430       traverse(TK_IgnoreUnlessSpelledInSource,
2431                integerLiteral(equals(3), hasParent(varDecl(hasName("i")))))));
2432 
2433   Code = R"cpp(
2434 const char *SomeString{"str"};
2435 )cpp";
2436   EXPECT_TRUE(
2437       matches(Code, traverse(TK_AsIs, stringLiteral(hasParent(implicitCastExpr(
2438                                           hasParent(initListExpr())))))));
2439   EXPECT_TRUE(
2440       matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
2441                              stringLiteral(hasParent(initListExpr())))));
2442 
2443   Code = R"cpp(
2444 struct String
2445 {
2446     String(const char*, int = -1) {}
2447 };
2448 
2449 void stringConstruct()
2450 {
2451     String s = "foo";
2452     s = "bar";
2453 }
2454 )cpp";
2455   EXPECT_TRUE(matches(
2456       Code,
2457       traverse(
2458           TK_AsIs,
2459           functionDecl(
2460               hasName("stringConstruct"),
2461               hasDescendant(varDecl(
2462                   hasName("s"),
2463                   hasInitializer(ignoringImplicit(cxxConstructExpr(hasArgument(
2464                       0, ignoringImplicit(cxxConstructExpr(hasArgument(
2465                              0, ignoringImplicit(stringLiteral()))))))))))))));
2466 
2467   EXPECT_TRUE(matches(
2468       Code,
2469       traverse(
2470           TK_AsIs,
2471           functionDecl(hasName("stringConstruct"),
2472                        hasDescendant(cxxOperatorCallExpr(
2473                            isAssignmentOperator(),
2474                            hasArgument(1, ignoringImplicit(
2475                             cxxConstructExpr(hasArgument(
2476                                0, ignoringImplicit(stringLiteral())))))
2477                            ))))));
2478 
2479   EXPECT_TRUE(matches(
2480       Code, traverse(TK_IgnoreUnlessSpelledInSource,
2481                      functionDecl(hasName("stringConstruct"),
2482                                   hasDescendant(varDecl(
2483                                       hasName("s"),
2484                                       hasInitializer(stringLiteral())))))));
2485 
2486   EXPECT_TRUE(
2487       matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
2488                              functionDecl(hasName("stringConstruct"),
2489                                           hasDescendant(cxxOperatorCallExpr(
2490                                               isAssignmentOperator(),
2491                                               hasArgument(1, stringLiteral())))))));
2492 
2493   Code = R"cpp(
2494 
2495 struct C1 {};
2496 struct C2 { operator C1(); };
2497 
2498 void conversionOperator()
2499 {
2500     C2* c2;
2501     C1 c1 = (*c2);
2502 }
2503 
2504 )cpp";
2505   EXPECT_TRUE(matches(
2506       Code,
2507       traverse(
2508           TK_AsIs,
2509           functionDecl(
2510               hasName("conversionOperator"),
2511               hasDescendant(
2512                   varDecl(
2513                       hasName("c1"),
2514                       hasInitializer(
2515                           ignoringImplicit(cxxConstructExpr(hasArgument(
2516                               0, ignoringImplicit(
2517                                      cxxMemberCallExpr(onImplicitObjectArgument(
2518                                          ignoringParenImpCasts(unaryOperator(
2519                                              hasOperatorName("*")))))))))))
2520                       .bind("c1"))))));
2521 
2522   EXPECT_TRUE(matches(
2523       Code,
2524       traverse(TK_IgnoreUnlessSpelledInSource,
2525                functionDecl(hasName("conversionOperator"),
2526                             hasDescendant(varDecl(
2527                                 hasName("c1"), hasInitializer(unaryOperator(
2528                                                    hasOperatorName("*")))))))));
2529 
2530   Code = R"cpp(
2531 
2532 template <unsigned alignment>
2533 void template_test() {
2534   static_assert(alignment, "");
2535 }
2536 void actual_template_test() {
2537   template_test<4>();
2538 }
2539 
2540 )cpp";
2541   EXPECT_TRUE(matches(
2542       Code,
2543       traverse(TK_AsIs,
2544                staticAssertDecl(has(implicitCastExpr(has(
2545                    substNonTypeTemplateParmExpr(has(integerLiteral())))))))));
2546   EXPECT_TRUE(matches(
2547       Code, traverse(TK_IgnoreUnlessSpelledInSource,
2548                      staticAssertDecl(has(declRefExpr(
2549                          to(nonTypeTemplateParmDecl(hasName("alignment"))),
2550                          hasType(asString("unsigned int"))))))));
2551 
2552   EXPECT_TRUE(matches(Code, traverse(TK_AsIs, staticAssertDecl(hasDescendant(
2553                                                   integerLiteral())))));
2554   EXPECT_FALSE(matches(
2555       Code, traverse(TK_IgnoreUnlessSpelledInSource,
2556                      staticAssertDecl(hasDescendant(integerLiteral())))));
2557 
2558   Code = R"cpp(
2559 
2560 struct OneParamCtor {
2561   explicit OneParamCtor(int);
2562 };
2563 struct TwoParamCtor {
2564   explicit TwoParamCtor(int, int);
2565 };
2566 
2567 void varDeclCtors() {
2568   {
2569   auto var1 = OneParamCtor(5);
2570   auto var2 = TwoParamCtor(6, 7);
2571   }
2572   {
2573   OneParamCtor var3(5);
2574   TwoParamCtor var4(6, 7);
2575   }
2576   int i = 0;
2577   {
2578   auto var5 = OneParamCtor(i);
2579   auto var6 = TwoParamCtor(i, 7);
2580   }
2581   {
2582   OneParamCtor var7(i);
2583   TwoParamCtor var8(i, 7);
2584   }
2585 }
2586 
2587 )cpp";
2588   EXPECT_TRUE(matches(
2589       Code,
2590       traverse(TK_AsIs, varDecl(hasName("var1"), hasInitializer(hasDescendant(
2591                                                      cxxConstructExpr()))))));
2592   EXPECT_TRUE(matches(
2593       Code,
2594       traverse(TK_AsIs, varDecl(hasName("var2"), hasInitializer(hasDescendant(
2595                                                      cxxConstructExpr()))))));
2596   EXPECT_TRUE(matches(
2597       Code, traverse(TK_AsIs, varDecl(hasName("var3"),
2598                                       hasInitializer(cxxConstructExpr())))));
2599   EXPECT_TRUE(matches(
2600       Code, traverse(TK_AsIs, varDecl(hasName("var4"),
2601                                       hasInitializer(cxxConstructExpr())))));
2602   EXPECT_TRUE(matches(
2603       Code,
2604       traverse(TK_AsIs, varDecl(hasName("var5"), hasInitializer(hasDescendant(
2605                                                      cxxConstructExpr()))))));
2606   EXPECT_TRUE(matches(
2607       Code,
2608       traverse(TK_AsIs, varDecl(hasName("var6"), hasInitializer(hasDescendant(
2609                                                      cxxConstructExpr()))))));
2610   EXPECT_TRUE(matches(
2611       Code, traverse(TK_AsIs, varDecl(hasName("var7"),
2612                                       hasInitializer(cxxConstructExpr())))));
2613   EXPECT_TRUE(matches(
2614       Code, traverse(TK_AsIs, varDecl(hasName("var8"),
2615                                       hasInitializer(cxxConstructExpr())))));
2616 
2617   EXPECT_TRUE(matches(
2618       Code,
2619       traverse(TK_IgnoreUnlessSpelledInSource,
2620                varDecl(hasName("var1"), hasInitializer(cxxConstructExpr())))));
2621   EXPECT_TRUE(matches(
2622       Code,
2623       traverse(TK_IgnoreUnlessSpelledInSource,
2624                varDecl(hasName("var2"), hasInitializer(cxxConstructExpr())))));
2625   EXPECT_TRUE(matches(
2626       Code,
2627       traverse(TK_IgnoreUnlessSpelledInSource,
2628                varDecl(hasName("var3"), hasInitializer(cxxConstructExpr())))));
2629   EXPECT_TRUE(matches(
2630       Code,
2631       traverse(TK_IgnoreUnlessSpelledInSource,
2632                varDecl(hasName("var4"), hasInitializer(cxxConstructExpr())))));
2633   EXPECT_TRUE(matches(
2634       Code,
2635       traverse(TK_IgnoreUnlessSpelledInSource,
2636                varDecl(hasName("var5"), hasInitializer(cxxConstructExpr())))));
2637   EXPECT_TRUE(matches(
2638       Code,
2639       traverse(TK_IgnoreUnlessSpelledInSource,
2640                varDecl(hasName("var6"), hasInitializer(cxxConstructExpr())))));
2641   EXPECT_TRUE(matches(
2642       Code,
2643       traverse(TK_IgnoreUnlessSpelledInSource,
2644                varDecl(hasName("var7"), hasInitializer(cxxConstructExpr())))));
2645   EXPECT_TRUE(matches(
2646       Code,
2647       traverse(TK_IgnoreUnlessSpelledInSource,
2648                varDecl(hasName("var8"), hasInitializer(cxxConstructExpr())))));
2649 
2650   Code = R"cpp(
2651 
2652 template<typename T>
2653 struct TemplStruct {
2654   TemplStruct() {}
2655   ~TemplStruct() {}
2656 
2657   void outOfLine(T);
2658 
2659 private:
2660   T m_t;
2661 };
2662 
2663 template<typename T>
2664 void TemplStruct<T>::outOfLine(T)
2665 {
2666 
2667 }
2668 
2669 template<typename T>
2670 T timesTwo(T input)
2671 {
2672   return input * 2;
2673 }
2674 
2675 void instantiate()
2676 {
2677   TemplStruct<int> ti;
2678   TemplStruct<double> td;
2679   (void)timesTwo<int>(2);
2680   (void)timesTwo<double>(2);
2681 }
2682 
2683 template class TemplStruct<float>;
2684 
2685 extern template class TemplStruct<long>;
2686 
2687 template<> class TemplStruct<bool> {
2688   TemplStruct() {}
2689   ~TemplStruct() {}
2690 
2691   void boolSpecializationMethodOnly() {}
2692 private:
2693   bool m_t;
2694 };
2695 
2696 template float timesTwo(float);
2697 template<> bool timesTwo<bool>(bool){
2698   return true;
2699 }
2700 )cpp";
2701   {
2702     auto M = cxxRecordDecl(hasName("TemplStruct"),
2703                            has(fieldDecl(hasType(asString("int")))));
2704     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2705     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2706   }
2707   {
2708     auto M = cxxRecordDecl(hasName("TemplStruct"),
2709                            has(fieldDecl(hasType(asString("double")))));
2710     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2711     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2712   }
2713   {
2714     auto M =
2715         functionDecl(hasName("timesTwo"),
2716                      hasParameter(0, parmVarDecl(hasType(asString("int")))));
2717     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2718     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2719   }
2720   {
2721     auto M =
2722         functionDecl(hasName("timesTwo"),
2723                      hasParameter(0, parmVarDecl(hasType(asString("double")))));
2724     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2725     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2726   }
2727   {
2728     // Match on the integer literal in the explicit instantiation:
2729     auto MDef =
2730         functionDecl(hasName("timesTwo"),
2731                      hasParameter(0, parmVarDecl(hasType(asString("float")))),
2732                      hasDescendant(integerLiteral(equals(2))));
2733     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MDef)));
2734     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MDef)));
2735 
2736     auto MTempl =
2737         functionDecl(hasName("timesTwo"),
2738                      hasTemplateArgument(0, refersToType(asString("float"))));
2739     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MTempl)));
2740     // TODO: If we could match on explicit instantiations of function templates,
2741     // this would be EXPECT_TRUE. See Sema::ActOnExplicitInstantiation.
2742     EXPECT_FALSE(
2743         matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MTempl)));
2744   }
2745   {
2746     auto M = functionDecl(hasName("timesTwo"),
2747                           hasParameter(0, parmVarDecl(hasType(booleanType()))));
2748     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2749     EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2750   }
2751   {
2752     // Match on the field within the explicit instantiation:
2753     auto MRecord = cxxRecordDecl(hasName("TemplStruct"),
2754                                  has(fieldDecl(hasType(asString("float")))));
2755     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MRecord)));
2756     EXPECT_FALSE(
2757         matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MRecord)));
2758 
2759     // Match on the explicit template instantiation itself:
2760     auto MTempl = classTemplateSpecializationDecl(
2761         hasName("TemplStruct"),
2762         hasTemplateArgument(0,
2763                             templateArgument(refersToType(asString("float")))));
2764     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MTempl)));
2765     EXPECT_TRUE(
2766         matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MTempl)));
2767   }
2768   {
2769     // The template argument is matchable, but the instantiation is not:
2770     auto M = classTemplateSpecializationDecl(
2771         hasName("TemplStruct"),
2772         hasTemplateArgument(0,
2773                             templateArgument(refersToType(asString("float")))),
2774         has(cxxConstructorDecl(hasName("TemplStruct"))));
2775     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2776     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2777   }
2778   {
2779     // The template argument is matchable, but the instantiation is not:
2780     auto M = classTemplateSpecializationDecl(
2781         hasName("TemplStruct"),
2782         hasTemplateArgument(0,
2783                             templateArgument(refersToType(asString("long")))),
2784         has(cxxConstructorDecl(hasName("TemplStruct"))));
2785     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2786     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2787   }
2788   {
2789     // Instantiated, out-of-line methods are not matchable.
2790     auto M =
2791         cxxMethodDecl(hasName("outOfLine"), isDefinition(),
2792                       hasParameter(0, parmVarDecl(hasType(asString("float")))));
2793     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2794     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2795   }
2796   {
2797     // Explicit specialization is written in source and it matches:
2798     auto M = classTemplateSpecializationDecl(
2799         hasName("TemplStruct"),
2800         hasTemplateArgument(0, templateArgument(refersToType(booleanType()))),
2801         has(cxxConstructorDecl(hasName("TemplStruct"))),
2802         has(cxxMethodDecl(hasName("boolSpecializationMethodOnly"))));
2803     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2804     EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2805   }
2806 
2807   Code = R"cpp(
2808 struct B {
2809   B(int);
2810 };
2811 
2812 B func1() { return 42; }
2813   )cpp";
2814   {
2815     auto M = expr(ignoringImplicit(integerLiteral(equals(42)).bind("intLit")));
2816     EXPECT_TRUE(matchAndVerifyResultTrue(
2817         Code, traverse(TK_AsIs, M),
2818         std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2819     EXPECT_TRUE(matchAndVerifyResultTrue(
2820         Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2821         std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2822   }
2823   {
2824     auto M = expr(unless(integerLiteral(equals(24)))).bind("intLit");
2825     EXPECT_TRUE(matchAndVerifyResultTrue(
2826         Code, traverse(TK_AsIs, M),
2827         std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 6)));
2828     EXPECT_TRUE(matchAndVerifyResultTrue(
2829         Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2830         std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2831   }
2832   {
2833     auto M =
2834         expr(anyOf(integerLiteral(equals(42)).bind("intLit"), unless(expr())));
2835     EXPECT_TRUE(matchAndVerifyResultTrue(
2836         Code, traverse(TK_AsIs, M),
2837         std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2838     EXPECT_TRUE(matchAndVerifyResultTrue(
2839         Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2840         std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2841   }
2842   {
2843     auto M = expr(allOf(integerLiteral(equals(42)).bind("intLit"), expr()));
2844     EXPECT_TRUE(matchAndVerifyResultTrue(
2845         Code, traverse(TK_AsIs, M),
2846         std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2847     EXPECT_TRUE(matchAndVerifyResultTrue(
2848         Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2849         std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2850   }
2851   {
2852     auto M = expr(integerLiteral(equals(42)).bind("intLit"), expr());
2853     EXPECT_TRUE(matchAndVerifyResultTrue(
2854         Code, traverse(TK_AsIs, M),
2855         std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2856     EXPECT_TRUE(matchAndVerifyResultTrue(
2857         Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2858         std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2859   }
2860   {
2861     auto M = expr(optionally(integerLiteral(equals(42)).bind("intLit")));
2862     EXPECT_TRUE(matchAndVerifyResultTrue(
2863         Code, traverse(TK_AsIs, M),
2864         std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2865     EXPECT_TRUE(matchAndVerifyResultTrue(
2866         Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2867         std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2868   }
2869   {
2870     auto M = expr().bind("allExprs");
2871     EXPECT_TRUE(matchAndVerifyResultTrue(
2872         Code, traverse(TK_AsIs, M),
2873         std::make_unique<VerifyIdIsBoundTo<Expr>>("allExprs", 6)));
2874     EXPECT_TRUE(matchAndVerifyResultTrue(
2875         Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2876         std::make_unique<VerifyIdIsBoundTo<Expr>>("allExprs", 1)));
2877   }
2878 
2879   Code = R"cpp(
2880 void foo()
2881 {
2882     int arr[3];
2883     auto &[f, s, t] = arr;
2884 
2885     f = 42;
2886 }
2887   )cpp";
2888   {
2889     auto M = bindingDecl(hasName("f"));
2890     EXPECT_TRUE(
2891         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++17"}));
2892     EXPECT_TRUE(
2893         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2894                              true, {"-std=c++17"}));
2895   }
2896   {
2897     auto M = bindingDecl(hasName("f"), has(expr()));
2898     EXPECT_TRUE(
2899         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++17"}));
2900     EXPECT_FALSE(
2901         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2902                              true, {"-std=c++17"}));
2903   }
2904   {
2905     auto M = integerLiteral(hasAncestor(bindingDecl(hasName("f"))));
2906     EXPECT_TRUE(
2907         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++17"}));
2908     EXPECT_FALSE(
2909         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2910                              true, {"-std=c++17"}));
2911   }
2912   {
2913     auto M = declRefExpr(hasAncestor(bindingDecl(hasName("f"))));
2914     EXPECT_TRUE(
2915         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++17"}));
2916     EXPECT_FALSE(
2917         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2918                              true, {"-std=c++17"}));
2919   }
2920 }
2921 
TEST(Traversal,traverseNoImplicit)2922 TEST(Traversal, traverseNoImplicit) {
2923   StringRef Code = R"cpp(
2924 struct NonTrivial {
2925     NonTrivial() {}
2926     NonTrivial(const NonTrivial&) {}
2927     NonTrivial& operator=(const NonTrivial&) { return *this; }
2928 
2929     ~NonTrivial() {}
2930 };
2931 
2932 struct NoSpecialMethods {
2933     NonTrivial nt;
2934 };
2935 
2936 struct ContainsArray {
2937     NonTrivial arr[2];
2938     ContainsArray& operator=(const ContainsArray &other) = default;
2939 };
2940 
2941 void copyIt()
2942 {
2943     NoSpecialMethods nc1;
2944     NoSpecialMethods nc2(nc1);
2945     nc2 = nc1;
2946 
2947     ContainsArray ca;
2948     ContainsArray ca2;
2949     ca2 = ca;
2950 }
2951 
2952 struct HasCtorInits : NoSpecialMethods, NonTrivial
2953 {
2954   int m_i;
2955   NonTrivial m_nt;
2956   HasCtorInits() : NoSpecialMethods(), m_i(42) {}
2957 };
2958 
2959 struct CtorInitsNonTrivial : NonTrivial
2960 {
2961   int m_i;
2962   NonTrivial m_nt;
2963   CtorInitsNonTrivial() : NonTrivial(), m_i(42) {}
2964 };
2965 
2966 )cpp";
2967   {
2968     auto M = cxxRecordDecl(hasName("NoSpecialMethods"),
2969                            has(cxxRecordDecl(hasName("NoSpecialMethods"))));
2970     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2971     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2972 
2973     M = cxxRecordDecl(hasName("NoSpecialMethods"),
2974                       has(cxxConstructorDecl(isCopyConstructor())));
2975     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2976     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2977 
2978     M = cxxRecordDecl(hasName("NoSpecialMethods"),
2979                       has(cxxMethodDecl(isCopyAssignmentOperator())));
2980     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2981     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2982 
2983     M = cxxRecordDecl(hasName("NoSpecialMethods"),
2984                       has(cxxConstructorDecl(isDefaultConstructor())));
2985     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2986     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2987 
2988     M = cxxRecordDecl(hasName("NoSpecialMethods"), has(cxxDestructorDecl()));
2989     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2990     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2991 
2992     M = cxxRecordDecl(hasName("NoSpecialMethods"),
2993                       hasMethod(cxxConstructorDecl(isCopyConstructor())));
2994     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2995     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2996 
2997     M = cxxRecordDecl(hasName("NoSpecialMethods"),
2998                       hasMethod(cxxMethodDecl(isCopyAssignmentOperator())));
2999     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3000     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3001 
3002     M = cxxRecordDecl(hasName("NoSpecialMethods"),
3003                       hasMethod(cxxConstructorDecl(isDefaultConstructor())));
3004     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3005     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3006 
3007     M = cxxRecordDecl(hasName("NoSpecialMethods"),
3008                       hasMethod(cxxDestructorDecl()));
3009     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3010     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3011   }
3012   {
3013     // Because the copy-assignment operator is not spelled in the
3014     // source (ie, isImplicit()), we don't match it
3015     auto M =
3016         cxxOperatorCallExpr(hasType(cxxRecordDecl(hasName("NoSpecialMethods"))),
3017                             callee(cxxMethodDecl(isCopyAssignmentOperator())));
3018     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3019     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3020   }
3021   {
3022     // Compiler generates a forStmt to copy the array
3023     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, forStmt())));
3024     EXPECT_FALSE(
3025         matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, forStmt())));
3026   }
3027   {
3028     // The defaulted method declaration can be matched, but not its
3029     // definition, in IgnoreUnlessSpelledInSource mode
3030     auto MDecl = cxxMethodDecl(ofClass(cxxRecordDecl(hasName("ContainsArray"))),
3031                                isCopyAssignmentOperator(), isDefaulted());
3032 
3033     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MDecl)));
3034     EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MDecl)));
3035 
3036     auto MDef = cxxMethodDecl(MDecl, has(compoundStmt()));
3037 
3038     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MDef)));
3039     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MDef)));
3040 
3041     auto MBody = cxxMethodDecl(MDecl, hasBody(compoundStmt()));
3042 
3043     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MBody)));
3044     EXPECT_FALSE(
3045         matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MBody)));
3046 
3047     auto MIsDefn = cxxMethodDecl(MDecl, isDefinition());
3048 
3049     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MIsDefn)));
3050     EXPECT_TRUE(
3051         matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MIsDefn)));
3052 
3053     auto MIsInline = cxxMethodDecl(MDecl, isInline());
3054 
3055     EXPECT_FALSE(matches(Code, traverse(TK_AsIs, MIsInline)));
3056     EXPECT_FALSE(
3057         matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MIsInline)));
3058 
3059     // The parameter of the defaulted method can still be matched.
3060     auto MParm =
3061         cxxMethodDecl(MDecl, hasParameter(0, parmVarDecl(hasName("other"))));
3062 
3063     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MParm)));
3064     EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MParm)));
3065   }
3066   {
3067     auto M =
3068         cxxConstructorDecl(hasName("HasCtorInits"),
3069                            has(cxxCtorInitializer(forField(hasName("m_i")))));
3070     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3071     EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3072   }
3073   {
3074     auto M =
3075         cxxConstructorDecl(hasName("HasCtorInits"),
3076                            has(cxxCtorInitializer(forField(hasName("m_nt")))));
3077     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3078     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3079   }
3080   {
3081     auto M = cxxConstructorDecl(hasName("HasCtorInits"),
3082                                 hasAnyConstructorInitializer(cxxCtorInitializer(
3083                                     forField(hasName("m_nt")))));
3084     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3085     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3086   }
3087   {
3088     auto M =
3089         cxxConstructorDecl(hasName("HasCtorInits"),
3090                            forEachConstructorInitializer(
3091                                cxxCtorInitializer(forField(hasName("m_nt")))));
3092     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3093     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3094   }
3095   {
3096     auto M = cxxConstructorDecl(
3097         hasName("CtorInitsNonTrivial"),
3098         has(cxxCtorInitializer(withInitializer(cxxConstructExpr(
3099             hasDeclaration(cxxConstructorDecl(hasName("NonTrivial"))))))));
3100     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3101     EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3102   }
3103   {
3104     auto M = cxxConstructorDecl(
3105         hasName("HasCtorInits"),
3106         has(cxxCtorInitializer(withInitializer(cxxConstructExpr(hasDeclaration(
3107             cxxConstructorDecl(hasName("NoSpecialMethods"))))))));
3108     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3109     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3110   }
3111   {
3112     auto M = cxxCtorInitializer(forField(hasName("m_nt")));
3113     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3114     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3115   }
3116 
3117   Code = R"cpp(
3118   void rangeFor()
3119   {
3120     int arr[2];
3121     for (auto i : arr)
3122     {
3123       if (true)
3124       {
3125       }
3126     }
3127   }
3128   )cpp";
3129   {
3130     auto M = cxxForRangeStmt(has(binaryOperator(hasOperatorName("!="))));
3131     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3132     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3133   }
3134   {
3135     auto M =
3136         cxxForRangeStmt(hasDescendant(binaryOperator(hasOperatorName("+"))));
3137     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3138     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3139   }
3140   {
3141     auto M =
3142         cxxForRangeStmt(hasDescendant(unaryOperator(hasOperatorName("++"))));
3143     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3144     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3145   }
3146   {
3147     auto M = cxxForRangeStmt(has(declStmt()));
3148     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3149     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3150   }
3151   {
3152     auto M =
3153         cxxForRangeStmt(hasLoopVariable(varDecl(hasName("i"))),
3154                         hasRangeInit(declRefExpr(to(varDecl(hasName("arr"))))));
3155     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3156     EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3157   }
3158   {
3159     auto M = cxxForRangeStmt(unless(hasInitStatement(stmt())));
3160     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3161     EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3162   }
3163   {
3164     auto M = cxxForRangeStmt(hasBody(stmt()));
3165     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3166     EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3167   }
3168   {
3169     auto M = cxxForRangeStmt(hasDescendant(ifStmt()));
3170     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3171     EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3172   }
3173   {
3174     EXPECT_TRUE(matches(
3175         Code, traverse(TK_AsIs, cxxForRangeStmt(has(declStmt(
3176                                     hasSingleDecl(varDecl(hasName("i")))))))));
3177     EXPECT_TRUE(
3178         matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
3179                                cxxForRangeStmt(has(varDecl(hasName("i")))))));
3180   }
3181   {
3182     EXPECT_TRUE(matches(
3183         Code, traverse(TK_AsIs, cxxForRangeStmt(has(declStmt(hasSingleDecl(
3184                                     varDecl(hasInitializer(declRefExpr(
3185                                         to(varDecl(hasName("arr")))))))))))));
3186     EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
3187                                        cxxForRangeStmt(has(declRefExpr(
3188                                            to(varDecl(hasName("arr")))))))));
3189   }
3190   {
3191     auto M = cxxForRangeStmt(has(compoundStmt()));
3192     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3193     EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3194   }
3195   {
3196     auto M = binaryOperator(hasOperatorName("!="));
3197     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3198     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3199   }
3200   {
3201     auto M = unaryOperator(hasOperatorName("++"));
3202     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3203     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3204   }
3205   {
3206     auto M = declStmt(hasSingleDecl(varDecl(matchesName("__range"))));
3207     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3208     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3209   }
3210   {
3211     auto M = declStmt(hasSingleDecl(varDecl(matchesName("__begin"))));
3212     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3213     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3214   }
3215   {
3216     auto M = declStmt(hasSingleDecl(varDecl(matchesName("__end"))));
3217     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3218     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3219   }
3220   {
3221     auto M = ifStmt(hasParent(compoundStmt(hasParent(cxxForRangeStmt()))));
3222     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3223     EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3224   }
3225   {
3226     auto M = cxxForRangeStmt(
3227         has(varDecl(hasName("i"), hasParent(cxxForRangeStmt()))));
3228     EXPECT_FALSE(matches(Code, traverse(TK_AsIs, M)));
3229     EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3230   }
3231   {
3232     auto M = cxxForRangeStmt(hasDescendant(varDecl(
3233         hasName("i"), hasParent(declStmt(hasParent(cxxForRangeStmt()))))));
3234     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3235     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3236   }
3237   {
3238     auto M = cxxForRangeStmt(hasRangeInit(declRefExpr(
3239         to(varDecl(hasName("arr"))), hasParent(cxxForRangeStmt()))));
3240     EXPECT_FALSE(matches(Code, traverse(TK_AsIs, M)));
3241     EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3242   }
3243 
3244   {
3245     auto M = cxxForRangeStmt(hasRangeInit(declRefExpr(
3246         to(varDecl(hasName("arr"))), hasParent(varDecl(hasParent(declStmt(
3247                                          hasParent(cxxForRangeStmt()))))))));
3248     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3249     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3250   }
3251 
3252   Code = R"cpp(
3253   struct Range {
3254     int* begin() const;
3255     int* end() const;
3256   };
3257   Range getRange(int);
3258 
3259   void rangeFor()
3260   {
3261     for (auto i : getRange(42))
3262     {
3263     }
3264   }
3265   )cpp";
3266   {
3267     auto M = integerLiteral(equals(42));
3268     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3269     EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3270   }
3271   {
3272     auto M = callExpr(hasDescendant(integerLiteral(equals(42))));
3273     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3274     EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3275   }
3276   {
3277     auto M = compoundStmt(hasDescendant(integerLiteral(equals(42))));
3278     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3279     EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3280   }
3281 
3282   Code = R"cpp(
3283   void rangeFor()
3284   {
3285     int arr[2];
3286     for (auto& a = arr; auto i : a)
3287     {
3288 
3289     }
3290   }
3291   )cpp";
3292   {
3293     auto M = cxxForRangeStmt(has(binaryOperator(hasOperatorName("!="))));
3294     EXPECT_TRUE(
3295         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3296     EXPECT_FALSE(
3297         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3298                              true, {"-std=c++20"}));
3299   }
3300   {
3301     auto M =
3302         cxxForRangeStmt(hasDescendant(binaryOperator(hasOperatorName("+"))));
3303     EXPECT_TRUE(
3304         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3305     EXPECT_FALSE(
3306         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3307                              true, {"-std=c++20"}));
3308   }
3309   {
3310     auto M =
3311         cxxForRangeStmt(hasDescendant(unaryOperator(hasOperatorName("++"))));
3312     EXPECT_TRUE(
3313         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3314     EXPECT_FALSE(
3315         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3316                              true, {"-std=c++20"}));
3317   }
3318   {
3319     auto M =
3320         cxxForRangeStmt(has(declStmt(hasSingleDecl(varDecl(hasName("i"))))));
3321     EXPECT_TRUE(
3322         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3323     EXPECT_FALSE(
3324         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3325                              true, {"-std=c++20"}));
3326   }
3327   {
3328     auto M = cxxForRangeStmt(
3329         hasInitStatement(declStmt(hasSingleDecl(varDecl(
3330             hasName("a"),
3331             hasInitializer(declRefExpr(to(varDecl(hasName("arr"))))))))),
3332         hasLoopVariable(varDecl(hasName("i"))),
3333         hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))));
3334     EXPECT_TRUE(
3335         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3336     EXPECT_TRUE(
3337         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3338                              true, {"-std=c++20"}));
3339   }
3340   {
3341     auto M = cxxForRangeStmt(
3342         has(declStmt(hasSingleDecl(varDecl(
3343             hasName("a"),
3344             hasInitializer(declRefExpr(to(varDecl(hasName("arr"))))))))),
3345         hasLoopVariable(varDecl(hasName("i"))),
3346         hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))));
3347     EXPECT_TRUE(
3348         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3349     EXPECT_TRUE(
3350         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3351                              true, {"-std=c++20"}));
3352   }
3353   {
3354     auto M = cxxForRangeStmt(hasInitStatement(declStmt(
3355         hasSingleDecl(varDecl(hasName("a"))), hasParent(cxxForRangeStmt()))));
3356     EXPECT_TRUE(
3357         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3358     EXPECT_TRUE(
3359         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3360                              true, {"-std=c++20"}));
3361   }
3362 
3363   Code = R"cpp(
3364   struct Range {
3365     int* begin() const;
3366     int* end() const;
3367   };
3368   Range getRange(int);
3369 
3370   int getNum(int);
3371 
3372   void rangeFor()
3373   {
3374     for (auto j = getNum(42); auto i : getRange(j))
3375     {
3376     }
3377   }
3378   )cpp";
3379   {
3380     auto M = integerLiteral(equals(42));
3381     EXPECT_TRUE(
3382         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3383     EXPECT_TRUE(
3384         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3385                              true, {"-std=c++20"}));
3386   }
3387   {
3388     auto M = compoundStmt(hasDescendant(integerLiteral(equals(42))));
3389     EXPECT_TRUE(
3390         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3391     EXPECT_TRUE(
3392         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3393                              true, {"-std=c++20"}));
3394   }
3395 
3396   Code = R"cpp(
3397 void hasDefaultArg(int i, int j = 0)
3398 {
3399 }
3400 void callDefaultArg()
3401 {
3402   hasDefaultArg(42);
3403 }
3404 )cpp";
3405   auto hasDefaultArgCall = [](auto InnerMatcher) {
3406     return callExpr(callee(functionDecl(hasName("hasDefaultArg"))),
3407                     InnerMatcher);
3408   };
3409   {
3410     auto M = hasDefaultArgCall(has(integerLiteral(equals(42))));
3411     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3412     EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3413   }
3414   {
3415     auto M = hasDefaultArgCall(has(cxxDefaultArgExpr()));
3416     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3417     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3418   }
3419   {
3420     auto M = hasDefaultArgCall(argumentCountIs(2));
3421     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3422     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3423   }
3424   {
3425     auto M = hasDefaultArgCall(argumentCountIs(1));
3426     EXPECT_FALSE(matches(Code, traverse(TK_AsIs, M)));
3427     EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3428   }
3429   {
3430     auto M = hasDefaultArgCall(hasArgument(1, cxxDefaultArgExpr()));
3431     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3432     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3433   }
3434   {
3435     auto M = hasDefaultArgCall(hasAnyArgument(cxxDefaultArgExpr()));
3436     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3437     EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3438   }
3439   Code = R"cpp(
3440 struct A
3441 {
3442     ~A();
3443 private:
3444     int i;
3445 };
3446 
3447 A::~A() = default;
3448 )cpp";
3449   {
3450     auto M = cxxDestructorDecl(isDefaulted(),
3451                                ofClass(cxxRecordDecl(has(fieldDecl()))));
3452     EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3453     EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3454   }
3455   Code = R"cpp(
3456 struct S
3457 {
3458     static constexpr bool getTrue() { return true; }
3459 };
3460 
3461 struct A
3462 {
3463     explicit(S::getTrue()) A();
3464 };
3465 
3466 A::A() = default;
3467 )cpp";
3468   {
3469     EXPECT_TRUE(matchesConditionally(
3470         Code,
3471         traverse(TK_AsIs,
3472                  cxxConstructorDecl(
3473                      isDefaulted(),
3474                      hasExplicitSpecifier(expr(ignoringImplicit(
3475                          callExpr(has(ignoringImplicit(declRefExpr())))))))),
3476         true, {"-std=c++20"}));
3477     EXPECT_TRUE(matchesConditionally(
3478         Code,
3479         traverse(TK_IgnoreUnlessSpelledInSource,
3480                  cxxConstructorDecl(
3481                      isDefaulted(),
3482                      hasExplicitSpecifier(callExpr(has(declRefExpr()))))),
3483         true, {"-std=c++20"}));
3484   }
3485 }
3486 
3487 template <typename MatcherT>
matcherTemplateWithBinding(StringRef Code,const MatcherT & M)3488 bool matcherTemplateWithBinding(StringRef Code, const MatcherT &M) {
3489   return matchAndVerifyResultTrue(
3490       Code, M.bind("matchedStmt"),
3491       std::make_unique<VerifyIdIsBoundTo<ReturnStmt>>("matchedStmt", 1));
3492 }
3493 
TEST(Traversal,traverseWithBinding)3494 TEST(Traversal, traverseWithBinding) {
3495   // Some existing matcher code expects to take a matcher as a
3496   // template arg and bind to it.  Verify that that works.
3497 
3498   llvm::StringRef Code = R"cpp(
3499 int foo()
3500 {
3501   return 42.0;
3502 }
3503 )cpp";
3504   EXPECT_TRUE(matcherTemplateWithBinding(
3505       Code, traverse(TK_AsIs,
3506                      returnStmt(has(implicitCastExpr(has(floatLiteral())))))));
3507 }
3508 
TEST(Traversal,traverseMatcherNesting)3509 TEST(Traversal, traverseMatcherNesting) {
3510 
3511   StringRef Code = R"cpp(
3512 float bar(int i)
3513 {
3514   return i;
3515 }
3516 
3517 void foo()
3518 {
3519   bar(bar(3.0));
3520 }
3521 )cpp";
3522 
3523   EXPECT_TRUE(
3524       matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
3525                              callExpr(has(callExpr(traverse(
3526                                  TK_AsIs, callExpr(has(implicitCastExpr(
3527                                               has(floatLiteral())))))))))));
3528 
3529   EXPECT_TRUE(matches(
3530       Code,
3531       traverse(TK_IgnoreUnlessSpelledInSource,
3532                traverse(TK_AsIs, implicitCastExpr(has(floatLiteral()))))));
3533 }
3534 
TEST(Traversal,traverseMatcherThroughImplicit)3535 TEST(Traversal, traverseMatcherThroughImplicit) {
3536   StringRef Code = R"cpp(
3537 struct S {
3538   S(int x);
3539 };
3540 
3541 void constructImplicit() {
3542   int a = 8;
3543   S s(a);
3544 }
3545   )cpp";
3546 
3547   auto Matcher = traverse(TK_IgnoreUnlessSpelledInSource, implicitCastExpr());
3548 
3549   // Verfiy that it does not segfault
3550   EXPECT_FALSE(matches(Code, Matcher));
3551 }
3552 
TEST(Traversal,traverseMatcherThroughMemoization)3553 TEST(Traversal, traverseMatcherThroughMemoization) {
3554 
3555   StringRef Code = R"cpp(
3556 void foo()
3557 {
3558   int i = 3.0;
3559 }
3560   )cpp";
3561 
3562   auto Matcher = varDecl(hasInitializer(floatLiteral()));
3563 
3564   // Matchers such as hasDescendant memoize their result regarding AST
3565   // nodes. In the matcher below, the first use of hasDescendant(Matcher)
3566   // fails, and the use of it inside the traverse() matcher should pass
3567   // causing the overall matcher to be a true match.
3568   // This test verifies that the first false result is not re-used, which
3569   // would cause the overall matcher to be incorrectly false.
3570 
3571   EXPECT_TRUE(matches(
3572       Code,
3573       functionDecl(anyOf(hasDescendant(Matcher),
3574                          traverse(TK_IgnoreUnlessSpelledInSource,
3575                                   functionDecl(hasDescendant(Matcher)))))));
3576 }
3577 
TEST(Traversal,traverseUnlessSpelledInSource)3578 TEST(Traversal, traverseUnlessSpelledInSource) {
3579 
3580   StringRef Code = R"cpp(
3581 
3582 struct A
3583 {
3584 };
3585 
3586 struct B
3587 {
3588   B(int);
3589   B(A const& a);
3590   B();
3591 };
3592 
3593 struct C
3594 {
3595   operator B();
3596 };
3597 
3598 B func1() {
3599   return 42;
3600 }
3601 
3602 B func2() {
3603   return B{42};
3604 }
3605 
3606 B func3() {
3607   return B(42);
3608 }
3609 
3610 B func4() {
3611   return B();
3612 }
3613 
3614 B func5() {
3615   return B{};
3616 }
3617 
3618 B func6() {
3619   return C();
3620 }
3621 
3622 B func7() {
3623   return A();
3624 }
3625 
3626 B func8() {
3627   return C{};
3628 }
3629 
3630 B func9() {
3631   return A{};
3632 }
3633 
3634 B func10() {
3635   A a;
3636   return a;
3637 }
3638 
3639 B func11() {
3640   B b;
3641   return b;
3642 }
3643 
3644 B func12() {
3645   C c;
3646   return c;
3647 }
3648 
3649 void func13() {
3650   int a = 0;
3651   int c = 0;
3652 
3653   [a, b = c](int d) { int e = d; };
3654 }
3655 
3656 void func14() {
3657   [] <typename TemplateType> (TemplateType t, TemplateType u) { int e = t + u; };
3658   float i = 42.0;
3659 }
3660 
3661 void func15() {
3662   int count = 0;
3663   auto l = [&] { ++count; };
3664   (void)l;
3665 }
3666 
3667 )cpp";
3668 
3669   EXPECT_TRUE(
3670       matches(Code,
3671               traverse(TK_IgnoreUnlessSpelledInSource,
3672                        returnStmt(forFunction(functionDecl(hasName("func1"))),
3673                                   hasReturnValue(integerLiteral(equals(42))))),
3674               langCxx20OrLater()));
3675 
3676   EXPECT_TRUE(
3677       matches(Code,
3678               traverse(TK_IgnoreUnlessSpelledInSource,
3679                        integerLiteral(equals(42),
3680                                       hasParent(returnStmt(forFunction(
3681                                           functionDecl(hasName("func1"))))))),
3682               langCxx20OrLater()));
3683 
3684   EXPECT_TRUE(matches(
3685       Code,
3686       traverse(TK_IgnoreUnlessSpelledInSource,
3687                returnStmt(forFunction(functionDecl(hasName("func2"))),
3688                           hasReturnValue(cxxTemporaryObjectExpr(
3689                               hasArgument(0, integerLiteral(equals(42))))))),
3690       langCxx20OrLater()));
3691   EXPECT_TRUE(matches(
3692       Code,
3693       traverse(
3694           TK_IgnoreUnlessSpelledInSource,
3695           integerLiteral(equals(42),
3696                          hasParent(cxxTemporaryObjectExpr(hasParent(returnStmt(
3697                              forFunction(functionDecl(hasName("func2"))))))))),
3698       langCxx20OrLater()));
3699 
3700   EXPECT_TRUE(
3701       matches(Code,
3702               traverse(TK_IgnoreUnlessSpelledInSource,
3703                        returnStmt(forFunction(functionDecl(hasName("func3"))),
3704                                   hasReturnValue(cxxConstructExpr(hasArgument(
3705                                       0, integerLiteral(equals(42))))))),
3706               langCxx20OrLater()));
3707 
3708   EXPECT_TRUE(matches(
3709       Code,
3710       traverse(
3711           TK_IgnoreUnlessSpelledInSource,
3712           integerLiteral(equals(42),
3713                          hasParent(cxxConstructExpr(hasParent(returnStmt(
3714                              forFunction(functionDecl(hasName("func3"))))))))),
3715       langCxx20OrLater()));
3716 
3717   EXPECT_TRUE(
3718       matches(Code,
3719               traverse(TK_IgnoreUnlessSpelledInSource,
3720                        returnStmt(forFunction(functionDecl(hasName("func4"))),
3721                                   hasReturnValue(cxxTemporaryObjectExpr()))),
3722               langCxx20OrLater()));
3723 
3724   EXPECT_TRUE(
3725       matches(Code,
3726               traverse(TK_IgnoreUnlessSpelledInSource,
3727                        returnStmt(forFunction(functionDecl(hasName("func5"))),
3728                                   hasReturnValue(cxxTemporaryObjectExpr()))),
3729               langCxx20OrLater()));
3730 
3731   EXPECT_TRUE(
3732       matches(Code,
3733               traverse(TK_IgnoreUnlessSpelledInSource,
3734                        returnStmt(forFunction(functionDecl(hasName("func6"))),
3735                                   hasReturnValue(cxxTemporaryObjectExpr()))),
3736               langCxx20OrLater()));
3737 
3738   EXPECT_TRUE(
3739       matches(Code,
3740               traverse(TK_IgnoreUnlessSpelledInSource,
3741                        returnStmt(forFunction(functionDecl(hasName("func7"))),
3742                                   hasReturnValue(cxxTemporaryObjectExpr()))),
3743               langCxx20OrLater()));
3744 
3745   EXPECT_TRUE(
3746       matches(Code,
3747               traverse(TK_IgnoreUnlessSpelledInSource,
3748                        returnStmt(forFunction(functionDecl(hasName("func8"))),
3749                                   hasReturnValue(cxxFunctionalCastExpr(
3750                                       hasSourceExpression(initListExpr()))))),
3751               langCxx20OrLater()));
3752 
3753   EXPECT_TRUE(
3754       matches(Code,
3755               traverse(TK_IgnoreUnlessSpelledInSource,
3756                        returnStmt(forFunction(functionDecl(hasName("func9"))),
3757                                   hasReturnValue(cxxFunctionalCastExpr(
3758                                       hasSourceExpression(initListExpr()))))),
3759               langCxx20OrLater()));
3760 
3761   EXPECT_TRUE(matches(
3762       Code,
3763       traverse(
3764           TK_IgnoreUnlessSpelledInSource,
3765           returnStmt(forFunction(functionDecl(hasName("func10"))),
3766                      hasReturnValue(declRefExpr(to(varDecl(hasName("a"))))))),
3767       langCxx20OrLater()));
3768 
3769   EXPECT_TRUE(
3770       matches(Code,
3771               traverse(TK_IgnoreUnlessSpelledInSource,
3772                        declRefExpr(to(varDecl(hasName("a"))),
3773                                    hasParent(returnStmt(forFunction(
3774                                        functionDecl(hasName("func10"))))))),
3775               langCxx20OrLater()));
3776 
3777   EXPECT_TRUE(matches(
3778       Code,
3779       traverse(
3780           TK_IgnoreUnlessSpelledInSource,
3781           returnStmt(forFunction(functionDecl(hasName("func11"))),
3782                      hasReturnValue(declRefExpr(to(varDecl(hasName("b"))))))),
3783       langCxx20OrLater()));
3784 
3785   EXPECT_TRUE(
3786       matches(Code,
3787               traverse(TK_IgnoreUnlessSpelledInSource,
3788                        declRefExpr(to(varDecl(hasName("b"))),
3789                                    hasParent(returnStmt(forFunction(
3790                                        functionDecl(hasName("func11"))))))),
3791               langCxx20OrLater()));
3792 
3793   EXPECT_TRUE(matches(
3794       Code,
3795       traverse(
3796           TK_IgnoreUnlessSpelledInSource,
3797           returnStmt(forFunction(functionDecl(hasName("func12"))),
3798                      hasReturnValue(declRefExpr(to(varDecl(hasName("c"))))))),
3799       langCxx20OrLater()));
3800 
3801   EXPECT_TRUE(
3802       matches(Code,
3803               traverse(TK_IgnoreUnlessSpelledInSource,
3804                        declRefExpr(to(varDecl(hasName("c"))),
3805                                    hasParent(returnStmt(forFunction(
3806                                        functionDecl(hasName("func12"))))))),
3807               langCxx20OrLater()));
3808 
3809   EXPECT_TRUE(matches(
3810       Code,
3811       traverse(
3812           TK_IgnoreUnlessSpelledInSource,
3813           lambdaExpr(forFunction(functionDecl(hasName("func13"))),
3814                      has(compoundStmt(hasDescendant(varDecl(hasName("e"))))),
3815                      has(declRefExpr(to(varDecl(hasName("a"))))),
3816                      has(varDecl(hasName("b"), hasInitializer(declRefExpr(to(
3817                                                    varDecl(hasName("c"))))))),
3818                      has(parmVarDecl(hasName("d"))))),
3819       langCxx20OrLater()));
3820 
3821   EXPECT_TRUE(
3822       matches(Code,
3823               traverse(TK_IgnoreUnlessSpelledInSource,
3824                        declRefExpr(to(varDecl(hasName("a"))),
3825                                    hasParent(lambdaExpr(forFunction(
3826                                        functionDecl(hasName("func13"))))))),
3827               langCxx20OrLater()));
3828 
3829   EXPECT_TRUE(matches(
3830       Code,
3831       traverse(TK_IgnoreUnlessSpelledInSource,
3832                varDecl(hasName("b"),
3833                        hasInitializer(declRefExpr(to(varDecl(hasName("c"))))),
3834                        hasParent(lambdaExpr(
3835                            forFunction(functionDecl(hasName("func13"))))))),
3836       langCxx20OrLater()));
3837 
3838   EXPECT_TRUE(matches(Code,
3839                       traverse(TK_IgnoreUnlessSpelledInSource,
3840                                compoundStmt(hasParent(lambdaExpr(forFunction(
3841                                    functionDecl(hasName("func13"))))))),
3842                       langCxx20OrLater()));
3843 
3844   EXPECT_TRUE(matches(
3845       Code,
3846       traverse(TK_IgnoreUnlessSpelledInSource,
3847                templateTypeParmDecl(hasName("TemplateType"),
3848                                     hasParent(lambdaExpr(forFunction(
3849                                         functionDecl(hasName("func14"))))))),
3850       langCxx20OrLater()));
3851 
3852   EXPECT_TRUE(matches(
3853       Code,
3854       traverse(TK_IgnoreUnlessSpelledInSource,
3855                lambdaExpr(forFunction(functionDecl(hasName("func14"))),
3856                           has(templateTypeParmDecl(hasName("TemplateType"))))),
3857       langCxx20OrLater()));
3858 
3859   EXPECT_TRUE(matches(
3860       Code,
3861       traverse(TK_IgnoreUnlessSpelledInSource,
3862                functionDecl(hasName("func14"), hasDescendant(floatLiteral()))),
3863       langCxx20OrLater()));
3864 
3865   EXPECT_TRUE(matches(
3866       Code,
3867       traverse(TK_IgnoreUnlessSpelledInSource,
3868                compoundStmt(
3869                    hasDescendant(varDecl(hasName("count")).bind("countVar")),
3870                    hasDescendant(
3871                        declRefExpr(to(varDecl(equalsBoundNode("countVar"))))))),
3872       langCxx20OrLater()));
3873 
3874   Code = R"cpp(
3875 void foo() {
3876     int explicit_captured = 0;
3877     int implicit_captured = 0;
3878     auto l = [&, explicit_captured](int i) {
3879         if (i || explicit_captured || implicit_captured) return;
3880     };
3881 }
3882 )cpp";
3883 
3884   EXPECT_TRUE(matches(Code, traverse(TK_AsIs, ifStmt())));
3885   EXPECT_TRUE(
3886       matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, ifStmt())));
3887 
3888   auto lambdaExplicitCapture = declRefExpr(
3889       to(varDecl(hasName("explicit_captured"))), unless(hasAncestor(ifStmt())));
3890   auto lambdaImplicitCapture = declRefExpr(
3891       to(varDecl(hasName("implicit_captured"))), unless(hasAncestor(ifStmt())));
3892 
3893   EXPECT_TRUE(matches(Code, traverse(TK_AsIs, lambdaExplicitCapture)));
3894   EXPECT_TRUE(matches(
3895       Code, traverse(TK_IgnoreUnlessSpelledInSource, lambdaExplicitCapture)));
3896 
3897   EXPECT_TRUE(matches(Code, traverse(TK_AsIs, lambdaImplicitCapture)));
3898   EXPECT_FALSE(matches(
3899       Code, traverse(TK_IgnoreUnlessSpelledInSource, lambdaImplicitCapture)));
3900 
3901   Code = R"cpp(
3902 struct S {};
3903 
3904 struct HasOpEq
3905 {
3906     bool operator==(const S& other)
3907     {
3908         return true;
3909     }
3910 };
3911 
3912 void binop()
3913 {
3914     HasOpEq s1;
3915     S s2;
3916     if (s1 != s2)
3917         return;
3918 }
3919 )cpp";
3920   {
3921     auto M = unaryOperator(
3922         hasOperatorName("!"),
3923         has(cxxOperatorCallExpr(hasOverloadedOperatorName("=="))));
3924     EXPECT_TRUE(
3925         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3926     EXPECT_FALSE(
3927         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3928                              true, {"-std=c++20"}));
3929   }
3930   {
3931     auto M = declRefExpr(to(varDecl(hasName("s1"))));
3932     EXPECT_TRUE(
3933         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3934     EXPECT_TRUE(
3935         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3936                              true, {"-std=c++20"}));
3937   }
3938   {
3939     auto M = cxxOperatorCallExpr(hasOverloadedOperatorName("=="));
3940     EXPECT_TRUE(
3941         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3942     EXPECT_FALSE(
3943         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3944                              true, {"-std=c++20"}));
3945   }
3946   {
3947     auto M = cxxOperatorCallExpr(hasOverloadedOperatorName("!="));
3948     EXPECT_FALSE(
3949         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3950     EXPECT_FALSE(
3951         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3952                              true, {"-std=c++20"}));
3953   }
3954   auto withDescendants = [](StringRef lName, StringRef rName) {
3955     return stmt(hasDescendant(declRefExpr(to(varDecl(hasName(lName))))),
3956                 hasDescendant(declRefExpr(to(varDecl(hasName(rName))))));
3957   };
3958   {
3959     auto M = cxxRewrittenBinaryOperator(withDescendants("s1", "s2"));
3960     EXPECT_TRUE(
3961         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3962     EXPECT_TRUE(
3963         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3964                              true, {"-std=c++20"}));
3965   }
3966   {
3967     auto M = cxxRewrittenBinaryOperator(
3968         has(declRefExpr(to(varDecl(hasName("s1"))))),
3969         has(declRefExpr(to(varDecl(hasName("s2"))))));
3970     EXPECT_FALSE(
3971         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3972     EXPECT_TRUE(
3973         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3974                              true, {"-std=c++20"}));
3975   }
3976   {
3977     auto M = cxxRewrittenBinaryOperator(
3978         hasLHS(expr(hasParent(cxxRewrittenBinaryOperator()))),
3979         hasRHS(expr(hasParent(cxxRewrittenBinaryOperator()))));
3980     EXPECT_FALSE(
3981         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3982     EXPECT_TRUE(
3983         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3984                              true, {"-std=c++20"}));
3985   }
3986   {
3987     EXPECT_TRUE(matchesConditionally(
3988         Code,
3989         traverse(TK_AsIs,
3990                  cxxRewrittenBinaryOperator(
3991                      hasOperatorName("!="), hasAnyOperatorName("<", "!="),
3992                      isComparisonOperator(),
3993                      hasLHS(ignoringImplicit(
3994                          declRefExpr(to(varDecl(hasName("s1")))))),
3995                      hasRHS(ignoringImplicit(
3996                          declRefExpr(to(varDecl(hasName("s2")))))),
3997                      hasEitherOperand(ignoringImplicit(
3998                          declRefExpr(to(varDecl(hasName("s2")))))),
3999                      hasOperands(ignoringImplicit(
4000                                      declRefExpr(to(varDecl(hasName("s1"))))),
4001                                  ignoringImplicit(declRefExpr(
4002                                      to(varDecl(hasName("s2")))))))),
4003         true, {"-std=c++20"}));
4004     EXPECT_TRUE(matchesConditionally(
4005         Code,
4006         traverse(TK_IgnoreUnlessSpelledInSource,
4007                  cxxRewrittenBinaryOperator(
4008                      hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4009                      isComparisonOperator(),
4010                      hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
4011                      hasRHS(declRefExpr(to(varDecl(hasName("s2"))))),
4012                      hasEitherOperand(declRefExpr(to(varDecl(hasName("s2"))))),
4013                      hasOperands(declRefExpr(to(varDecl(hasName("s1")))),
4014                                  declRefExpr(to(varDecl(hasName("s2"))))))),
4015         true, {"-std=c++20"}));
4016   }
4017 
4018   Code = R"cpp(
4019 namespace std {
4020 struct strong_ordering {
4021   int n;
4022   constexpr operator int() const { return n; }
4023   static const strong_ordering equal, greater, less;
4024 };
4025 constexpr strong_ordering strong_ordering::equal = {0};
4026 constexpr strong_ordering strong_ordering::greater = {1};
4027 constexpr strong_ordering strong_ordering::less = {-1};
4028 }
4029 
4030 struct HasSpaceshipMem {
4031   int a;
4032   constexpr auto operator<=>(const HasSpaceshipMem&) const = default;
4033 };
4034 
4035 void binop()
4036 {
4037     HasSpaceshipMem hs1, hs2;
4038     if (hs1 == hs2)
4039         return;
4040 
4041     HasSpaceshipMem hs3, hs4;
4042     if (hs3 != hs4)
4043         return;
4044 
4045     HasSpaceshipMem hs5, hs6;
4046     if (hs5 < hs6)
4047         return;
4048 
4049     HasSpaceshipMem hs7, hs8;
4050     if (hs7 > hs8)
4051         return;
4052 
4053     HasSpaceshipMem hs9, hs10;
4054     if (hs9 <= hs10)
4055         return;
4056 
4057     HasSpaceshipMem hs11, hs12;
4058     if (hs11 >= hs12)
4059         return;
4060 }
4061 )cpp";
4062   auto withArgs = [](StringRef lName, StringRef rName) {
4063     return cxxOperatorCallExpr(
4064         hasArgument(0, declRefExpr(to(varDecl(hasName(lName))))),
4065         hasArgument(1, declRefExpr(to(varDecl(hasName(rName))))));
4066   };
4067   {
4068     auto M = ifStmt(hasCondition(cxxOperatorCallExpr(
4069         hasOverloadedOperatorName("=="), withArgs("hs1", "hs2"))));
4070     EXPECT_TRUE(
4071         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4072     EXPECT_TRUE(
4073         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4074                              true, {"-std=c++20"}));
4075   }
4076   {
4077     auto M =
4078         unaryOperator(hasOperatorName("!"),
4079                       has(cxxOperatorCallExpr(hasOverloadedOperatorName("=="),
4080                                               withArgs("hs3", "hs4"))));
4081     EXPECT_TRUE(
4082         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4083     EXPECT_FALSE(
4084         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4085                              true, {"-std=c++20"}));
4086   }
4087   {
4088     auto M =
4089         unaryOperator(hasOperatorName("!"),
4090                       has(cxxOperatorCallExpr(hasOverloadedOperatorName("=="),
4091                                               withArgs("hs3", "hs4"))));
4092     EXPECT_TRUE(
4093         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4094     EXPECT_FALSE(
4095         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4096                              true, {"-std=c++20"}));
4097   }
4098   {
4099     auto M = binaryOperator(
4100         hasOperatorName("<"),
4101         hasLHS(hasDescendant(cxxOperatorCallExpr(
4102             hasOverloadedOperatorName("<=>"), withArgs("hs5", "hs6")))),
4103         hasRHS(integerLiteral(equals(0))));
4104     EXPECT_TRUE(
4105         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4106     EXPECT_FALSE(
4107         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4108                              true, {"-std=c++20"}));
4109   }
4110   {
4111     auto M = cxxRewrittenBinaryOperator(withDescendants("hs3", "hs4"));
4112     EXPECT_TRUE(
4113         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4114     EXPECT_TRUE(
4115         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4116                              true, {"-std=c++20"}));
4117   }
4118   {
4119     auto M = declRefExpr(to(varDecl(hasName("hs3"))));
4120     EXPECT_TRUE(
4121         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4122     EXPECT_TRUE(
4123         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4124                              true, {"-std=c++20"}));
4125   }
4126   {
4127     auto M = cxxRewrittenBinaryOperator(has(
4128         unaryOperator(hasOperatorName("!"), withDescendants("hs3", "hs4"))));
4129     EXPECT_TRUE(
4130         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4131     EXPECT_FALSE(
4132         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4133                              true, {"-std=c++20"}));
4134   }
4135   {
4136     auto M = cxxRewrittenBinaryOperator(
4137         has(declRefExpr(to(varDecl(hasName("hs3"))))),
4138         has(declRefExpr(to(varDecl(hasName("hs4"))))));
4139     EXPECT_FALSE(
4140         matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4141     EXPECT_TRUE(
4142         matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4143                              true, {"-std=c++20"}));
4144   }
4145   {
4146     EXPECT_TRUE(matchesConditionally(
4147         Code,
4148         traverse(TK_AsIs,
4149                  cxxRewrittenBinaryOperator(
4150                      hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4151                      isComparisonOperator(),
4152                      hasLHS(ignoringImplicit(
4153                          declRefExpr(to(varDecl(hasName("hs3")))))),
4154                      hasRHS(ignoringImplicit(
4155                          declRefExpr(to(varDecl(hasName("hs4")))))),
4156                      hasEitherOperand(ignoringImplicit(
4157                          declRefExpr(to(varDecl(hasName("hs3")))))),
4158                      hasOperands(ignoringImplicit(
4159                                      declRefExpr(to(varDecl(hasName("hs3"))))),
4160                                  ignoringImplicit(declRefExpr(
4161                                      to(varDecl(hasName("hs4")))))))),
4162         true, {"-std=c++20"}));
4163     EXPECT_TRUE(matchesConditionally(
4164         Code,
4165         traverse(TK_IgnoreUnlessSpelledInSource,
4166                  cxxRewrittenBinaryOperator(
4167                      hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4168                      isComparisonOperator(),
4169                      hasLHS(declRefExpr(to(varDecl(hasName("hs3"))))),
4170                      hasRHS(declRefExpr(to(varDecl(hasName("hs4"))))),
4171                      hasEitherOperand(declRefExpr(to(varDecl(hasName("hs3"))))),
4172                      hasOperands(declRefExpr(to(varDecl(hasName("hs3")))),
4173                                  declRefExpr(to(varDecl(hasName("hs4"))))))),
4174         true, {"-std=c++20"}));
4175   }
4176   {
4177     EXPECT_TRUE(matchesConditionally(
4178         Code,
4179         traverse(TK_AsIs,
4180                  cxxRewrittenBinaryOperator(
4181                      hasOperatorName("<"), hasAnyOperatorName("<", "!="),
4182                      isComparisonOperator(),
4183                      hasLHS(ignoringImplicit(
4184                          declRefExpr(to(varDecl(hasName("hs5")))))),
4185                      hasRHS(ignoringImplicit(
4186                          declRefExpr(to(varDecl(hasName("hs6")))))),
4187                      hasEitherOperand(ignoringImplicit(
4188                          declRefExpr(to(varDecl(hasName("hs5")))))),
4189                      hasOperands(ignoringImplicit(
4190                                      declRefExpr(to(varDecl(hasName("hs5"))))),
4191                                  ignoringImplicit(declRefExpr(
4192                                      to(varDecl(hasName("hs6")))))))),
4193         true, {"-std=c++20"}));
4194     EXPECT_TRUE(matchesConditionally(
4195         Code,
4196         traverse(TK_IgnoreUnlessSpelledInSource,
4197                  cxxRewrittenBinaryOperator(
4198                      hasOperatorName("<"), hasAnyOperatorName("<", "!="),
4199                      isComparisonOperator(),
4200                      hasLHS(declRefExpr(to(varDecl(hasName("hs5"))))),
4201                      hasRHS(declRefExpr(to(varDecl(hasName("hs6"))))),
4202                      hasEitherOperand(declRefExpr(to(varDecl(hasName("hs5"))))),
4203                      hasOperands(declRefExpr(to(varDecl(hasName("hs5")))),
4204                                  declRefExpr(to(varDecl(hasName("hs6"))))))),
4205         true, {"-std=c++20"}));
4206   }
4207   {
4208     EXPECT_TRUE(matchesConditionally(
4209         Code,
4210         traverse(TK_AsIs,
4211                  cxxRewrittenBinaryOperator(
4212                      hasOperatorName(">"), hasAnyOperatorName("<", ">"),
4213                      isComparisonOperator(),
4214                      hasLHS(ignoringImplicit(
4215                          declRefExpr(to(varDecl(hasName("hs7")))))),
4216                      hasRHS(ignoringImplicit(
4217                          declRefExpr(to(varDecl(hasName("hs8")))))),
4218                      hasEitherOperand(ignoringImplicit(
4219                          declRefExpr(to(varDecl(hasName("hs7")))))),
4220                      hasOperands(ignoringImplicit(
4221                                      declRefExpr(to(varDecl(hasName("hs7"))))),
4222                                  ignoringImplicit(declRefExpr(
4223                                      to(varDecl(hasName("hs8")))))))),
4224         true, {"-std=c++20"}));
4225     EXPECT_TRUE(matchesConditionally(
4226         Code,
4227         traverse(TK_IgnoreUnlessSpelledInSource,
4228                  cxxRewrittenBinaryOperator(
4229                      hasOperatorName(">"), hasAnyOperatorName("<", ">"),
4230                      isComparisonOperator(),
4231                      hasLHS(declRefExpr(to(varDecl(hasName("hs7"))))),
4232                      hasRHS(declRefExpr(to(varDecl(hasName("hs8"))))),
4233                      hasEitherOperand(declRefExpr(to(varDecl(hasName("hs7"))))),
4234                      hasOperands(declRefExpr(to(varDecl(hasName("hs7")))),
4235                                  declRefExpr(to(varDecl(hasName("hs8"))))))),
4236         true, {"-std=c++20"}));
4237   }
4238   {
4239     EXPECT_TRUE(matchesConditionally(
4240         Code,
4241         traverse(TK_AsIs,
4242                  cxxRewrittenBinaryOperator(
4243                      hasOperatorName("<="), hasAnyOperatorName("<", "<="),
4244                      isComparisonOperator(),
4245                      hasLHS(ignoringImplicit(
4246                          declRefExpr(to(varDecl(hasName("hs9")))))),
4247                      hasRHS(ignoringImplicit(
4248                          declRefExpr(to(varDecl(hasName("hs10")))))),
4249                      hasEitherOperand(ignoringImplicit(
4250                          declRefExpr(to(varDecl(hasName("hs9")))))),
4251                      hasOperands(ignoringImplicit(
4252                                      declRefExpr(to(varDecl(hasName("hs9"))))),
4253                                  ignoringImplicit(declRefExpr(
4254                                      to(varDecl(hasName("hs10")))))))),
4255         true, {"-std=c++20"}));
4256     EXPECT_TRUE(matchesConditionally(
4257         Code,
4258         traverse(TK_IgnoreUnlessSpelledInSource,
4259                  cxxRewrittenBinaryOperator(
4260                      hasOperatorName("<="), hasAnyOperatorName("<", "<="),
4261                      isComparisonOperator(),
4262                      hasLHS(declRefExpr(to(varDecl(hasName("hs9"))))),
4263                      hasRHS(declRefExpr(to(varDecl(hasName("hs10"))))),
4264                      hasEitherOperand(declRefExpr(to(varDecl(hasName("hs9"))))),
4265                      hasOperands(declRefExpr(to(varDecl(hasName("hs9")))),
4266                                  declRefExpr(to(varDecl(hasName("hs10"))))))),
4267         true, {"-std=c++20"}));
4268   }
4269   {
4270     EXPECT_TRUE(matchesConditionally(
4271         Code,
4272         traverse(TK_AsIs,
4273                  cxxRewrittenBinaryOperator(
4274                      hasOperatorName(">="), hasAnyOperatorName("<", ">="),
4275                      isComparisonOperator(),
4276                      hasLHS(ignoringImplicit(
4277                          declRefExpr(to(varDecl(hasName("hs11")))))),
4278                      hasRHS(ignoringImplicit(
4279                          declRefExpr(to(varDecl(hasName("hs12")))))),
4280                      hasEitherOperand(ignoringImplicit(
4281                          declRefExpr(to(varDecl(hasName("hs11")))))),
4282                      hasOperands(ignoringImplicit(
4283                                      declRefExpr(to(varDecl(hasName("hs11"))))),
4284                                  ignoringImplicit(declRefExpr(
4285                                      to(varDecl(hasName("hs12")))))))),
4286         true, {"-std=c++20"}));
4287     EXPECT_TRUE(matchesConditionally(
4288         Code,
4289         traverse(
4290             TK_IgnoreUnlessSpelledInSource,
4291             cxxRewrittenBinaryOperator(
4292                 hasOperatorName(">="), hasAnyOperatorName("<", ">="),
4293                 isComparisonOperator(),
4294                 hasLHS(declRefExpr(to(varDecl(hasName("hs11"))))),
4295                 hasRHS(declRefExpr(to(varDecl(hasName("hs12"))))),
4296                 hasEitherOperand(declRefExpr(to(varDecl(hasName("hs11"))))),
4297                 hasOperands(declRefExpr(to(varDecl(hasName("hs11")))),
4298                             declRefExpr(to(varDecl(hasName("hs12"))))))),
4299         true, {"-std=c++20"}));
4300   }
4301 
4302   Code = R"cpp(
4303 struct S {};
4304 
4305 struct HasOpEq
4306 {
4307     bool operator==(const S& other) const
4308     {
4309         return true;
4310     }
4311 };
4312 
4313 struct HasOpEqMem {
4314   bool operator==(const HasOpEqMem&) const { return true; }
4315 };
4316 
4317 struct HasOpEqFree {
4318 };
4319 bool operator==(const HasOpEqFree&, const HasOpEqFree&) { return true; }
4320 
4321 void binop()
4322 {
4323     {
4324     HasOpEq s1;
4325     S s2;
4326     if (s1 != s2)
4327         return;
4328     }
4329 
4330     {
4331       int i1;
4332       int i2;
4333       if (i1 != i2)
4334           return;
4335     }
4336 
4337     {
4338       HasOpEqMem M1;
4339       HasOpEqMem M2;
4340       if (M1 == M2)
4341           return;
4342     }
4343 
4344     {
4345       HasOpEqFree F1;
4346       HasOpEqFree F2;
4347       if (F1 == F2)
4348           return;
4349     }
4350 }
4351 )cpp";
4352   {
4353     EXPECT_TRUE(matchesConditionally(
4354         Code,
4355         traverse(TK_AsIs,
4356                  binaryOperation(
4357                      hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4358                      isComparisonOperator(),
4359                      hasLHS(ignoringImplicit(
4360                          declRefExpr(to(varDecl(hasName("s1")))))),
4361                      hasRHS(ignoringImplicit(
4362                          declRefExpr(to(varDecl(hasName("s2")))))),
4363                      hasEitherOperand(ignoringImplicit(
4364                          declRefExpr(to(varDecl(hasName("s2")))))),
4365                      hasOperands(ignoringImplicit(
4366                                      declRefExpr(to(varDecl(hasName("s1"))))),
4367                                  ignoringImplicit(declRefExpr(
4368                                      to(varDecl(hasName("s2")))))))),
4369         true, {"-std=c++20"}));
4370     EXPECT_TRUE(matchesConditionally(
4371         Code,
4372         traverse(TK_AsIs, binaryOperation(hasOperatorName("!="),
4373                                           hasLHS(ignoringImplicit(declRefExpr(
4374                                               to(varDecl(hasName("i1")))))),
4375                                           hasRHS(ignoringImplicit(declRefExpr(
4376                                               to(varDecl(hasName("i2")))))))),
4377         true, {"-std=c++20"}));
4378     EXPECT_TRUE(matchesConditionally(
4379         Code,
4380         traverse(TK_AsIs, binaryOperation(hasOperatorName("=="),
4381                                           hasLHS(ignoringImplicit(declRefExpr(
4382                                               to(varDecl(hasName("M1")))))),
4383                                           hasRHS(ignoringImplicit(declRefExpr(
4384                                               to(varDecl(hasName("M2")))))))),
4385         true, {"-std=c++20"}));
4386     EXPECT_TRUE(matchesConditionally(
4387         Code,
4388         traverse(TK_AsIs, binaryOperation(hasOperatorName("=="),
4389                                           hasLHS(ignoringImplicit(declRefExpr(
4390                                               to(varDecl(hasName("F1")))))),
4391                                           hasRHS(ignoringImplicit(declRefExpr(
4392                                               to(varDecl(hasName("F2")))))))),
4393         true, {"-std=c++20"}));
4394     EXPECT_TRUE(matchesConditionally(
4395         Code,
4396         traverse(TK_IgnoreUnlessSpelledInSource,
4397                  binaryOperation(
4398                      hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4399                      isComparisonOperator(),
4400                      hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
4401                      hasRHS(declRefExpr(to(varDecl(hasName("s2"))))),
4402                      hasEitherOperand(declRefExpr(to(varDecl(hasName("s2"))))),
4403                      hasOperands(declRefExpr(to(varDecl(hasName("s1")))),
4404                                  declRefExpr(to(varDecl(hasName("s2"))))))),
4405         true, {"-std=c++20"}));
4406     EXPECT_TRUE(matchesConditionally(
4407         Code,
4408         traverse(
4409             TK_IgnoreUnlessSpelledInSource,
4410             binaryOperation(hasOperatorName("!="),
4411                             hasLHS(declRefExpr(to(varDecl(hasName("i1"))))),
4412                             hasRHS(declRefExpr(to(varDecl(hasName("i2"))))))),
4413         true, {"-std=c++20"}));
4414     EXPECT_TRUE(matchesConditionally(
4415         Code,
4416         traverse(
4417             TK_IgnoreUnlessSpelledInSource,
4418             binaryOperation(hasOperatorName("=="),
4419                             hasLHS(declRefExpr(to(varDecl(hasName("M1"))))),
4420                             hasRHS(declRefExpr(to(varDecl(hasName("M2"))))))),
4421         true, {"-std=c++20"}));
4422     EXPECT_TRUE(matchesConditionally(
4423         Code,
4424         traverse(
4425             TK_IgnoreUnlessSpelledInSource,
4426             binaryOperation(hasOperatorName("=="),
4427                             hasLHS(declRefExpr(to(varDecl(hasName("F1"))))),
4428                             hasRHS(declRefExpr(to(varDecl(hasName("F2"))))))),
4429         true, {"-std=c++20"}));
4430   }
4431 }
4432 
TEST(IgnoringImpCasts,PathologicalLambda)4433 TEST(IgnoringImpCasts, PathologicalLambda) {
4434 
4435   // Test that deeply nested lambdas are not a performance penalty
4436   StringRef Code = R"cpp(
4437 void f() {
4438   [] {
4439   [] {
4440   [] {
4441   [] {
4442   [] {
4443   [] {
4444   [] {
4445   [] {
4446   [] {
4447   [] {
4448   [] {
4449   [] {
4450   [] {
4451   [] {
4452   [] {
4453   [] {
4454   [] {
4455   [] {
4456   [] {
4457   [] {
4458   [] {
4459   [] {
4460   [] {
4461   [] {
4462   [] {
4463   [] {
4464   [] {
4465   [] {
4466   [] {
4467     int i = 42;
4468     (void)i;
4469   }();
4470   }();
4471   }();
4472   }();
4473   }();
4474   }();
4475   }();
4476   }();
4477   }();
4478   }();
4479   }();
4480   }();
4481   }();
4482   }();
4483   }();
4484   }();
4485   }();
4486   }();
4487   }();
4488   }();
4489   }();
4490   }();
4491   }();
4492   }();
4493   }();
4494   }();
4495   }();
4496   }();
4497   }();
4498 }
4499   )cpp";
4500 
4501   EXPECT_TRUE(matches(Code, integerLiteral(equals(42))));
4502   EXPECT_TRUE(matches(Code, functionDecl(hasDescendant(integerLiteral(equals(42))))));
4503 }
4504 
TEST(IgnoringImpCasts,MatchesImpCasts)4505 TEST(IgnoringImpCasts, MatchesImpCasts) {
4506   // This test checks that ignoringImpCasts matches when implicit casts are
4507   // present and its inner matcher alone does not match.
4508   // Note that this test creates an implicit const cast.
4509   EXPECT_TRUE(matches("int x = 0; const int y = x;",
4510                       varDecl(hasInitializer(ignoringImpCasts(
4511                         declRefExpr(to(varDecl(hasName("x")))))))));
4512   // This test creates an implict cast from int to char.
4513   EXPECT_TRUE(matches("char x = 0;",
4514                       varDecl(hasInitializer(ignoringImpCasts(
4515                         integerLiteral(equals(0)))))));
4516 }
4517 
TEST(IgnoringImpCasts,DoesNotMatchIncorrectly)4518 TEST(IgnoringImpCasts, DoesNotMatchIncorrectly) {
4519   // These tests verify that ignoringImpCasts does not match if the inner
4520   // matcher does not match.
4521   // Note that the first test creates an implicit const cast.
4522   EXPECT_TRUE(notMatches("int x; const int y = x;",
4523                          varDecl(hasInitializer(ignoringImpCasts(
4524                            unless(anything()))))));
4525   EXPECT_TRUE(notMatches("int x; int y = x;",
4526                          varDecl(hasInitializer(ignoringImpCasts(
4527                            unless(anything()))))));
4528 
4529   // These tests verify that ignoringImplictCasts does not look through explicit
4530   // casts or parentheses.
4531   EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
4532                          varDecl(hasInitializer(ignoringImpCasts(
4533                            integerLiteral())))));
4534   EXPECT_TRUE(notMatches(
4535       "int i = (0);",
4536       traverse(TK_AsIs,
4537                varDecl(hasInitializer(ignoringImpCasts(integerLiteral()))))));
4538   EXPECT_TRUE(notMatches("float i = (float)0;",
4539                          varDecl(hasInitializer(ignoringImpCasts(
4540                            integerLiteral())))));
4541   EXPECT_TRUE(notMatches("float i = float(0);",
4542                          varDecl(hasInitializer(ignoringImpCasts(
4543                            integerLiteral())))));
4544 }
4545 
TEST(IgnoringImpCasts,MatchesWithoutImpCasts)4546 TEST(IgnoringImpCasts, MatchesWithoutImpCasts) {
4547   // This test verifies that expressions that do not have implicit casts
4548   // still match the inner matcher.
4549   EXPECT_TRUE(matches("int x = 0; int &y = x;",
4550                       varDecl(hasInitializer(ignoringImpCasts(
4551                         declRefExpr(to(varDecl(hasName("x")))))))));
4552 }
4553 
TEST(IgnoringParenCasts,MatchesParenCasts)4554 TEST(IgnoringParenCasts, MatchesParenCasts) {
4555   // This test checks that ignoringParenCasts matches when parentheses and/or
4556   // casts are present and its inner matcher alone does not match.
4557   EXPECT_TRUE(matches("int x = (0);",
4558                       varDecl(hasInitializer(ignoringParenCasts(
4559                         integerLiteral(equals(0)))))));
4560   EXPECT_TRUE(matches("int x = (((((0)))));",
4561                       varDecl(hasInitializer(ignoringParenCasts(
4562                         integerLiteral(equals(0)))))));
4563 
4564   // This test creates an implict cast from int to char in addition to the
4565   // parentheses.
4566   EXPECT_TRUE(matches("char x = (0);",
4567                       varDecl(hasInitializer(ignoringParenCasts(
4568                         integerLiteral(equals(0)))))));
4569 
4570   EXPECT_TRUE(matches("char x = (char)0;",
4571                       varDecl(hasInitializer(ignoringParenCasts(
4572                         integerLiteral(equals(0)))))));
4573   EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
4574                       varDecl(hasInitializer(ignoringParenCasts(
4575                         integerLiteral(equals(0)))))));
4576 }
4577 
TEST(IgnoringParenCasts,MatchesWithoutParenCasts)4578 TEST(IgnoringParenCasts, MatchesWithoutParenCasts) {
4579   // This test verifies that expressions that do not have any casts still match.
4580   EXPECT_TRUE(matches("int x = 0;",
4581                       varDecl(hasInitializer(ignoringParenCasts(
4582                         integerLiteral(equals(0)))))));
4583 }
4584 
TEST(IgnoringParenCasts,DoesNotMatchIncorrectly)4585 TEST(IgnoringParenCasts, DoesNotMatchIncorrectly) {
4586   // These tests verify that ignoringImpCasts does not match if the inner
4587   // matcher does not match.
4588   EXPECT_TRUE(notMatches("int x = ((0));",
4589                          varDecl(hasInitializer(ignoringParenCasts(
4590                            unless(anything()))))));
4591 
4592   // This test creates an implicit cast from int to char in addition to the
4593   // parentheses.
4594   EXPECT_TRUE(notMatches("char x = ((0));",
4595                          varDecl(hasInitializer(ignoringParenCasts(
4596                            unless(anything()))))));
4597 
4598   EXPECT_TRUE(notMatches("char *x = static_cast<char *>((0));",
4599                          varDecl(hasInitializer(ignoringParenCasts(
4600                            unless(anything()))))));
4601 }
4602 
TEST(IgnoringParenAndImpCasts,MatchesParenImpCasts)4603 TEST(IgnoringParenAndImpCasts, MatchesParenImpCasts) {
4604   // This test checks that ignoringParenAndImpCasts matches when
4605   // parentheses and/or implicit casts are present and its inner matcher alone
4606   // does not match.
4607   // Note that this test creates an implicit const cast.
4608   EXPECT_TRUE(matches("int x = 0; const int y = x;",
4609                       varDecl(hasInitializer(ignoringParenImpCasts(
4610                         declRefExpr(to(varDecl(hasName("x")))))))));
4611   // This test creates an implicit cast from int to char.
4612   EXPECT_TRUE(matches("const char x = (0);",
4613                       varDecl(hasInitializer(ignoringParenImpCasts(
4614                         integerLiteral(equals(0)))))));
4615 }
4616 
TEST(IgnoringParenAndImpCasts,MatchesWithoutParenImpCasts)4617 TEST(IgnoringParenAndImpCasts, MatchesWithoutParenImpCasts) {
4618   // This test verifies that expressions that do not have parentheses or
4619   // implicit casts still match.
4620   EXPECT_TRUE(matches("int x = 0; int &y = x;",
4621                       varDecl(hasInitializer(ignoringParenImpCasts(
4622                         declRefExpr(to(varDecl(hasName("x")))))))));
4623   EXPECT_TRUE(matches("int x = 0;",
4624                       varDecl(hasInitializer(ignoringParenImpCasts(
4625                         integerLiteral(equals(0)))))));
4626 }
4627 
TEST(IgnoringParenAndImpCasts,DoesNotMatchIncorrectly)4628 TEST(IgnoringParenAndImpCasts, DoesNotMatchIncorrectly) {
4629   // These tests verify that ignoringParenImpCasts does not match if
4630   // the inner matcher does not match.
4631   // This test creates an implicit cast.
4632   EXPECT_TRUE(notMatches("char c = ((3));",
4633                          varDecl(hasInitializer(ignoringParenImpCasts(
4634                            unless(anything()))))));
4635   // These tests verify that ignoringParenAndImplictCasts does not look
4636   // through explicit casts.
4637   EXPECT_TRUE(notMatches("float y = (float(0));",
4638                          varDecl(hasInitializer(ignoringParenImpCasts(
4639                            integerLiteral())))));
4640   EXPECT_TRUE(notMatches("float y = (float)0;",
4641                          varDecl(hasInitializer(ignoringParenImpCasts(
4642                            integerLiteral())))));
4643   EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
4644                          varDecl(hasInitializer(ignoringParenImpCasts(
4645                            integerLiteral())))));
4646 }
4647 
TEST(HasSourceExpression,MatchesImplicitCasts)4648 TEST(HasSourceExpression, MatchesImplicitCasts) {
4649   EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
4650                       "void r() {string a_string; URL url = a_string; }",
4651                       traverse(TK_AsIs, implicitCastExpr(hasSourceExpression(
4652                                             cxxConstructExpr())))));
4653 }
4654 
TEST(HasSourceExpression,MatchesExplicitCasts)4655 TEST(HasSourceExpression, MatchesExplicitCasts) {
4656   EXPECT_TRUE(
4657       matches("float x = static_cast<float>(42);",
4658               traverse(TK_AsIs, explicitCastExpr(hasSourceExpression(
4659                                     hasDescendant(expr(integerLiteral())))))));
4660 }
4661 
TEST(UsingDeclaration,MatchesSpecificTarget)4662 TEST(UsingDeclaration, MatchesSpecificTarget) {
4663   EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
4664                       usingDecl(hasAnyUsingShadowDecl(
4665                         hasTargetDecl(functionDecl())))));
4666   EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
4667                          usingDecl(hasAnyUsingShadowDecl(
4668                            hasTargetDecl(functionDecl())))));
4669 }
4670 
TEST(UsingDeclaration,ThroughUsingDeclaration)4671 TEST(UsingDeclaration, ThroughUsingDeclaration) {
4672   EXPECT_TRUE(matches(
4673     "namespace a { void f(); } using a::f; void g() { f(); }",
4674     declRefExpr(throughUsingDecl(anything()))));
4675   EXPECT_TRUE(notMatches(
4676     "namespace a { void f(); } using a::f; void g() { a::f(); }",
4677     declRefExpr(throughUsingDecl(anything()))));
4678 }
4679 
TEST(SingleDecl,IsSingleDecl)4680 TEST(SingleDecl, IsSingleDecl) {
4681   StatementMatcher SingleDeclStmt =
4682     declStmt(hasSingleDecl(varDecl(hasInitializer(anything()))));
4683   EXPECT_TRUE(matches("void f() {int a = 4;}", SingleDeclStmt));
4684   EXPECT_TRUE(notMatches("void f() {int a;}", SingleDeclStmt));
4685   EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
4686                          SingleDeclStmt));
4687 }
4688 
TEST(DeclStmt,ContainsDeclaration)4689 TEST(DeclStmt, ContainsDeclaration) {
4690   DeclarationMatcher MatchesInit = varDecl(hasInitializer(anything()));
4691 
4692   EXPECT_TRUE(matches("void f() {int a = 4;}",
4693                       declStmt(containsDeclaration(0, MatchesInit))));
4694   EXPECT_TRUE(matches("void f() {int a = 4, b = 3;}",
4695                       declStmt(containsDeclaration(0, MatchesInit),
4696                                containsDeclaration(1, MatchesInit))));
4697   unsigned WrongIndex = 42;
4698   EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
4699                          declStmt(containsDeclaration(WrongIndex,
4700                                                       MatchesInit))));
4701 }
4702 
TEST(SwitchCase,MatchesEachCase)4703 TEST(SwitchCase, MatchesEachCase) {
4704   EXPECT_TRUE(notMatches("void x() { switch(42); }",
4705                          switchStmt(forEachSwitchCase(caseStmt()))));
4706   EXPECT_TRUE(matches("void x() { switch(42) case 42:; }",
4707                       switchStmt(forEachSwitchCase(caseStmt()))));
4708   EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }",
4709                       switchStmt(forEachSwitchCase(caseStmt()))));
4710   EXPECT_TRUE(notMatches(
4711     "void x() { if (1) switch(42) { case 42: switch (42) { default:; } } }",
4712     ifStmt(has(switchStmt(forEachSwitchCase(defaultStmt()))))));
4713   EXPECT_TRUE(matches(
4714       "void x() { switch(42) { case 1+1: case 4:; } }",
4715       traverse(TK_AsIs, switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant(
4716                             constantExpr(has(integerLiteral())))))))));
4717   EXPECT_TRUE(notMatches(
4718       "void x() { switch(42) { case 1+1: case 2+2:; } }",
4719       traverse(TK_AsIs, switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant(
4720                             constantExpr(has(integerLiteral())))))))));
4721   EXPECT_TRUE(notMatches(
4722       "void x() { switch(42) { case 1 ... 2:; } }",
4723       traverse(TK_AsIs, switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant(
4724                             constantExpr(has(integerLiteral())))))))));
4725   EXPECT_TRUE(matchAndVerifyResultTrue(
4726     "void x() { switch (42) { case 1: case 2: case 3: default:; } }",
4727     switchStmt(forEachSwitchCase(caseStmt().bind("x"))),
4728     std::make_unique<VerifyIdIsBoundTo<CaseStmt>>("x", 3)));
4729 }
4730 
TEST(Declaration,HasExplicitSpecifier)4731 TEST(Declaration, HasExplicitSpecifier) {
4732 
4733   EXPECT_TRUE(notMatches("void f();",
4734                          functionDecl(hasExplicitSpecifier(constantExpr())),
4735                          langCxx20OrLater()));
4736   EXPECT_TRUE(
4737       notMatches("template<bool b> struct S { explicit operator int(); };",
4738                  cxxConversionDecl(
4739                      hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
4740                  langCxx20OrLater()));
4741   EXPECT_TRUE(
4742       notMatches("template<bool b> struct S { explicit(b) operator int(); };",
4743                  cxxConversionDecl(
4744                      hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
4745                  langCxx20OrLater()));
4746   EXPECT_TRUE(
4747       matches("struct S { explicit(true) operator int(); };",
4748               traverse(TK_AsIs, cxxConversionDecl(hasExplicitSpecifier(
4749                                     constantExpr(has(cxxBoolLiteral()))))),
4750               langCxx20OrLater()));
4751   EXPECT_TRUE(
4752       matches("struct S { explicit(false) operator int(); };",
4753               traverse(TK_AsIs, cxxConversionDecl(hasExplicitSpecifier(
4754                                     constantExpr(has(cxxBoolLiteral()))))),
4755               langCxx20OrLater()));
4756   EXPECT_TRUE(
4757       notMatches("template<bool b> struct S { explicit(b) S(int); };",
4758                  traverse(TK_AsIs, cxxConstructorDecl(hasExplicitSpecifier(
4759                                        constantExpr(has(cxxBoolLiteral()))))),
4760                  langCxx20OrLater()));
4761   EXPECT_TRUE(
4762       matches("struct S { explicit(true) S(int); };",
4763               traverse(TK_AsIs, cxxConstructorDecl(hasExplicitSpecifier(
4764                                     constantExpr(has(cxxBoolLiteral()))))),
4765               langCxx20OrLater()));
4766   EXPECT_TRUE(
4767       matches("struct S { explicit(false) S(int); };",
4768               traverse(TK_AsIs, cxxConstructorDecl(hasExplicitSpecifier(
4769                                     constantExpr(has(cxxBoolLiteral()))))),
4770               langCxx20OrLater()));
4771   EXPECT_TRUE(
4772       notMatches("template<typename T> struct S { S(int); };"
4773                  "template<bool b = true> explicit(b) S(int) -> S<int>;",
4774                  traverse(TK_AsIs, cxxDeductionGuideDecl(hasExplicitSpecifier(
4775                                        constantExpr(has(cxxBoolLiteral()))))),
4776                  langCxx20OrLater()));
4777   EXPECT_TRUE(
4778       matches("template<typename T> struct S { S(int); };"
4779               "explicit(true) S(int) -> S<int>;",
4780               traverse(TK_AsIs, cxxDeductionGuideDecl(hasExplicitSpecifier(
4781                                     constantExpr(has(cxxBoolLiteral()))))),
4782               langCxx20OrLater()));
4783   EXPECT_TRUE(
4784       matches("template<typename T> struct S { S(int); };"
4785               "explicit(false) S(int) -> S<int>;",
4786               traverse(TK_AsIs, cxxDeductionGuideDecl(hasExplicitSpecifier(
4787                                     constantExpr(has(cxxBoolLiteral()))))),
4788               langCxx20OrLater()));
4789 }
4790 
TEST(ForEachConstructorInitializer,MatchesInitializers)4791 TEST(ForEachConstructorInitializer, MatchesInitializers) {
4792   EXPECT_TRUE(matches(
4793     "struct X { X() : i(42), j(42) {} int i, j; };",
4794     cxxConstructorDecl(forEachConstructorInitializer(cxxCtorInitializer()))));
4795 }
4796 
TEST(ForEachLambdaCapture,MatchesCaptures)4797 TEST(ForEachLambdaCapture, MatchesCaptures) {
4798   EXPECT_TRUE(matches(
4799       "int main() { int x, y; auto f = [x, y]() { return x + y; }; }",
4800       lambdaExpr(forEachLambdaCapture(lambdaCapture())), langCxx11OrLater()));
4801   auto matcher = lambdaExpr(forEachLambdaCapture(
4802       lambdaCapture(capturesVar(varDecl(hasType(isInteger())))).bind("LC")));
4803   EXPECT_TRUE(matchAndVerifyResultTrue(
4804       "int main() { int x, y; float z; auto f = [=]() { return x + y + z; }; }",
4805       matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 2)));
4806   EXPECT_TRUE(matchAndVerifyResultTrue(
4807       "int main() { int x, y; float z; auto f = [x, y, z]() { return x + y + "
4808       "z; }; }",
4809       matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 2)));
4810 }
4811 
TEST(ForEachLambdaCapture,IgnoreUnlessSpelledInSource)4812 TEST(ForEachLambdaCapture, IgnoreUnlessSpelledInSource) {
4813   auto matcher =
4814       traverse(TK_IgnoreUnlessSpelledInSource,
4815                lambdaExpr(forEachLambdaCapture(
4816                    lambdaCapture(capturesVar(varDecl(hasType(isInteger()))))
4817                        .bind("LC"))));
4818   EXPECT_TRUE(
4819       notMatches("int main() { int x, y; auto f = [=]() { return x + y; }; }",
4820                  matcher, langCxx11OrLater()));
4821   EXPECT_TRUE(
4822       notMatches("int main() { int x, y; auto f = [&]() { return x + y; }; }",
4823                  matcher, langCxx11OrLater()));
4824   EXPECT_TRUE(matchAndVerifyResultTrue(
4825       R"cc(
4826       int main() {
4827         int x, y;
4828         float z;
4829         auto f = [=, &y]() { return x + y + z; };
4830       }
4831       )cc",
4832       matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 1)));
4833 }
4834 
TEST(ForEachLambdaCapture,MatchImplicitCapturesOnly)4835 TEST(ForEachLambdaCapture, MatchImplicitCapturesOnly) {
4836   auto matcher =
4837       lambdaExpr(forEachLambdaCapture(lambdaCapture(isImplicit()).bind("LC")));
4838   EXPECT_TRUE(matchAndVerifyResultTrue(
4839       "int main() { int x, y, z; auto f = [=, &z]() { return x + y + z; }; }",
4840       matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 2)));
4841   EXPECT_TRUE(matchAndVerifyResultTrue(
4842       "int main() { int x, y, z; auto f = [&, z]() { return x + y + z; }; }",
4843       matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 2)));
4844 }
4845 
TEST(ForEachLambdaCapture,MatchExplicitCapturesOnly)4846 TEST(ForEachLambdaCapture, MatchExplicitCapturesOnly) {
4847   auto matcher = lambdaExpr(
4848       forEachLambdaCapture(lambdaCapture(unless(isImplicit())).bind("LC")));
4849   EXPECT_TRUE(matchAndVerifyResultTrue(
4850       "int main() { int x, y, z; auto f = [=, &z]() { return x + y + z; }; }",
4851       matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 1)));
4852   EXPECT_TRUE(matchAndVerifyResultTrue(
4853       "int main() { int x, y, z; auto f = [&, z]() { return x + y + z; }; }",
4854       matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 1)));
4855 }
4856 
TEST(HasConditionVariableStatement,DoesNotMatchCondition)4857 TEST(HasConditionVariableStatement, DoesNotMatchCondition) {
4858   EXPECT_TRUE(notMatches(
4859     "void x() { if(true) {} }",
4860     ifStmt(hasConditionVariableStatement(declStmt()))));
4861   EXPECT_TRUE(notMatches(
4862     "void x() { int x; if((x = 42)) {} }",
4863     ifStmt(hasConditionVariableStatement(declStmt()))));
4864 }
4865 
TEST(HasConditionVariableStatement,MatchesConditionVariables)4866 TEST(HasConditionVariableStatement, MatchesConditionVariables) {
4867   EXPECT_TRUE(matches(
4868     "void x() { if(int* a = 0) {} }",
4869     ifStmt(hasConditionVariableStatement(declStmt()))));
4870 }
4871 
TEST(ForEach,BindsOneNode)4872 TEST(ForEach, BindsOneNode) {
4873   EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
4874                                        recordDecl(hasName("C"), forEach(fieldDecl(hasName("x")).bind("x"))),
4875                                        std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("x", 1)));
4876 }
4877 
TEST(ForEach,BindsMultipleNodes)4878 TEST(ForEach, BindsMultipleNodes) {
4879   EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
4880                                        recordDecl(hasName("C"), forEach(fieldDecl().bind("f"))),
4881                                        std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 3)));
4882 }
4883 
TEST(ForEach,BindsRecursiveCombinations)4884 TEST(ForEach, BindsRecursiveCombinations) {
4885   EXPECT_TRUE(matchAndVerifyResultTrue(
4886     "class C { class D { int x; int y; }; class E { int y; int z; }; };",
4887     recordDecl(hasName("C"),
4888                forEach(recordDecl(forEach(fieldDecl().bind("f"))))),
4889     std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 4)));
4890 }
4891 
TEST(ForEach,DoesNotIgnoreImplicit)4892 TEST(ForEach, DoesNotIgnoreImplicit) {
4893   StringRef Code = R"cpp(
4894 void foo()
4895 {
4896     int i = 0;
4897     int b = 4;
4898     i < b;
4899 }
4900 )cpp";
4901   EXPECT_TRUE(matchAndVerifyResultFalse(
4902       Code, binaryOperator(forEach(declRefExpr().bind("dre"))),
4903       std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 0)));
4904 
4905   EXPECT_TRUE(matchAndVerifyResultTrue(
4906       Code,
4907       binaryOperator(forEach(
4908           implicitCastExpr(hasSourceExpression(declRefExpr().bind("dre"))))),
4909       std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 2)));
4910 
4911   EXPECT_TRUE(matchAndVerifyResultTrue(
4912       Code,
4913       binaryOperator(
4914           forEach(expr(ignoringImplicit(declRefExpr().bind("dre"))))),
4915       std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 2)));
4916 
4917   EXPECT_TRUE(matchAndVerifyResultTrue(
4918       Code,
4919       traverse(TK_IgnoreUnlessSpelledInSource,
4920                binaryOperator(forEach(declRefExpr().bind("dre")))),
4921       std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 2)));
4922 }
4923 
TEST(ForEachDescendant,BindsOneNode)4924 TEST(ForEachDescendant, BindsOneNode) {
4925   EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
4926                                        recordDecl(hasName("C"),
4927                                                   forEachDescendant(fieldDecl(hasName("x")).bind("x"))),
4928                                        std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("x", 1)));
4929 }
4930 
TEST(ForEachDescendant,NestedForEachDescendant)4931 TEST(ForEachDescendant, NestedForEachDescendant) {
4932   DeclarationMatcher m = recordDecl(
4933     isDefinition(), decl().bind("x"), hasName("C"));
4934   EXPECT_TRUE(matchAndVerifyResultTrue(
4935     "class A { class B { class C {}; }; };",
4936     recordDecl(hasName("A"), anyOf(m, forEachDescendant(m))),
4937     std::make_unique<VerifyIdIsBoundTo<Decl>>("x", "C")));
4938 
4939   // Check that a partial match of 'm' that binds 'x' in the
4940   // first part of anyOf(m, anything()) will not overwrite the
4941   // binding created by the earlier binding in the hasDescendant.
4942   EXPECT_TRUE(matchAndVerifyResultTrue(
4943     "class A { class B { class C {}; }; };",
4944     recordDecl(hasName("A"), allOf(hasDescendant(m), anyOf(m, anything()))),
4945     std::make_unique<VerifyIdIsBoundTo<Decl>>("x", "C")));
4946 }
4947 
TEST(ForEachDescendant,BindsMultipleNodes)4948 TEST(ForEachDescendant, BindsMultipleNodes) {
4949   EXPECT_TRUE(matchAndVerifyResultTrue(
4950     "class C { class D { int x; int y; }; "
4951       "          class E { class F { int y; int z; }; }; };",
4952     recordDecl(hasName("C"), forEachDescendant(fieldDecl().bind("f"))),
4953     std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 4)));
4954 }
4955 
TEST(ForEachDescendant,BindsRecursiveCombinations)4956 TEST(ForEachDescendant, BindsRecursiveCombinations) {
4957   EXPECT_TRUE(matchAndVerifyResultTrue(
4958     "class C { class D { "
4959       "          class E { class F { class G { int y; int z; }; }; }; }; };",
4960     recordDecl(hasName("C"), forEachDescendant(recordDecl(
4961       forEachDescendant(fieldDecl().bind("f"))))),
4962     std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 8)));
4963 }
4964 
TEST(ForEachDescendant,BindsCombinations)4965 TEST(ForEachDescendant, BindsCombinations) {
4966   EXPECT_TRUE(matchAndVerifyResultTrue(
4967     "void f() { if(true) {} if (true) {} while (true) {} if (true) {} while "
4968       "(true) {} }",
4969     compoundStmt(forEachDescendant(ifStmt().bind("if")),
4970                  forEachDescendant(whileStmt().bind("while"))),
4971     std::make_unique<VerifyIdIsBoundTo<IfStmt>>("if", 6)));
4972 }
4973 
TEST(ForEachTemplateArgument,OnFunctionDecl)4974 TEST(ForEachTemplateArgument, OnFunctionDecl) {
4975   const std::string Code = R"(
4976 template <typename T, typename U> void f(T, U) {}
4977 void test() {
4978   int I = 1;
4979   bool B = false;
4980   f(I, B);
4981 })";
4982   EXPECT_TRUE(matches(
4983       Code, functionDecl(forEachTemplateArgument(refersToType(builtinType()))),
4984       langCxx11OrLater()));
4985   auto matcher =
4986       functionDecl(forEachTemplateArgument(
4987                        templateArgument(refersToType(builtinType().bind("BT")))
4988                            .bind("TA")))
4989           .bind("FN");
4990 
4991   EXPECT_TRUE(matchAndVerifyResultTrue(
4992       Code, matcher,
4993       std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("FN", 2)));
4994   EXPECT_TRUE(matchAndVerifyResultTrue(
4995       Code, matcher,
4996       std::make_unique<VerifyIdIsBoundTo<TemplateArgument>>("TA", 2)));
4997   EXPECT_TRUE(matchAndVerifyResultTrue(
4998       Code, matcher,
4999       std::make_unique<VerifyIdIsBoundTo<BuiltinType>>("BT", 2)));
5000 }
5001 
TEST(ForEachTemplateArgument,OnClassTemplateSpecialization)5002 TEST(ForEachTemplateArgument, OnClassTemplateSpecialization) {
5003   const std::string Code = R"(
5004 template <typename T, unsigned N, unsigned M>
5005 struct Matrix {};
5006 
5007 static constexpr unsigned R = 2;
5008 
5009 Matrix<int, R * 2, R * 4> M;
5010 )";
5011   EXPECT_TRUE(matches(
5012       Code, templateSpecializationType(forEachTemplateArgument(isExpr(expr()))),
5013       langCxx11OrLater()));
5014   auto matcher = templateSpecializationType(
5015                      forEachTemplateArgument(
5016                          templateArgument(isExpr(expr().bind("E"))).bind("TA")))
5017                      .bind("TST");
5018 
5019   EXPECT_TRUE(matchAndVerifyResultTrue(
5020       Code, matcher,
5021       std::make_unique<VerifyIdIsBoundTo<TemplateSpecializationType>>("TST",
5022                                                                       2)));
5023   EXPECT_TRUE(matchAndVerifyResultTrue(
5024       Code, matcher,
5025       std::make_unique<VerifyIdIsBoundTo<TemplateArgument>>("TA", 2)));
5026   EXPECT_TRUE(matchAndVerifyResultTrue(
5027       Code, matcher, std::make_unique<VerifyIdIsBoundTo<Expr>>("E", 2)));
5028 }
5029 
TEST(Has,DoesNotDeleteBindings)5030 TEST(Has, DoesNotDeleteBindings) {
5031   EXPECT_TRUE(matchAndVerifyResultTrue(
5032     "class X { int a; };", recordDecl(decl().bind("x"), has(fieldDecl())),
5033     std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5034 }
5035 
TEST(TemplateArgumentLoc,Matches)5036 TEST(TemplateArgumentLoc, Matches) {
5037   EXPECT_TRUE(matchAndVerifyResultTrue(
5038       R"cpp(
5039         template <typename A, int B, template <typename> class C> class X {};
5040         class A {};
5041         const int B = 42;
5042         template <typename> class C {};
5043         X<A, B, C> x;
5044       )cpp",
5045       templateArgumentLoc().bind("x"),
5046       std::make_unique<VerifyIdIsBoundTo<TemplateArgumentLoc>>("x", 3)));
5047 }
5048 
TEST(LoopingMatchers,DoNotOverwritePreviousMatchResultOnFailure)5049 TEST(LoopingMatchers, DoNotOverwritePreviousMatchResultOnFailure) {
5050   // Those matchers cover all the cases where an inner matcher is called
5051   // and there is not a 1:1 relationship between the match of the outer
5052   // matcher and the match of the inner matcher.
5053   // The pattern to look for is:
5054   //   ... return InnerMatcher.matches(...); ...
5055   // In which case no special handling is needed.
5056   //
5057   // On the other hand, if there are multiple alternative matches
5058   // (for example forEach*) or matches might be discarded (for example has*)
5059   // the implementation must make sure that the discarded matches do not
5060   // affect the bindings.
5061   // When new such matchers are added, add a test here that:
5062   // - matches a simple node, and binds it as the first thing in the matcher:
5063   //     recordDecl(decl().bind("x"), hasName("X")))
5064   // - uses the matcher under test afterwards in a way that not the first
5065   //   alternative is matched; for anyOf, that means the first branch
5066   //   would need to return false; for hasAncestor, it means that not
5067   //   the direct parent matches the inner matcher.
5068 
5069   EXPECT_TRUE(matchAndVerifyResultTrue(
5070     "class X { int y; };",
5071     recordDecl(
5072       recordDecl().bind("x"), hasName("::X"),
5073       anyOf(forEachDescendant(recordDecl(hasName("Y"))), anything())),
5074     std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("x", 1)));
5075   EXPECT_TRUE(matchAndVerifyResultTrue(
5076     "class X {};", recordDecl(recordDecl().bind("x"), hasName("::X"),
5077                               anyOf(unless(anything()), anything())),
5078     std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("x", 1)));
5079   EXPECT_TRUE(matchAndVerifyResultTrue(
5080     "template<typename T1, typename T2> class X {}; X<float, int> x;",
5081     classTemplateSpecializationDecl(
5082       decl().bind("x"),
5083       hasAnyTemplateArgument(refersToType(asString("int")))),
5084     std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5085   EXPECT_TRUE(matchAndVerifyResultTrue(
5086     "class X { void f(); void g(); };",
5087     cxxRecordDecl(decl().bind("x"), hasMethod(hasName("g"))),
5088     std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5089   EXPECT_TRUE(matchAndVerifyResultTrue(
5090     "class X { X() : a(1), b(2) {} double a; int b; };",
5091     recordDecl(decl().bind("x"),
5092                has(cxxConstructorDecl(
5093                  hasAnyConstructorInitializer(forField(hasName("b")))))),
5094     std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5095   EXPECT_TRUE(matchAndVerifyResultTrue(
5096     "void x(int, int) { x(0, 42); }",
5097     callExpr(expr().bind("x"), hasAnyArgument(integerLiteral(equals(42)))),
5098     std::make_unique<VerifyIdIsBoundTo<Expr>>("x", 1)));
5099   EXPECT_TRUE(matchAndVerifyResultTrue(
5100     "void x(int, int y) {}",
5101     functionDecl(decl().bind("x"), hasAnyParameter(hasName("y"))),
5102     std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5103   EXPECT_TRUE(matchAndVerifyResultTrue(
5104     "void x() { return; if (true) {} }",
5105     functionDecl(decl().bind("x"),
5106                  has(compoundStmt(hasAnySubstatement(ifStmt())))),
5107     std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5108   EXPECT_TRUE(matchAndVerifyResultTrue(
5109     "namespace X { void b(int); void b(); }"
5110       "using X::b;",
5111     usingDecl(decl().bind("x"), hasAnyUsingShadowDecl(hasTargetDecl(
5112       functionDecl(parameterCountIs(1))))),
5113     std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5114   EXPECT_TRUE(matchAndVerifyResultTrue(
5115     "class A{}; class B{}; class C : B, A {};",
5116     cxxRecordDecl(decl().bind("x"), isDerivedFrom("::A")),
5117     std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5118   EXPECT_TRUE(matchAndVerifyResultTrue(
5119     "class A{}; typedef A B; typedef A C; typedef A D;"
5120       "class E : A {};",
5121     cxxRecordDecl(decl().bind("x"), isDerivedFrom("C")),
5122     std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5123   EXPECT_TRUE(matchAndVerifyResultTrue(
5124     "class A { class B { void f() {} }; };",
5125     functionDecl(decl().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
5126     std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5127   EXPECT_TRUE(matchAndVerifyResultTrue(
5128     "template <typename T> struct A { struct B {"
5129       "  void f() { if(true) {} }"
5130       "}; };"
5131       "void t() { A<int>::B b; b.f(); }",
5132     ifStmt(stmt().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
5133     std::make_unique<VerifyIdIsBoundTo<Stmt>>("x", 2)));
5134   EXPECT_TRUE(matchAndVerifyResultTrue(
5135     "class A {};",
5136     recordDecl(hasName("::A"), decl().bind("x"), unless(hasName("fooble"))),
5137     std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5138   EXPECT_TRUE(matchAndVerifyResultTrue(
5139     "class A { A() : s(), i(42) {} const char *s; int i; };",
5140     cxxConstructorDecl(hasName("::A::A"), decl().bind("x"),
5141                        forEachConstructorInitializer(forField(hasName("i")))),
5142     std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5143 }
5144 
TEST(ForEachDescendant,BindsCorrectNodes)5145 TEST(ForEachDescendant, BindsCorrectNodes) {
5146   EXPECT_TRUE(matchAndVerifyResultTrue(
5147     "class C { void f(); int i; };",
5148     recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
5149     std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("decl", 1)));
5150   EXPECT_TRUE(matchAndVerifyResultTrue(
5151     "class C { void f() {} int i; };",
5152     recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
5153     std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("decl", 1)));
5154 }
5155 
TEST(FindAll,BindsNodeOnMatch)5156 TEST(FindAll, BindsNodeOnMatch) {
5157   EXPECT_TRUE(matchAndVerifyResultTrue(
5158     "class A {};",
5159     recordDecl(hasName("::A"), findAll(recordDecl(hasName("::A")).bind("v"))),
5160     std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("v", 1)));
5161 }
5162 
TEST(FindAll,BindsDescendantNodeOnMatch)5163 TEST(FindAll, BindsDescendantNodeOnMatch) {
5164   EXPECT_TRUE(matchAndVerifyResultTrue(
5165     "class A { int a; int b; };",
5166     recordDecl(hasName("::A"), findAll(fieldDecl().bind("v"))),
5167     std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 2)));
5168 }
5169 
TEST(FindAll,BindsNodeAndDescendantNodesOnOneMatch)5170 TEST(FindAll, BindsNodeAndDescendantNodesOnOneMatch) {
5171   EXPECT_TRUE(matchAndVerifyResultTrue(
5172     "class A { int a; int b; };",
5173     recordDecl(hasName("::A"),
5174                findAll(decl(anyOf(recordDecl(hasName("::A")).bind("v"),
5175                                   fieldDecl().bind("v"))))),
5176     std::make_unique<VerifyIdIsBoundTo<Decl>>("v", 3)));
5177 
5178   EXPECT_TRUE(matchAndVerifyResultTrue(
5179     "class A { class B {}; class C {}; };",
5180     recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("v"))),
5181     std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("v", 3)));
5182 }
5183 
TEST(HasAncenstor,MatchesDeclarationAncestors)5184 TEST(HasAncenstor, MatchesDeclarationAncestors) {
5185   EXPECT_TRUE(matches(
5186     "class A { class B { class C {}; }; };",
5187     recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("A"))))));
5188 }
5189 
TEST(HasAncenstor,FailsIfNoAncestorMatches)5190 TEST(HasAncenstor, FailsIfNoAncestorMatches) {
5191   EXPECT_TRUE(notMatches(
5192     "class A { class B { class C {}; }; };",
5193     recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("X"))))));
5194 }
5195 
TEST(HasAncestor,MatchesDeclarationsThatGetVisitedLater)5196 TEST(HasAncestor, MatchesDeclarationsThatGetVisitedLater) {
5197   EXPECT_TRUE(matches(
5198     "class A { class B { void f() { C c; } class C {}; }; };",
5199     varDecl(hasName("c"), hasType(recordDecl(hasName("C"),
5200                                              hasAncestor(recordDecl(hasName("A"))))))));
5201 }
5202 
TEST(HasAncenstor,MatchesStatementAncestors)5203 TEST(HasAncenstor, MatchesStatementAncestors) {
5204   EXPECT_TRUE(matches(
5205     "void f() { if (true) { while (false) { 42; } } }",
5206     integerLiteral(equals(42), hasAncestor(ifStmt()))));
5207 }
5208 
TEST(HasAncestor,DrillsThroughDifferentHierarchies)5209 TEST(HasAncestor, DrillsThroughDifferentHierarchies) {
5210   EXPECT_TRUE(matches(
5211     "void f() { if (true) { int x = 42; } }",
5212     integerLiteral(equals(42), hasAncestor(functionDecl(hasName("f"))))));
5213 }
5214 
TEST(HasAncestor,BindsRecursiveCombinations)5215 TEST(HasAncestor, BindsRecursiveCombinations) {
5216   EXPECT_TRUE(matchAndVerifyResultTrue(
5217     "class C { class D { class E { class F { int y; }; }; }; };",
5218     fieldDecl(hasAncestor(recordDecl(hasAncestor(recordDecl().bind("r"))))),
5219     std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("r", 1)));
5220 }
5221 
TEST(HasAncestor,BindsCombinationsWithHasDescendant)5222 TEST(HasAncestor, BindsCombinationsWithHasDescendant) {
5223   EXPECT_TRUE(matchAndVerifyResultTrue(
5224     "class C { class D { class E { class F { int y; }; }; }; };",
5225     fieldDecl(hasAncestor(
5226       decl(
5227         hasDescendant(recordDecl(isDefinition(),
5228                                  hasAncestor(recordDecl())))
5229       ).bind("d")
5230     )),
5231     std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("d", "E")));
5232 }
5233 
TEST(HasAncestor,MatchesClosestAncestor)5234 TEST(HasAncestor, MatchesClosestAncestor) {
5235   EXPECT_TRUE(matchAndVerifyResultTrue(
5236     "template <typename T> struct C {"
5237       "  void f(int) {"
5238       "    struct I { void g(T) { int x; } } i; i.g(42);"
5239       "  }"
5240       "};"
5241       "template struct C<int>;",
5242     varDecl(hasName("x"),
5243             hasAncestor(functionDecl(hasParameter(
5244               0, varDecl(hasType(asString("int"))))).bind("f"))).bind("v"),
5245     std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("f", "g", 2)));
5246 }
5247 
TEST(HasAncestor,MatchesInTemplateInstantiations)5248 TEST(HasAncestor, MatchesInTemplateInstantiations) {
5249   EXPECT_TRUE(matches(
5250     "template <typename T> struct A { struct B { struct C { T t; }; }; }; "
5251       "A<int>::B::C a;",
5252     fieldDecl(hasType(asString("int")),
5253               hasAncestor(recordDecl(hasName("A"))))));
5254 }
5255 
TEST(HasAncestor,MatchesInImplicitCode)5256 TEST(HasAncestor, MatchesInImplicitCode) {
5257   EXPECT_TRUE(matches(
5258     "struct X {}; struct A { A() {} X x; };",
5259     cxxConstructorDecl(
5260       hasAnyConstructorInitializer(withInitializer(expr(
5261         hasAncestor(recordDecl(hasName("A")))))))));
5262 }
5263 
TEST(HasParent,MatchesOnlyParent)5264 TEST(HasParent, MatchesOnlyParent) {
5265   EXPECT_TRUE(matches(
5266     "void f() { if (true) { int x = 42; } }",
5267     compoundStmt(hasParent(ifStmt()))));
5268   EXPECT_TRUE(notMatches(
5269     "void f() { for (;;) { int x = 42; } }",
5270     compoundStmt(hasParent(ifStmt()))));
5271   EXPECT_TRUE(notMatches(
5272     "void f() { if (true) for (;;) { int x = 42; } }",
5273     compoundStmt(hasParent(ifStmt()))));
5274 }
5275 
TEST(MatcherMemoize,HasParentDiffersFromHas)5276 TEST(MatcherMemoize, HasParentDiffersFromHas) {
5277   // Test introduced after detecting a bug in memoization
5278   constexpr auto code = "void f() { throw 1; }";
5279   EXPECT_TRUE(notMatches(
5280     code,
5281     cxxThrowExpr(hasParent(expr()))));
5282   EXPECT_TRUE(matches(
5283     code,
5284     cxxThrowExpr(has(expr()))));
5285   EXPECT_TRUE(matches(
5286     code,
5287     cxxThrowExpr(anyOf(hasParent(expr()), has(expr())))));
5288 }
5289 
TEST(MatcherMemoize,HasDiffersFromHasDescendant)5290 TEST(MatcherMemoize, HasDiffersFromHasDescendant) {
5291   // Test introduced after detecting a bug in memoization
5292   constexpr auto code = "void f() { throw 1+1; }";
5293   EXPECT_TRUE(notMatches(
5294     code,
5295     cxxThrowExpr(has(integerLiteral()))));
5296   EXPECT_TRUE(matches(
5297     code,
5298     cxxThrowExpr(hasDescendant(integerLiteral()))));
5299   EXPECT_TRUE(
5300       notMatches(code, cxxThrowExpr(allOf(hasDescendant(integerLiteral()),
5301                                           has(integerLiteral())))));
5302 }
TEST(HasAncestor,MatchesAllAncestors)5303 TEST(HasAncestor, MatchesAllAncestors) {
5304   EXPECT_TRUE(matches(
5305     "template <typename T> struct C { static void f() { 42; } };"
5306       "void t() { C<int>::f(); }",
5307     integerLiteral(
5308       equals(42),
5309       allOf(
5310         hasAncestor(cxxRecordDecl(isTemplateInstantiation())),
5311         hasAncestor(cxxRecordDecl(unless(isTemplateInstantiation())))))));
5312 }
5313 
TEST(HasAncestor,ImplicitArrayCopyCtorDeclRefExpr)5314 TEST(HasAncestor, ImplicitArrayCopyCtorDeclRefExpr) {
5315   EXPECT_TRUE(matches("struct MyClass {\n"
5316                         "  int c[1];\n"
5317                         "  static MyClass Create() { return MyClass(); }\n"
5318                         "};",
5319                       declRefExpr(to(decl(hasAncestor(decl()))))));
5320 }
5321 
TEST(HasAncestor,AnonymousUnionMemberExpr)5322 TEST(HasAncestor, AnonymousUnionMemberExpr) {
5323   EXPECT_TRUE(matches("int F() {\n"
5324                         "  union { int i; };\n"
5325                         "  return i;\n"
5326                         "}\n",
5327                       memberExpr(member(hasAncestor(decl())))));
5328   EXPECT_TRUE(matches("void f() {\n"
5329                         "  struct {\n"
5330                         "    struct { int a; int b; };\n"
5331                         "  } s;\n"
5332                         "  s.a = 4;\n"
5333                         "}\n",
5334                       memberExpr(member(hasAncestor(decl())))));
5335   EXPECT_TRUE(matches("void f() {\n"
5336                         "  struct {\n"
5337                         "    struct { int a; int b; };\n"
5338                         "  } s;\n"
5339                         "  s.a = 4;\n"
5340                         "}\n",
5341                       declRefExpr(to(decl(hasAncestor(decl()))))));
5342 }
TEST(HasAncestor,NonParmDependentTemplateParmVarDeclRefExpr)5343 TEST(HasAncestor, NonParmDependentTemplateParmVarDeclRefExpr) {
5344   EXPECT_TRUE(matches("struct PartitionAllocator {\n"
5345                         "  template<typename T>\n"
5346                         "  static int quantizedSize(int count) {\n"
5347                         "    return count;\n"
5348                         "  }\n"
5349                         "  void f() { quantizedSize<int>(10); }\n"
5350                         "};",
5351                       declRefExpr(to(decl(hasAncestor(decl()))))));
5352 }
5353 
TEST(HasAncestor,AddressOfExplicitSpecializationFunction)5354 TEST(HasAncestor, AddressOfExplicitSpecializationFunction) {
5355   EXPECT_TRUE(matches("template <class T> void f();\n"
5356                         "template <> void f<int>();\n"
5357                         "void (*get_f())() { return f<int>; }\n",
5358                       declRefExpr(to(decl(hasAncestor(decl()))))));
5359 }
5360 
TEST(HasParent,MatchesAllParents)5361 TEST(HasParent, MatchesAllParents) {
5362   EXPECT_TRUE(matches(
5363     "template <typename T> struct C { static void f() { 42; } };"
5364       "void t() { C<int>::f(); }",
5365     integerLiteral(
5366       equals(42),
5367       hasParent(compoundStmt(hasParent(functionDecl(
5368         hasParent(cxxRecordDecl(isTemplateInstantiation())))))))));
5369   EXPECT_TRUE(
5370     matches("template <typename T> struct C { static void f() { 42; } };"
5371               "void t() { C<int>::f(); }",
5372             integerLiteral(
5373               equals(42),
5374               hasParent(compoundStmt(hasParent(functionDecl(hasParent(
5375                 cxxRecordDecl(unless(isTemplateInstantiation()))))))))));
5376   EXPECT_TRUE(matches(
5377     "template <typename T> struct C { static void f() { 42; } };"
5378       "void t() { C<int>::f(); }",
5379     integerLiteral(equals(42),
5380                    hasParent(compoundStmt(
5381                      allOf(hasParent(functionDecl(hasParent(
5382                        cxxRecordDecl(isTemplateInstantiation())))),
5383                            hasParent(functionDecl(hasParent(cxxRecordDecl(
5384                              unless(isTemplateInstantiation())))))))))));
5385   EXPECT_TRUE(
5386     notMatches("template <typename T> struct C { static void f() {} };"
5387                  "void t() { C<int>::f(); }",
5388                compoundStmt(hasParent(recordDecl()))));
5389 }
5390 
TEST(HasParent,NoDuplicateParents)5391 TEST(HasParent, NoDuplicateParents) {
5392   class HasDuplicateParents : public BoundNodesCallback {
5393   public:
5394     bool run(const BoundNodes *Nodes) override { return false; }
5395     bool run(const BoundNodes *Nodes, ASTContext *Context) override {
5396       const Stmt *Node = Nodes->getNodeAs<Stmt>("node");
5397       std::set<const void *> Parents;
5398       for (const auto &Parent : Context->getParents(*Node)) {
5399         if (!Parents.insert(Parent.getMemoizationData()).second) {
5400           return true;
5401         }
5402       }
5403       return false;
5404     }
5405   };
5406   EXPECT_FALSE(matchAndVerifyResultTrue(
5407     "template <typename T> int Foo() { return 1 + 2; }\n"
5408       "int x = Foo<int>() + Foo<unsigned>();",
5409     stmt().bind("node"), std::make_unique<HasDuplicateParents>()));
5410 }
5411 
TEST(TypeMatching,PointeeTypes)5412 TEST(TypeMatching, PointeeTypes) {
5413   EXPECT_TRUE(matches("int b; int &a = b;",
5414                       referenceType(pointee(builtinType()))));
5415   EXPECT_TRUE(matches("int *a;", pointerType(pointee(builtinType()))));
5416 
5417   EXPECT_TRUE(matches("int *a;",
5418                       loc(pointerType(pointee(builtinType())))));
5419 
5420   EXPECT_TRUE(matches(
5421     "int const *A;",
5422     pointerType(pointee(isConstQualified(), builtinType()))));
5423   EXPECT_TRUE(notMatches(
5424     "int *A;",
5425     pointerType(pointee(isConstQualified(), builtinType()))));
5426 }
5427 
TEST(ElaboratedTypeNarrowing,hasQualifier)5428 TEST(ElaboratedTypeNarrowing, hasQualifier) {
5429   EXPECT_TRUE(matches(
5430     "namespace N {"
5431       "  namespace M {"
5432       "    class D {};"
5433       "  }"
5434       "}"
5435       "N::M::D d;",
5436     elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
5437   EXPECT_TRUE(notMatches(
5438     "namespace M {"
5439       "  class D {};"
5440       "}"
5441       "M::D d;",
5442     elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
5443   EXPECT_TRUE(notMatches(
5444     "struct D {"
5445       "} d;",
5446     elaboratedType(hasQualifier(nestedNameSpecifier()))));
5447 }
5448 
TEST(ElaboratedTypeNarrowing,namesType)5449 TEST(ElaboratedTypeNarrowing, namesType) {
5450   EXPECT_TRUE(matches(
5451     "namespace N {"
5452       "  namespace M {"
5453       "    class D {};"
5454       "  }"
5455       "}"
5456       "N::M::D d;",
5457     elaboratedType(elaboratedType(namesType(recordType(
5458       hasDeclaration(namedDecl(hasName("D")))))))));
5459   EXPECT_TRUE(notMatches(
5460     "namespace M {"
5461       "  class D {};"
5462       "}"
5463       "M::D d;",
5464     elaboratedType(elaboratedType(namesType(typedefType())))));
5465 }
5466 
TEST(NNS,BindsNestedNameSpecifiers)5467 TEST(NNS, BindsNestedNameSpecifiers) {
5468   EXPECT_TRUE(matchAndVerifyResultTrue(
5469     "namespace ns { struct E { struct B {}; }; } ns::E::B b;",
5470     nestedNameSpecifier(specifiesType(asString("struct ns::E"))).bind("nns"),
5471     std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>(
5472       "nns", "ns::struct E::")));
5473 }
5474 
TEST(NNS,BindsNestedNameSpecifierLocs)5475 TEST(NNS, BindsNestedNameSpecifierLocs) {
5476   EXPECT_TRUE(matchAndVerifyResultTrue(
5477     "namespace ns { struct B {}; } ns::B b;",
5478     loc(nestedNameSpecifier()).bind("loc"),
5479     std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifierLoc>>("loc", 1)));
5480 }
5481 
TEST(NNS,DescendantsOfNestedNameSpecifiers)5482 TEST(NNS, DescendantsOfNestedNameSpecifiers) {
5483   StringRef Fragment =
5484       "namespace a { struct A { struct B { struct C {}; }; }; };"
5485       "void f() { a::A::B::C c; }";
5486   EXPECT_TRUE(matches(
5487     Fragment,
5488     nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
5489                         hasDescendant(nestedNameSpecifier(
5490                           specifiesNamespace(hasName("a")))))));
5491   EXPECT_TRUE(notMatches(
5492     Fragment,
5493     nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
5494                         has(nestedNameSpecifier(
5495                           specifiesNamespace(hasName("a")))))));
5496   EXPECT_TRUE(matches(
5497     Fragment,
5498     nestedNameSpecifier(specifiesType(asString("struct a::A")),
5499                         has(nestedNameSpecifier(
5500                           specifiesNamespace(hasName("a")))))));
5501 
5502   // Not really useful because a NestedNameSpecifier can af at most one child,
5503   // but to complete the interface.
5504   EXPECT_TRUE(matchAndVerifyResultTrue(
5505     Fragment,
5506     nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
5507                         forEach(nestedNameSpecifier().bind("x"))),
5508     std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>("x", 1)));
5509 }
5510 
TEST(NNS,NestedNameSpecifiersAsDescendants)5511 TEST(NNS, NestedNameSpecifiersAsDescendants) {
5512   StringRef Fragment =
5513       "namespace a { struct A { struct B { struct C {}; }; }; };"
5514       "void f() { a::A::B::C c; }";
5515   EXPECT_TRUE(matches(
5516     Fragment,
5517     decl(hasDescendant(nestedNameSpecifier(specifiesType(
5518       asString("struct a::A")))))));
5519   EXPECT_TRUE(matchAndVerifyResultTrue(
5520     Fragment,
5521     functionDecl(hasName("f"),
5522                  forEachDescendant(nestedNameSpecifier().bind("x"))),
5523     // Nested names: a, a::A and a::A::B.
5524     std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>("x", 3)));
5525 }
5526 
TEST(NNSLoc,DescendantsOfNestedNameSpecifierLocs)5527 TEST(NNSLoc, DescendantsOfNestedNameSpecifierLocs) {
5528   StringRef Fragment =
5529       "namespace a { struct A { struct B { struct C {}; }; }; };"
5530       "void f() { a::A::B::C c; }";
5531   EXPECT_TRUE(matches(
5532     Fragment,
5533     nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5534                            hasDescendant(loc(nestedNameSpecifier(
5535                              specifiesNamespace(hasName("a"))))))));
5536   EXPECT_TRUE(notMatches(
5537     Fragment,
5538     nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5539                            has(loc(nestedNameSpecifier(
5540                              specifiesNamespace(hasName("a"))))))));
5541   EXPECT_TRUE(matches(
5542     Fragment,
5543     nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A"))),
5544                            has(loc(nestedNameSpecifier(
5545                              specifiesNamespace(hasName("a"))))))));
5546 
5547   EXPECT_TRUE(matchAndVerifyResultTrue(
5548     Fragment,
5549     nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5550                            forEach(nestedNameSpecifierLoc().bind("x"))),
5551     std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifierLoc>>("x", 1)));
5552 }
5553 
TEST(NNSLoc,NestedNameSpecifierLocsAsDescendants)5554 TEST(NNSLoc, NestedNameSpecifierLocsAsDescendants) {
5555   StringRef Fragment =
5556       "namespace a { struct A { struct B { struct C {}; }; }; };"
5557       "void f() { a::A::B::C c; }";
5558   EXPECT_TRUE(matches(
5559     Fragment,
5560     decl(hasDescendant(loc(nestedNameSpecifier(specifiesType(
5561       asString("struct a::A"))))))));
5562   EXPECT_TRUE(matchAndVerifyResultTrue(
5563     Fragment,
5564     functionDecl(hasName("f"),
5565                  forEachDescendant(nestedNameSpecifierLoc().bind("x"))),
5566     // Nested names: a, a::A and a::A::B.
5567     std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifierLoc>>("x", 3)));
5568 }
5569 
TEST(Attr,AttrsAsDescendants)5570 TEST(Attr, AttrsAsDescendants) {
5571   StringRef Fragment = "namespace a { struct [[clang::warn_unused_result]] "
5572                        "F{}; [[noreturn]] void foo(); }";
5573   EXPECT_TRUE(matches(Fragment, namespaceDecl(hasDescendant(attr()))));
5574   EXPECT_TRUE(matchAndVerifyResultTrue(
5575       Fragment,
5576       namespaceDecl(hasName("a"),
5577                     forEachDescendant(attr(unless(isImplicit())).bind("x"))),
5578       std::make_unique<VerifyIdIsBoundTo<Attr>>("x", 2)));
5579 }
5580 
TEST(Attr,ParentsOfAttrs)5581 TEST(Attr, ParentsOfAttrs) {
5582   StringRef Fragment =
5583       "namespace a { struct [[clang::warn_unused_result]] F{}; }";
5584   EXPECT_TRUE(matches(Fragment, attr(hasAncestor(namespaceDecl()))));
5585 }
5586 
5587 template <typename T> class VerifyMatchOnNode : public BoundNodesCallback {
5588 public:
VerifyMatchOnNode(StringRef Id,const internal::Matcher<T> & InnerMatcher,StringRef InnerId)5589   VerifyMatchOnNode(StringRef Id, const internal::Matcher<T> &InnerMatcher,
5590                     StringRef InnerId)
5591     : Id(Id), InnerMatcher(InnerMatcher), InnerId(InnerId) {
5592   }
5593 
run(const BoundNodes * Nodes)5594   bool run(const BoundNodes *Nodes) override { return false; }
5595 
run(const BoundNodes * Nodes,ASTContext * Context)5596   bool run(const BoundNodes *Nodes, ASTContext *Context) override {
5597     const T *Node = Nodes->getNodeAs<T>(Id);
5598     return selectFirst<T>(InnerId, match(InnerMatcher, *Node, *Context)) !=
5599       nullptr;
5600   }
5601 private:
5602   std::string Id;
5603   internal::Matcher<T> InnerMatcher;
5604   std::string InnerId;
5605 };
5606 
TEST(MatchFinder,CanMatchDeclarationsRecursively)5607 TEST(MatchFinder, CanMatchDeclarationsRecursively) {
5608   EXPECT_TRUE(matchAndVerifyResultTrue(
5609     "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5610     std::make_unique<VerifyMatchOnNode<Decl>>(
5611       "X", decl(hasDescendant(recordDecl(hasName("X::Y")).bind("Y"))),
5612       "Y")));
5613   EXPECT_TRUE(matchAndVerifyResultFalse(
5614     "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5615     std::make_unique<VerifyMatchOnNode<Decl>>(
5616       "X", decl(hasDescendant(recordDecl(hasName("X::Z")).bind("Z"))),
5617       "Z")));
5618 }
5619 
TEST(MatchFinder,CanMatchStatementsRecursively)5620 TEST(MatchFinder, CanMatchStatementsRecursively) {
5621   EXPECT_TRUE(matchAndVerifyResultTrue(
5622     "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
5623     std::make_unique<VerifyMatchOnNode<Stmt>>(
5624       "if", stmt(hasDescendant(forStmt().bind("for"))), "for")));
5625   EXPECT_TRUE(matchAndVerifyResultFalse(
5626     "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
5627     std::make_unique<VerifyMatchOnNode<Stmt>>(
5628       "if", stmt(hasDescendant(declStmt().bind("decl"))), "decl")));
5629 }
5630 
TEST(MatchFinder,CanMatchSingleNodesRecursively)5631 TEST(MatchFinder, CanMatchSingleNodesRecursively) {
5632   EXPECT_TRUE(matchAndVerifyResultTrue(
5633     "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5634     std::make_unique<VerifyMatchOnNode<Decl>>(
5635       "X", recordDecl(has(recordDecl(hasName("X::Y")).bind("Y"))), "Y")));
5636   EXPECT_TRUE(matchAndVerifyResultFalse(
5637     "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5638     std::make_unique<VerifyMatchOnNode<Decl>>(
5639       "X", recordDecl(has(recordDecl(hasName("X::Z")).bind("Z"))), "Z")));
5640 }
5641 
TEST(StatementMatcher,HasReturnValue)5642 TEST(StatementMatcher, HasReturnValue) {
5643   StatementMatcher RetVal = returnStmt(hasReturnValue(binaryOperator()));
5644   EXPECT_TRUE(matches("int F() { int a, b; return a + b; }", RetVal));
5645   EXPECT_FALSE(matches("int F() { int a; return a; }", RetVal));
5646   EXPECT_FALSE(matches("void F() { return; }", RetVal));
5647 }
5648 
TEST(StatementMatcher,ForFunction)5649 TEST(StatementMatcher, ForFunction) {
5650   StringRef CppString1 = "struct PosVec {"
5651                          "  PosVec& operator=(const PosVec&) {"
5652                          "    auto x = [] { return 1; };"
5653                          "    return *this;"
5654                          "  }"
5655                          "};";
5656   StringRef CppString2 = "void F() {"
5657                          "  struct S {"
5658                          "    void F2() {"
5659                          "       return;"
5660                          "    }"
5661                          "  };"
5662                          "}";
5663   EXPECT_TRUE(
5664     matches(
5665       CppString1,
5666       returnStmt(forFunction(hasName("operator=")),
5667                  has(unaryOperator(hasOperatorName("*"))))));
5668   EXPECT_TRUE(
5669     notMatches(
5670       CppString1,
5671       returnStmt(forFunction(hasName("operator=")),
5672                  has(integerLiteral()))));
5673   EXPECT_TRUE(
5674     matches(
5675       CppString1,
5676       returnStmt(forFunction(hasName("operator()")),
5677                  has(integerLiteral()))));
5678   EXPECT_TRUE(matches(CppString2, returnStmt(forFunction(hasName("F2")))));
5679   EXPECT_TRUE(notMatches(CppString2, returnStmt(forFunction(hasName("F")))));
5680 }
5681 
TEST(StatementMatcher,ForCallable)5682 TEST(StatementMatcher, ForCallable) {
5683   // These tests are copied over from the forFunction() test above.
5684   StringRef CppString1 = "struct PosVec {"
5685                          "  PosVec& operator=(const PosVec&) {"
5686                          "    auto x = [] { return 1; };"
5687                          "    return *this;"
5688                          "  }"
5689                          "};";
5690   StringRef CppString2 = "void F() {"
5691                          "  struct S {"
5692                          "    void F2() {"
5693                          "       return;"
5694                          "    }"
5695                          "  };"
5696                          "}";
5697 
5698   EXPECT_TRUE(
5699     matches(
5700       CppString1,
5701       returnStmt(forCallable(functionDecl(hasName("operator="))),
5702                  has(unaryOperator(hasOperatorName("*"))))));
5703   EXPECT_TRUE(
5704     notMatches(
5705       CppString1,
5706       returnStmt(forCallable(functionDecl(hasName("operator="))),
5707                  has(integerLiteral()))));
5708   EXPECT_TRUE(
5709     matches(
5710       CppString1,
5711       returnStmt(forCallable(functionDecl(hasName("operator()"))),
5712                  has(integerLiteral()))));
5713   EXPECT_TRUE(matches(CppString2,
5714                       returnStmt(forCallable(functionDecl(hasName("F2"))))));
5715   EXPECT_TRUE(notMatches(CppString2,
5716                          returnStmt(forCallable(functionDecl(hasName("F"))))));
5717 
5718   // These tests are specific to forCallable().
5719   StringRef ObjCString1 = "@interface I"
5720                           "-(void) foo;"
5721                           "@end"
5722                           "@implementation I"
5723                           "-(void) foo {"
5724                           "  void (^block)() = ^{ 0x2b | ~0x2b; };"
5725                           "}"
5726                           "@end";
5727 
5728   EXPECT_TRUE(
5729     matchesObjC(
5730       ObjCString1,
5731       binaryOperator(forCallable(blockDecl()))));
5732 
5733   EXPECT_TRUE(
5734     notMatchesObjC(
5735       ObjCString1,
5736       binaryOperator(forCallable(objcMethodDecl()))));
5737 
5738   StringRef ObjCString2 = "@interface I"
5739                           "-(void) foo;"
5740                           "@end"
5741                           "@implementation I"
5742                           "-(void) foo {"
5743                           "  0x2b | ~0x2b;"
5744                           "  void (^block)() = ^{};"
5745                           "}"
5746                           "@end";
5747 
5748   EXPECT_TRUE(
5749     matchesObjC(
5750       ObjCString2,
5751       binaryOperator(forCallable(objcMethodDecl()))));
5752 
5753   EXPECT_TRUE(
5754     notMatchesObjC(
5755       ObjCString2,
5756       binaryOperator(forCallable(blockDecl()))));
5757 }
5758 
TEST(Matcher,ForEachOverriden)5759 TEST(Matcher, ForEachOverriden) {
5760   const auto ForEachOverriddenInClass = [](const char *ClassName) {
5761     return cxxMethodDecl(ofClass(hasName(ClassName)), isVirtual(),
5762                          forEachOverridden(cxxMethodDecl().bind("overridden")))
5763         .bind("override");
5764   };
5765   static const char Code1[] = "class A { virtual void f(); };"
5766                               "class B : public A { void f(); };"
5767                               "class C : public B { void f(); };";
5768   // C::f overrides A::f.
5769   EXPECT_TRUE(matchAndVerifyResultTrue(
5770       Code1, ForEachOverriddenInClass("C"),
5771       std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("override", "f", 1)));
5772   EXPECT_TRUE(matchAndVerifyResultTrue(
5773       Code1, ForEachOverriddenInClass("C"),
5774       std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("overridden", "f",
5775                                                           1)));
5776   // B::f overrides A::f.
5777   EXPECT_TRUE(matchAndVerifyResultTrue(
5778       Code1, ForEachOverriddenInClass("B"),
5779       std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("override", "f", 1)));
5780   EXPECT_TRUE(matchAndVerifyResultTrue(
5781       Code1, ForEachOverriddenInClass("B"),
5782       std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("overridden", "f",
5783                                                           1)));
5784   // A::f overrides nothing.
5785   EXPECT_TRUE(notMatches(Code1, ForEachOverriddenInClass("A")));
5786 
5787   static const char Code2[] =
5788       "class A1 { virtual void f(); };"
5789       "class A2 { virtual void f(); };"
5790       "class B : public A1, public A2 { void f(); };";
5791   // B::f overrides A1::f and A2::f. This produces two matches.
5792   EXPECT_TRUE(matchAndVerifyResultTrue(
5793       Code2, ForEachOverriddenInClass("B"),
5794       std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("override", "f", 2)));
5795   EXPECT_TRUE(matchAndVerifyResultTrue(
5796       Code2, ForEachOverriddenInClass("B"),
5797       std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("overridden", "f",
5798                                                           2)));
5799   // A1::f overrides nothing.
5800   EXPECT_TRUE(notMatches(Code2, ForEachOverriddenInClass("A1")));
5801 }
5802 
TEST(Matcher,HasAnyDeclaration)5803 TEST(Matcher, HasAnyDeclaration) {
5804   StringRef Fragment = "void foo(int p1);"
5805                        "void foo(int *p2);"
5806                        "void bar(int p3);"
5807                        "template <typename T> void baz(T t) { foo(t); }";
5808 
5809   EXPECT_TRUE(
5810       matches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(functionDecl(
5811                             hasParameter(0, parmVarDecl(hasName("p1"))))))));
5812   EXPECT_TRUE(
5813       matches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(functionDecl(
5814                             hasParameter(0, parmVarDecl(hasName("p2"))))))));
5815   EXPECT_TRUE(
5816       notMatches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(functionDecl(
5817                                hasParameter(0, parmVarDecl(hasName("p3"))))))));
5818   EXPECT_TRUE(notMatches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(
5819                                        functionDecl(hasName("bar"))))));
5820 }
5821 
TEST(SubstTemplateTypeParmType,HasReplacementType)5822 TEST(SubstTemplateTypeParmType, HasReplacementType) {
5823   StringRef Fragment = "template<typename T>"
5824                        "double F(T t);"
5825                        "int i;"
5826                        "double j = F(i);";
5827   EXPECT_TRUE(matches(Fragment, substTemplateTypeParmType(hasReplacementType(
5828                                     qualType(asString("int"))))));
5829   EXPECT_TRUE(notMatches(Fragment, substTemplateTypeParmType(hasReplacementType(
5830                                        qualType(asString("double"))))));
5831   EXPECT_TRUE(
5832       notMatches("template<int N>"
5833                  "double F();"
5834                  "double j = F<5>();",
5835                  substTemplateTypeParmType(hasReplacementType(qualType()))));
5836 }
5837 
TEST(ClassTemplateSpecializationDecl,HasSpecializedTemplate)5838 TEST(ClassTemplateSpecializationDecl, HasSpecializedTemplate) {
5839   auto Matcher = classTemplateSpecializationDecl(
5840       hasSpecializedTemplate(classTemplateDecl()));
5841   EXPECT_TRUE(
5842       matches("template<typename T> class A {}; typedef A<int> B;", Matcher));
5843   EXPECT_TRUE(notMatches("template<typename T> class A {};", Matcher));
5844 }
5845 
TEST(CXXNewExpr,Array)5846 TEST(CXXNewExpr, Array) {
5847   StatementMatcher NewArray = cxxNewExpr(isArray());
5848 
5849   EXPECT_TRUE(matches("void foo() { int *Ptr = new int[10]; }", NewArray));
5850   EXPECT_TRUE(notMatches("void foo() { int *Ptr = new int; }", NewArray));
5851 
5852   StatementMatcher NewArraySize10 =
5853       cxxNewExpr(hasArraySize(integerLiteral(equals(10))));
5854   EXPECT_TRUE(
5855       matches("void foo() { int *Ptr = new int[10]; }", NewArraySize10));
5856   EXPECT_TRUE(
5857       notMatches("void foo() { int *Ptr = new int[20]; }", NewArraySize10));
5858 }
5859 
TEST(CXXNewExpr,PlacementArgs)5860 TEST(CXXNewExpr, PlacementArgs) {
5861   StatementMatcher IsPlacementNew = cxxNewExpr(hasAnyPlacementArg(anything()));
5862 
5863   EXPECT_TRUE(matches(R"(
5864     void* operator new(decltype(sizeof(void*)), void*);
5865     int *foo(void* Storage) {
5866       return new (Storage) int;
5867     })",
5868                       IsPlacementNew));
5869 
5870   EXPECT_TRUE(matches(R"(
5871     void* operator new(decltype(sizeof(void*)), void*, unsigned);
5872     int *foo(void* Storage) {
5873       return new (Storage, 16) int;
5874     })",
5875                       cxxNewExpr(hasPlacementArg(
5876                           1, ignoringImpCasts(integerLiteral(equals(16)))))));
5877 
5878   EXPECT_TRUE(notMatches(R"(
5879     void* operator new(decltype(sizeof(void*)), void*);
5880     int *foo(void* Storage) {
5881       return new int;
5882     })",
5883                          IsPlacementNew));
5884 }
5885 
TEST(HasUnqualifiedLoc,BindsToConstIntVarDecl)5886 TEST(HasUnqualifiedLoc, BindsToConstIntVarDecl) {
5887   EXPECT_TRUE(matches(
5888       "const int x = 0;",
5889       varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
5890                                 hasUnqualifiedLoc(loc(asString("int"))))))));
5891 }
5892 
TEST(HasUnqualifiedLoc,BindsToVolatileIntVarDecl)5893 TEST(HasUnqualifiedLoc, BindsToVolatileIntVarDecl) {
5894   EXPECT_TRUE(matches(
5895       "volatile int x = 0;",
5896       varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
5897                                 hasUnqualifiedLoc(loc(asString("int"))))))));
5898 }
5899 
TEST(HasUnqualifiedLoc,BindsToConstVolatileIntVarDecl)5900 TEST(HasUnqualifiedLoc, BindsToConstVolatileIntVarDecl) {
5901   EXPECT_TRUE(matches(
5902       "const volatile int x = 0;",
5903       varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
5904                                 hasUnqualifiedLoc(loc(asString("int"))))))));
5905 }
5906 
TEST(HasUnqualifiedLoc,BindsToConstPointerVarDecl)5907 TEST(HasUnqualifiedLoc, BindsToConstPointerVarDecl) {
5908   auto matcher = varDecl(
5909       hasName("x"),
5910       hasTypeLoc(qualifiedTypeLoc(hasUnqualifiedLoc(pointerTypeLoc()))));
5911   EXPECT_TRUE(matches("int* const x = 0;", matcher));
5912   EXPECT_TRUE(notMatches("int const x = 0;", matcher));
5913 }
5914 
TEST(HasUnqualifiedLoc,BindsToPointerToConstVolatileIntVarDecl)5915 TEST(HasUnqualifiedLoc, BindsToPointerToConstVolatileIntVarDecl) {
5916   EXPECT_TRUE(
5917       matches("const volatile int* x = 0;",
5918               varDecl(hasName("x"),
5919                       hasTypeLoc(pointerTypeLoc(hasPointeeLoc(qualifiedTypeLoc(
5920                           hasUnqualifiedLoc(loc(asString("int"))))))))));
5921 }
5922 
TEST(HasUnqualifiedLoc,BindsToConstIntFunctionDecl)5923 TEST(HasUnqualifiedLoc, BindsToConstIntFunctionDecl) {
5924   EXPECT_TRUE(
5925       matches("const int f() { return 5; }",
5926               functionDecl(hasName("f"),
5927                            hasReturnTypeLoc(qualifiedTypeLoc(
5928                                hasUnqualifiedLoc(loc(asString("int"))))))));
5929 }
5930 
TEST(HasUnqualifiedLoc,FloatBindsToConstFloatVarDecl)5931 TEST(HasUnqualifiedLoc, FloatBindsToConstFloatVarDecl) {
5932   EXPECT_TRUE(matches(
5933       "const float x = 0;",
5934       varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
5935                                 hasUnqualifiedLoc(loc(asString("float"))))))));
5936 }
5937 
TEST(HasUnqualifiedLoc,FloatDoesNotBindToIntVarDecl)5938 TEST(HasUnqualifiedLoc, FloatDoesNotBindToIntVarDecl) {
5939   EXPECT_TRUE(notMatches(
5940       "int x = 0;",
5941       varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
5942                                 hasUnqualifiedLoc(loc(asString("float"))))))));
5943 }
5944 
TEST(HasUnqualifiedLoc,FloatDoesNotBindToConstIntVarDecl)5945 TEST(HasUnqualifiedLoc, FloatDoesNotBindToConstIntVarDecl) {
5946   EXPECT_TRUE(notMatches(
5947       "const int x = 0;",
5948       varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
5949                                 hasUnqualifiedLoc(loc(asString("float"))))))));
5950 }
5951 
TEST(HasReturnTypeLoc,BindsToIntReturnTypeLoc)5952 TEST(HasReturnTypeLoc, BindsToIntReturnTypeLoc) {
5953   EXPECT_TRUE(matches(
5954       "int f() { return 5; }",
5955       functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("int"))))));
5956 }
5957 
TEST(HasReturnTypeLoc,BindsToFloatReturnTypeLoc)5958 TEST(HasReturnTypeLoc, BindsToFloatReturnTypeLoc) {
5959   EXPECT_TRUE(matches(
5960       "float f() { return 5.0; }",
5961       functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("float"))))));
5962 }
5963 
TEST(HasReturnTypeLoc,BindsToVoidReturnTypeLoc)5964 TEST(HasReturnTypeLoc, BindsToVoidReturnTypeLoc) {
5965   EXPECT_TRUE(matches(
5966       "void f() {}",
5967       functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("void"))))));
5968 }
5969 
TEST(HasReturnTypeLoc,FloatDoesNotBindToIntReturnTypeLoc)5970 TEST(HasReturnTypeLoc, FloatDoesNotBindToIntReturnTypeLoc) {
5971   EXPECT_TRUE(notMatches(
5972       "int f() { return 5; }",
5973       functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("float"))))));
5974 }
5975 
TEST(HasReturnTypeLoc,IntDoesNotBindToFloatReturnTypeLoc)5976 TEST(HasReturnTypeLoc, IntDoesNotBindToFloatReturnTypeLoc) {
5977   EXPECT_TRUE(notMatches(
5978       "float f() { return 5.0; }",
5979       functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("int"))))));
5980 }
5981 
TEST(HasPointeeLoc,BindsToAnyPointeeTypeLoc)5982 TEST(HasPointeeLoc, BindsToAnyPointeeTypeLoc) {
5983   auto matcher = varDecl(hasName("x"),
5984                          hasTypeLoc(pointerTypeLoc(hasPointeeLoc(typeLoc()))));
5985   EXPECT_TRUE(matches("int* x;", matcher));
5986   EXPECT_TRUE(matches("float* x;", matcher));
5987   EXPECT_TRUE(matches("char* x;", matcher));
5988   EXPECT_TRUE(matches("void* x;", matcher));
5989 }
5990 
TEST(HasPointeeLoc,DoesNotBindToTypeLocWithoutPointee)5991 TEST(HasPointeeLoc, DoesNotBindToTypeLocWithoutPointee) {
5992   auto matcher = varDecl(hasName("x"),
5993                          hasTypeLoc(pointerTypeLoc(hasPointeeLoc(typeLoc()))));
5994   EXPECT_TRUE(notMatches("int x;", matcher));
5995   EXPECT_TRUE(notMatches("float x;", matcher));
5996   EXPECT_TRUE(notMatches("char x;", matcher));
5997 }
5998 
TEST(HasPointeeLoc,BindsToTypeLocPointingToInt)5999 TEST(HasPointeeLoc, BindsToTypeLocPointingToInt) {
6000   EXPECT_TRUE(
6001       matches("int* x;", pointerTypeLoc(hasPointeeLoc(loc(asString("int"))))));
6002 }
6003 
TEST(HasPointeeLoc,BindsToTypeLocPointingToIntPointer)6004 TEST(HasPointeeLoc, BindsToTypeLocPointingToIntPointer) {
6005   EXPECT_TRUE(matches("int** x;",
6006                       pointerTypeLoc(hasPointeeLoc(loc(asString("int *"))))));
6007 }
6008 
TEST(HasPointeeLoc,BindsToTypeLocPointingToTypeLocPointingToInt)6009 TEST(HasPointeeLoc, BindsToTypeLocPointingToTypeLocPointingToInt) {
6010   EXPECT_TRUE(matches("int** x;", pointerTypeLoc(hasPointeeLoc(pointerTypeLoc(
6011                                       hasPointeeLoc(loc(asString("int"))))))));
6012 }
6013 
TEST(HasPointeeLoc,BindsToTypeLocPointingToFloat)6014 TEST(HasPointeeLoc, BindsToTypeLocPointingToFloat) {
6015   EXPECT_TRUE(matches("float* x;",
6016                       pointerTypeLoc(hasPointeeLoc(loc(asString("float"))))));
6017 }
6018 
TEST(HasPointeeLoc,IntPointeeDoesNotBindToTypeLocPointingToFloat)6019 TEST(HasPointeeLoc, IntPointeeDoesNotBindToTypeLocPointingToFloat) {
6020   EXPECT_TRUE(notMatches("float* x;",
6021                          pointerTypeLoc(hasPointeeLoc(loc(asString("int"))))));
6022 }
6023 
TEST(HasPointeeLoc,FloatPointeeDoesNotBindToTypeLocPointingToInt)6024 TEST(HasPointeeLoc, FloatPointeeDoesNotBindToTypeLocPointingToInt) {
6025   EXPECT_TRUE(notMatches(
6026       "int* x;", pointerTypeLoc(hasPointeeLoc(loc(asString("float"))))));
6027 }
6028 
TEST(HasReferentLoc,BindsToAnyReferentTypeLoc)6029 TEST(HasReferentLoc, BindsToAnyReferentTypeLoc) {
6030   auto matcher = varDecl(
6031       hasName("r"), hasTypeLoc(referenceTypeLoc(hasReferentLoc(typeLoc()))));
6032   EXPECT_TRUE(matches("int rr = 3; int& r = rr;", matcher));
6033   EXPECT_TRUE(matches("int rr = 3; auto& r = rr;", matcher));
6034   EXPECT_TRUE(matches("int rr = 3; const int& r = rr;", matcher));
6035   EXPECT_TRUE(matches("float rr = 3.0; float& r = rr;", matcher));
6036   EXPECT_TRUE(matches("char rr = 'a'; char& r = rr;", matcher));
6037 }
6038 
TEST(HasReferentLoc,DoesNotBindToTypeLocWithoutReferent)6039 TEST(HasReferentLoc, DoesNotBindToTypeLocWithoutReferent) {
6040   auto matcher = varDecl(
6041       hasName("r"), hasTypeLoc(referenceTypeLoc(hasReferentLoc(typeLoc()))));
6042   EXPECT_TRUE(notMatches("int r;", matcher));
6043   EXPECT_TRUE(notMatches("int r = 3;", matcher));
6044   EXPECT_TRUE(notMatches("const int r = 3;", matcher));
6045   EXPECT_TRUE(notMatches("int* r;", matcher));
6046   EXPECT_TRUE(notMatches("float r;", matcher));
6047   EXPECT_TRUE(notMatches("char r;", matcher));
6048 }
6049 
TEST(HasReferentLoc,BindsToAnyRvalueReference)6050 TEST(HasReferentLoc, BindsToAnyRvalueReference) {
6051   auto matcher = varDecl(
6052       hasName("r"), hasTypeLoc(referenceTypeLoc(hasReferentLoc(typeLoc()))));
6053   EXPECT_TRUE(matches("int&& r = 3;", matcher));
6054   EXPECT_TRUE(matches("auto&& r = 3;", matcher));
6055   EXPECT_TRUE(matches("float&& r = 3.0;", matcher));
6056 }
6057 
TEST(HasReferentLoc,BindsToIntReferenceTypeLoc)6058 TEST(HasReferentLoc, BindsToIntReferenceTypeLoc) {
6059   EXPECT_TRUE(matches("int rr = 3; int& r = rr;",
6060                       referenceTypeLoc(hasReferentLoc(loc(asString("int"))))));
6061 }
6062 
TEST(HasReferentLoc,BindsToIntRvalueReferenceTypeLoc)6063 TEST(HasReferentLoc, BindsToIntRvalueReferenceTypeLoc) {
6064   EXPECT_TRUE(matches("int&& r = 3;",
6065                       referenceTypeLoc(hasReferentLoc(loc(asString("int"))))));
6066 }
6067 
TEST(HasReferentLoc,BindsToFloatReferenceTypeLoc)6068 TEST(HasReferentLoc, BindsToFloatReferenceTypeLoc) {
6069   EXPECT_TRUE(
6070       matches("float rr = 3.0; float& r = rr;",
6071               referenceTypeLoc(hasReferentLoc(loc(asString("float"))))));
6072 }
6073 
TEST(HasReferentLoc,BindsToParameterWithIntReferenceTypeLoc)6074 TEST(HasReferentLoc, BindsToParameterWithIntReferenceTypeLoc) {
6075   EXPECT_TRUE(matches(
6076       "int f(int& r) { return r; }",
6077       parmVarDecl(hasName("r"), hasTypeLoc(referenceTypeLoc(
6078                                     hasReferentLoc(loc(asString("int"))))))));
6079 }
6080 
TEST(HasReferentLoc,IntReferenceDoesNotBindToFloatReferenceTypeLoc)6081 TEST(HasReferentLoc, IntReferenceDoesNotBindToFloatReferenceTypeLoc) {
6082   EXPECT_TRUE(
6083       notMatches("float rr = 3.0; float& r = rr;",
6084                  referenceTypeLoc(hasReferentLoc(loc(asString("int"))))));
6085 }
6086 
TEST(HasReferentLoc,FloatReferenceDoesNotBindToIntReferenceTypeLoc)6087 TEST(HasReferentLoc, FloatReferenceDoesNotBindToIntReferenceTypeLoc) {
6088   EXPECT_TRUE(
6089       notMatches("int rr = 3; int& r = rr;",
6090                  referenceTypeLoc(hasReferentLoc(loc(asString("float"))))));
6091 }
6092 
TEST(HasReferentLoc,DoesNotBindToParameterWithoutIntReferenceTypeLoc)6093 TEST(HasReferentLoc, DoesNotBindToParameterWithoutIntReferenceTypeLoc) {
6094   EXPECT_TRUE(notMatches(
6095       "int f(int r) { return r; }",
6096       parmVarDecl(hasName("r"), hasTypeLoc(referenceTypeLoc(
6097                                     hasReferentLoc(loc(asString("int"))))))));
6098 }
6099 
TEST(HasAnyTemplateArgumentLoc,BindsToSpecializationWithIntArgument)6100 TEST(HasAnyTemplateArgumentLoc, BindsToSpecializationWithIntArgument) {
6101   EXPECT_TRUE(
6102       matches("template<typename T> class A {}; A<int> a;",
6103               varDecl(hasName("a"), hasTypeLoc(templateSpecializationTypeLoc(
6104                                         hasAnyTemplateArgumentLoc(hasTypeLoc(
6105                                             loc(asString("int")))))))));
6106 }
6107 
TEST(HasAnyTemplateArgumentLoc,BindsToSpecializationWithDoubleArgument)6108 TEST(HasAnyTemplateArgumentLoc, BindsToSpecializationWithDoubleArgument) {
6109   EXPECT_TRUE(
6110       matches("template<typename T> class A {}; A<double> a;",
6111               varDecl(hasName("a"), hasTypeLoc(templateSpecializationTypeLoc(
6112                                         hasAnyTemplateArgumentLoc(hasTypeLoc(
6113                                             loc(asString("double")))))))));
6114 }
6115 
TEST(HasAnyTemplateArgumentLoc,BindsToExplicitSpecializationWithIntArgument)6116 TEST(HasAnyTemplateArgumentLoc, BindsToExplicitSpecializationWithIntArgument) {
6117   EXPECT_TRUE(matches(
6118       "template<typename T> class A {}; template<> class A<int> {};",
6119       classTemplateSpecializationDecl(
6120           hasName("A"),
6121           hasTypeLoc(templateSpecializationTypeLoc(
6122               hasAnyTemplateArgumentLoc(hasTypeLoc(loc(asString("int")))))))));
6123 }
6124 
TEST(HasAnyTemplateArgumentLoc,BindsToExplicitSpecializationWithDoubleArgument)6125 TEST(HasAnyTemplateArgumentLoc,
6126      BindsToExplicitSpecializationWithDoubleArgument) {
6127   EXPECT_TRUE(matches(
6128       "template<typename T> class A {}; template<> class A<double> {};",
6129       classTemplateSpecializationDecl(
6130           hasName("A"),
6131           hasTypeLoc(templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
6132               hasTypeLoc(loc(asString("double")))))))));
6133 }
6134 
TEST(HasAnyTemplateArgumentLoc,BindsToSpecializationWithMultipleArguments)6135 TEST(HasAnyTemplateArgumentLoc, BindsToSpecializationWithMultipleArguments) {
6136   auto code = R"(
6137   template<typename T, typename U> class A {};
6138   template<> class A<double, int> {};
6139   )";
6140   EXPECT_TRUE(
6141       matches(code, classTemplateSpecializationDecl(
6142                         hasName("A"), hasTypeLoc(templateSpecializationTypeLoc(
6143                                           hasAnyTemplateArgumentLoc(hasTypeLoc(
6144                                               loc(asString("double")))))))));
6145   EXPECT_TRUE(matches(
6146       code,
6147       classTemplateSpecializationDecl(
6148           hasName("A"),
6149           hasTypeLoc(templateSpecializationTypeLoc(
6150               hasAnyTemplateArgumentLoc(hasTypeLoc(loc(asString("int")))))))));
6151 }
6152 
TEST(HasAnyTemplateArgumentLoc,DoesNotBindToSpecializationWithIntArgument)6153 TEST(HasAnyTemplateArgumentLoc, DoesNotBindToSpecializationWithIntArgument) {
6154   EXPECT_TRUE(notMatches(
6155       "template<typename T> class A {}; A<int> a;",
6156       classTemplateSpecializationDecl(
6157           hasName("A"),
6158           hasTypeLoc(templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
6159               hasTypeLoc(loc(asString("double")))))))));
6160 }
6161 
TEST(HasAnyTemplateArgumentLoc,DoesNotBindToExplicitSpecializationWithIntArgument)6162 TEST(HasAnyTemplateArgumentLoc,
6163      DoesNotBindToExplicitSpecializationWithIntArgument) {
6164   EXPECT_TRUE(notMatches(
6165       "template<typename T> class A {}; template<> class A<int> {};",
6166       classTemplateSpecializationDecl(
6167           hasName("A"),
6168           hasTypeLoc(templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
6169               hasTypeLoc(loc(asString("double")))))))));
6170 }
6171 
TEST(HasTemplateArgumentLoc,BindsToSpecializationWithIntArgument)6172 TEST(HasTemplateArgumentLoc, BindsToSpecializationWithIntArgument) {
6173   EXPECT_TRUE(matches(
6174       "template<typename T> class A {}; A<int> a;",
6175       varDecl(hasName("a"),
6176               hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6177                   0, hasTypeLoc(loc(asString("int")))))))));
6178 }
6179 
TEST(HasTemplateArgumentLoc,BindsToSpecializationWithDoubleArgument)6180 TEST(HasTemplateArgumentLoc, BindsToSpecializationWithDoubleArgument) {
6181   EXPECT_TRUE(matches(
6182       "template<typename T> class A {}; A<double> a;",
6183       varDecl(hasName("a"),
6184               hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6185                   0, hasTypeLoc(loc(asString("double")))))))));
6186 }
6187 
TEST(HasTemplateArgumentLoc,BindsToExplicitSpecializationWithIntArgument)6188 TEST(HasTemplateArgumentLoc, BindsToExplicitSpecializationWithIntArgument) {
6189   EXPECT_TRUE(matches(
6190       "template<typename T> class A {}; template<> class A<int> {};",
6191       classTemplateSpecializationDecl(
6192           hasName("A"),
6193           hasTypeLoc(templateSpecializationTypeLoc(
6194               hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("int")))))))));
6195 }
6196 
TEST(HasTemplateArgumentLoc,BindsToExplicitSpecializationWithDoubleArgument)6197 TEST(HasTemplateArgumentLoc, BindsToExplicitSpecializationWithDoubleArgument) {
6198   EXPECT_TRUE(matches(
6199       "template<typename T> class A {}; template<> class A<double> {};",
6200       classTemplateSpecializationDecl(
6201           hasName("A"),
6202           hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6203               0, hasTypeLoc(loc(asString("double")))))))));
6204 }
6205 
TEST(HasTemplateArgumentLoc,BindsToSpecializationWithMultipleArguments)6206 TEST(HasTemplateArgumentLoc, BindsToSpecializationWithMultipleArguments) {
6207   auto code = R"(
6208   template<typename T, typename U> class A {};
6209   template<> class A<double, int> {};
6210   )";
6211   EXPECT_TRUE(matches(
6212       code, classTemplateSpecializationDecl(
6213                 hasName("A"),
6214                 hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6215                     0, hasTypeLoc(loc(asString("double")))))))));
6216   EXPECT_TRUE(matches(
6217       code, classTemplateSpecializationDecl(
6218                 hasName("A"),
6219                 hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6220                     1, hasTypeLoc(loc(asString("int")))))))));
6221 }
6222 
TEST(HasTemplateArgumentLoc,DoesNotBindToSpecializationWithIntArgument)6223 TEST(HasTemplateArgumentLoc, DoesNotBindToSpecializationWithIntArgument) {
6224   EXPECT_TRUE(notMatches(
6225       "template<typename T> class A {}; A<int> a;",
6226       classTemplateSpecializationDecl(
6227           hasName("A"),
6228           hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6229               0, hasTypeLoc(loc(asString("double")))))))));
6230 }
6231 
TEST(HasTemplateArgumentLoc,DoesNotBindToExplicitSpecializationWithIntArgument)6232 TEST(HasTemplateArgumentLoc,
6233      DoesNotBindToExplicitSpecializationWithIntArgument) {
6234   EXPECT_TRUE(notMatches(
6235       "template<typename T> class A {}; template<> class A<int> {};",
6236       classTemplateSpecializationDecl(
6237           hasName("A"),
6238           hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6239               0, hasTypeLoc(loc(asString("double")))))))));
6240 }
6241 
TEST(HasTemplateArgumentLoc,DoesNotBindToSpecializationWithMisplacedArguments)6242 TEST(HasTemplateArgumentLoc,
6243      DoesNotBindToSpecializationWithMisplacedArguments) {
6244   auto code = R"(
6245   template<typename T, typename U> class A {};
6246   template<> class A<double, int> {};
6247   )";
6248   EXPECT_TRUE(notMatches(
6249       code, classTemplateSpecializationDecl(
6250                 hasName("A"),
6251                 hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6252                     1, hasTypeLoc(loc(asString("double")))))))));
6253   EXPECT_TRUE(notMatches(
6254       code, classTemplateSpecializationDecl(
6255                 hasName("A"),
6256                 hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6257                     0, hasTypeLoc(loc(asString("int")))))))));
6258 }
6259 
TEST(HasTemplateArgumentLoc,DoesNotBindWithBadIndex)6260 TEST(HasTemplateArgumentLoc, DoesNotBindWithBadIndex) {
6261   auto code = R"(
6262   template<typename T, typename U> class A {};
6263   template<> class A<double, int> {};
6264   )";
6265   EXPECT_TRUE(notMatches(
6266       code, classTemplateSpecializationDecl(
6267                 hasName("A"),
6268                 hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6269                     -1, hasTypeLoc(loc(asString("double")))))))));
6270   EXPECT_TRUE(notMatches(
6271       code, classTemplateSpecializationDecl(
6272                 hasName("A"),
6273                 hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6274                     100, hasTypeLoc(loc(asString("int")))))))));
6275 }
6276 
TEST(HasTemplateArgumentLoc,BindsToDeclRefExprWithIntArgument)6277 TEST(HasTemplateArgumentLoc, BindsToDeclRefExprWithIntArgument) {
6278   EXPECT_TRUE(matches(R"(
6279       template<typename T> T f(T t) { return t; }
6280       int g() { int i = f<int>(3); return i; }
6281       )",
6282                       declRefExpr(to(functionDecl(hasName("f"))),
6283                                   hasTemplateArgumentLoc(
6284                                       0, hasTypeLoc(loc(asString("int")))))));
6285 }
6286 
TEST(HasTemplateArgumentLoc,BindsToDeclRefExprWithDoubleArgument)6287 TEST(HasTemplateArgumentLoc, BindsToDeclRefExprWithDoubleArgument) {
6288   EXPECT_TRUE(matches(
6289       R"(
6290       template<typename T> T f(T t) { return t; }
6291       double g() { double i = f<double>(3.0); return i; }
6292       )",
6293       declRefExpr(
6294           to(functionDecl(hasName("f"))),
6295           hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("double")))))));
6296 }
6297 
TEST(HasTemplateArgumentLoc,DoesNotBindToDeclRefExprWithDoubleArgument)6298 TEST(HasTemplateArgumentLoc, DoesNotBindToDeclRefExprWithDoubleArgument) {
6299   EXPECT_TRUE(notMatches(
6300       R"(
6301       template<typename T> T f(T t) { return t; }
6302       double g() { double i = f<double>(3.0); return i; }
6303       )",
6304       declRefExpr(
6305           to(functionDecl(hasName("f"))),
6306           hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("int")))))));
6307 }
6308 
TEST(HasNamedTypeLoc,BindsToElaboratedObjectDeclaration)6309 TEST(HasNamedTypeLoc, BindsToElaboratedObjectDeclaration) {
6310   EXPECT_TRUE(matches(
6311       R"(
6312       template <typename T>
6313       class C {};
6314       class C<int> c;
6315       )",
6316       varDecl(hasName("c"),
6317               hasTypeLoc(elaboratedTypeLoc(
6318                   hasNamedTypeLoc(templateSpecializationTypeLoc(
6319                       hasAnyTemplateArgumentLoc(templateArgumentLoc()))))))));
6320 }
6321 
TEST(HasNamedTypeLoc,DoesNotBindToNonElaboratedObjectDeclaration)6322 TEST(HasNamedTypeLoc, DoesNotBindToNonElaboratedObjectDeclaration) {
6323   EXPECT_TRUE(notMatches(
6324       R"(
6325       template <typename T>
6326       class C {};
6327       C<int> c;
6328       )",
6329       varDecl(hasName("c"),
6330               hasTypeLoc(elaboratedTypeLoc(
6331                   hasNamedTypeLoc(templateSpecializationTypeLoc(
6332                       hasAnyTemplateArgumentLoc(templateArgumentLoc()))))))));
6333 }
6334 
6335 } // namespace ast_matchers
6336 } // namespace clang
6337