llvm-project

Форк
0
/
ASTMatchersTraversalTest.cpp 
6712 строк · 241.1 Кб
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/DeclCXX.h"
12
#include "clang/AST/PrettyPrinter.h"
13
#include "clang/ASTMatchers/ASTMatchFinder.h"
14
#include "clang/ASTMatchers/ASTMatchers.h"
15
#include "clang/Tooling/Tooling.h"
16
#include "llvm/ADT/StringRef.h"
17
#include "llvm/TargetParser/Host.h"
18
#include "llvm/TargetParser/Triple.h"
19
#include "gtest/gtest.h"
20

21
namespace clang {
22
namespace ast_matchers {
23

24
TEST(DeclarationMatcher, hasMethod) {
25
  EXPECT_TRUE(matches("class A { void func(); };",
26
                      cxxRecordDecl(hasMethod(hasName("func")))));
27
  EXPECT_TRUE(notMatches("class A { void func(); };",
28
                         cxxRecordDecl(hasMethod(isPublic()))));
29
}
30

31
TEST(DeclarationMatcher, ClassDerivedFromDependentTemplateSpecialization) {
32
  EXPECT_TRUE(matches(
33
    "template <typename T> struct A {"
34
      "  template <typename T2> struct F {};"
35
      "};"
36
      "template <typename T> struct B : A<T>::template F<T> {};"
37
      "B<int> b;",
38
    cxxRecordDecl(hasName("B"), isDerivedFrom(recordDecl()))));
39
}
40

41
TEST(DeclarationMatcher, hasDeclContext) {
42
  EXPECT_TRUE(matches(
43
    "namespace N {"
44
      "  namespace M {"
45
      "    class D {};"
46
      "  }"
47
      "}",
48
    recordDecl(hasDeclContext(namespaceDecl(hasName("M"))))));
49
  EXPECT_TRUE(notMatches(
50
    "namespace N {"
51
      "  namespace M {"
52
      "    class D {};"
53
      "  }"
54
      "}",
55
    recordDecl(hasDeclContext(namespaceDecl(hasName("N"))))));
56

57
  EXPECT_TRUE(matches("namespace {"
58
                        "  namespace M {"
59
                        "    class D {};"
60
                        "  }"
61
                        "}",
62
                      recordDecl(hasDeclContext(namespaceDecl(
63
                        hasName("M"), hasDeclContext(namespaceDecl()))))));
64

65
  EXPECT_TRUE(matches("class D{};", decl(hasDeclContext(decl()))));
66
}
67

68
TEST(HasDescendant, MatchesDescendantTypes) {
69
  EXPECT_TRUE(matches("void f() { int i = 3; }",
70
                      decl(hasDescendant(loc(builtinType())))));
71
  EXPECT_TRUE(matches("void f() { int i = 3; }",
72
                      stmt(hasDescendant(builtinType()))));
73

74
  EXPECT_TRUE(matches("void f() { int i = 3; }",
75
                      stmt(hasDescendant(loc(builtinType())))));
76
  EXPECT_TRUE(matches("void f() { int i = 3; }",
77
                      stmt(hasDescendant(qualType(builtinType())))));
78

79
  EXPECT_TRUE(notMatches("void f() { float f = 2.0f; }",
80
                         stmt(hasDescendant(isInteger()))));
81

82
  EXPECT_TRUE(matchAndVerifyResultTrue(
83
    "void f() { int a; float c; int d; int e; }",
84
    functionDecl(forEachDescendant(
85
      varDecl(hasDescendant(isInteger())).bind("x"))),
86
    std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 3)));
87
}
88

89
TEST(HasDescendant, MatchesDescendantsOfTypes) {
90
  EXPECT_TRUE(matches("void f() { int*** i; }",
91
                      qualType(hasDescendant(builtinType()))));
92
  EXPECT_TRUE(matches("void f() { int*** i; }",
93
                      qualType(hasDescendant(
94
                        pointerType(pointee(builtinType()))))));
95
  EXPECT_TRUE(matches("void f() { int*** i; }",
96
                      typeLoc(hasDescendant(loc(builtinType())))));
97

98
  EXPECT_TRUE(matchAndVerifyResultTrue(
99
    "void f() { int*** i; }",
100
    qualType(asString("int ***"), forEachDescendant(pointerType().bind("x"))),
101
    std::make_unique<VerifyIdIsBoundTo<Type>>("x", 2)));
102
}
103

104

105
TEST(Has, MatchesChildrenOfTypes) {
106
  EXPECT_TRUE(matches("int i;",
107
                      varDecl(hasName("i"), has(isInteger()))));
108
  EXPECT_TRUE(notMatches("int** i;",
109
                         varDecl(hasName("i"), has(isInteger()))));
110
  EXPECT_TRUE(matchAndVerifyResultTrue(
111
    "int (*f)(float, int);",
112
    qualType(functionType(), forEach(qualType(isInteger()).bind("x"))),
113
    std::make_unique<VerifyIdIsBoundTo<QualType>>("x", 2)));
114
}
115

116
TEST(Has, MatchesChildTypes) {
117
  EXPECT_TRUE(matches(
118
    "int* i;",
119
    varDecl(hasName("i"), hasType(qualType(has(builtinType()))))));
120
  EXPECT_TRUE(notMatches(
121
    "int* i;",
122
    varDecl(hasName("i"), hasType(qualType(has(pointerType()))))));
123
}
124

125
TEST(StatementMatcher, Has) {
126
  StatementMatcher HasVariableI =
127
      expr(hasType(pointsTo(recordDecl(hasName("X")))),
128
           has(ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("i")))))));
129

130
  EXPECT_TRUE(matches(
131
    "class X; X *x(int); void c() { int i; x(i); }", HasVariableI));
132
  EXPECT_TRUE(notMatches(
133
    "class X; X *x(int); void c() { int i; x(42); }", HasVariableI));
134
}
135

136
TEST(StatementMatcher, HasDescendant) {
137
  StatementMatcher HasDescendantVariableI =
138
    expr(hasType(pointsTo(recordDecl(hasName("X")))),
139
         hasDescendant(declRefExpr(to(varDecl(hasName("i"))))));
140

141
  EXPECT_TRUE(matches(
142
    "class X; X *x(bool); bool b(int); void c() { int i; x(b(i)); }",
143
    HasDescendantVariableI));
144
  EXPECT_TRUE(notMatches(
145
    "class X; X *x(bool); bool b(int); void c() { int i; x(b(42)); }",
146
    HasDescendantVariableI));
147
}
148

149
TEST(TypeMatcher, MatchesClassType) {
150
  TypeMatcher TypeA = hasDeclaration(recordDecl(hasName("A")));
151

152
  EXPECT_TRUE(matches("class A { public: A *a; };", TypeA));
153
  EXPECT_TRUE(notMatches("class A {};", TypeA));
154

155
  TypeMatcher TypeDerivedFromA =
156
    hasDeclaration(cxxRecordDecl(isDerivedFrom("A")));
157

158
  EXPECT_TRUE(matches("class A {}; class B : public A { public: B *b; };",
159
                      TypeDerivedFromA));
160
  EXPECT_TRUE(notMatches("class A {};", TypeA));
161

162
  TypeMatcher TypeAHasClassB = hasDeclaration(
163
    recordDecl(hasName("A"), has(recordDecl(hasName("B")))));
164

165
  EXPECT_TRUE(
166
    matches("class A { public: A *a; class B {}; };", TypeAHasClassB));
167

168
  EXPECT_TRUE(matchesC("struct S {}; void f(void) { struct S s; }",
169
                       varDecl(hasType(namedDecl(hasName("S"))))));
170
}
171

172
TEST(TypeMatcher, MatchesDeclTypes) {
173
  // TypedefType -> TypedefNameDecl
174
  EXPECT_TRUE(matches("typedef int I; void f(I i);",
175
                      parmVarDecl(hasType(namedDecl(hasName("I"))))));
176
  // ObjCObjectPointerType
177
  EXPECT_TRUE(matchesObjC("@interface Foo @end void f(Foo *f);",
178
                          parmVarDecl(hasType(objcObjectPointerType()))));
179
  // ObjCObjectPointerType -> ObjCInterfaceType -> ObjCInterfaceDecl
180
  EXPECT_TRUE(matchesObjC(
181
    "@interface Foo @end void f(Foo *f);",
182
    parmVarDecl(hasType(pointsTo(objcInterfaceDecl(hasName("Foo")))))));
183
  // TemplateTypeParmType
184
  EXPECT_TRUE(matches("template <typename T> void f(T t);",
185
                      parmVarDecl(hasType(templateTypeParmType()))));
186
  // TemplateTypeParmType -> TemplateTypeParmDecl
187
  EXPECT_TRUE(matches("template <typename T> void f(T t);",
188
                      parmVarDecl(hasType(namedDecl(hasName("T"))))));
189
  // InjectedClassNameType
190
  EXPECT_TRUE(matches("template <typename T> struct S {"
191
                      "  void f(S s);"
192
                      "};",
193
                      parmVarDecl(hasType(elaboratedType(
194
                          namesType(injectedClassNameType()))))));
195
  EXPECT_TRUE(notMatches("template <typename T> struct S {"
196
                         "  void g(S<T> s);"
197
                         "};",
198
                         parmVarDecl(hasType(elaboratedType(
199
                             namesType(injectedClassNameType()))))));
200
  // InjectedClassNameType -> CXXRecordDecl
201
  EXPECT_TRUE(matches("template <typename T> struct S {"
202
                        "  void f(S s);"
203
                        "};",
204
                      parmVarDecl(hasType(namedDecl(hasName("S"))))));
205

206
  static const char Using[] = "template <typename T>"
207
    "struct Base {"
208
    "  typedef T Foo;"
209
    "};"
210
    ""
211
    "template <typename T>"
212
    "struct S : private Base<T> {"
213
    "  using typename Base<T>::Foo;"
214
    "  void f(Foo);"
215
    "};";
216
  // UnresolvedUsingTypenameDecl
217
  EXPECT_TRUE(matches(Using, unresolvedUsingTypenameDecl(hasName("Foo"))));
218
  // UnresolvedUsingTypenameType -> UnresolvedUsingTypenameDecl
219
  EXPECT_TRUE(matches(Using, parmVarDecl(hasType(namedDecl(hasName("Foo"))))));
220
}
221

222
TEST(HasDeclaration, HasDeclarationOfEnumType) {
223
  EXPECT_TRUE(matches("enum X {}; void y(X *x) { x; }",
224
                      expr(hasType(pointsTo(
225
                        qualType(hasDeclaration(enumDecl(hasName("X")))))))));
226
}
227

228
TEST(HasDeclaration, HasGetDeclTraitTest) {
229
  static_assert(internal::has_getDecl<TypedefType>::value,
230
                "Expected TypedefType to have a getDecl.");
231
  static_assert(internal::has_getDecl<RecordType>::value,
232
                "Expected RecordType to have a getDecl.");
233
  static_assert(!internal::has_getDecl<TemplateSpecializationType>::value,
234
                "Expected TemplateSpecializationType to *not* have a getDecl.");
235
}
236

237
TEST(HasDeclaration, ElaboratedType) {
238
  EXPECT_TRUE(matches(
239
      "namespace n { template <typename T> struct X {}; }"
240
      "void f(n::X<int>);",
241
      parmVarDecl(hasType(qualType(hasDeclaration(cxxRecordDecl()))))));
242
  EXPECT_TRUE(matches(
243
      "namespace n { template <typename T> struct X {}; }"
244
      "void f(n::X<int>);",
245
      parmVarDecl(hasType(elaboratedType(hasDeclaration(cxxRecordDecl()))))));
246
}
247

248
TEST(HasDeclaration, HasDeclarationOfTypeWithDecl) {
249
  EXPECT_TRUE(matches(
250
      "typedef int X; X a;",
251
      varDecl(hasName("a"), hasType(elaboratedType(namesType(
252
                                typedefType(hasDeclaration(decl()))))))));
253

254
  // FIXME: Add tests for other types with getDecl() (e.g. RecordType)
255
}
256

257
TEST(HasDeclaration, HasDeclarationOfTemplateSpecializationType) {
258
  EXPECT_TRUE(matches(
259
      "template <typename T> class A {}; A<int> a;",
260
      varDecl(hasType(elaboratedType(namesType(templateSpecializationType(
261
          hasDeclaration(namedDecl(hasName("A"))))))))));
262
  EXPECT_TRUE(matches(
263
      "template <typename T> class A {};"
264
      "template <typename T> class B { A<T> a; };",
265
      fieldDecl(hasType(elaboratedType(namesType(templateSpecializationType(
266
          hasDeclaration(namedDecl(hasName("A"))))))))));
267
  EXPECT_TRUE(matches(
268
      "template <typename T> class A {}; A<int> a;",
269
      varDecl(hasType(elaboratedType(namesType(
270
          templateSpecializationType(hasDeclaration(cxxRecordDecl()))))))));
271
}
272

273
TEST(HasDeclaration, HasDeclarationOfCXXNewExpr) {
274
  EXPECT_TRUE(
275
      matches("int *A = new int();",
276
              cxxNewExpr(hasDeclaration(functionDecl(parameterCountIs(1))))));
277
}
278

279
TEST(HasDeclaration, HasDeclarationOfTypeAlias) {
280
  EXPECT_TRUE(matches(
281
      "template <typename T> using C = T; C<int> c;",
282
      varDecl(hasType(elaboratedType(namesType(templateSpecializationType(
283
          hasDeclaration(typeAliasTemplateDecl()))))))));
284
}
285

286
TEST(HasUnqualifiedDesugaredType, DesugarsUsing) {
287
  EXPECT_TRUE(
288
      matches("struct A {}; using B = A; B b;",
289
              varDecl(hasType(hasUnqualifiedDesugaredType(recordType())))));
290
  EXPECT_TRUE(
291
      matches("struct A {}; using B = A; using C = B; C b;",
292
              varDecl(hasType(hasUnqualifiedDesugaredType(recordType())))));
293
}
294

295
TEST(HasUnderlyingDecl, Matches) {
296
  EXPECT_TRUE(matches("namespace N { template <class T> void f(T t); }"
297
                      "template <class T> void g() { using N::f; f(T()); }",
298
                      unresolvedLookupExpr(hasAnyDeclaration(
299
                          namedDecl(hasUnderlyingDecl(hasName("::N::f")))))));
300
  EXPECT_TRUE(matches(
301
      "namespace N { template <class T> void f(T t); }"
302
      "template <class T> void g() { N::f(T()); }",
303
      unresolvedLookupExpr(hasAnyDeclaration(namedDecl(hasName("::N::f"))))));
304
  EXPECT_TRUE(notMatches(
305
      "namespace N { template <class T> void f(T t); }"
306
      "template <class T> void g() { using N::f; f(T()); }",
307
      unresolvedLookupExpr(hasAnyDeclaration(namedDecl(hasName("::N::f"))))));
308
}
309

310
TEST(HasType, TakesQualTypeMatcherAndMatchesExpr) {
311
  TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
312
  EXPECT_TRUE(
313
    matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX))));
314
  EXPECT_TRUE(
315
    notMatches("class X {}; void y(X *x) { x; }",
316
               expr(hasType(ClassX))));
317
  EXPECT_TRUE(
318
    matches("class X {}; void y(X *x) { x; }",
319
            expr(hasType(pointsTo(ClassX)))));
320
}
321

322
TEST(HasType, TakesQualTypeMatcherAndMatchesValueDecl) {
323
  TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
324
  EXPECT_TRUE(
325
    matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX))));
326
  EXPECT_TRUE(
327
    notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX))));
328
  EXPECT_TRUE(
329
    matches("class X {}; void y() { X *x; }",
330
            varDecl(hasType(pointsTo(ClassX)))));
331
}
332

333
TEST(HasType, TakesQualTypeMatcherAndMatchesCXXBaseSpecifier) {
334
  TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
335
  CXXBaseSpecifierMatcher BaseClassX = cxxBaseSpecifier(hasType(ClassX));
336
  DeclarationMatcher ClassHasBaseClassX =
337
      cxxRecordDecl(hasDirectBase(BaseClassX));
338
  EXPECT_TRUE(matches("class X {}; class Y : X {};", ClassHasBaseClassX));
339
  EXPECT_TRUE(notMatches("class Z {}; class Y : Z {};", ClassHasBaseClassX));
340
}
341

342
TEST(HasType, TakesDeclMatcherAndMatchesExpr) {
343
  DeclarationMatcher ClassX = recordDecl(hasName("X"));
344
  EXPECT_TRUE(
345
    matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX))));
346
  EXPECT_TRUE(
347
    notMatches("class X {}; void y(X *x) { x; }",
348
               expr(hasType(ClassX))));
349
}
350

351
TEST(HasType, TakesDeclMatcherAndMatchesValueDecl) {
352
  DeclarationMatcher ClassX = recordDecl(hasName("X"));
353
  EXPECT_TRUE(
354
    matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX))));
355
  EXPECT_TRUE(
356
    notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX))));
357
}
358

359
TEST(HasType, TakesDeclMatcherAndMatchesCXXBaseSpecifier) {
360
  DeclarationMatcher ClassX = recordDecl(hasName("X"));
361
  CXXBaseSpecifierMatcher BaseClassX = cxxBaseSpecifier(hasType(ClassX));
362
  DeclarationMatcher ClassHasBaseClassX =
363
      cxxRecordDecl(hasDirectBase(BaseClassX));
364
  EXPECT_TRUE(matches("class X {}; class Y : X {};", ClassHasBaseClassX));
365
  EXPECT_TRUE(notMatches("class Z {}; class Y : Z {};", ClassHasBaseClassX));
366
}
367

368
TEST(HasType, MatchesTypedefDecl) {
369
  EXPECT_TRUE(matches("typedef int X;", typedefDecl(hasType(asString("int")))));
370
  EXPECT_TRUE(matches("typedef const int T;",
371
                      typedefDecl(hasType(asString("const int")))));
372
  EXPECT_TRUE(notMatches("typedef const int T;",
373
                         typedefDecl(hasType(asString("int")))));
374
  EXPECT_TRUE(matches("typedef int foo; typedef foo bar;",
375
                      typedefDecl(hasType(asString("foo")), hasName("bar"))));
376
}
377

378
TEST(HasType, MatchesTypedefNameDecl) {
379
  EXPECT_TRUE(matches("using X = int;", typedefNameDecl(hasType(asString("int")))));
380
  EXPECT_TRUE(matches("using T = const int;",
381
                      typedefNameDecl(hasType(asString("const int")))));
382
  EXPECT_TRUE(notMatches("using T = const int;",
383
                         typedefNameDecl(hasType(asString("int")))));
384
  EXPECT_TRUE(matches("using foo = int; using bar = foo;",
385
                      typedefNameDecl(hasType(asString("foo")), hasName("bar"))));
386
}
387

388
TEST(HasTypeLoc, MatchesBlockDecl) {
389
  EXPECT_TRUE(matchesConditionally(
390
      "auto x = ^int (int a, int b) { return a + b; };",
391
      blockDecl(hasTypeLoc(loc(asString("int (int, int)")))), true,
392
      {"-fblocks"}));
393
}
394

395
TEST(HasTypeLoc, MatchesCXXBaseSpecifierAndCtorInitializer) {
396
  llvm::StringRef code = R"cpp(
397
  class Foo {};
398
  class Bar : public Foo {
399
    Bar() : Foo() {}
400
  };
401
  )cpp";
402

403
  EXPECT_TRUE(matches(
404
      code, cxxRecordDecl(hasAnyBase(hasTypeLoc(loc(asString("Foo")))))));
405
  EXPECT_TRUE(
406
      matches(code, cxxCtorInitializer(hasTypeLoc(loc(asString("Foo"))))));
407
}
408

409
TEST(HasTypeLoc, MatchesCXXFunctionalCastExpr) {
410
  EXPECT_TRUE(matches("auto x = int(3);",
411
                      cxxFunctionalCastExpr(hasTypeLoc(loc(asString("int"))))));
412
}
413

414
TEST(HasTypeLoc, MatchesCXXNewExpr) {
415
  EXPECT_TRUE(matches("auto* x = new int(3);",
416
                      cxxNewExpr(hasTypeLoc(loc(asString("int"))))));
417
  EXPECT_TRUE(matches("class Foo{}; auto* x = new Foo();",
418
                      cxxNewExpr(hasTypeLoc(loc(asString("Foo"))))));
419
}
420

421
TEST(HasTypeLoc, MatchesCXXTemporaryObjectExpr) {
422
  EXPECT_TRUE(
423
      matches("struct Foo { Foo(int, int); }; auto x = Foo(1, 2);",
424
              cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("Foo"))))));
425
}
426

427
TEST(HasTypeLoc, MatchesCXXUnresolvedConstructExpr) {
428
  EXPECT_TRUE(
429
      matches("template <typename T> T make() { return T(); }",
430
              cxxUnresolvedConstructExpr(hasTypeLoc(loc(asString("T"))))));
431
}
432

433
TEST(HasTypeLoc, MatchesCompoundLiteralExpr) {
434
  EXPECT_TRUE(
435
      matches("int* x = (int[2]) { 0, 1 };",
436
              compoundLiteralExpr(hasTypeLoc(loc(asString("int[2]"))))));
437
}
438

439
TEST(HasTypeLoc, MatchesDeclaratorDecl) {
440
  EXPECT_TRUE(matches("int x;",
441
                      varDecl(hasName("x"), hasTypeLoc(loc(asString("int"))))));
442
  EXPECT_TRUE(matches("int x(3);",
443
                      varDecl(hasName("x"), hasTypeLoc(loc(asString("int"))))));
444
  EXPECT_TRUE(matches("struct Foo { Foo(int, int); }; Foo x(1, 2);",
445
                      varDecl(hasName("x"), hasTypeLoc(loc(asString("Foo"))))));
446

447
  // Make sure we don't crash on implicit constructors.
448
  EXPECT_TRUE(notMatches("class X {}; X x;",
449
                         declaratorDecl(hasTypeLoc(loc(asString("int"))))));
450
}
451

452
TEST(HasTypeLoc, MatchesExplicitCastExpr) {
453
  EXPECT_TRUE(matches("auto x = (int) 3;",
454
                      explicitCastExpr(hasTypeLoc(loc(asString("int"))))));
455
  EXPECT_TRUE(matches("auto x = static_cast<int>(3);",
456
                      explicitCastExpr(hasTypeLoc(loc(asString("int"))))));
457
}
458

459
TEST(HasTypeLoc, MatchesObjCPropertyDecl) {
460
  EXPECT_TRUE(matchesObjC(R"objc(
461
      @interface Foo
462
      @property int enabled;
463
      @end
464
    )objc",
465
                          objcPropertyDecl(hasTypeLoc(loc(asString("int"))))));
466
}
467

468
TEST(HasTypeLoc, MatchesTemplateArgumentLoc) {
469
  EXPECT_TRUE(matches("template <typename T> class Foo {}; Foo<int> x;",
470
                      templateArgumentLoc(hasTypeLoc(loc(asString("int"))))));
471
}
472

473
TEST(HasTypeLoc, MatchesTypedefNameDecl) {
474
  EXPECT_TRUE(matches("typedef int X;",
475
                      typedefNameDecl(hasTypeLoc(loc(asString("int"))))));
476
  EXPECT_TRUE(matches("using X = int;",
477
                      typedefNameDecl(hasTypeLoc(loc(asString("int"))))));
478
}
479

480
TEST(Callee, MatchesDeclarations) {
481
  StatementMatcher CallMethodX = callExpr(callee(cxxMethodDecl(hasName("x"))));
482

483
  EXPECT_TRUE(matches("class Y { void x() { x(); } };", CallMethodX));
484
  EXPECT_TRUE(notMatches("class Y { void x() {} };", CallMethodX));
485

486
  CallMethodX = traverse(TK_AsIs, callExpr(callee(cxxConversionDecl())));
487
  EXPECT_TRUE(
488
    matches("struct Y { operator int() const; }; int i = Y();", CallMethodX));
489
  EXPECT_TRUE(notMatches("struct Y { operator int() const; }; Y y = Y();",
490
                         CallMethodX));
491
}
492

493
TEST(Callee, MatchesMemberExpressions) {
494
  EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
495
                      callExpr(callee(memberExpr()))));
496
  EXPECT_TRUE(
497
    notMatches("class Y { void x() { this->x(); } };", callExpr(callee(callExpr()))));
498
}
499

500
TEST(Matcher, Argument) {
501
  StatementMatcher CallArgumentY = callExpr(
502
    hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
503

504
  EXPECT_TRUE(matches("void x(int) { int y; x(y); }", CallArgumentY));
505
  EXPECT_TRUE(
506
    matches("class X { void x(int) { int y; x(y); } };", CallArgumentY));
507
  EXPECT_TRUE(notMatches("void x(int) { int z; x(z); }", CallArgumentY));
508

509
  StatementMatcher WrongIndex = callExpr(
510
    hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
511
  EXPECT_TRUE(notMatches("void x(int) { int y; x(y); }", WrongIndex));
512
}
513

514
TEST(Matcher, AnyArgument) {
515
  auto HasArgumentY = hasAnyArgument(
516
      ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("y"))))));
517
  StatementMatcher CallArgumentY = callExpr(HasArgumentY);
518
  StatementMatcher CtorArgumentY = cxxConstructExpr(HasArgumentY);
519
  StatementMatcher UnresolvedCtorArgumentY =
520
      cxxUnresolvedConstructExpr(HasArgumentY);
521
  StatementMatcher ObjCCallArgumentY = objcMessageExpr(HasArgumentY);
522
  EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
523
  EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
524
  EXPECT_TRUE(matches("struct Y { Y(int, int); };"
525
                      "void x() { int y; (void)Y(1, y); }",
526
                      CtorArgumentY));
527
  EXPECT_TRUE(matches("struct Y { Y(int, int); };"
528
                      "void x() { int y; (void)Y(y, 42); }",
529
                      CtorArgumentY));
530
  EXPECT_TRUE(matches("template <class Y> void x() { int y; (void)Y(1, y); }",
531
                      UnresolvedCtorArgumentY));
532
  EXPECT_TRUE(matches("template <class Y> void x() { int y; (void)Y(y, 42); }",
533
                      UnresolvedCtorArgumentY));
534
  EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) y; @end "
535
                          "void x(I* i) { int y; [i f:y]; }",
536
                          ObjCCallArgumentY));
537
  EXPECT_FALSE(matchesObjC("@interface I -(void)f:(int) z; @end "
538
                           "void x(I* i) { int z; [i f:z]; }",
539
                           ObjCCallArgumentY));
540
  EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
541
  EXPECT_TRUE(notMatches("struct Y { Y(int, int); };"
542
                         "void x() { int y; (void)Y(1, 2); }",
543
                         CtorArgumentY));
544
  EXPECT_TRUE(notMatches("template <class Y>"
545
                         "void x() { int y; (void)Y(1, 2); }",
546
                         UnresolvedCtorArgumentY));
547

548
  StatementMatcher ImplicitCastedArgument =
549
      traverse(TK_AsIs, callExpr(hasAnyArgument(implicitCastExpr())));
550
  EXPECT_TRUE(matches("void x(long) { int y; x(y); }", ImplicitCastedArgument));
551
}
552

553
TEST(Matcher, HasReceiver) {
554
  EXPECT_TRUE(matchesObjC(
555
      "@interface NSString @end "
556
      "void f(NSString *x) {"
557
      "[x containsString];"
558
      "}",
559
      objcMessageExpr(hasReceiver(declRefExpr(to(varDecl(hasName("x"))))))));
560

561
  EXPECT_FALSE(matchesObjC(
562
      "@interface NSString +(NSString *) stringWithFormat; @end "
563
      "void f() { [NSString stringWithFormat]; }",
564
      objcMessageExpr(hasReceiver(declRefExpr(to(varDecl(hasName("x"))))))));
565
}
566

567
TEST(Matcher, MatchesMethodsOnLambda) {
568
  StringRef Code = R"cpp(
569
struct A {
570
  ~A() {}
571
};
572
void foo()
573
{
574
  A a;
575
  auto l = [a] { };
576
  auto lCopy = l;
577
  auto lPtrDecay = +[] { };
578
  (void)lPtrDecay;
579
}
580
)cpp";
581

582
  EXPECT_TRUE(matches(
583
      Code, cxxConstructorDecl(
584
                hasBody(compoundStmt()),
585
                hasAncestor(lambdaExpr(hasAncestor(varDecl(hasName("l"))))),
586
                isCopyConstructor())));
587
  EXPECT_TRUE(matches(
588
      Code, cxxConstructorDecl(
589
                hasBody(compoundStmt()),
590
                hasAncestor(lambdaExpr(hasAncestor(varDecl(hasName("l"))))),
591
                isMoveConstructor())));
592
  EXPECT_TRUE(matches(
593
      Code, cxxDestructorDecl(
594
                hasBody(compoundStmt()),
595
                hasAncestor(lambdaExpr(hasAncestor(varDecl(hasName("l"))))))));
596
  EXPECT_TRUE(matches(
597
      Code, cxxConversionDecl(hasBody(compoundStmt(has(returnStmt(
598
                                  hasReturnValue(implicitCastExpr()))))),
599
                              hasAncestor(lambdaExpr(hasAncestor(
600
                                  varDecl(hasName("lPtrDecay"))))))));
601
}
602

603
TEST(Matcher, MatchesCoroutine) {
604
  FileContentMappings M;
605
  M.push_back(std::make_pair("/coro_header", R"cpp(
606
namespace std {
607

608
template <class... Args>
609
struct void_t_imp {
610
  using type = void;
611
};
612
template <class... Args>
613
using void_t = typename void_t_imp<Args...>::type;
614

615
template <class T, class = void>
616
struct traits_sfinae_base {};
617

618
template <class T>
619
struct traits_sfinae_base<T, void_t<typename T::promise_type>> {
620
  using promise_type = typename T::promise_type;
621
};
622

623
template <class Ret, class... Args>
624
struct coroutine_traits : public traits_sfinae_base<Ret> {};
625
}  // namespace std
626
struct awaitable {
627
  bool await_ready() noexcept;
628
  template <typename F>
629
  void await_suspend(F) noexcept;
630
  void await_resume() noexcept;
631
} a;
632
struct promise {
633
  void get_return_object();
634
  awaitable initial_suspend();
635
  awaitable final_suspend() noexcept;
636
  awaitable yield_value(int); // expected-note 2{{candidate}}
637
  void return_value(int); // expected-note 2{{here}}
638
  void unhandled_exception();
639
};
640
template <typename... T>
641
struct std::coroutine_traits<void, T...> { using promise_type = promise; };
642
namespace std {
643
template <class PromiseType = void>
644
struct coroutine_handle {
645
  static coroutine_handle from_address(void *) noexcept;
646
};
647
} // namespace std
648
)cpp"));
649
  StringRef CoReturnCode = R"cpp(
650
#include <coro_header>
651
void check_match_co_return() {
652
  co_return 1;
653
}
654
)cpp";
655
  EXPECT_TRUE(matchesConditionally(CoReturnCode,
656
                                   coreturnStmt(isExpansionInMainFile()), true,
657
                                   {"-std=c++20", "-I/"}, M));
658
  StringRef CoAwaitCode = R"cpp(
659
#include <coro_header>
660
void check_match_co_await() {
661
  co_await a;
662
}
663
)cpp";
664
  EXPECT_TRUE(matchesConditionally(CoAwaitCode,
665
                                   coawaitExpr(isExpansionInMainFile()), true,
666
                                   {"-std=c++20", "-I/"}, M));
667
  StringRef CoYieldCode = R"cpp(
668
#include <coro_header>
669
void check_match_co_yield() {
670
  co_yield 1.0;
671
}
672
)cpp";
673
  EXPECT_TRUE(matchesConditionally(CoYieldCode,
674
                                   coyieldExpr(isExpansionInMainFile()), true,
675
                                   {"-std=c++20", "-I/"}, M));
676

677
  StringRef NonCoroCode = R"cpp(
678
#include <coro_header>
679
void non_coro_function() {
680
}
681
)cpp";
682

683
  EXPECT_TRUE(matchesConditionally(CoReturnCode, coroutineBodyStmt(), true,
684
                                   {"-std=c++20", "-I/"}, M));
685
  EXPECT_TRUE(matchesConditionally(CoAwaitCode, coroutineBodyStmt(), true,
686
                                   {"-std=c++20", "-I/"}, M));
687
  EXPECT_TRUE(matchesConditionally(CoYieldCode, coroutineBodyStmt(), true,
688
                                   {"-std=c++20", "-I/"}, M));
689

690
  EXPECT_FALSE(matchesConditionally(NonCoroCode, coroutineBodyStmt(), true,
691
                                    {"-std=c++20", "-I/"}, M));
692

693
  StringRef CoroWithDeclCode = R"cpp(
694
#include <coro_header>
695
void coro() {
696
  int thevar;
697
  co_return 1;
698
}
699
)cpp";
700
  EXPECT_TRUE(matchesConditionally(
701
      CoroWithDeclCode,
702
      coroutineBodyStmt(hasBody(compoundStmt(
703
          has(declStmt(containsDeclaration(0, varDecl(hasName("thevar")))))))),
704
      true, {"-std=c++20", "-I/"}, M));
705

706
  StringRef CoroWithTryCatchDeclCode = R"cpp(
707
#include <coro_header>
708
void coro() try {
709
  int thevar;
710
  co_return 1;
711
} catch (...) {}
712
)cpp";
713
  EXPECT_TRUE(matchesConditionally(
714
      CoroWithTryCatchDeclCode,
715
      coroutineBodyStmt(hasBody(compoundStmt(has(cxxTryStmt(has(compoundStmt(has(
716
          declStmt(containsDeclaration(0, varDecl(hasName("thevar")))))))))))),
717
      true, {"-std=c++20", "-I/"}, M));
718
}
719

720
TEST(Matcher, isClassMessage) {
721
  EXPECT_TRUE(matchesObjC(
722
      "@interface NSString +(NSString *) stringWithFormat; @end "
723
      "void f() { [NSString stringWithFormat]; }",
724
      objcMessageExpr(isClassMessage())));
725

726
  EXPECT_FALSE(matchesObjC(
727
      "@interface NSString @end "
728
      "void f(NSString *x) {"
729
      "[x containsString];"
730
      "}",
731
      objcMessageExpr(isClassMessage())));
732
}
733

734
TEST(Matcher, isInstanceMessage) {
735
  EXPECT_TRUE(matchesObjC(
736
      "@interface NSString @end "
737
      "void f(NSString *x) {"
738
      "[x containsString];"
739
      "}",
740
      objcMessageExpr(isInstanceMessage())));
741

742
  EXPECT_FALSE(matchesObjC(
743
      "@interface NSString +(NSString *) stringWithFormat; @end "
744
      "void f() { [NSString stringWithFormat]; }",
745
      objcMessageExpr(isInstanceMessage())));
746

747
}
748

749
TEST(Matcher, isClassMethod) {
750
  EXPECT_TRUE(matchesObjC(
751
    "@interface Bar + (void)bar; @end",
752
    objcMethodDecl(isClassMethod())));
753

754
  EXPECT_TRUE(matchesObjC(
755
    "@interface Bar @end"
756
    "@implementation Bar + (void)bar {} @end",
757
    objcMethodDecl(isClassMethod())));
758

759
  EXPECT_FALSE(matchesObjC(
760
    "@interface Foo - (void)foo; @end",
761
    objcMethodDecl(isClassMethod())));
762

763
  EXPECT_FALSE(matchesObjC(
764
    "@interface Foo @end "
765
    "@implementation Foo - (void)foo {} @end",
766
    objcMethodDecl(isClassMethod())));
767
}
768

769
TEST(Matcher, isInstanceMethod) {
770
  EXPECT_TRUE(matchesObjC(
771
    "@interface Foo - (void)foo; @end",
772
    objcMethodDecl(isInstanceMethod())));
773

774
  EXPECT_TRUE(matchesObjC(
775
    "@interface Foo @end "
776
    "@implementation Foo - (void)foo {} @end",
777
    objcMethodDecl(isInstanceMethod())));
778

779
  EXPECT_FALSE(matchesObjC(
780
    "@interface Bar + (void)bar; @end",
781
    objcMethodDecl(isInstanceMethod())));
782

783
  EXPECT_FALSE(matchesObjC(
784
    "@interface Bar @end"
785
    "@implementation Bar + (void)bar {} @end",
786
    objcMethodDecl(isInstanceMethod())));
787
}
788

789
TEST(MatcherCXXMemberCallExpr, On) {
790
  StringRef Snippet1 = R"cc(
791
        struct Y {
792
          void m();
793
        };
794
        void z(Y y) { y.m(); }
795
      )cc";
796
  StringRef Snippet2 = R"cc(
797
        struct Y {
798
          void m();
799
        };
800
        struct X : public Y {};
801
        void z(X x) { x.m(); }
802
      )cc";
803
  auto MatchesY = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y")))));
804
  EXPECT_TRUE(matches(Snippet1, MatchesY));
805
  EXPECT_TRUE(notMatches(Snippet2, MatchesY));
806

807
  auto MatchesX = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("X")))));
808
  EXPECT_TRUE(matches(Snippet2, MatchesX));
809

810
  // Parens are ignored.
811
  StringRef Snippet3 = R"cc(
812
    struct Y {
813
      void m();
814
    };
815
    Y g();
816
    void z(Y y) { (g()).m(); }
817
  )cc";
818
  auto MatchesCall = cxxMemberCallExpr(on(callExpr()));
819
  EXPECT_TRUE(matches(Snippet3, MatchesCall));
820
}
821

822
TEST(MatcherCXXMemberCallExpr, OnImplicitObjectArgument) {
823
  StringRef Snippet1 = R"cc(
824
    struct Y {
825
      void m();
826
    };
827
    void z(Y y) { y.m(); }
828
  )cc";
829
  StringRef Snippet2 = R"cc(
830
    struct Y {
831
      void m();
832
    };
833
    struct X : public Y {};
834
    void z(X x) { x.m(); }
835
  )cc";
836
  auto MatchesY = traverse(TK_AsIs, cxxMemberCallExpr(onImplicitObjectArgument(
837
                                        hasType(cxxRecordDecl(hasName("Y"))))));
838
  EXPECT_TRUE(matches(Snippet1, MatchesY));
839
  EXPECT_TRUE(matches(Snippet2, MatchesY));
840

841
  auto MatchesX = traverse(TK_AsIs, cxxMemberCallExpr(onImplicitObjectArgument(
842
                                        hasType(cxxRecordDecl(hasName("X"))))));
843
  EXPECT_TRUE(notMatches(Snippet2, MatchesX));
844

845
  // Parens are not ignored.
846
  StringRef Snippet3 = R"cc(
847
    struct Y {
848
      void m();
849
    };
850
    Y g();
851
    void z(Y y) { (g()).m(); }
852
  )cc";
853
  auto MatchesCall = traverse(
854
      TK_AsIs, cxxMemberCallExpr(onImplicitObjectArgument(callExpr())));
855
  EXPECT_TRUE(notMatches(Snippet3, MatchesCall));
856
}
857

858
TEST(Matcher, HasObjectExpr) {
859
  StringRef Snippet1 = R"cc(
860
        struct X {
861
          int m;
862
          int f(X x) { return x.m; }
863
        };
864
      )cc";
865
  StringRef Snippet2 = R"cc(
866
        struct X {
867
          int m;
868
          int f(X x) { return m; }
869
        };
870
      )cc";
871
  auto MatchesX =
872
      memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))));
873
  EXPECT_TRUE(matches(Snippet1, MatchesX));
874
  EXPECT_TRUE(notMatches(Snippet2, MatchesX));
875

876
  auto MatchesXPointer = memberExpr(
877
      hasObjectExpression(hasType(pointsTo(cxxRecordDecl(hasName("X"))))));
878
  EXPECT_TRUE(notMatches(Snippet1, MatchesXPointer));
879
  EXPECT_TRUE(matches(Snippet2, MatchesXPointer));
880
}
881

882
TEST(ForEachArgumentWithParam, ReportsNoFalsePositives) {
883
  StatementMatcher ArgumentY =
884
    declRefExpr(to(varDecl(hasName("y")))).bind("arg");
885
  DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
886
  StatementMatcher CallExpr =
887
    callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
888

889
  // IntParam does not match.
890
  EXPECT_TRUE(notMatches("void f(int* i) { int* y; f(y); }", CallExpr));
891
  // ArgumentY does not match.
892
  EXPECT_TRUE(notMatches("void f(int i) { int x; f(x); }", CallExpr));
893
}
894

895
TEST(ForEachArgumentWithParam, MatchesCXXMemberCallExpr) {
896
  StatementMatcher ArgumentY =
897
    declRefExpr(to(varDecl(hasName("y")))).bind("arg");
898
  DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
899
  StatementMatcher CallExpr =
900
    callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
901
  EXPECT_TRUE(matchAndVerifyResultTrue(
902
    "struct S {"
903
      "  const S& operator[](int i) { return *this; }"
904
      "};"
905
      "void f(S S1) {"
906
      "  int y = 1;"
907
      "  S1[y];"
908
      "}",
909
    CallExpr, std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param", 1)));
910

911
  StatementMatcher CallExpr2 =
912
    callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
913
  EXPECT_TRUE(matchAndVerifyResultTrue(
914
    "struct S {"
915
      "  static void g(int i);"
916
      "};"
917
      "void f() {"
918
      "  int y = 1;"
919
      "  S::g(y);"
920
      "}",
921
    CallExpr2, std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param", 1)));
922
}
923

924
TEST(ForEachArgumentWithParam, MatchesCallExpr) {
925
  StatementMatcher ArgumentY =
926
    declRefExpr(to(varDecl(hasName("y")))).bind("arg");
927
  DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
928
  StatementMatcher CallExpr =
929
    callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
930

931
  EXPECT_TRUE(
932
    matchAndVerifyResultTrue("void f(int i) { int y; f(y); }", CallExpr,
933
                             std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>(
934
                               "param")));
935
  EXPECT_TRUE(
936
    matchAndVerifyResultTrue("void f(int i) { int y; f(y); }", CallExpr,
937
                             std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>(
938
                               "arg")));
939

940
  EXPECT_TRUE(matchAndVerifyResultTrue(
941
    "void f(int i, int j) { int y; f(y, y); }", CallExpr,
942
    std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param", 2)));
943
  EXPECT_TRUE(matchAndVerifyResultTrue(
944
    "void f(int i, int j) { int y; f(y, y); }", CallExpr,
945
    std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg", 2)));
946
}
947

948
TEST(ForEachArgumentWithParam, MatchesConstructExpr) {
949
  StatementMatcher ArgumentY =
950
    declRefExpr(to(varDecl(hasName("y")))).bind("arg");
951
  DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
952
  StatementMatcher ConstructExpr = traverse(
953
      TK_AsIs, cxxConstructExpr(forEachArgumentWithParam(ArgumentY, IntParam)));
954

955
  EXPECT_TRUE(matchAndVerifyResultTrue(
956
    "struct C {"
957
      "  C(int i) {}"
958
      "};"
959
      "int y = 0;"
960
      "C Obj(y);",
961
    ConstructExpr,
962
    std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param")));
963
}
964

965
TEST(ForEachArgumentWithParam, HandlesBoundNodesForNonMatches) {
966
  EXPECT_TRUE(matchAndVerifyResultTrue(
967
    "void g(int i, int j) {"
968
      "  int a;"
969
      "  int b;"
970
      "  int c;"
971
      "  g(a, 0);"
972
      "  g(a, b);"
973
      "  g(0, b);"
974
      "}",
975
    functionDecl(
976
      forEachDescendant(varDecl().bind("v")),
977
      forEachDescendant(callExpr(forEachArgumentWithParam(
978
        declRefExpr(to(decl(equalsBoundNode("v")))), parmVarDecl())))),
979
    std::make_unique<VerifyIdIsBoundTo<VarDecl>>("v", 4)));
980
}
981

982
TEST_P(ASTMatchersTest,
983
       ForEachArgumentWithParamMatchesExplicitObjectParamOnOperatorCalls) {
984
  if (!GetParam().isCXX23OrLater()) {
985
    return;
986
  }
987

988
  auto DeclRef = declRefExpr(to(varDecl().bind("declOfArg"))).bind("arg");
989
  auto SelfParam = parmVarDecl().bind("param");
990
  StatementMatcher CallExpr =
991
      callExpr(forEachArgumentWithParam(DeclRef, SelfParam));
992

993
  StringRef S = R"cpp(
994
  struct A {
995
    int operator()(this const A &self);
996
  };
997
  A obj;
998
  int global = obj();
999
  )cpp";
1000

1001
  auto Args = GetParam().getCommandLineArgs();
1002
  auto Filename = getFilenameForTesting(GetParam().Language);
1003

1004
  EXPECT_TRUE(matchAndVerifyResultTrue(
1005
      S, CallExpr,
1006
      std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param", "self"), Args,
1007
      Filename));
1008
  EXPECT_TRUE(matchAndVerifyResultTrue(
1009
      S, CallExpr,
1010
      std::make_unique<VerifyIdIsBoundTo<VarDecl>>("declOfArg", "obj"), Args,
1011
      Filename));
1012
}
1013

1014
TEST(ForEachArgumentWithParamType, ReportsNoFalsePositives) {
1015
  StatementMatcher ArgumentY =
1016
      declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1017
  TypeMatcher IntType = qualType(isInteger()).bind("type");
1018
  StatementMatcher CallExpr =
1019
      callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1020

1021
  // IntParam does not match.
1022
  EXPECT_TRUE(notMatches("void f(int* i) { int* y; f(y); }", CallExpr));
1023
  // ArgumentY does not match.
1024
  EXPECT_TRUE(notMatches("void f(int i) { int x; f(x); }", CallExpr));
1025
}
1026

1027
TEST(ForEachArgumentWithParamType, MatchesCXXMemberCallExpr) {
1028
  StatementMatcher ArgumentY =
1029
      declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1030
  TypeMatcher IntType = qualType(isInteger()).bind("type");
1031
  StatementMatcher CallExpr =
1032
      callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1033
  EXPECT_TRUE(matchAndVerifyResultTrue(
1034
      "struct S {"
1035
      "  const S& operator[](int i) { return *this; }"
1036
      "};"
1037
      "void f(S S1) {"
1038
      "  int y = 1;"
1039
      "  S1[y];"
1040
      "}",
1041
      CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type", 1)));
1042

1043
  StatementMatcher CallExpr2 =
1044
      callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1045
  EXPECT_TRUE(matchAndVerifyResultTrue(
1046
      "struct S {"
1047
      "  static void g(int i);"
1048
      "};"
1049
      "void f() {"
1050
      "  int y = 1;"
1051
      "  S::g(y);"
1052
      "}",
1053
      CallExpr2, std::make_unique<VerifyIdIsBoundTo<QualType>>("type", 1)));
1054
}
1055

1056
TEST(ForEachArgumentWithParamType, MatchesCallExpr) {
1057
  StatementMatcher ArgumentY =
1058
      declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1059
  TypeMatcher IntType = qualType(isInteger()).bind("type");
1060
  StatementMatcher CallExpr =
1061
      callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1062

1063
  EXPECT_TRUE(matchAndVerifyResultTrue(
1064
      "void f(int i) { int y; f(y); }", CallExpr,
1065
      std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
1066
  EXPECT_TRUE(matchAndVerifyResultTrue(
1067
      "void f(int i) { int y; f(y); }", CallExpr,
1068
      std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
1069

1070
  EXPECT_TRUE(matchAndVerifyResultTrue(
1071
      "void f(int i, int j) { int y; f(y, y); }", CallExpr,
1072
      std::make_unique<VerifyIdIsBoundTo<QualType>>("type", 2)));
1073
  EXPECT_TRUE(matchAndVerifyResultTrue(
1074
      "void f(int i, int j) { int y; f(y, y); }", CallExpr,
1075
      std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg", 2)));
1076
}
1077

1078
TEST(ForEachArgumentWithParamType, MatchesConstructExpr) {
1079
  StatementMatcher ArgumentY =
1080
      declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1081
  TypeMatcher IntType = qualType(isInteger()).bind("type");
1082
  StatementMatcher ConstructExpr =
1083
      cxxConstructExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1084

1085
  EXPECT_TRUE(matchAndVerifyResultTrue(
1086
      "struct C {"
1087
      "  C(int i) {}"
1088
      "};"
1089
      "int y = 0;"
1090
      "C Obj(y);",
1091
      ConstructExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
1092
  EXPECT_TRUE(matchAndVerifyResultTrue(
1093
      "struct C {"
1094
      "  C(int i) {}"
1095
      "};"
1096
      "int y = 0;"
1097
      "C Obj(y);",
1098
      ConstructExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
1099
}
1100

1101
TEST(ForEachArgumentWithParamType, HandlesKandRFunctions) {
1102
  StatementMatcher ArgumentY =
1103
      declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1104
  TypeMatcher IntType = qualType(isInteger()).bind("type");
1105
  StatementMatcher CallExpr =
1106
      callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1107

1108
  EXPECT_TRUE(matchesC("void f();\n"
1109
                       "void call_it(void) { int x, y; f(x, y); }\n"
1110
                       "void f(a, b) int a, b; {}\n"
1111
                       "void call_it2(void) { int x, y; f(x, y); }",
1112
                       CallExpr));
1113
}
1114

1115
TEST(ForEachArgumentWithParamType, HandlesBoundNodesForNonMatches) {
1116
  EXPECT_TRUE(matchAndVerifyResultTrue(
1117
      "void g(int i, int j) {"
1118
      "  int a;"
1119
      "  int b;"
1120
      "  int c;"
1121
      "  g(a, 0);"
1122
      "  g(a, b);"
1123
      "  g(0, b);"
1124
      "}",
1125
      functionDecl(
1126
          forEachDescendant(varDecl().bind("v")),
1127
          forEachDescendant(callExpr(forEachArgumentWithParamType(
1128
              declRefExpr(to(decl(equalsBoundNode("v")))), qualType())))),
1129
      std::make_unique<VerifyIdIsBoundTo<VarDecl>>("v", 4)));
1130
}
1131

1132
TEST(ForEachArgumentWithParamType, MatchesFunctionPtrCalls) {
1133
  StatementMatcher ArgumentY =
1134
      declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1135
  TypeMatcher IntType = qualType(builtinType()).bind("type");
1136
  StatementMatcher CallExpr =
1137
      callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1138

1139
  EXPECT_TRUE(matchAndVerifyResultTrue(
1140
      "void f(int i) {"
1141
      "void (*f_ptr)(int) = f; int y; f_ptr(y); }",
1142
      CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
1143
  EXPECT_TRUE(matchAndVerifyResultTrue(
1144
      "void f(int i) {"
1145
      "void (*f_ptr)(int) = f; int y; f_ptr(y); }",
1146
      CallExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
1147
}
1148

1149
TEST(ForEachArgumentWithParamType, MatchesMemberFunctionPtrCalls) {
1150
  StatementMatcher ArgumentY =
1151
      declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1152
  TypeMatcher IntType = qualType(builtinType()).bind("type");
1153
  StatementMatcher CallExpr =
1154
      callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1155

1156
  StringRef S = "struct A {\n"
1157
                "  int f(int i) { return i + 1; }\n"
1158
                "  int (A::*x)(int);\n"
1159
                "};\n"
1160
                "void f() {\n"
1161
                "  int y = 42;\n"
1162
                "  A a;\n"
1163
                "  a.x = &A::f;\n"
1164
                "  (a.*(a.x))(y);\n"
1165
                "}";
1166
  EXPECT_TRUE(matchAndVerifyResultTrue(
1167
      S, CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
1168
  EXPECT_TRUE(matchAndVerifyResultTrue(
1169
      S, CallExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
1170
}
1171

1172
TEST(ForEachArgumentWithParamType, MatchesVariadicFunctionPtrCalls) {
1173
  StatementMatcher ArgumentY =
1174
      declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1175
  TypeMatcher IntType = qualType(builtinType()).bind("type");
1176
  StatementMatcher CallExpr =
1177
      callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1178

1179
  StringRef S = R"cpp(
1180
    void fcntl(int fd, int cmd, ...) {}
1181

1182
    template <typename Func>
1183
    void f(Func F) {
1184
      int y = 42;
1185
      F(y, 1, 3);
1186
    }
1187

1188
    void g() { f(fcntl); }
1189
  )cpp";
1190

1191
  EXPECT_TRUE(matchAndVerifyResultTrue(
1192
      S, CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
1193
  EXPECT_TRUE(matchAndVerifyResultTrue(
1194
      S, CallExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
1195
}
1196

1197
TEST_P(ASTMatchersTest,
1198
       ForEachArgumentWithParamTypeMatchesExplicitObjectParamOnOperatorCalls) {
1199
  if (!GetParam().isCXX23OrLater()) {
1200
    return;
1201
  }
1202

1203
  auto DeclRef = declRefExpr(to(varDecl().bind("declOfArg"))).bind("arg");
1204
  auto SelfTy = qualType(asString("const A &")).bind("selfType");
1205
  StatementMatcher CallExpr =
1206
      callExpr(forEachArgumentWithParamType(DeclRef, SelfTy));
1207

1208
  StringRef S = R"cpp(
1209
  struct A {
1210
    int operator()(this const A &self);
1211
  };
1212
  A obj;
1213
  int global = obj();
1214
  )cpp";
1215

1216
  auto Args = GetParam().getCommandLineArgs();
1217
  auto Filename = getFilenameForTesting(GetParam().Language);
1218

1219
  EXPECT_TRUE(matchAndVerifyResultTrue(
1220
      S, CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("selfType"),
1221
      Args, Filename));
1222
  EXPECT_TRUE(matchAndVerifyResultTrue(
1223
      S, CallExpr,
1224
      std::make_unique<VerifyIdIsBoundTo<VarDecl>>("declOfArg", "obj"), Args,
1225
      Filename));
1226
}
1227

1228
TEST(QualType, hasCanonicalType) {
1229
  EXPECT_TRUE(notMatches("typedef int &int_ref;"
1230
                           "int a;"
1231
                           "int_ref b = a;",
1232
                         varDecl(hasType(qualType(referenceType())))));
1233
  EXPECT_TRUE(
1234
    matches("typedef int &int_ref;"
1235
              "int a;"
1236
              "int_ref b = a;",
1237
            varDecl(hasType(qualType(hasCanonicalType(referenceType()))))));
1238
}
1239

1240
TEST(HasParameter, CallsInnerMatcher) {
1241
  EXPECT_TRUE(matches("class X { void x(int) {} };",
1242
                      cxxMethodDecl(hasParameter(0, varDecl()))));
1243
  EXPECT_TRUE(notMatches("class X { void x(int) {} };",
1244
                         cxxMethodDecl(hasParameter(0, hasName("x")))));
1245
  EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) x; @end",
1246
                          objcMethodDecl(hasParameter(0, hasName("x")))));
1247
  EXPECT_TRUE(matchesObjC("int main() { void (^b)(int) = ^(int p) {}; }",
1248
                          blockDecl(hasParameter(0, hasName("p")))));
1249
}
1250

1251
TEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) {
1252
  EXPECT_TRUE(notMatches("class X { void x(int) {} };",
1253
                         cxxMethodDecl(hasParameter(42, varDecl()))));
1254
}
1255

1256
TEST(HasType, MatchesParameterVariableTypesStrictly) {
1257
  EXPECT_TRUE(matches(
1258
    "class X { void x(X x) {} };",
1259
    cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
1260
  EXPECT_TRUE(notMatches(
1261
    "class X { void x(const X &x) {} };",
1262
    cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
1263
  EXPECT_TRUE(matches("class X { void x(const X *x) {} };",
1264
                      cxxMethodDecl(hasParameter(
1265
                        0, hasType(pointsTo(recordDecl(hasName("X"))))))));
1266
  EXPECT_TRUE(matches("class X { void x(const X &x) {} };",
1267
                      cxxMethodDecl(hasParameter(
1268
                        0, hasType(references(recordDecl(hasName("X"))))))));
1269
}
1270

1271
TEST(HasAnyParameter, MatchesIndependentlyOfPosition) {
1272
  EXPECT_TRUE(matches(
1273
    "class Y {}; class X { void x(X x, Y y) {} };",
1274
    cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
1275
  EXPECT_TRUE(matches(
1276
    "class Y {}; class X { void x(Y y, X x) {} };",
1277
    cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
1278
  EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) x; @end",
1279
                          objcMethodDecl(hasAnyParameter(hasName("x")))));
1280
  EXPECT_TRUE(matchesObjC("int main() { void (^b)(int) = ^(int p) {}; }",
1281
                          blockDecl(hasAnyParameter(hasName("p")))));
1282
}
1283

1284
TEST(Returns, MatchesReturnTypes) {
1285
  EXPECT_TRUE(matches("class Y { int f() { return 1; } };",
1286
                      functionDecl(returns(asString("int")))));
1287
  EXPECT_TRUE(notMatches("class Y { int f() { return 1; } };",
1288
                         functionDecl(returns(asString("float")))));
1289
  EXPECT_TRUE(matches("class Y { Y getMe() { return *this; } };",
1290
                      functionDecl(returns(hasDeclaration(
1291
                        recordDecl(hasName("Y")))))));
1292
}
1293

1294
TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
1295
  EXPECT_TRUE(notMatches(
1296
    "class Y {}; class X { void x(int) {} };",
1297
    cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
1298
}
1299

1300
TEST(HasAnyParameter, DoesNotMatchThisPointer) {
1301
  EXPECT_TRUE(notMatches("class Y {}; class X { void x() {} };",
1302
                         cxxMethodDecl(hasAnyParameter(
1303
                           hasType(pointsTo(recordDecl(hasName("X"))))))));
1304
}
1305

1306
TEST(HasName, MatchesParameterVariableDeclarations) {
1307
  EXPECT_TRUE(matches("class Y {}; class X { void x(int x) {} };",
1308
                      cxxMethodDecl(hasAnyParameter(hasName("x")))));
1309
  EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
1310
                         cxxMethodDecl(hasAnyParameter(hasName("x")))));
1311
}
1312

1313
TEST(Matcher, MatchesTypeTemplateArgument) {
1314
  EXPECT_TRUE(matches(
1315
    "template<typename T> struct B {};"
1316
      "B<int> b;",
1317
    classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToType(
1318
      asString("int"))))));
1319
}
1320

1321
TEST(Matcher, MatchesTemplateTemplateArgument) {
1322
  EXPECT_TRUE(matches("template<template <typename> class S> class X {};"
1323
                      "template<typename T> class Y {};"
1324
                      "X<Y> xi;",
1325
                      classTemplateSpecializationDecl(hasAnyTemplateArgument(
1326
                          refersToTemplate(templateName())))));
1327
}
1328

1329
TEST(Matcher, MatchesDeclarationReferenceTemplateArgument) {
1330
  EXPECT_TRUE(matches(
1331
    "struct B { int next; };"
1332
      "template<int(B::*next_ptr)> struct A {};"
1333
      "A<&B::next> a;",
1334
    classTemplateSpecializationDecl(hasAnyTemplateArgument(
1335
      refersToDeclaration(fieldDecl(hasName("next")))))));
1336

1337
  EXPECT_TRUE(notMatches(
1338
    "template <typename T> struct A {};"
1339
      "A<int> a;",
1340
    classTemplateSpecializationDecl(hasAnyTemplateArgument(
1341
      refersToDeclaration(decl())))));
1342

1343
  EXPECT_TRUE(matches(
1344
    "struct B { int next; };"
1345
      "template<int(B::*next_ptr)> struct A {};"
1346
      "A<&B::next> a;",
1347
    templateSpecializationType(hasAnyTemplateArgument(isExpr(
1348
      hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))));
1349

1350
  EXPECT_TRUE(notMatches(
1351
    "template <typename T> struct A {};"
1352
      "A<int> a;",
1353
    templateSpecializationType(hasAnyTemplateArgument(
1354
      refersToDeclaration(decl())))));
1355
}
1356

1357

1358
TEST(Matcher, MatchesSpecificArgument) {
1359
  EXPECT_TRUE(matches(
1360
    "template<typename T, typename U> class A {};"
1361
      "A<bool, int> a;",
1362
    classTemplateSpecializationDecl(hasTemplateArgument(
1363
      1, refersToType(asString("int"))))));
1364
  EXPECT_TRUE(notMatches(
1365
    "template<typename T, typename U> class A {};"
1366
      "A<int, bool> a;",
1367
    classTemplateSpecializationDecl(hasTemplateArgument(
1368
      1, refersToType(asString("int"))))));
1369

1370
  EXPECT_TRUE(matches(
1371
    "template<typename T, typename U> class A {};"
1372
      "A<bool, int> a;",
1373
    templateSpecializationType(hasTemplateArgument(
1374
      1, refersToType(asString("int"))))));
1375
  EXPECT_TRUE(notMatches(
1376
    "template<typename T, typename U> class A {};"
1377
      "A<int, bool> a;",
1378
    templateSpecializationType(hasTemplateArgument(
1379
      1, refersToType(asString("int"))))));
1380

1381
  EXPECT_TRUE(matches(
1382
    "template<typename T> void f() {};"
1383
      "void func() { f<int>(); }",
1384
    functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))));
1385
  EXPECT_TRUE(notMatches(
1386
    "template<typename T> void f() {};",
1387
    functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))));
1388
}
1389

1390
TEST(TemplateArgument, Matches) {
1391
  EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
1392
                      classTemplateSpecializationDecl(
1393
                        hasAnyTemplateArgument(templateArgument()))));
1394
  EXPECT_TRUE(matches(
1395
    "template<typename T> struct C {}; C<int> c;",
1396
    templateSpecializationType(hasAnyTemplateArgument(templateArgument()))));
1397

1398
  EXPECT_TRUE(matches(
1399
    "template<typename T> void f() {};"
1400
      "void func() { f<int>(); }",
1401
    functionDecl(hasAnyTemplateArgument(templateArgument()))));
1402
}
1403

1404
TEST(TemplateTypeParmDecl, CXXMethodDecl) {
1405
  const char input[] =
1406
      "template<typename T>\n"
1407
      "class Class {\n"
1408
      "  void method();\n"
1409
      "};\n"
1410
      "template<typename U>\n"
1411
      "void Class<U>::method() {}\n";
1412
  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1413
  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1414
}
1415

1416
TEST(TemplateTypeParmDecl, VarDecl) {
1417
  const char input[] =
1418
      "template<typename T>\n"
1419
      "class Class {\n"
1420
      "  static T pi;\n"
1421
      "};\n"
1422
      "template<typename U>\n"
1423
      "U Class<U>::pi = U(3.1415926535897932385);\n";
1424
  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1425
  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1426
}
1427

1428
TEST(TemplateTypeParmDecl, VarTemplatePartialSpecializationDecl) {
1429
  const char input[] =
1430
      "template<typename T>\n"
1431
      "struct Struct {\n"
1432
      "  template<typename T2> static int field;\n"
1433
      "};\n"
1434
      "template<typename U>\n"
1435
      "template<typename U2>\n"
1436
      "int Struct<U>::field<U2*> = 123;\n";
1437
  EXPECT_TRUE(
1438
      matches(input, templateTypeParmDecl(hasName("T")), langCxx14OrLater()));
1439
  EXPECT_TRUE(
1440
      matches(input, templateTypeParmDecl(hasName("T2")), langCxx14OrLater()));
1441
  EXPECT_TRUE(
1442
      matches(input, templateTypeParmDecl(hasName("U")), langCxx14OrLater()));
1443
  EXPECT_TRUE(
1444
      matches(input, templateTypeParmDecl(hasName("U2")), langCxx14OrLater()));
1445
}
1446

1447
TEST(TemplateTypeParmDecl, ClassTemplatePartialSpecializationDecl) {
1448
  const char input[] =
1449
      "template<typename T>\n"
1450
      "class Class {\n"
1451
      "  template<typename T2> struct Struct;\n"
1452
      "};\n"
1453
      "template<typename U>\n"
1454
      "template<typename U2>\n"
1455
      "struct Class<U>::Struct<U2*> {};\n";
1456
  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1457
  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T2"))));
1458
  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1459
  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U2"))));
1460
}
1461

1462
TEST(TemplateTypeParmDecl, EnumDecl) {
1463
  const char input[] =
1464
      "template<typename T>\n"
1465
      "struct Struct {\n"
1466
      "  enum class Enum : T;\n"
1467
      "};\n"
1468
      "template<typename U>\n"
1469
      "enum class Struct<U>::Enum : U {\n"
1470
      "  e1,\n"
1471
      "  e2\n"
1472
      "};\n";
1473
  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1474
  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1475
}
1476

1477
TEST(TemplateTypeParmDecl, RecordDecl) {
1478
  const char input[] =
1479
      "template<typename T>\n"
1480
      "class Class {\n"
1481
      "  struct Struct;\n"
1482
      "};\n"
1483
      "template<typename U>\n"
1484
      "struct Class<U>::Struct {\n"
1485
      "  U field;\n"
1486
      "};\n";
1487
  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1488
  EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1489
}
1490

1491
TEST(RefersToIntegralType, Matches) {
1492
  EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
1493
                      classTemplateSpecializationDecl(
1494
                        hasAnyTemplateArgument(refersToIntegralType(
1495
                          asString("int"))))));
1496
  EXPECT_TRUE(notMatches("template<unsigned T> struct C {}; C<42> c;",
1497
                         classTemplateSpecializationDecl(hasAnyTemplateArgument(
1498
                           refersToIntegralType(asString("int"))))));
1499
}
1500

1501
TEST(ConstructorDeclaration, SimpleCase) {
1502
  EXPECT_TRUE(matches("class Foo { Foo(int i); };",
1503
                      cxxConstructorDecl(ofClass(hasName("Foo")))));
1504
  EXPECT_TRUE(notMatches("class Foo { Foo(int i); };",
1505
                         cxxConstructorDecl(ofClass(hasName("Bar")))));
1506
}
1507

1508
TEST(DestructorDeclaration, MatchesVirtualDestructor) {
1509
  EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };",
1510
                      cxxDestructorDecl(ofClass(hasName("Foo")))));
1511
}
1512

1513
TEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) {
1514
  EXPECT_TRUE(notMatches("class Foo {};",
1515
                         cxxDestructorDecl(ofClass(hasName("Foo")))));
1516
}
1517

1518
TEST(HasAnyConstructorInitializer, SimpleCase) {
1519
  EXPECT_TRUE(
1520
    notMatches("class Foo { Foo() { } };",
1521
               cxxConstructorDecl(hasAnyConstructorInitializer(anything()))));
1522
  EXPECT_TRUE(
1523
    matches("class Foo {"
1524
              "  Foo() : foo_() { }"
1525
              "  int foo_;"
1526
              "};",
1527
            cxxConstructorDecl(hasAnyConstructorInitializer(anything()))));
1528
}
1529

1530
TEST(HasAnyConstructorInitializer, ForField) {
1531
  static const char Code[] =
1532
    "class Baz { };"
1533
      "class Foo {"
1534
      "  Foo() : foo_(), bar_() { }"
1535
      "  Baz foo_;"
1536
      "  struct {"
1537
      "    Baz bar_;"
1538
      "  };"
1539
      "};";
1540
  EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1541
    forField(hasType(recordDecl(hasName("Baz"))))))));
1542
  EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1543
    forField(hasName("foo_"))))));
1544
  EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1545
    forField(hasName("bar_"))))));
1546
  EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1547
    forField(hasType(recordDecl(hasName("Bar"))))))));
1548
}
1549

1550
TEST(HasAnyConstructorInitializer, WithInitializer) {
1551
  static const char Code[] =
1552
    "class Foo {"
1553
      "  Foo() : foo_(0) { }"
1554
      "  int foo_;"
1555
      "};";
1556
  EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1557
    withInitializer(integerLiteral(equals(0)))))));
1558
  EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1559
    withInitializer(integerLiteral(equals(1)))))));
1560
}
1561

1562
TEST(HasAnyConstructorInitializer, IsWritten) {
1563
  static const char Code[] =
1564
    "struct Bar { Bar(){} };"
1565
      "class Foo {"
1566
      "  Foo() : foo_() { }"
1567
      "  Bar foo_;"
1568
      "  Bar bar_;"
1569
      "};";
1570
  EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1571
    allOf(forField(hasName("foo_")), isWritten())))));
1572
  EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1573
    allOf(forField(hasName("bar_")), isWritten())))));
1574
  EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1575
    allOf(forField(hasName("bar_")), unless(isWritten()))))));
1576
}
1577

1578
TEST(HasAnyConstructorInitializer, IsBaseInitializer) {
1579
  static const char Code[] =
1580
    "struct B {};"
1581
      "struct D : B {"
1582
      "  int I;"
1583
      "  D(int i) : I(i) {}"
1584
      "};"
1585
      "struct E : B {"
1586
      "  E() : B() {}"
1587
      "};";
1588
  EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf(
1589
    hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())),
1590
    hasName("E")))));
1591
  EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf(
1592
    hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())),
1593
    hasName("D")))));
1594
  EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf(
1595
    hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())),
1596
    hasName("D")))));
1597
  EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf(
1598
    hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())),
1599
    hasName("E")))));
1600
}
1601

1602
TEST(IfStmt, ChildTraversalMatchers) {
1603
  EXPECT_TRUE(matches("void f() { if (false) true; else false; }",
1604
                      ifStmt(hasThen(cxxBoolLiteral(equals(true))))));
1605
  EXPECT_TRUE(notMatches("void f() { if (false) false; else true; }",
1606
                         ifStmt(hasThen(cxxBoolLiteral(equals(true))))));
1607
  EXPECT_TRUE(matches("void f() { if (false) false; else true; }",
1608
                      ifStmt(hasElse(cxxBoolLiteral(equals(true))))));
1609
  EXPECT_TRUE(notMatches("void f() { if (false) true; else false; }",
1610
                         ifStmt(hasElse(cxxBoolLiteral(equals(true))))));
1611
}
1612

1613
TEST(MatchBinaryOperator, HasOperatorName) {
1614
  StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
1615

1616
  EXPECT_TRUE(matches("void x() { true || false; }", OperatorOr));
1617
  EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
1618
}
1619

1620
TEST(MatchBinaryOperator, HasAnyOperatorName) {
1621
  StatementMatcher Matcher =
1622
      binaryOperator(hasAnyOperatorName("+", "-", "*", "/"));
1623

1624
  EXPECT_TRUE(matches("int x(int I) { return I + 2; }", Matcher));
1625
  EXPECT_TRUE(matches("int x(int I) { return I - 2; }", Matcher));
1626
  EXPECT_TRUE(matches("int x(int I) { return I * 2; }", Matcher));
1627
  EXPECT_TRUE(matches("int x(int I) { return I / 2; }", Matcher));
1628
  EXPECT_TRUE(notMatches("int x(int I) { return I % 2; }", Matcher));
1629
  // Ensure '+= isn't mistaken.
1630
  EXPECT_TRUE(notMatches("void x(int &I) { I += 1; }", Matcher));
1631
}
1632

1633
TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
1634
  StatementMatcher OperatorTrueFalse =
1635
    binaryOperator(hasLHS(cxxBoolLiteral(equals(true))),
1636
                   hasRHS(cxxBoolLiteral(equals(false))));
1637

1638
  EXPECT_TRUE(matches("void x() { true || false; }", OperatorTrueFalse));
1639
  EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse));
1640
  EXPECT_TRUE(notMatches("void x() { false || true; }", OperatorTrueFalse));
1641

1642
  StatementMatcher OperatorIntPointer = arraySubscriptExpr(
1643
      hasLHS(hasType(isInteger())),
1644
      traverse(TK_AsIs, hasRHS(hasType(pointsTo(qualType())))));
1645
  EXPECT_TRUE(matches("void x() { 1[\"abc\"]; }", OperatorIntPointer));
1646
  EXPECT_TRUE(notMatches("void x() { \"abc\"[1]; }", OperatorIntPointer));
1647

1648
  StringRef Code = R"cpp(
1649
struct HasOpEqMem
1650
{
1651
    bool operator==(const HasOpEqMem& other) const
1652
    {
1653
        return true;
1654
    }
1655
};
1656

1657
struct HasOpFree
1658
{
1659
};
1660
bool operator==(const HasOpFree& lhs, const HasOpFree& rhs)
1661
{
1662
    return true;
1663
}
1664

1665
void opMem()
1666
{
1667
    HasOpEqMem s1;
1668
    HasOpEqMem s2;
1669
    if (s1 == s2)
1670
        return;
1671
}
1672

1673
void opFree()
1674
{
1675
    HasOpFree s1;
1676
    HasOpFree s2;
1677
    if (s1 == s2)
1678
        return;
1679
}
1680
)cpp";
1681
  auto s1Expr = declRefExpr(to(varDecl(hasName("s1"))));
1682
  auto s2Expr = declRefExpr(to(varDecl(hasName("s2"))));
1683
  EXPECT_TRUE(matches(
1684
      Code,
1685
      traverse(TK_IgnoreUnlessSpelledInSource,
1686
               cxxOperatorCallExpr(forFunction(functionDecl(hasName("opMem"))),
1687
                                   hasOperatorName("=="), hasLHS(s1Expr),
1688
                                   hasRHS(s2Expr)))));
1689
  EXPECT_TRUE(matches(
1690
      Code, traverse(TK_IgnoreUnlessSpelledInSource,
1691
                     cxxOperatorCallExpr(
1692
                         forFunction(functionDecl(hasName("opMem"))),
1693
                         hasAnyOperatorName("!=", "=="), hasLHS(s1Expr)))));
1694
  EXPECT_TRUE(matches(
1695
      Code, traverse(TK_IgnoreUnlessSpelledInSource,
1696
                     cxxOperatorCallExpr(
1697
                         forFunction(functionDecl(hasName("opMem"))),
1698
                         hasOperatorName("=="), hasOperands(s1Expr, s2Expr)))));
1699
  EXPECT_TRUE(matches(
1700
      Code, traverse(TK_IgnoreUnlessSpelledInSource,
1701
                     cxxOperatorCallExpr(
1702
                         forFunction(functionDecl(hasName("opMem"))),
1703
                         hasOperatorName("=="), hasEitherOperand(s2Expr)))));
1704

1705
  EXPECT_TRUE(matches(
1706
      Code,
1707
      traverse(TK_IgnoreUnlessSpelledInSource,
1708
               cxxOperatorCallExpr(forFunction(functionDecl(hasName("opFree"))),
1709
                                   hasOperatorName("=="), hasLHS(s1Expr),
1710
                                   hasRHS(s2Expr)))));
1711
  EXPECT_TRUE(matches(
1712
      Code, traverse(TK_IgnoreUnlessSpelledInSource,
1713
                     cxxOperatorCallExpr(
1714
                         forFunction(functionDecl(hasName("opFree"))),
1715
                         hasAnyOperatorName("!=", "=="), hasLHS(s1Expr)))));
1716
  EXPECT_TRUE(matches(
1717
      Code, traverse(TK_IgnoreUnlessSpelledInSource,
1718
                     cxxOperatorCallExpr(
1719
                         forFunction(functionDecl(hasName("opFree"))),
1720
                         hasOperatorName("=="), hasOperands(s1Expr, s2Expr)))));
1721
  EXPECT_TRUE(matches(
1722
      Code, traverse(TK_IgnoreUnlessSpelledInSource,
1723
                     cxxOperatorCallExpr(
1724
                         forFunction(functionDecl(hasName("opFree"))),
1725
                         hasOperatorName("=="), hasEitherOperand(s2Expr)))));
1726
}
1727

1728
TEST(MatchBinaryOperator, HasEitherOperand) {
1729
  StatementMatcher HasOperand =
1730
    binaryOperator(hasEitherOperand(cxxBoolLiteral(equals(false))));
1731

1732
  EXPECT_TRUE(matches("void x() { true || false; }", HasOperand));
1733
  EXPECT_TRUE(matches("void x() { false && true; }", HasOperand));
1734
  EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand));
1735
}
1736

1737
TEST(MatchBinaryOperator, HasOperands) {
1738
  StatementMatcher HasOperands = binaryOperator(
1739
      hasOperands(integerLiteral(equals(1)), integerLiteral(equals(2))));
1740
  EXPECT_TRUE(matches("void x() { 1 + 2; }", HasOperands));
1741
  EXPECT_TRUE(matches("void x() { 2 + 1; }", HasOperands));
1742
  EXPECT_TRUE(notMatches("void x() { 1 + 1; }", HasOperands));
1743
  EXPECT_TRUE(notMatches("void x() { 2 + 2; }", HasOperands));
1744
  EXPECT_TRUE(notMatches("void x() { 0 + 0; }", HasOperands));
1745
  EXPECT_TRUE(notMatches("void x() { 0 + 1; }", HasOperands));
1746
}
1747

1748
TEST(Matcher, BinaryOperatorTypes) {
1749
  // Integration test that verifies the AST provides all binary operators in
1750
  // a way we expect.
1751
  // FIXME: Operator ','
1752
  EXPECT_TRUE(
1753
    matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(","))));
1754
  EXPECT_TRUE(
1755
    matches("bool b; bool c = (b = true);",
1756
            binaryOperator(hasOperatorName("="))));
1757
  EXPECT_TRUE(
1758
    matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!="))));
1759
  EXPECT_TRUE(
1760
    matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("=="))));
1761
  EXPECT_TRUE(matches("bool b = 1 < 2;", binaryOperator(hasOperatorName("<"))));
1762
  EXPECT_TRUE(
1763
    matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<="))));
1764
  EXPECT_TRUE(
1765
    matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<"))));
1766
  EXPECT_TRUE(
1767
    matches("int i = 1; int j = (i <<= 2);",
1768
            binaryOperator(hasOperatorName("<<="))));
1769
  EXPECT_TRUE(matches("bool b = 1 > 2;", binaryOperator(hasOperatorName(">"))));
1770
  EXPECT_TRUE(
1771
    matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">="))));
1772
  EXPECT_TRUE(
1773
    matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>"))));
1774
  EXPECT_TRUE(
1775
    matches("int i = 1; int j = (i >>= 2);",
1776
            binaryOperator(hasOperatorName(">>="))));
1777
  EXPECT_TRUE(
1778
    matches("int i = 42 ^ 23;", binaryOperator(hasOperatorName("^"))));
1779
  EXPECT_TRUE(
1780
    matches("int i = 42; int j = (i ^= 42);",
1781
            binaryOperator(hasOperatorName("^="))));
1782
  EXPECT_TRUE(
1783
    matches("int i = 42 % 23;", binaryOperator(hasOperatorName("%"))));
1784
  EXPECT_TRUE(
1785
    matches("int i = 42; int j = (i %= 42);",
1786
            binaryOperator(hasOperatorName("%="))));
1787
  EXPECT_TRUE(
1788
    matches("bool b = 42  &23;", binaryOperator(hasOperatorName("&"))));
1789
  EXPECT_TRUE(
1790
    matches("bool b = true && false;",
1791
            binaryOperator(hasOperatorName("&&"))));
1792
  EXPECT_TRUE(
1793
    matches("bool b = true; bool c = (b &= false);",
1794
            binaryOperator(hasOperatorName("&="))));
1795
  EXPECT_TRUE(
1796
    matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|"))));
1797
  EXPECT_TRUE(
1798
    matches("bool b = true || false;",
1799
            binaryOperator(hasOperatorName("||"))));
1800
  EXPECT_TRUE(
1801
    matches("bool b = true; bool c = (b |= false);",
1802
            binaryOperator(hasOperatorName("|="))));
1803
  EXPECT_TRUE(
1804
    matches("int i = 42  *23;", binaryOperator(hasOperatorName("*"))));
1805
  EXPECT_TRUE(
1806
    matches("int i = 42; int j = (i *= 23);",
1807
            binaryOperator(hasOperatorName("*="))));
1808
  EXPECT_TRUE(
1809
    matches("int i = 42 / 23;", binaryOperator(hasOperatorName("/"))));
1810
  EXPECT_TRUE(
1811
    matches("int i = 42; int j = (i /= 23);",
1812
            binaryOperator(hasOperatorName("/="))));
1813
  EXPECT_TRUE(
1814
    matches("int i = 42 + 23;", binaryOperator(hasOperatorName("+"))));
1815
  EXPECT_TRUE(
1816
    matches("int i = 42; int j = (i += 23);",
1817
            binaryOperator(hasOperatorName("+="))));
1818
  EXPECT_TRUE(
1819
    matches("int i = 42 - 23;", binaryOperator(hasOperatorName("-"))));
1820
  EXPECT_TRUE(
1821
    matches("int i = 42; int j = (i -= 23);",
1822
            binaryOperator(hasOperatorName("-="))));
1823
  EXPECT_TRUE(
1824
    matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };",
1825
            binaryOperator(hasOperatorName("->*"))));
1826
  EXPECT_TRUE(
1827
    matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };",
1828
            binaryOperator(hasOperatorName(".*"))));
1829

1830
  // Member expressions as operators are not supported in matches.
1831
  EXPECT_TRUE(
1832
    notMatches("struct A { void x(A *a) { a->x(this); } };",
1833
               binaryOperator(hasOperatorName("->"))));
1834

1835
  // Initializer assignments are not represented as operator equals.
1836
  EXPECT_TRUE(
1837
    notMatches("bool b = true;", binaryOperator(hasOperatorName("="))));
1838

1839
  // Array indexing is not represented as operator.
1840
  EXPECT_TRUE(notMatches("int a[42]; void x() { a[23]; }", unaryOperator()));
1841

1842
  // Overloaded operators do not match at all.
1843
  EXPECT_TRUE(notMatches(
1844
    "struct A { bool operator&&(const A &a) const { return false; } };"
1845
      "void x() { A a, b; a && b; }",
1846
    binaryOperator()));
1847
}
1848

1849
TEST(MatchUnaryOperator, HasOperatorName) {
1850
  StatementMatcher OperatorNot = unaryOperator(hasOperatorName("!"));
1851

1852
  EXPECT_TRUE(matches("void x() { !true; } ", OperatorNot));
1853
  EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
1854
}
1855

1856
TEST(MatchUnaryOperator, HasAnyOperatorName) {
1857
  StatementMatcher Matcher = unaryOperator(hasAnyOperatorName("-", "*", "++"));
1858

1859
  EXPECT_TRUE(matches("int x(int *I) { return *I; }", Matcher));
1860
  EXPECT_TRUE(matches("int x(int I) { return -I; }", Matcher));
1861
  EXPECT_TRUE(matches("void x(int &I) { I++; }", Matcher));
1862
  EXPECT_TRUE(matches("void x(int &I) { ++I; }", Matcher));
1863
  EXPECT_TRUE(notMatches("void x(int &I) { I--; }", Matcher));
1864
  EXPECT_TRUE(notMatches("void x(int &I) { --I; }", Matcher));
1865
  EXPECT_TRUE(notMatches("int *x(int &I) { return &I; }", Matcher));
1866
}
1867

1868
TEST(MatchUnaryOperator, HasUnaryOperand) {
1869
  StatementMatcher OperatorOnFalse =
1870
    unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false))));
1871

1872
  EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse));
1873
  EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse));
1874

1875
  StringRef Code = R"cpp(
1876
struct HasOpBangMem
1877
{
1878
    bool operator!() const
1879
    {
1880
        return false;
1881
    }
1882
};
1883
struct HasOpBangFree
1884
{
1885
};
1886
bool operator!(HasOpBangFree const&)
1887
{
1888
    return false;
1889
}
1890

1891
void opMem()
1892
{
1893
    HasOpBangMem s1;
1894
    if (!s1)
1895
        return;
1896
}
1897
void opFree()
1898
{
1899
    HasOpBangFree s1;
1900
    if (!s1)
1901
        return;
1902
}
1903
)cpp";
1904
  auto s1Expr = declRefExpr(to(varDecl(hasName("s1"))));
1905
  EXPECT_TRUE(matches(
1906
      Code, traverse(TK_IgnoreUnlessSpelledInSource,
1907
                     cxxOperatorCallExpr(
1908
                         forFunction(functionDecl(hasName("opMem"))),
1909
                         hasOperatorName("!"), hasUnaryOperand(s1Expr)))));
1910
  EXPECT_TRUE(matches(
1911
      Code,
1912
      traverse(TK_IgnoreUnlessSpelledInSource,
1913
               cxxOperatorCallExpr(forFunction(functionDecl(hasName("opMem"))),
1914
                                   hasAnyOperatorName("+", "!"),
1915
                                   hasUnaryOperand(s1Expr)))));
1916

1917
  EXPECT_TRUE(matches(
1918
      Code, traverse(TK_IgnoreUnlessSpelledInSource,
1919
                     cxxOperatorCallExpr(
1920
                         forFunction(functionDecl(hasName("opFree"))),
1921
                         hasOperatorName("!"), hasUnaryOperand(s1Expr)))));
1922
  EXPECT_TRUE(matches(
1923
      Code,
1924
      traverse(TK_IgnoreUnlessSpelledInSource,
1925
               cxxOperatorCallExpr(forFunction(functionDecl(hasName("opFree"))),
1926
                                   hasAnyOperatorName("+", "!"),
1927
                                   hasUnaryOperand(s1Expr)))));
1928

1929
  Code = R"cpp(
1930
struct HasIncOperatorsMem
1931
{
1932
    HasIncOperatorsMem& operator++();
1933
    HasIncOperatorsMem operator++(int);
1934
};
1935
struct HasIncOperatorsFree
1936
{
1937
};
1938
HasIncOperatorsFree& operator++(HasIncOperatorsFree&);
1939
HasIncOperatorsFree operator++(HasIncOperatorsFree&, int);
1940

1941
void prefixIncOperatorMem()
1942
{
1943
    HasIncOperatorsMem s1;
1944
    ++s1;
1945
}
1946
void prefixIncOperatorFree()
1947
{
1948
    HasIncOperatorsFree s1;
1949
    ++s1;
1950
}
1951
void postfixIncOperatorMem()
1952
{
1953
    HasIncOperatorsMem s1;
1954
    s1++;
1955
}
1956
void postfixIncOperatorFree()
1957
{
1958
    HasIncOperatorsFree s1;
1959
    s1++;
1960
}
1961

1962
struct HasOpPlusInt
1963
{
1964
    HasOpPlusInt& operator+(int);
1965
};
1966
void plusIntOperator()
1967
{
1968
    HasOpPlusInt s1;
1969
    s1+1;
1970
}
1971
)cpp";
1972

1973
  EXPECT_TRUE(matches(
1974
      Code,
1975
      traverse(TK_IgnoreUnlessSpelledInSource,
1976
               cxxOperatorCallExpr(
1977
                   forFunction(functionDecl(hasName("prefixIncOperatorMem"))),
1978
                   hasOperatorName("++"), hasUnaryOperand(declRefExpr())))));
1979

1980
  EXPECT_TRUE(matches(
1981
      Code,
1982
      traverse(TK_IgnoreUnlessSpelledInSource,
1983
               cxxOperatorCallExpr(
1984
                   forFunction(functionDecl(hasName("prefixIncOperatorFree"))),
1985
                   hasOperatorName("++"), hasUnaryOperand(declRefExpr())))));
1986

1987
  EXPECT_TRUE(matches(
1988
      Code,
1989
      traverse(TK_IgnoreUnlessSpelledInSource,
1990
               cxxOperatorCallExpr(
1991
                   forFunction(functionDecl(hasName("postfixIncOperatorMem"))),
1992
                   hasOperatorName("++"), hasUnaryOperand(declRefExpr())))));
1993

1994
  EXPECT_TRUE(matches(
1995
      Code,
1996
      traverse(TK_IgnoreUnlessSpelledInSource,
1997
               cxxOperatorCallExpr(
1998
                   forFunction(functionDecl(hasName("postfixIncOperatorFree"))),
1999
                   hasOperatorName("++"), hasUnaryOperand(declRefExpr())))));
2000

2001
  EXPECT_FALSE(matches(
2002
      Code, traverse(TK_IgnoreUnlessSpelledInSource,
2003
                     cxxOperatorCallExpr(
2004
                         forFunction(functionDecl(hasName("plusIntOperator"))),
2005
                         hasOperatorName("+"), hasUnaryOperand(expr())))));
2006

2007
  Code = R"cpp(
2008
struct HasOpArrow
2009
{
2010
    int& operator*();
2011
};
2012
void foo()
2013
{
2014
    HasOpArrow s1;
2015
    *s1;
2016
}
2017
)cpp";
2018

2019
  EXPECT_TRUE(
2020
      matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
2021
                             cxxOperatorCallExpr(hasOperatorName("*"),
2022
                                                 hasUnaryOperand(expr())))));
2023
}
2024

2025
TEST(Matcher, UnaryOperatorTypes) {
2026
  // Integration test that verifies the AST provides all unary operators in
2027
  // a way we expect.
2028
  EXPECT_TRUE(matches("bool b = !true;", unaryOperator(hasOperatorName("!"))));
2029
  EXPECT_TRUE(
2030
    matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&"))));
2031
  EXPECT_TRUE(matches("int i = ~ 1;", unaryOperator(hasOperatorName("~"))));
2032
  EXPECT_TRUE(
2033
    matches("bool *p; bool b = *p;", unaryOperator(hasOperatorName("*"))));
2034
  EXPECT_TRUE(
2035
    matches("int i; int j = +i;", unaryOperator(hasOperatorName("+"))));
2036
  EXPECT_TRUE(
2037
    matches("int i; int j = -i;", unaryOperator(hasOperatorName("-"))));
2038
  EXPECT_TRUE(
2039
    matches("int i; int j = ++i;", unaryOperator(hasOperatorName("++"))));
2040
  EXPECT_TRUE(
2041
    matches("int i; int j = i++;", unaryOperator(hasOperatorName("++"))));
2042
  EXPECT_TRUE(
2043
    matches("int i; int j = --i;", unaryOperator(hasOperatorName("--"))));
2044
  EXPECT_TRUE(
2045
    matches("int i; int j = i--;", unaryOperator(hasOperatorName("--"))));
2046

2047
  // We don't match conversion operators.
2048
  EXPECT_TRUE(notMatches("int i; double d = (double)i;", unaryOperator()));
2049

2050
  // Function calls are not represented as operator.
2051
  EXPECT_TRUE(notMatches("void f(); void x() { f(); }", unaryOperator()));
2052

2053
  // Overloaded operators do not match at all.
2054
  // FIXME: We probably want to add that.
2055
  EXPECT_TRUE(notMatches(
2056
    "struct A { bool operator!() const { return false; } };"
2057
      "void x() { A a; !a; }", unaryOperator(hasOperatorName("!"))));
2058
}
2059

2060
TEST_P(ASTMatchersTest, HasInit) {
2061
  if (!GetParam().isCXX11OrLater()) {
2062
    // FIXME: Add a test for `hasInit()` that does not depend on C++.
2063
    return;
2064
  }
2065

2066
  EXPECT_TRUE(matches("int x{0};", initListExpr(hasInit(0, expr()))));
2067
  EXPECT_FALSE(matches("int x{0};", initListExpr(hasInit(1, expr()))));
2068
  EXPECT_FALSE(matches("int x;", initListExpr(hasInit(0, expr()))));
2069
}
2070

2071
TEST_P(ASTMatchersTest, HasFoldInit) {
2072
  if (!GetParam().isCXX17OrLater()) {
2073
    return;
2074
  }
2075

2076
  EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2077
                      "return (0 + ... + args); }",
2078
                      cxxFoldExpr(hasFoldInit(expr()))));
2079
  EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2080
                      "return (args + ... + 0); }",
2081
                      cxxFoldExpr(hasFoldInit(expr()))));
2082
  EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
2083
                       "return (... + args); };",
2084
                       cxxFoldExpr(hasFoldInit(expr()))));
2085
}
2086

2087
TEST_P(ASTMatchersTest, HasPattern) {
2088
  if (!GetParam().isCXX17OrLater()) {
2089
    return;
2090
  }
2091

2092
  EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2093
                      "return (0 + ... + args); }",
2094
                      cxxFoldExpr(hasPattern(expr()))));
2095
  EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2096
                      "return (args + ... + 0); }",
2097
                      cxxFoldExpr(hasPattern(expr()))));
2098
  EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2099
                      "return (... + args); };",
2100
                      cxxFoldExpr(hasPattern(expr()))));
2101
}
2102

2103
TEST_P(ASTMatchersTest, HasLHSAndHasRHS) {
2104
  if (!GetParam().isCXX17OrLater()) {
2105
    return;
2106
  }
2107

2108
  EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2109
                      "return (0 + ... + args); }",
2110
                      cxxFoldExpr(hasLHS(expr()))));
2111
  EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2112
                      "return (args + ... + 0); }",
2113
                      cxxFoldExpr(hasLHS(expr()))));
2114
  EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
2115
                       "return (... + args); };",
2116
                       cxxFoldExpr(hasLHS(expr()))));
2117
  EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2118
                      "return (args + ...); };",
2119
                      cxxFoldExpr(hasLHS(expr()))));
2120

2121
  EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2122
                      "return (0 + ... + args); }",
2123
                      cxxFoldExpr(hasRHS(expr()))));
2124
  EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2125
                      "return (args + ... + 0); }",
2126
                      cxxFoldExpr(hasRHS(expr()))));
2127
  EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2128
                      "return (... + args); };",
2129
                      cxxFoldExpr(hasRHS(expr()))));
2130
  EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
2131
                       "return (args + ...); };",
2132
                       cxxFoldExpr(hasRHS(expr()))));
2133
}
2134

2135
TEST_P(ASTMatchersTest, HasEitherOperandAndHasOperands) {
2136
  if (!GetParam().isCXX17OrLater()) {
2137
    return;
2138
  }
2139

2140
  EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2141
                      "return (0 + ... + args); }",
2142
                      cxxFoldExpr(hasEitherOperand(integerLiteral()))));
2143
  EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2144
                      "return (args + ... + 0); }",
2145
                      cxxFoldExpr(hasEitherOperand(integerLiteral()))));
2146

2147
  EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2148
                      "return (0 + ... + args); }",
2149
                      cxxFoldExpr(hasEitherOperand(
2150
                          declRefExpr(to(namedDecl(hasName("args"))))))));
2151
  EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2152
                      "return (args + ... + 0); }",
2153
                      cxxFoldExpr(hasEitherOperand(
2154
                          declRefExpr(to(namedDecl(hasName("args"))))))));
2155
  EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2156
                      "return (... + args); };",
2157
                      cxxFoldExpr(hasEitherOperand(
2158
                          declRefExpr(to(namedDecl(hasName("args"))))))));
2159
  EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2160
                      "return (args + ...); };",
2161
                      cxxFoldExpr(hasEitherOperand(
2162
                          declRefExpr(to(namedDecl(hasName("args"))))))));
2163

2164
  EXPECT_TRUE(matches(
2165
      "template <typename... Args> auto sum(Args... args) { "
2166
      "return (0 + ... + args); }",
2167
      cxxFoldExpr(hasOperands(declRefExpr(to(namedDecl(hasName("args")))),
2168
                              integerLiteral()))));
2169
  EXPECT_TRUE(matches(
2170
      "template <typename... Args> auto sum(Args... args) { "
2171
      "return (args + ... + 0); }",
2172
      cxxFoldExpr(hasOperands(declRefExpr(to(namedDecl(hasName("args")))),
2173
                              integerLiteral()))));
2174
  EXPECT_FALSE(matches(
2175
      "template <typename... Args> auto sum(Args... args) { "
2176
      "return (... + args); };",
2177
      cxxFoldExpr(hasOperands(declRefExpr(to(namedDecl(hasName("args")))),
2178
                              integerLiteral()))));
2179
  EXPECT_FALSE(matches(
2180
      "template <typename... Args> auto sum(Args... args) { "
2181
      "return (args + ...); };",
2182
      cxxFoldExpr(hasOperands(declRefExpr(to(namedDecl(hasName("args")))),
2183
                              integerLiteral()))));
2184
}
2185

2186
TEST_P(ASTMatchersTest, Callee) {
2187
  if (!GetParam().isCXX17OrLater()) {
2188
    return;
2189
  }
2190

2191
  EXPECT_TRUE(matches(
2192
      "struct Dummy {}; Dummy operator+(Dummy, Dummy); template "
2193
      "<typename... Args> auto sum(Args... args) { return (0 + ... + args); }",
2194
      cxxFoldExpr(callee(expr()))));
2195
  EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
2196
                       "return (0 + ... + args); }",
2197
                       cxxFoldExpr(callee(expr()))));
2198
}
2199

2200
TEST(ArraySubscriptMatchers, ArrayIndex) {
2201
  EXPECT_TRUE(matches(
2202
    "int i[2]; void f() { i[1] = 1; }",
2203
    arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
2204
  EXPECT_TRUE(matches(
2205
    "int i[2]; void f() { 1[i] = 1; }",
2206
    arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
2207
  EXPECT_TRUE(notMatches(
2208
    "int i[2]; void f() { i[1] = 1; }",
2209
    arraySubscriptExpr(hasIndex(integerLiteral(equals(0))))));
2210
}
2211

2212
TEST(ArraySubscriptMatchers, MatchesArrayBase) {
2213
  EXPECT_TRUE(
2214
      matches("int i[2]; void f() { i[1] = 2; }",
2215
              traverse(TK_AsIs, arraySubscriptExpr(hasBase(implicitCastExpr(
2216
                                    hasSourceExpression(declRefExpr())))))));
2217
}
2218

2219
TEST(Matcher, OfClass) {
2220
  StatementMatcher Constructor = cxxConstructExpr(hasDeclaration(cxxMethodDecl(
2221
    ofClass(hasName("X")))));
2222

2223
  EXPECT_TRUE(
2224
    matches("class X { public: X(); }; void x(int) { X x; }", Constructor));
2225
  EXPECT_TRUE(
2226
    matches("class X { public: X(); }; void x(int) { X x = X(); }",
2227
            Constructor));
2228
  EXPECT_TRUE(
2229
    notMatches("class Y { public: Y(); }; void x(int) { Y y; }",
2230
               Constructor));
2231
}
2232

2233
TEST(Matcher, VisitsTemplateInstantiations) {
2234
  EXPECT_TRUE(matches(
2235
    "class A { public: void x(); };"
2236
      "template <typename T> class B { public: void y() { T t; t.x(); } };"
2237
      "void f() { B<A> b; b.y(); }",
2238
    callExpr(callee(cxxMethodDecl(hasName("x"))))));
2239

2240
  EXPECT_TRUE(matches(
2241
    "class A { public: void x(); };"
2242
      "class C {"
2243
      " public:"
2244
      "  template <typename T> class B { public: void y() { T t; t.x(); } };"
2245
      "};"
2246
      "void f() {"
2247
      "  C::B<A> b; b.y();"
2248
      "}",
2249
    recordDecl(hasName("C"), hasDescendant(callExpr(
2250
      callee(cxxMethodDecl(hasName("x"))))))));
2251
}
2252

2253
TEST(Matcher, HasCondition) {
2254
  StatementMatcher IfStmt =
2255
    ifStmt(hasCondition(cxxBoolLiteral(equals(true))));
2256
  EXPECT_TRUE(matches("void x() { if (true) {} }", IfStmt));
2257
  EXPECT_TRUE(notMatches("void x() { if (false) {} }", IfStmt));
2258

2259
  StatementMatcher ForStmt =
2260
    forStmt(hasCondition(cxxBoolLiteral(equals(true))));
2261
  EXPECT_TRUE(matches("void x() { for (;true;) {} }", ForStmt));
2262
  EXPECT_TRUE(notMatches("void x() { for (;false;) {} }", ForStmt));
2263

2264
  StatementMatcher WhileStmt =
2265
    whileStmt(hasCondition(cxxBoolLiteral(equals(true))));
2266
  EXPECT_TRUE(matches("void x() { while (true) {} }", WhileStmt));
2267
  EXPECT_TRUE(notMatches("void x() { while (false) {} }", WhileStmt));
2268

2269
  StatementMatcher SwitchStmt =
2270
    switchStmt(hasCondition(integerLiteral(equals(42))));
2271
  EXPECT_TRUE(matches("void x() { switch (42) {case 42:;} }", SwitchStmt));
2272
  EXPECT_TRUE(notMatches("void x() { switch (43) {case 43:;} }", SwitchStmt));
2273
}
2274

2275
TEST(For, ForLoopInternals) {
2276
  EXPECT_TRUE(matches("void f(){ int i; for (; i < 3 ; ); }",
2277
                      forStmt(hasCondition(anything()))));
2278
  EXPECT_TRUE(matches("void f() { for (int i = 0; ;); }",
2279
                      forStmt(hasLoopInit(anything()))));
2280
}
2281

2282
TEST(For, ForRangeLoopInternals) {
2283
  EXPECT_TRUE(matches("void f(){ int a[] {1, 2}; for (int i : a); }",
2284
                      cxxForRangeStmt(hasLoopVariable(anything()))));
2285
  EXPECT_TRUE(matches(
2286
    "void f(){ int a[] {1, 2}; for (int i : a); }",
2287
    cxxForRangeStmt(hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))))));
2288
}
2289

2290
TEST(For, NegativeForLoopInternals) {
2291
  EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }",
2292
                         forStmt(hasCondition(expr()))));
2293
  EXPECT_TRUE(notMatches("void f() {int i; for (; i < 4; ++i) {} }",
2294
                         forStmt(hasLoopInit(anything()))));
2295
}
2296

2297
TEST(HasBody, FindsBodyOfForWhileDoLoops) {
2298
  EXPECT_TRUE(matches("void f() { for(;;) {} }",
2299
                      forStmt(hasBody(compoundStmt()))));
2300
  EXPECT_TRUE(notMatches("void f() { for(;;); }",
2301
                         forStmt(hasBody(compoundStmt()))));
2302
  EXPECT_TRUE(matches("void f() { while(true) {} }",
2303
                      whileStmt(hasBody(compoundStmt()))));
2304
  EXPECT_TRUE(matches("void f() { do {} while(true); }",
2305
                      doStmt(hasBody(compoundStmt()))));
2306
  EXPECT_TRUE(matches("void f() { int p[2]; for (auto x : p) {} }",
2307
                      cxxForRangeStmt(hasBody(compoundStmt()))));
2308
}
2309

2310
TEST(HasBody, FindsBodyOfFunctions) {
2311
  EXPECT_TRUE(matches("void f() {}", functionDecl(hasBody(compoundStmt()))));
2312
  EXPECT_TRUE(notMatches("void f();", functionDecl(hasBody(compoundStmt()))));
2313
  EXPECT_TRUE(matchAndVerifyResultTrue(
2314
      "void f(); void f() {}",
2315
      functionDecl(hasBody(compoundStmt())).bind("func"),
2316
      std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("func", 1)));
2317
  EXPECT_TRUE(matchAndVerifyResultTrue(
2318
      "class C { void f(); }; void C::f() {}",
2319
      cxxMethodDecl(hasBody(compoundStmt())).bind("met"),
2320
      std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("met", 1)));
2321
  EXPECT_TRUE(matchAndVerifyResultTrue(
2322
      "class C { C(); }; C::C() {}",
2323
      cxxConstructorDecl(hasBody(compoundStmt())).bind("ctr"),
2324
      std::make_unique<VerifyIdIsBoundTo<CXXConstructorDecl>>("ctr", 1)));
2325
  EXPECT_TRUE(matchAndVerifyResultTrue(
2326
      "class C { ~C(); }; C::~C() {}",
2327
      cxxDestructorDecl(hasBody(compoundStmt())).bind("dtr"),
2328
      std::make_unique<VerifyIdIsBoundTo<CXXDestructorDecl>>("dtr", 1)));
2329
}
2330

2331
TEST(HasAnyBody, FindsAnyBodyOfFunctions) {
2332
  EXPECT_TRUE(matches("void f() {}", functionDecl(hasAnyBody(compoundStmt()))));
2333
  EXPECT_TRUE(notMatches("void f();",
2334
                         functionDecl(hasAnyBody(compoundStmt()))));
2335
  EXPECT_TRUE(matchAndVerifyResultTrue(
2336
      "void f(); void f() {}",
2337
      functionDecl(hasAnyBody(compoundStmt())).bind("func"),
2338
      std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("func", 2)));
2339
  EXPECT_TRUE(matchAndVerifyResultTrue(
2340
      "class C { void f(); }; void C::f() {}",
2341
      cxxMethodDecl(hasAnyBody(compoundStmt())).bind("met"),
2342
      std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("met", 2)));
2343
  EXPECT_TRUE(matchAndVerifyResultTrue(
2344
      "class C { C(); }; C::C() {}",
2345
      cxxConstructorDecl(hasAnyBody(compoundStmt())).bind("ctr"),
2346
      std::make_unique<VerifyIdIsBoundTo<CXXConstructorDecl>>("ctr", 2)));
2347
  EXPECT_TRUE(matchAndVerifyResultTrue(
2348
      "class C { ~C(); }; C::~C() {}",
2349
      cxxDestructorDecl(hasAnyBody(compoundStmt())).bind("dtr"),
2350
      std::make_unique<VerifyIdIsBoundTo<CXXDestructorDecl>>("dtr", 2)));
2351
}
2352

2353
TEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
2354
  // The simplest case: every compound statement is in a function
2355
  // definition, and the function body itself must be a compound
2356
  // statement.
2357
  EXPECT_TRUE(matches("void f() { for (;;); }",
2358
                      compoundStmt(hasAnySubstatement(forStmt()))));
2359
}
2360

2361
TEST(HasAnySubstatement, IsNotRecursive) {
2362
  // It's really "has any immediate substatement".
2363
  EXPECT_TRUE(notMatches("void f() { if (true) for (;;); }",
2364
                         compoundStmt(hasAnySubstatement(forStmt()))));
2365
}
2366

2367
TEST(HasAnySubstatement, MatchesInNestedCompoundStatements) {
2368
  EXPECT_TRUE(matches("void f() { if (true) { for (;;); } }",
2369
                      compoundStmt(hasAnySubstatement(forStmt()))));
2370
}
2371

2372
TEST(HasAnySubstatement, FindsSubstatementBetweenOthers) {
2373
  EXPECT_TRUE(matches("void f() { 1; 2; 3; for (;;); 4; 5; 6; }",
2374
                      compoundStmt(hasAnySubstatement(forStmt()))));
2375
}
2376

2377
TEST(Member, MatchesMemberAllocationFunction) {
2378
  // Fails in C++11 mode
2379
  EXPECT_TRUE(matchesConditionally(
2380
      "namespace std { typedef typeof(sizeof(int)) size_t; }"
2381
      "class X { void *operator new(std::size_t); };",
2382
      cxxMethodDecl(ofClass(hasName("X"))), true, {"-std=gnu++03"}));
2383

2384
  EXPECT_TRUE(matches("class X { void operator delete(void*); };",
2385
                      cxxMethodDecl(ofClass(hasName("X")))));
2386

2387
  // Fails in C++11 mode
2388
  EXPECT_TRUE(matchesConditionally(
2389
      "namespace std { typedef typeof(sizeof(int)) size_t; }"
2390
      "class X { void operator delete[](void*, std::size_t); };",
2391
      cxxMethodDecl(ofClass(hasName("X"))), true, {"-std=gnu++03"}));
2392
}
2393

2394
TEST(HasDestinationType, MatchesSimpleCase) {
2395
  EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
2396
                      cxxStaticCastExpr(hasDestinationType(
2397
                        pointsTo(TypeMatcher(anything()))))));
2398
}
2399

2400
TEST(HasImplicitDestinationType, MatchesSimpleCase) {
2401
  // This test creates an implicit const cast.
2402
  EXPECT_TRUE(matches(
2403
      "int x; const int i = x;",
2404
      traverse(TK_AsIs,
2405
               implicitCastExpr(hasImplicitDestinationType(isInteger())))));
2406
  // This test creates an implicit array-to-pointer cast.
2407
  EXPECT_TRUE(
2408
      matches("int arr[3]; int *p = arr;",
2409
              traverse(TK_AsIs, implicitCastExpr(hasImplicitDestinationType(
2410
                                    pointsTo(TypeMatcher(anything())))))));
2411
}
2412

2413
TEST(HasImplicitDestinationType, DoesNotMatchIncorrectly) {
2414
  // This test creates an implicit cast from int to char.
2415
  EXPECT_TRUE(notMatches("char c = 0;",
2416
                         implicitCastExpr(hasImplicitDestinationType(
2417
                           unless(anything())))));
2418
  // This test creates an implicit array-to-pointer cast.
2419
  EXPECT_TRUE(notMatches("int arr[3]; int *p = arr;",
2420
                         implicitCastExpr(hasImplicitDestinationType(
2421
                           unless(anything())))));
2422
}
2423

2424
TEST(Matcher, IgnoresElidableConstructors) {
2425
  EXPECT_TRUE(
2426
      matches("struct H {};"
2427
              "template<typename T> H B(T A);"
2428
              "void f() {"
2429
              "  H D1;"
2430
              "  D1 = B(B(1));"
2431
              "}",
2432
              cxxOperatorCallExpr(hasArgument(
2433
                  1, callExpr(hasArgument(
2434
                         0, ignoringElidableConstructorCall(callExpr()))))),
2435
              langCxx11OrLater()));
2436
  EXPECT_TRUE(
2437
      matches("struct H {};"
2438
              "template<typename T> H B(T A);"
2439
              "void f() {"
2440
              "  H D1;"
2441
              "  D1 = B(1);"
2442
              "}",
2443
              cxxOperatorCallExpr(hasArgument(
2444
                  1, callExpr(hasArgument(0, ignoringElidableConstructorCall(
2445
                                                 integerLiteral()))))),
2446
              langCxx11OrLater()));
2447
  EXPECT_TRUE(matches(
2448
      "struct H {};"
2449
      "H G();"
2450
      "void f() {"
2451
      "  H D = G();"
2452
      "}",
2453
      varDecl(hasInitializer(anyOf(
2454
          ignoringElidableConstructorCall(callExpr()),
2455
          exprWithCleanups(has(ignoringElidableConstructorCall(callExpr())))))),
2456
      langCxx11OrLater()));
2457
}
2458

2459
TEST(Matcher, IgnoresElidableInReturn) {
2460
  auto matcher = expr(ignoringElidableConstructorCall(declRefExpr()));
2461
  EXPECT_TRUE(matches("struct H {};"
2462
                      "H f() {"
2463
                      "  H g;"
2464
                      "  return g;"
2465
                      "}",
2466
                      matcher, langCxx11OrLater()));
2467
  EXPECT_TRUE(notMatches("struct H {};"
2468
                         "H f() {"
2469
                         "  return H();"
2470
                         "}",
2471
                         matcher, langCxx11OrLater()));
2472
}
2473

2474
TEST(Matcher, IgnoreElidableConstructorDoesNotMatchConstructors) {
2475
  EXPECT_TRUE(matches("struct H {};"
2476
                      "void f() {"
2477
                      "  H D;"
2478
                      "}",
2479
                      varDecl(hasInitializer(
2480
                          ignoringElidableConstructorCall(cxxConstructExpr()))),
2481
                      langCxx11OrLater()));
2482
}
2483

2484
TEST(Matcher, IgnoresElidableDoesNotPreventMatches) {
2485
  EXPECT_TRUE(matches("void f() {"
2486
                      "  int D = 10;"
2487
                      "}",
2488
                      expr(ignoringElidableConstructorCall(integerLiteral())),
2489
                      langCxx11OrLater()));
2490
}
2491

2492
TEST(Matcher, IgnoresElidableInVarInit) {
2493
  auto matcher =
2494
      varDecl(hasInitializer(ignoringElidableConstructorCall(callExpr())));
2495
  EXPECT_TRUE(matches("struct H {};"
2496
                      "H G();"
2497
                      "void f(H D = G()) {"
2498
                      "  return;"
2499
                      "}",
2500
                      matcher, langCxx11OrLater()));
2501
  EXPECT_TRUE(matches("struct H {};"
2502
                      "H G();"
2503
                      "void f() {"
2504
                      "  H D = G();"
2505
                      "}",
2506
                      matcher, langCxx11OrLater()));
2507
}
2508

2509
TEST(IgnoringImplicit, MatchesImplicit) {
2510
  EXPECT_TRUE(matches("class C {}; C a = C();",
2511
                      varDecl(has(ignoringImplicit(cxxConstructExpr())))));
2512
}
2513

2514
TEST(IgnoringImplicit, MatchesNestedImplicit) {
2515
  StringRef Code = R"(
2516

2517
struct OtherType;
2518

2519
struct SomeType
2520
{
2521
    SomeType() {}
2522
    SomeType(const OtherType&) {}
2523
    SomeType& operator=(OtherType const&) { return *this; }
2524
};
2525

2526
struct OtherType
2527
{
2528
    OtherType() {}
2529
    ~OtherType() {}
2530
};
2531

2532
OtherType something()
2533
{
2534
    return {};
2535
}
2536

2537
int main()
2538
{
2539
    SomeType i = something();
2540
}
2541
)";
2542
  EXPECT_TRUE(matches(
2543
      Code,
2544
      traverse(TK_AsIs,
2545
               varDecl(hasName("i"),
2546
                       hasInitializer(exprWithCleanups(has(cxxConstructExpr(
2547
                           has(expr(ignoringImplicit(cxxConstructExpr(has(
2548
                               expr(ignoringImplicit(callExpr())))))))))))))));
2549
}
2550

2551
TEST(IgnoringImplicit, DoesNotMatchIncorrectly) {
2552
  EXPECT_TRUE(notMatches("class C {}; C a = C();",
2553
                         traverse(TK_AsIs, varDecl(has(cxxConstructExpr())))));
2554
}
2555

2556
TEST(Traversal, traverseMatcher) {
2557

2558
  StringRef VarDeclCode = R"cpp(
2559
void foo()
2560
{
2561
  int i = 3.0;
2562
}
2563
)cpp";
2564

2565
  auto Matcher = varDecl(hasInitializer(floatLiteral()));
2566

2567
  EXPECT_TRUE(notMatches(VarDeclCode, traverse(TK_AsIs, Matcher)));
2568
  EXPECT_TRUE(
2569
      matches(VarDeclCode, traverse(TK_IgnoreUnlessSpelledInSource, Matcher)));
2570

2571
  auto ParentMatcher = floatLiteral(hasParent(varDecl(hasName("i"))));
2572

2573
  EXPECT_TRUE(notMatches(VarDeclCode, traverse(TK_AsIs, ParentMatcher)));
2574
  EXPECT_TRUE(matches(VarDeclCode,
2575
                      traverse(TK_IgnoreUnlessSpelledInSource, ParentMatcher)));
2576

2577
  EXPECT_TRUE(matches(
2578
      VarDeclCode, decl(traverse(TK_AsIs, anyOf(cxxRecordDecl(), varDecl())))));
2579

2580
  EXPECT_TRUE(
2581
      matches(VarDeclCode,
2582
              floatLiteral(traverse(TK_AsIs, hasParent(implicitCastExpr())))));
2583

2584
  EXPECT_TRUE(
2585
      matches(VarDeclCode, floatLiteral(traverse(TK_IgnoreUnlessSpelledInSource,
2586
                                                 hasParent(varDecl())))));
2587

2588
  EXPECT_TRUE(
2589
      matches(VarDeclCode, varDecl(traverse(TK_IgnoreUnlessSpelledInSource,
2590
                                            unless(parmVarDecl())))));
2591

2592
  EXPECT_TRUE(
2593
      notMatches(VarDeclCode, varDecl(traverse(TK_IgnoreUnlessSpelledInSource,
2594
                                               has(implicitCastExpr())))));
2595

2596
  EXPECT_TRUE(matches(VarDeclCode,
2597
                      varDecl(traverse(TK_AsIs, has(implicitCastExpr())))));
2598

2599
  EXPECT_TRUE(matches(
2600
      VarDeclCode, traverse(TK_IgnoreUnlessSpelledInSource,
2601
                            // The has() below strips away the ImplicitCastExpr
2602
                            // before the traverse(AsIs) gets to process it.
2603
                            varDecl(has(traverse(TK_AsIs, floatLiteral()))))));
2604

2605
  EXPECT_TRUE(
2606
      matches(VarDeclCode, functionDecl(traverse(TK_AsIs, hasName("foo")))));
2607

2608
  EXPECT_TRUE(matches(
2609
      VarDeclCode,
2610
      functionDecl(traverse(TK_IgnoreUnlessSpelledInSource, hasName("foo")))));
2611

2612
  EXPECT_TRUE(matches(
2613
      VarDeclCode, functionDecl(traverse(TK_AsIs, hasAnyName("foo", "bar")))));
2614

2615
  EXPECT_TRUE(
2616
      matches(VarDeclCode, functionDecl(traverse(TK_IgnoreUnlessSpelledInSource,
2617
                                                 hasAnyName("foo", "bar")))));
2618

2619
  StringRef Code = R"cpp(
2620
void foo(int a)
2621
{
2622
  int i = 3.0 + a;
2623
}
2624
void bar()
2625
{
2626
  foo(7.0);
2627
}
2628
)cpp";
2629
  EXPECT_TRUE(
2630
      matches(Code, callExpr(traverse(TK_IgnoreUnlessSpelledInSource,
2631
                                      hasArgument(0, floatLiteral())))));
2632

2633
  EXPECT_TRUE(
2634
      matches(Code, callExpr(traverse(TK_IgnoreUnlessSpelledInSource,
2635
                                      hasAnyArgument(floatLiteral())))));
2636

2637
  EXPECT_TRUE(matches(
2638
      R"cpp(
2639
void takesBool(bool){}
2640

2641
template <typename T>
2642
void neverInstantiatedTemplate() {
2643
  takesBool(T{});
2644
}
2645
)cpp",
2646
      traverse(TK_IgnoreUnlessSpelledInSource,
2647
               callExpr(unless(callExpr(hasDeclaration(functionDecl())))))));
2648

2649
  EXPECT_TRUE(
2650
      matches(VarDeclCode, varDecl(traverse(TK_IgnoreUnlessSpelledInSource,
2651
                                            hasType(builtinType())))));
2652

2653
  EXPECT_TRUE(
2654
      matches(VarDeclCode,
2655
              functionDecl(hasName("foo"),
2656
                           traverse(TK_AsIs, hasDescendant(floatLiteral())))));
2657

2658
  EXPECT_TRUE(notMatches(
2659
      Code, traverse(TK_AsIs, floatLiteral(hasParent(callExpr(
2660
                                  callee(functionDecl(hasName("foo")))))))));
2661
  EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
2662
                                     floatLiteral(hasParent(callExpr(callee(
2663
                                         functionDecl(hasName("foo")))))))));
2664

2665
  Code = R"cpp(
2666
void foo()
2667
{
2668
  int i = (3);
2669
}
2670
)cpp";
2671
  EXPECT_TRUE(matches(
2672
      Code, traverse(TK_IgnoreUnlessSpelledInSource,
2673
                     varDecl(hasInitializer(integerLiteral(equals(3)))))));
2674
  EXPECT_TRUE(matches(
2675
      Code,
2676
      traverse(TK_IgnoreUnlessSpelledInSource,
2677
               integerLiteral(equals(3), hasParent(varDecl(hasName("i")))))));
2678

2679
  Code = R"cpp(
2680
const char *SomeString{"str"};
2681
)cpp";
2682
  EXPECT_TRUE(
2683
      matches(Code, traverse(TK_AsIs, stringLiteral(hasParent(implicitCastExpr(
2684
                                          hasParent(initListExpr())))))));
2685
  EXPECT_TRUE(
2686
      matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
2687
                             stringLiteral(hasParent(initListExpr())))));
2688

2689
  Code = R"cpp(
2690
struct String
2691
{
2692
    String(const char*, int = -1) {}
2693
};
2694

2695
void stringConstruct()
2696
{
2697
    String s = "foo";
2698
    s = "bar";
2699
}
2700
)cpp";
2701
  EXPECT_TRUE(matches(
2702
      Code,
2703
      traverse(
2704
          TK_AsIs,
2705
          functionDecl(
2706
              hasName("stringConstruct"),
2707
              hasDescendant(varDecl(
2708
                  hasName("s"),
2709
                  hasInitializer(ignoringImplicit(cxxConstructExpr(hasArgument(
2710
                      0, ignoringImplicit(cxxConstructExpr(hasArgument(
2711
                             0, ignoringImplicit(stringLiteral()))))))))))))));
2712

2713
  EXPECT_TRUE(matches(
2714
      Code,
2715
      traverse(
2716
          TK_AsIs,
2717
          functionDecl(hasName("stringConstruct"),
2718
                       hasDescendant(cxxOperatorCallExpr(
2719
                           isAssignmentOperator(),
2720
                           hasArgument(1, ignoringImplicit(
2721
                            cxxConstructExpr(hasArgument(
2722
                               0, ignoringImplicit(stringLiteral())))))
2723
                           ))))));
2724

2725
  EXPECT_TRUE(matches(
2726
      Code, traverse(TK_IgnoreUnlessSpelledInSource,
2727
                     functionDecl(hasName("stringConstruct"),
2728
                                  hasDescendant(varDecl(
2729
                                      hasName("s"),
2730
                                      hasInitializer(stringLiteral())))))));
2731

2732
  EXPECT_TRUE(
2733
      matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
2734
                             functionDecl(hasName("stringConstruct"),
2735
                                          hasDescendant(cxxOperatorCallExpr(
2736
                                              isAssignmentOperator(),
2737
                                              hasArgument(1, stringLiteral())))))));
2738

2739
  Code = R"cpp(
2740

2741
struct C1 {};
2742
struct C2 { operator C1(); };
2743

2744
void conversionOperator()
2745
{
2746
    C2* c2;
2747
    C1 c1 = (*c2);
2748
}
2749

2750
)cpp";
2751
  EXPECT_TRUE(matches(
2752
      Code,
2753
      traverse(
2754
          TK_AsIs,
2755
          functionDecl(
2756
              hasName("conversionOperator"),
2757
              hasDescendant(
2758
                  varDecl(
2759
                      hasName("c1"),
2760
                      hasInitializer(
2761
                          ignoringImplicit(cxxConstructExpr(hasArgument(
2762
                              0, ignoringImplicit(
2763
                                     cxxMemberCallExpr(onImplicitObjectArgument(
2764
                                         ignoringParenImpCasts(unaryOperator(
2765
                                             hasOperatorName("*")))))))))))
2766
                      .bind("c1"))))));
2767

2768
  EXPECT_TRUE(matches(
2769
      Code,
2770
      traverse(TK_IgnoreUnlessSpelledInSource,
2771
               functionDecl(hasName("conversionOperator"),
2772
                            hasDescendant(varDecl(
2773
                                hasName("c1"), hasInitializer(unaryOperator(
2774
                                                   hasOperatorName("*")))))))));
2775

2776
  Code = R"cpp(
2777

2778
template <unsigned alignment>
2779
void template_test() {
2780
  static_assert(alignment, "");
2781
}
2782
void actual_template_test() {
2783
  template_test<4>();
2784
}
2785

2786
)cpp";
2787
  EXPECT_TRUE(matches(
2788
      Code,
2789
      traverse(TK_AsIs,
2790
               staticAssertDecl(has(implicitCastExpr(has(
2791
                   substNonTypeTemplateParmExpr(has(integerLiteral())))))))));
2792
  EXPECT_TRUE(matches(
2793
      Code, traverse(TK_IgnoreUnlessSpelledInSource,
2794
                     staticAssertDecl(has(declRefExpr(
2795
                         to(nonTypeTemplateParmDecl(hasName("alignment"))),
2796
                         hasType(asString("unsigned int"))))))));
2797

2798
  EXPECT_TRUE(matches(Code, traverse(TK_AsIs, staticAssertDecl(hasDescendant(
2799
                                                  integerLiteral())))));
2800
  EXPECT_FALSE(matches(
2801
      Code, traverse(TK_IgnoreUnlessSpelledInSource,
2802
                     staticAssertDecl(hasDescendant(integerLiteral())))));
2803

2804
  Code = R"cpp(
2805

2806
struct OneParamCtor {
2807
  explicit OneParamCtor(int);
2808
};
2809
struct TwoParamCtor {
2810
  explicit TwoParamCtor(int, int);
2811
};
2812

2813
void varDeclCtors() {
2814
  {
2815
  auto var1 = OneParamCtor(5);
2816
  auto var2 = TwoParamCtor(6, 7);
2817
  }
2818
  {
2819
  OneParamCtor var3(5);
2820
  TwoParamCtor var4(6, 7);
2821
  }
2822
  int i = 0;
2823
  {
2824
  auto var5 = OneParamCtor(i);
2825
  auto var6 = TwoParamCtor(i, 7);
2826
  }
2827
  {
2828
  OneParamCtor var7(i);
2829
  TwoParamCtor var8(i, 7);
2830
  }
2831
}
2832

2833
)cpp";
2834
  EXPECT_TRUE(matches(
2835
      Code,
2836
      traverse(TK_AsIs, varDecl(hasName("var1"), hasInitializer(hasDescendant(
2837
                                                     cxxConstructExpr()))))));
2838
  EXPECT_TRUE(matches(
2839
      Code,
2840
      traverse(TK_AsIs, varDecl(hasName("var2"), hasInitializer(hasDescendant(
2841
                                                     cxxConstructExpr()))))));
2842
  EXPECT_TRUE(matches(
2843
      Code, traverse(TK_AsIs, varDecl(hasName("var3"),
2844
                                      hasInitializer(cxxConstructExpr())))));
2845
  EXPECT_TRUE(matches(
2846
      Code, traverse(TK_AsIs, varDecl(hasName("var4"),
2847
                                      hasInitializer(cxxConstructExpr())))));
2848
  EXPECT_TRUE(matches(
2849
      Code,
2850
      traverse(TK_AsIs, varDecl(hasName("var5"), hasInitializer(hasDescendant(
2851
                                                     cxxConstructExpr()))))));
2852
  EXPECT_TRUE(matches(
2853
      Code,
2854
      traverse(TK_AsIs, varDecl(hasName("var6"), hasInitializer(hasDescendant(
2855
                                                     cxxConstructExpr()))))));
2856
  EXPECT_TRUE(matches(
2857
      Code, traverse(TK_AsIs, varDecl(hasName("var7"),
2858
                                      hasInitializer(cxxConstructExpr())))));
2859
  EXPECT_TRUE(matches(
2860
      Code, traverse(TK_AsIs, varDecl(hasName("var8"),
2861
                                      hasInitializer(cxxConstructExpr())))));
2862

2863
  EXPECT_TRUE(matches(
2864
      Code,
2865
      traverse(TK_IgnoreUnlessSpelledInSource,
2866
               varDecl(hasName("var1"), hasInitializer(cxxConstructExpr())))));
2867
  EXPECT_TRUE(matches(
2868
      Code,
2869
      traverse(TK_IgnoreUnlessSpelledInSource,
2870
               varDecl(hasName("var2"), hasInitializer(cxxConstructExpr())))));
2871
  EXPECT_TRUE(matches(
2872
      Code,
2873
      traverse(TK_IgnoreUnlessSpelledInSource,
2874
               varDecl(hasName("var3"), hasInitializer(cxxConstructExpr())))));
2875
  EXPECT_TRUE(matches(
2876
      Code,
2877
      traverse(TK_IgnoreUnlessSpelledInSource,
2878
               varDecl(hasName("var4"), hasInitializer(cxxConstructExpr())))));
2879
  EXPECT_TRUE(matches(
2880
      Code,
2881
      traverse(TK_IgnoreUnlessSpelledInSource,
2882
               varDecl(hasName("var5"), hasInitializer(cxxConstructExpr())))));
2883
  EXPECT_TRUE(matches(
2884
      Code,
2885
      traverse(TK_IgnoreUnlessSpelledInSource,
2886
               varDecl(hasName("var6"), hasInitializer(cxxConstructExpr())))));
2887
  EXPECT_TRUE(matches(
2888
      Code,
2889
      traverse(TK_IgnoreUnlessSpelledInSource,
2890
               varDecl(hasName("var7"), hasInitializer(cxxConstructExpr())))));
2891
  EXPECT_TRUE(matches(
2892
      Code,
2893
      traverse(TK_IgnoreUnlessSpelledInSource,
2894
               varDecl(hasName("var8"), hasInitializer(cxxConstructExpr())))));
2895

2896
  Code = R"cpp(
2897

2898
template<typename T>
2899
struct TemplStruct {
2900
  TemplStruct() {}
2901
  ~TemplStruct() {}
2902

2903
  void outOfLine(T);
2904

2905
private:
2906
  T m_t;
2907
};
2908

2909
template<typename T>
2910
void TemplStruct<T>::outOfLine(T)
2911
{
2912

2913
}
2914

2915
template<typename T>
2916
T timesTwo(T input)
2917
{
2918
  return input * 2;
2919
}
2920

2921
void instantiate()
2922
{
2923
  TemplStruct<int> ti;
2924
  TemplStruct<double> td;
2925
  (void)timesTwo<int>(2);
2926
  (void)timesTwo<double>(2);
2927
}
2928

2929
template class TemplStruct<float>;
2930

2931
extern template class TemplStruct<long>;
2932

2933
template<> class TemplStruct<bool> {
2934
  TemplStruct() {}
2935
  ~TemplStruct() {}
2936

2937
  void boolSpecializationMethodOnly() {}
2938
private:
2939
  bool m_t;
2940
};
2941

2942
template float timesTwo(float);
2943
template<> bool timesTwo<bool>(bool){
2944
  return true;
2945
}
2946
)cpp";
2947
  {
2948
    auto M = cxxRecordDecl(hasName("TemplStruct"),
2949
                           has(fieldDecl(hasType(asString("int")))));
2950
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2951
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2952
  }
2953
  {
2954
    auto M = cxxRecordDecl(hasName("TemplStruct"),
2955
                           has(fieldDecl(hasType(asString("double")))));
2956
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2957
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2958
  }
2959
  {
2960
    auto M =
2961
        functionDecl(hasName("timesTwo"),
2962
                     hasParameter(0, parmVarDecl(hasType(asString("int")))));
2963
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2964
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2965
  }
2966
  {
2967
    auto M =
2968
        functionDecl(hasName("timesTwo"),
2969
                     hasParameter(0, parmVarDecl(hasType(asString("double")))));
2970
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2971
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2972
  }
2973
  {
2974
    // Match on the integer literal in the explicit instantiation:
2975
    auto MDef =
2976
        functionDecl(hasName("timesTwo"),
2977
                     hasParameter(0, parmVarDecl(hasType(asString("float")))),
2978
                     hasDescendant(integerLiteral(equals(2))));
2979
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MDef)));
2980
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MDef)));
2981

2982
    auto MTempl =
2983
        functionDecl(hasName("timesTwo"),
2984
                     hasTemplateArgument(0, refersToType(asString("float"))));
2985
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MTempl)));
2986
    // TODO: If we could match on explicit instantiations of function templates,
2987
    // this would be EXPECT_TRUE. See Sema::ActOnExplicitInstantiation.
2988
    EXPECT_FALSE(
2989
        matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MTempl)));
2990
  }
2991
  {
2992
    auto M = functionDecl(hasName("timesTwo"),
2993
                          hasParameter(0, parmVarDecl(hasType(booleanType()))));
2994
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2995
    EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2996
  }
2997
  {
2998
    // Match on the field within the explicit instantiation:
2999
    auto MRecord = cxxRecordDecl(hasName("TemplStruct"),
3000
                                 has(fieldDecl(hasType(asString("float")))));
3001
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MRecord)));
3002
    EXPECT_FALSE(
3003
        matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MRecord)));
3004

3005
    // Match on the explicit template instantiation itself:
3006
    auto MTempl = classTemplateSpecializationDecl(
3007
        hasName("TemplStruct"),
3008
        hasTemplateArgument(0,
3009
                            templateArgument(refersToType(asString("float")))));
3010
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MTempl)));
3011
    EXPECT_TRUE(
3012
        matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MTempl)));
3013
  }
3014
  {
3015
    // The template argument is matchable, but the instantiation is not:
3016
    auto M = classTemplateSpecializationDecl(
3017
        hasName("TemplStruct"),
3018
        hasTemplateArgument(0,
3019
                            templateArgument(refersToType(asString("float")))),
3020
        has(cxxConstructorDecl(hasName("TemplStruct"))));
3021
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3022
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3023
  }
3024
  {
3025
    // The template argument is matchable, but the instantiation is not:
3026
    auto M = classTemplateSpecializationDecl(
3027
        hasName("TemplStruct"),
3028
        hasTemplateArgument(0,
3029
                            templateArgument(refersToType(asString("long")))),
3030
        has(cxxConstructorDecl(hasName("TemplStruct"))));
3031
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3032
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3033
  }
3034
  {
3035
    // Instantiated, out-of-line methods are not matchable.
3036
    auto M =
3037
        cxxMethodDecl(hasName("outOfLine"), isDefinition(),
3038
                      hasParameter(0, parmVarDecl(hasType(asString("float")))));
3039
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3040
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3041
  }
3042
  {
3043
    // Explicit specialization is written in source and it matches:
3044
    auto M = classTemplateSpecializationDecl(
3045
        hasName("TemplStruct"),
3046
        hasTemplateArgument(0, templateArgument(refersToType(booleanType()))),
3047
        has(cxxConstructorDecl(hasName("TemplStruct"))),
3048
        has(cxxMethodDecl(hasName("boolSpecializationMethodOnly"))));
3049
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3050
    EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3051
  }
3052

3053
  Code = R"cpp(
3054
struct B {
3055
  B(int);
3056
};
3057

3058
B func1() { return 42; }
3059
  )cpp";
3060
  {
3061
    auto M = expr(ignoringImplicit(integerLiteral(equals(42)).bind("intLit")));
3062
    EXPECT_TRUE(matchAndVerifyResultTrue(
3063
        Code, traverse(TK_AsIs, M),
3064
        std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
3065
    EXPECT_TRUE(matchAndVerifyResultTrue(
3066
        Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3067
        std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
3068
  }
3069
  {
3070
    auto M = expr(unless(integerLiteral(equals(24)))).bind("intLit");
3071
    EXPECT_TRUE(matchAndVerifyResultTrue(
3072
        Code, traverse(TK_AsIs, M),
3073
        std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 6)));
3074
    EXPECT_TRUE(matchAndVerifyResultTrue(
3075
        Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3076
        std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
3077
  }
3078
  {
3079
    auto M =
3080
        expr(anyOf(integerLiteral(equals(42)).bind("intLit"), unless(expr())));
3081
    EXPECT_TRUE(matchAndVerifyResultTrue(
3082
        Code, traverse(TK_AsIs, M),
3083
        std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
3084
    EXPECT_TRUE(matchAndVerifyResultTrue(
3085
        Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3086
        std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
3087
  }
3088
  {
3089
    auto M = expr(allOf(integerLiteral(equals(42)).bind("intLit"), expr()));
3090
    EXPECT_TRUE(matchAndVerifyResultTrue(
3091
        Code, traverse(TK_AsIs, M),
3092
        std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
3093
    EXPECT_TRUE(matchAndVerifyResultTrue(
3094
        Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3095
        std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
3096
  }
3097
  {
3098
    auto M = expr(integerLiteral(equals(42)).bind("intLit"), expr());
3099
    EXPECT_TRUE(matchAndVerifyResultTrue(
3100
        Code, traverse(TK_AsIs, M),
3101
        std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
3102
    EXPECT_TRUE(matchAndVerifyResultTrue(
3103
        Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3104
        std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
3105
  }
3106
  {
3107
    auto M = expr(optionally(integerLiteral(equals(42)).bind("intLit")));
3108
    EXPECT_TRUE(matchAndVerifyResultTrue(
3109
        Code, traverse(TK_AsIs, M),
3110
        std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
3111
    EXPECT_TRUE(matchAndVerifyResultTrue(
3112
        Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3113
        std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
3114
  }
3115
  {
3116
    auto M = expr().bind("allExprs");
3117
    EXPECT_TRUE(matchAndVerifyResultTrue(
3118
        Code, traverse(TK_AsIs, M),
3119
        std::make_unique<VerifyIdIsBoundTo<Expr>>("allExprs", 6)));
3120
    EXPECT_TRUE(matchAndVerifyResultTrue(
3121
        Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3122
        std::make_unique<VerifyIdIsBoundTo<Expr>>("allExprs", 1)));
3123
  }
3124

3125
  Code = R"cpp(
3126
void foo()
3127
{
3128
    int arr[3];
3129
    auto &[f, s, t] = arr;
3130

3131
    f = 42;
3132
}
3133
  )cpp";
3134
  {
3135
    auto M = bindingDecl(hasName("f"));
3136
    EXPECT_TRUE(
3137
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++17"}));
3138
    EXPECT_TRUE(
3139
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3140
                             true, {"-std=c++17"}));
3141
  }
3142
  {
3143
    auto M = bindingDecl(hasName("f"), has(expr()));
3144
    EXPECT_TRUE(
3145
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++17"}));
3146
    EXPECT_FALSE(
3147
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3148
                             true, {"-std=c++17"}));
3149
  }
3150
  {
3151
    auto M = integerLiteral(hasAncestor(bindingDecl(hasName("f"))));
3152
    EXPECT_TRUE(
3153
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++17"}));
3154
    EXPECT_FALSE(
3155
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3156
                             true, {"-std=c++17"}));
3157
  }
3158
  {
3159
    auto M = declRefExpr(hasAncestor(bindingDecl(hasName("f"))));
3160
    EXPECT_TRUE(
3161
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++17"}));
3162
    EXPECT_FALSE(
3163
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3164
                             true, {"-std=c++17"}));
3165
  }
3166
}
3167

3168
TEST(Traversal, traverseNoImplicit) {
3169
  StringRef Code = R"cpp(
3170
struct NonTrivial {
3171
    NonTrivial() {}
3172
    NonTrivial(const NonTrivial&) {}
3173
    NonTrivial& operator=(const NonTrivial&) { return *this; }
3174

3175
    ~NonTrivial() {}
3176
};
3177

3178
struct NoSpecialMethods {
3179
    NonTrivial nt;
3180
};
3181

3182
struct ContainsArray {
3183
    NonTrivial arr[2];
3184
    ContainsArray& operator=(const ContainsArray &other) = default;
3185
};
3186

3187
void copyIt()
3188
{
3189
    NoSpecialMethods nc1;
3190
    NoSpecialMethods nc2(nc1);
3191
    nc2 = nc1;
3192

3193
    ContainsArray ca;
3194
    ContainsArray ca2;
3195
    ca2 = ca;
3196
}
3197

3198
struct HasCtorInits : NoSpecialMethods, NonTrivial
3199
{
3200
  int m_i;
3201
  NonTrivial m_nt;
3202
  HasCtorInits() : NoSpecialMethods(), m_i(42) {}
3203
};
3204

3205
struct CtorInitsNonTrivial : NonTrivial
3206
{
3207
  int m_i;
3208
  NonTrivial m_nt;
3209
  CtorInitsNonTrivial() : NonTrivial(), m_i(42) {}
3210
};
3211

3212
)cpp";
3213
  {
3214
    auto M = cxxRecordDecl(hasName("NoSpecialMethods"),
3215
                           has(cxxRecordDecl(hasName("NoSpecialMethods"))));
3216
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3217
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3218

3219
    M = cxxRecordDecl(hasName("NoSpecialMethods"),
3220
                      has(cxxConstructorDecl(isCopyConstructor())));
3221
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3222
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3223

3224
    M = cxxRecordDecl(hasName("NoSpecialMethods"),
3225
                      has(cxxMethodDecl(isCopyAssignmentOperator())));
3226
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3227
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3228

3229
    M = cxxRecordDecl(hasName("NoSpecialMethods"),
3230
                      has(cxxConstructorDecl(isDefaultConstructor())));
3231
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3232
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3233

3234
    M = cxxRecordDecl(hasName("NoSpecialMethods"), has(cxxDestructorDecl()));
3235
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3236
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3237

3238
    M = cxxRecordDecl(hasName("NoSpecialMethods"),
3239
                      hasMethod(cxxConstructorDecl(isCopyConstructor())));
3240
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3241
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3242

3243
    M = cxxRecordDecl(hasName("NoSpecialMethods"),
3244
                      hasMethod(cxxMethodDecl(isCopyAssignmentOperator())));
3245
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3246
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3247

3248
    M = cxxRecordDecl(hasName("NoSpecialMethods"),
3249
                      hasMethod(cxxConstructorDecl(isDefaultConstructor())));
3250
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3251
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3252

3253
    M = cxxRecordDecl(hasName("NoSpecialMethods"),
3254
                      hasMethod(cxxDestructorDecl()));
3255
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3256
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3257
  }
3258
  {
3259
    // Because the copy-assignment operator is not spelled in the
3260
    // source (ie, isImplicit()), we don't match it
3261
    auto M =
3262
        cxxOperatorCallExpr(hasType(cxxRecordDecl(hasName("NoSpecialMethods"))),
3263
                            callee(cxxMethodDecl(isCopyAssignmentOperator())));
3264
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3265
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3266
  }
3267
  {
3268
    // Compiler generates a forStmt to copy the array
3269
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, forStmt())));
3270
    EXPECT_FALSE(
3271
        matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, forStmt())));
3272
  }
3273
  {
3274
    // The defaulted method declaration can be matched, but not its
3275
    // definition, in IgnoreUnlessSpelledInSource mode
3276
    auto MDecl = cxxMethodDecl(ofClass(cxxRecordDecl(hasName("ContainsArray"))),
3277
                               isCopyAssignmentOperator(), isDefaulted());
3278

3279
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MDecl)));
3280
    EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MDecl)));
3281

3282
    auto MDef = cxxMethodDecl(MDecl, has(compoundStmt()));
3283

3284
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MDef)));
3285
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MDef)));
3286

3287
    auto MBody = cxxMethodDecl(MDecl, hasBody(compoundStmt()));
3288

3289
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MBody)));
3290
    EXPECT_FALSE(
3291
        matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MBody)));
3292

3293
    auto MIsDefn = cxxMethodDecl(MDecl, isDefinition());
3294

3295
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MIsDefn)));
3296
    EXPECT_TRUE(
3297
        matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MIsDefn)));
3298

3299
    auto MIsInline = cxxMethodDecl(MDecl, isInline());
3300

3301
    EXPECT_FALSE(matches(Code, traverse(TK_AsIs, MIsInline)));
3302
    EXPECT_FALSE(
3303
        matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MIsInline)));
3304

3305
    // The parameter of the defaulted method can still be matched.
3306
    auto MParm =
3307
        cxxMethodDecl(MDecl, hasParameter(0, parmVarDecl(hasName("other"))));
3308

3309
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MParm)));
3310
    EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MParm)));
3311
  }
3312
  {
3313
    auto M =
3314
        cxxConstructorDecl(hasName("HasCtorInits"),
3315
                           has(cxxCtorInitializer(forField(hasName("m_i")))));
3316
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3317
    EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3318
  }
3319
  {
3320
    auto M =
3321
        cxxConstructorDecl(hasName("HasCtorInits"),
3322
                           has(cxxCtorInitializer(forField(hasName("m_nt")))));
3323
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3324
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3325
  }
3326
  {
3327
    auto M = cxxConstructorDecl(hasName("HasCtorInits"),
3328
                                hasAnyConstructorInitializer(cxxCtorInitializer(
3329
                                    forField(hasName("m_nt")))));
3330
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3331
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3332
  }
3333
  {
3334
    auto M =
3335
        cxxConstructorDecl(hasName("HasCtorInits"),
3336
                           forEachConstructorInitializer(
3337
                               cxxCtorInitializer(forField(hasName("m_nt")))));
3338
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3339
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3340
  }
3341
  {
3342
    auto M = cxxConstructorDecl(
3343
        hasName("CtorInitsNonTrivial"),
3344
        has(cxxCtorInitializer(withInitializer(cxxConstructExpr(
3345
            hasDeclaration(cxxConstructorDecl(hasName("NonTrivial"))))))));
3346
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3347
    EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3348
  }
3349
  {
3350
    auto M = cxxConstructorDecl(
3351
        hasName("HasCtorInits"),
3352
        has(cxxCtorInitializer(withInitializer(cxxConstructExpr(hasDeclaration(
3353
            cxxConstructorDecl(hasName("NoSpecialMethods"))))))));
3354
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3355
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3356
  }
3357
  {
3358
    auto M = cxxCtorInitializer(forField(hasName("m_nt")));
3359
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3360
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3361
  }
3362

3363
  Code = R"cpp(
3364
  void rangeFor()
3365
  {
3366
    int arr[2];
3367
    for (auto i : arr)
3368
    {
3369
      if (true)
3370
      {
3371
      }
3372
    }
3373
  }
3374
  )cpp";
3375
  {
3376
    auto M = cxxForRangeStmt(has(binaryOperator(hasOperatorName("!="))));
3377
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3378
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3379
  }
3380
  {
3381
    auto M =
3382
        cxxForRangeStmt(hasDescendant(binaryOperator(hasOperatorName("+"))));
3383
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3384
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3385
  }
3386
  {
3387
    auto M =
3388
        cxxForRangeStmt(hasDescendant(unaryOperator(hasOperatorName("++"))));
3389
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3390
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3391
  }
3392
  {
3393
    auto M = cxxForRangeStmt(has(declStmt()));
3394
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3395
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3396
  }
3397
  {
3398
    auto M =
3399
        cxxForRangeStmt(hasLoopVariable(varDecl(hasName("i"))),
3400
                        hasRangeInit(declRefExpr(to(varDecl(hasName("arr"))))));
3401
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3402
    EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3403
  }
3404
  {
3405
    auto M = cxxForRangeStmt(unless(hasInitStatement(stmt())));
3406
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3407
    EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3408
  }
3409
  {
3410
    auto M = cxxForRangeStmt(hasBody(stmt()));
3411
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3412
    EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3413
  }
3414
  {
3415
    auto M = cxxForRangeStmt(hasDescendant(ifStmt()));
3416
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3417
    EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3418
  }
3419
  {
3420
    EXPECT_TRUE(matches(
3421
        Code, traverse(TK_AsIs, cxxForRangeStmt(has(declStmt(
3422
                                    hasSingleDecl(varDecl(hasName("i")))))))));
3423
    EXPECT_TRUE(
3424
        matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
3425
                               cxxForRangeStmt(has(varDecl(hasName("i")))))));
3426
  }
3427
  {
3428
    EXPECT_TRUE(matches(
3429
        Code, traverse(TK_AsIs, cxxForRangeStmt(has(declStmt(hasSingleDecl(
3430
                                    varDecl(hasInitializer(declRefExpr(
3431
                                        to(varDecl(hasName("arr")))))))))))));
3432
    EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
3433
                                       cxxForRangeStmt(has(declRefExpr(
3434
                                           to(varDecl(hasName("arr")))))))));
3435
  }
3436
  {
3437
    auto M = cxxForRangeStmt(has(compoundStmt()));
3438
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3439
    EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3440
  }
3441
  {
3442
    auto M = binaryOperator(hasOperatorName("!="));
3443
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3444
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3445
  }
3446
  {
3447
    auto M = unaryOperator(hasOperatorName("++"));
3448
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3449
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3450
  }
3451
  {
3452
    auto M = declStmt(hasSingleDecl(varDecl(matchesName("__range"))));
3453
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3454
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3455
  }
3456
  {
3457
    auto M = declStmt(hasSingleDecl(varDecl(matchesName("__begin"))));
3458
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3459
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3460
  }
3461
  {
3462
    auto M = declStmt(hasSingleDecl(varDecl(matchesName("__end"))));
3463
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3464
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3465
  }
3466
  {
3467
    auto M = ifStmt(hasParent(compoundStmt(hasParent(cxxForRangeStmt()))));
3468
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3469
    EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3470
  }
3471
  {
3472
    auto M = cxxForRangeStmt(
3473
        has(varDecl(hasName("i"), hasParent(cxxForRangeStmt()))));
3474
    EXPECT_FALSE(matches(Code, traverse(TK_AsIs, M)));
3475
    EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3476
  }
3477
  {
3478
    auto M = cxxForRangeStmt(hasDescendant(varDecl(
3479
        hasName("i"), hasParent(declStmt(hasParent(cxxForRangeStmt()))))));
3480
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3481
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3482
  }
3483
  {
3484
    auto M = cxxForRangeStmt(hasRangeInit(declRefExpr(
3485
        to(varDecl(hasName("arr"))), hasParent(cxxForRangeStmt()))));
3486
    EXPECT_FALSE(matches(Code, traverse(TK_AsIs, M)));
3487
    EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3488
  }
3489

3490
  {
3491
    auto M = cxxForRangeStmt(hasRangeInit(declRefExpr(
3492
        to(varDecl(hasName("arr"))), hasParent(varDecl(hasParent(declStmt(
3493
                                         hasParent(cxxForRangeStmt()))))))));
3494
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3495
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3496
  }
3497

3498
  Code = R"cpp(
3499
  struct Range {
3500
    int* begin() const;
3501
    int* end() const;
3502
  };
3503
  Range getRange(int);
3504

3505
  void rangeFor()
3506
  {
3507
    for (auto i : getRange(42))
3508
    {
3509
    }
3510
  }
3511
  )cpp";
3512
  {
3513
    auto M = integerLiteral(equals(42));
3514
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3515
    EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3516
  }
3517
  {
3518
    auto M = callExpr(hasDescendant(integerLiteral(equals(42))));
3519
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3520
    EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3521
  }
3522
  {
3523
    auto M = compoundStmt(hasDescendant(integerLiteral(equals(42))));
3524
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3525
    EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3526
  }
3527

3528
  Code = R"cpp(
3529
  void rangeFor()
3530
  {
3531
    int arr[2];
3532
    for (auto& a = arr; auto i : a)
3533
    {
3534

3535
    }
3536
  }
3537
  )cpp";
3538
  {
3539
    auto M = cxxForRangeStmt(has(binaryOperator(hasOperatorName("!="))));
3540
    EXPECT_TRUE(
3541
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3542
    EXPECT_FALSE(
3543
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3544
                             true, {"-std=c++20"}));
3545
  }
3546
  {
3547
    auto M =
3548
        cxxForRangeStmt(hasDescendant(binaryOperator(hasOperatorName("+"))));
3549
    EXPECT_TRUE(
3550
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3551
    EXPECT_FALSE(
3552
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3553
                             true, {"-std=c++20"}));
3554
  }
3555
  {
3556
    auto M =
3557
        cxxForRangeStmt(hasDescendant(unaryOperator(hasOperatorName("++"))));
3558
    EXPECT_TRUE(
3559
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3560
    EXPECT_FALSE(
3561
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3562
                             true, {"-std=c++20"}));
3563
  }
3564
  {
3565
    auto M =
3566
        cxxForRangeStmt(has(declStmt(hasSingleDecl(varDecl(hasName("i"))))));
3567
    EXPECT_TRUE(
3568
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3569
    EXPECT_FALSE(
3570
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3571
                             true, {"-std=c++20"}));
3572
  }
3573
  {
3574
    auto M = cxxForRangeStmt(
3575
        hasInitStatement(declStmt(hasSingleDecl(varDecl(
3576
            hasName("a"),
3577
            hasInitializer(declRefExpr(to(varDecl(hasName("arr"))))))))),
3578
        hasLoopVariable(varDecl(hasName("i"))),
3579
        hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))));
3580
    EXPECT_TRUE(
3581
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3582
    EXPECT_TRUE(
3583
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3584
                             true, {"-std=c++20"}));
3585
  }
3586
  {
3587
    auto M = cxxForRangeStmt(
3588
        has(declStmt(hasSingleDecl(varDecl(
3589
            hasName("a"),
3590
            hasInitializer(declRefExpr(to(varDecl(hasName("arr"))))))))),
3591
        hasLoopVariable(varDecl(hasName("i"))),
3592
        hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))));
3593
    EXPECT_TRUE(
3594
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3595
    EXPECT_TRUE(
3596
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3597
                             true, {"-std=c++20"}));
3598
  }
3599
  {
3600
    auto M = cxxForRangeStmt(hasInitStatement(declStmt(
3601
        hasSingleDecl(varDecl(hasName("a"))), hasParent(cxxForRangeStmt()))));
3602
    EXPECT_TRUE(
3603
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3604
    EXPECT_TRUE(
3605
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3606
                             true, {"-std=c++20"}));
3607
  }
3608

3609
  Code = R"cpp(
3610
  struct Range {
3611
    int* begin() const;
3612
    int* end() const;
3613
  };
3614
  Range getRange(int);
3615

3616
  int getNum(int);
3617

3618
  void rangeFor()
3619
  {
3620
    for (auto j = getNum(42); auto i : getRange(j))
3621
    {
3622
    }
3623
  }
3624
  )cpp";
3625
  {
3626
    auto M = integerLiteral(equals(42));
3627
    EXPECT_TRUE(
3628
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3629
    EXPECT_TRUE(
3630
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3631
                             true, {"-std=c++20"}));
3632
  }
3633
  {
3634
    auto M = compoundStmt(hasDescendant(integerLiteral(equals(42))));
3635
    EXPECT_TRUE(
3636
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3637
    EXPECT_TRUE(
3638
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3639
                             true, {"-std=c++20"}));
3640
  }
3641

3642
  Code = R"cpp(
3643
void hasDefaultArg(int i, int j = 0)
3644
{
3645
}
3646
void callDefaultArg()
3647
{
3648
  hasDefaultArg(42);
3649
}
3650
)cpp";
3651
  auto hasDefaultArgCall = [](auto InnerMatcher) {
3652
    return callExpr(callee(functionDecl(hasName("hasDefaultArg"))),
3653
                    InnerMatcher);
3654
  };
3655
  {
3656
    auto M = hasDefaultArgCall(has(integerLiteral(equals(42))));
3657
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3658
    EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3659
  }
3660
  {
3661
    auto M = hasDefaultArgCall(has(cxxDefaultArgExpr()));
3662
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3663
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3664
  }
3665
  {
3666
    auto M = hasDefaultArgCall(argumentCountIs(2));
3667
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3668
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3669
  }
3670
  {
3671
    auto M = hasDefaultArgCall(argumentCountIs(1));
3672
    EXPECT_FALSE(matches(Code, traverse(TK_AsIs, M)));
3673
    EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3674
  }
3675
  {
3676
    auto M = hasDefaultArgCall(hasArgument(1, cxxDefaultArgExpr()));
3677
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3678
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3679
  }
3680
  {
3681
    auto M = hasDefaultArgCall(hasAnyArgument(cxxDefaultArgExpr()));
3682
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3683
    EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3684
  }
3685
  Code = R"cpp(
3686
struct A
3687
{
3688
    ~A();
3689
private:
3690
    int i;
3691
};
3692

3693
A::~A() = default;
3694
)cpp";
3695
  {
3696
    auto M = cxxDestructorDecl(isDefaulted(),
3697
                               ofClass(cxxRecordDecl(has(fieldDecl()))));
3698
    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3699
    EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3700
  }
3701
  Code = R"cpp(
3702
struct S
3703
{
3704
    static constexpr bool getTrue() { return true; }
3705
};
3706

3707
struct A
3708
{
3709
    explicit(S::getTrue()) A();
3710
};
3711

3712
A::A() = default;
3713
)cpp";
3714
  {
3715
    EXPECT_TRUE(matchesConditionally(
3716
        Code,
3717
        traverse(TK_AsIs,
3718
                 cxxConstructorDecl(
3719
                     isDefaulted(),
3720
                     hasExplicitSpecifier(expr(ignoringImplicit(
3721
                         callExpr(has(ignoringImplicit(declRefExpr())))))))),
3722
        true, {"-std=c++20"}));
3723
    EXPECT_TRUE(matchesConditionally(
3724
        Code,
3725
        traverse(TK_IgnoreUnlessSpelledInSource,
3726
                 cxxConstructorDecl(
3727
                     isDefaulted(),
3728
                     hasExplicitSpecifier(callExpr(has(declRefExpr()))))),
3729
        true, {"-std=c++20"}));
3730
  }
3731
}
3732

3733
template <typename MatcherT>
3734
bool matcherTemplateWithBinding(StringRef Code, const MatcherT &M) {
3735
  return matchAndVerifyResultTrue(
3736
      Code, M.bind("matchedStmt"),
3737
      std::make_unique<VerifyIdIsBoundTo<ReturnStmt>>("matchedStmt", 1));
3738
}
3739

3740
TEST(Traversal, traverseWithBinding) {
3741
  // Some existing matcher code expects to take a matcher as a
3742
  // template arg and bind to it.  Verify that that works.
3743

3744
  llvm::StringRef Code = R"cpp(
3745
int foo()
3746
{
3747
  return 42.0;
3748
}
3749
)cpp";
3750
  EXPECT_TRUE(matcherTemplateWithBinding(
3751
      Code, traverse(TK_AsIs,
3752
                     returnStmt(has(implicitCastExpr(has(floatLiteral())))))));
3753
}
3754

3755
TEST(Traversal, traverseMatcherNesting) {
3756

3757
  StringRef Code = R"cpp(
3758
float bar(int i)
3759
{
3760
  return i;
3761
}
3762

3763
void foo()
3764
{
3765
  bar(bar(3.0));
3766
}
3767
)cpp";
3768

3769
  EXPECT_TRUE(
3770
      matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
3771
                             callExpr(has(callExpr(traverse(
3772
                                 TK_AsIs, callExpr(has(implicitCastExpr(
3773
                                              has(floatLiteral())))))))))));
3774

3775
  EXPECT_TRUE(matches(
3776
      Code,
3777
      traverse(TK_IgnoreUnlessSpelledInSource,
3778
               traverse(TK_AsIs, implicitCastExpr(has(floatLiteral()))))));
3779
}
3780

3781
TEST(Traversal, traverseMatcherThroughImplicit) {
3782
  StringRef Code = R"cpp(
3783
struct S {
3784
  S(int x);
3785
};
3786

3787
void constructImplicit() {
3788
  int a = 8;
3789
  S s(a);
3790
}
3791
  )cpp";
3792

3793
  auto Matcher = traverse(TK_IgnoreUnlessSpelledInSource, implicitCastExpr());
3794

3795
  // Verfiy that it does not segfault
3796
  EXPECT_FALSE(matches(Code, Matcher));
3797
}
3798

3799
TEST(Traversal, traverseMatcherThroughMemoization) {
3800

3801
  StringRef Code = R"cpp(
3802
void foo()
3803
{
3804
  int i = 3.0;
3805
}
3806
  )cpp";
3807

3808
  auto Matcher = varDecl(hasInitializer(floatLiteral()));
3809

3810
  // Matchers such as hasDescendant memoize their result regarding AST
3811
  // nodes. In the matcher below, the first use of hasDescendant(Matcher)
3812
  // fails, and the use of it inside the traverse() matcher should pass
3813
  // causing the overall matcher to be a true match.
3814
  // This test verifies that the first false result is not re-used, which
3815
  // would cause the overall matcher to be incorrectly false.
3816

3817
  EXPECT_TRUE(matches(
3818
      Code,
3819
      functionDecl(anyOf(hasDescendant(Matcher),
3820
                         traverse(TK_IgnoreUnlessSpelledInSource,
3821
                                  functionDecl(hasDescendant(Matcher)))))));
3822
}
3823

3824
TEST(Traversal, traverseUnlessSpelledInSource) {
3825

3826
  StringRef Code = R"cpp(
3827

3828
struct A
3829
{
3830
};
3831

3832
struct B
3833
{
3834
  B(int);
3835
  B(A const& a);
3836
  B();
3837
};
3838

3839
struct C
3840
{
3841
  operator B();
3842
};
3843

3844
B func1() {
3845
  return 42;
3846
}
3847

3848
B func2() {
3849
  return B{42};
3850
}
3851

3852
B func3() {
3853
  return B(42);
3854
}
3855

3856
B func4() {
3857
  return B();
3858
}
3859

3860
B func5() {
3861
  return B{};
3862
}
3863

3864
B func6() {
3865
  return C();
3866
}
3867

3868
B func7() {
3869
  return A();
3870
}
3871

3872
B func8() {
3873
  return C{};
3874
}
3875

3876
B func9() {
3877
  return A{};
3878
}
3879

3880
B func10() {
3881
  A a;
3882
  return a;
3883
}
3884

3885
B func11() {
3886
  B b;
3887
  return b;
3888
}
3889

3890
B func12() {
3891
  C c;
3892
  return c;
3893
}
3894

3895
void func13() {
3896
  int a = 0;
3897
  int c = 0;
3898

3899
  [a, b = c](int d) { int e = d; };
3900
}
3901

3902
void func14() {
3903
  [] <typename TemplateType> (TemplateType t, TemplateType u) { int e = t + u; };
3904
  float i = 42.0;
3905
}
3906

3907
void func15() {
3908
  int count = 0;
3909
  auto l = [&] { ++count; };
3910
  (void)l;
3911
}
3912

3913
)cpp";
3914

3915
  EXPECT_TRUE(
3916
      matches(Code,
3917
              traverse(TK_IgnoreUnlessSpelledInSource,
3918
                       returnStmt(forFunction(functionDecl(hasName("func1"))),
3919
                                  hasReturnValue(integerLiteral(equals(42))))),
3920
              langCxx20OrLater()));
3921

3922
  EXPECT_TRUE(
3923
      matches(Code,
3924
              traverse(TK_IgnoreUnlessSpelledInSource,
3925
                       integerLiteral(equals(42),
3926
                                      hasParent(returnStmt(forFunction(
3927
                                          functionDecl(hasName("func1"))))))),
3928
              langCxx20OrLater()));
3929

3930
  EXPECT_TRUE(matches(
3931
      Code,
3932
      traverse(TK_IgnoreUnlessSpelledInSource,
3933
               returnStmt(forFunction(functionDecl(hasName("func2"))),
3934
                          hasReturnValue(cxxTemporaryObjectExpr(
3935
                              hasArgument(0, integerLiteral(equals(42))))))),
3936
      langCxx20OrLater()));
3937
  EXPECT_TRUE(matches(
3938
      Code,
3939
      traverse(
3940
          TK_IgnoreUnlessSpelledInSource,
3941
          integerLiteral(equals(42),
3942
                         hasParent(cxxTemporaryObjectExpr(hasParent(returnStmt(
3943
                             forFunction(functionDecl(hasName("func2"))))))))),
3944
      langCxx20OrLater()));
3945

3946
  EXPECT_TRUE(
3947
      matches(Code,
3948
              traverse(TK_IgnoreUnlessSpelledInSource,
3949
                       returnStmt(forFunction(functionDecl(hasName("func3"))),
3950
                                  hasReturnValue(cxxConstructExpr(hasArgument(
3951
                                      0, integerLiteral(equals(42))))))),
3952
              langCxx20OrLater()));
3953

3954
  EXPECT_TRUE(matches(
3955
      Code,
3956
      traverse(
3957
          TK_IgnoreUnlessSpelledInSource,
3958
          integerLiteral(equals(42),
3959
                         hasParent(cxxConstructExpr(hasParent(returnStmt(
3960
                             forFunction(functionDecl(hasName("func3"))))))))),
3961
      langCxx20OrLater()));
3962

3963
  EXPECT_TRUE(
3964
      matches(Code,
3965
              traverse(TK_IgnoreUnlessSpelledInSource,
3966
                       returnStmt(forFunction(functionDecl(hasName("func4"))),
3967
                                  hasReturnValue(cxxTemporaryObjectExpr()))),
3968
              langCxx20OrLater()));
3969

3970
  EXPECT_TRUE(
3971
      matches(Code,
3972
              traverse(TK_IgnoreUnlessSpelledInSource,
3973
                       returnStmt(forFunction(functionDecl(hasName("func5"))),
3974
                                  hasReturnValue(cxxTemporaryObjectExpr()))),
3975
              langCxx20OrLater()));
3976

3977
  EXPECT_TRUE(
3978
      matches(Code,
3979
              traverse(TK_IgnoreUnlessSpelledInSource,
3980
                       returnStmt(forFunction(functionDecl(hasName("func6"))),
3981
                                  hasReturnValue(cxxTemporaryObjectExpr()))),
3982
              langCxx20OrLater()));
3983

3984
  EXPECT_TRUE(
3985
      matches(Code,
3986
              traverse(TK_IgnoreUnlessSpelledInSource,
3987
                       returnStmt(forFunction(functionDecl(hasName("func7"))),
3988
                                  hasReturnValue(cxxTemporaryObjectExpr()))),
3989
              langCxx20OrLater()));
3990

3991
  EXPECT_TRUE(
3992
      matches(Code,
3993
              traverse(TK_IgnoreUnlessSpelledInSource,
3994
                       returnStmt(forFunction(functionDecl(hasName("func8"))),
3995
                                  hasReturnValue(cxxFunctionalCastExpr(
3996
                                      hasSourceExpression(initListExpr()))))),
3997
              langCxx20OrLater()));
3998

3999
  EXPECT_TRUE(
4000
      matches(Code,
4001
              traverse(TK_IgnoreUnlessSpelledInSource,
4002
                       returnStmt(forFunction(functionDecl(hasName("func9"))),
4003
                                  hasReturnValue(cxxFunctionalCastExpr(
4004
                                      hasSourceExpression(initListExpr()))))),
4005
              langCxx20OrLater()));
4006

4007
  EXPECT_TRUE(matches(
4008
      Code,
4009
      traverse(
4010
          TK_IgnoreUnlessSpelledInSource,
4011
          returnStmt(forFunction(functionDecl(hasName("func10"))),
4012
                     hasReturnValue(declRefExpr(to(varDecl(hasName("a"))))))),
4013
      langCxx20OrLater()));
4014

4015
  EXPECT_TRUE(
4016
      matches(Code,
4017
              traverse(TK_IgnoreUnlessSpelledInSource,
4018
                       declRefExpr(to(varDecl(hasName("a"))),
4019
                                   hasParent(returnStmt(forFunction(
4020
                                       functionDecl(hasName("func10"))))))),
4021
              langCxx20OrLater()));
4022

4023
  EXPECT_TRUE(matches(
4024
      Code,
4025
      traverse(
4026
          TK_IgnoreUnlessSpelledInSource,
4027
          returnStmt(forFunction(functionDecl(hasName("func11"))),
4028
                     hasReturnValue(declRefExpr(to(varDecl(hasName("b"))))))),
4029
      langCxx20OrLater()));
4030

4031
  EXPECT_TRUE(
4032
      matches(Code,
4033
              traverse(TK_IgnoreUnlessSpelledInSource,
4034
                       declRefExpr(to(varDecl(hasName("b"))),
4035
                                   hasParent(returnStmt(forFunction(
4036
                                       functionDecl(hasName("func11"))))))),
4037
              langCxx20OrLater()));
4038

4039
  EXPECT_TRUE(matches(
4040
      Code,
4041
      traverse(
4042
          TK_IgnoreUnlessSpelledInSource,
4043
          returnStmt(forFunction(functionDecl(hasName("func12"))),
4044
                     hasReturnValue(declRefExpr(to(varDecl(hasName("c"))))))),
4045
      langCxx20OrLater()));
4046

4047
  EXPECT_TRUE(
4048
      matches(Code,
4049
              traverse(TK_IgnoreUnlessSpelledInSource,
4050
                       declRefExpr(to(varDecl(hasName("c"))),
4051
                                   hasParent(returnStmt(forFunction(
4052
                                       functionDecl(hasName("func12"))))))),
4053
              langCxx20OrLater()));
4054

4055
  EXPECT_TRUE(matches(
4056
      Code,
4057
      traverse(
4058
          TK_IgnoreUnlessSpelledInSource,
4059
          lambdaExpr(forFunction(functionDecl(hasName("func13"))),
4060
                     has(compoundStmt(hasDescendant(varDecl(hasName("e"))))),
4061
                     has(declRefExpr(to(varDecl(hasName("a"))))),
4062
                     has(varDecl(hasName("b"), hasInitializer(declRefExpr(to(
4063
                                                   varDecl(hasName("c"))))))),
4064
                     has(parmVarDecl(hasName("d"))))),
4065
      langCxx20OrLater()));
4066

4067
  EXPECT_TRUE(
4068
      matches(Code,
4069
              traverse(TK_IgnoreUnlessSpelledInSource,
4070
                       declRefExpr(to(varDecl(hasName("a"))),
4071
                                   hasParent(lambdaExpr(forFunction(
4072
                                       functionDecl(hasName("func13"))))))),
4073
              langCxx20OrLater()));
4074

4075
  EXPECT_TRUE(matches(
4076
      Code,
4077
      traverse(TK_IgnoreUnlessSpelledInSource,
4078
               varDecl(hasName("b"),
4079
                       hasInitializer(declRefExpr(to(varDecl(hasName("c"))))),
4080
                       hasParent(lambdaExpr(
4081
                           forFunction(functionDecl(hasName("func13"))))))),
4082
      langCxx20OrLater()));
4083

4084
  EXPECT_TRUE(matches(Code,
4085
                      traverse(TK_IgnoreUnlessSpelledInSource,
4086
                               compoundStmt(hasParent(lambdaExpr(forFunction(
4087
                                   functionDecl(hasName("func13"))))))),
4088
                      langCxx20OrLater()));
4089

4090
  EXPECT_TRUE(matches(
4091
      Code,
4092
      traverse(TK_IgnoreUnlessSpelledInSource,
4093
               templateTypeParmDecl(hasName("TemplateType"),
4094
                                    hasParent(lambdaExpr(forFunction(
4095
                                        functionDecl(hasName("func14"))))))),
4096
      langCxx20OrLater()));
4097

4098
  EXPECT_TRUE(matches(
4099
      Code,
4100
      traverse(TK_IgnoreUnlessSpelledInSource,
4101
               lambdaExpr(forFunction(functionDecl(hasName("func14"))),
4102
                          has(templateTypeParmDecl(hasName("TemplateType"))))),
4103
      langCxx20OrLater()));
4104

4105
  EXPECT_TRUE(matches(
4106
      Code,
4107
      traverse(TK_IgnoreUnlessSpelledInSource,
4108
               functionDecl(hasName("func14"), hasDescendant(floatLiteral()))),
4109
      langCxx20OrLater()));
4110

4111
  EXPECT_TRUE(matches(
4112
      Code,
4113
      traverse(TK_IgnoreUnlessSpelledInSource,
4114
               compoundStmt(
4115
                   hasDescendant(varDecl(hasName("count")).bind("countVar")),
4116
                   hasDescendant(
4117
                       declRefExpr(to(varDecl(equalsBoundNode("countVar"))))))),
4118
      langCxx20OrLater()));
4119

4120
  Code = R"cpp(
4121
void foo() {
4122
    int explicit_captured = 0;
4123
    int implicit_captured = 0;
4124
    auto l = [&, explicit_captured](int i) {
4125
        if (i || explicit_captured || implicit_captured) return;
4126
    };
4127
}
4128
)cpp";
4129

4130
  EXPECT_TRUE(matches(Code, traverse(TK_AsIs, ifStmt())));
4131
  EXPECT_TRUE(
4132
      matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, ifStmt())));
4133

4134
  auto lambdaExplicitCapture = declRefExpr(
4135
      to(varDecl(hasName("explicit_captured"))), unless(hasAncestor(ifStmt())));
4136
  auto lambdaImplicitCapture = declRefExpr(
4137
      to(varDecl(hasName("implicit_captured"))), unless(hasAncestor(ifStmt())));
4138

4139
  EXPECT_TRUE(matches(Code, traverse(TK_AsIs, lambdaExplicitCapture)));
4140
  EXPECT_TRUE(matches(
4141
      Code, traverse(TK_IgnoreUnlessSpelledInSource, lambdaExplicitCapture)));
4142

4143
  EXPECT_TRUE(matches(Code, traverse(TK_AsIs, lambdaImplicitCapture)));
4144
  EXPECT_FALSE(matches(
4145
      Code, traverse(TK_IgnoreUnlessSpelledInSource, lambdaImplicitCapture)));
4146

4147
  Code = R"cpp(
4148
struct S {};
4149

4150
struct HasOpEq
4151
{
4152
    bool operator==(const S& other)
4153
    {
4154
        return true;
4155
    }
4156
};
4157

4158
void binop()
4159
{
4160
    HasOpEq s1;
4161
    S s2;
4162
    if (s1 != s2)
4163
        return;
4164
}
4165
)cpp";
4166
  {
4167
    auto M = unaryOperator(
4168
        hasOperatorName("!"),
4169
        has(cxxOperatorCallExpr(hasOverloadedOperatorName("=="))));
4170
    EXPECT_TRUE(
4171
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4172
    EXPECT_FALSE(
4173
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4174
                             true, {"-std=c++20"}));
4175
  }
4176
  {
4177
    auto M = declRefExpr(to(varDecl(hasName("s1"))));
4178
    EXPECT_TRUE(
4179
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4180
    EXPECT_TRUE(
4181
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4182
                             true, {"-std=c++20"}));
4183
  }
4184
  {
4185
    auto M = cxxOperatorCallExpr(hasOverloadedOperatorName("=="));
4186
    EXPECT_TRUE(
4187
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4188
    EXPECT_FALSE(
4189
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4190
                             true, {"-std=c++20"}));
4191
  }
4192
  {
4193
    auto M = cxxOperatorCallExpr(hasOverloadedOperatorName("!="));
4194
    EXPECT_FALSE(
4195
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4196
    EXPECT_FALSE(
4197
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4198
                             true, {"-std=c++20"}));
4199
  }
4200
  auto withDescendants = [](StringRef lName, StringRef rName) {
4201
    return stmt(hasDescendant(declRefExpr(to(varDecl(hasName(lName))))),
4202
                hasDescendant(declRefExpr(to(varDecl(hasName(rName))))));
4203
  };
4204
  {
4205
    auto M = cxxRewrittenBinaryOperator(withDescendants("s1", "s2"));
4206
    EXPECT_TRUE(
4207
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4208
    EXPECT_TRUE(
4209
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4210
                             true, {"-std=c++20"}));
4211
  }
4212
  {
4213
    auto M = cxxRewrittenBinaryOperator(
4214
        has(declRefExpr(to(varDecl(hasName("s1"))))),
4215
        has(declRefExpr(to(varDecl(hasName("s2"))))));
4216
    EXPECT_FALSE(
4217
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4218
    EXPECT_TRUE(
4219
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4220
                             true, {"-std=c++20"}));
4221
  }
4222
  {
4223
    auto M = cxxRewrittenBinaryOperator(
4224
        hasLHS(expr(hasParent(cxxRewrittenBinaryOperator()))),
4225
        hasRHS(expr(hasParent(cxxRewrittenBinaryOperator()))));
4226
    EXPECT_FALSE(
4227
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4228
    EXPECT_TRUE(
4229
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4230
                             true, {"-std=c++20"}));
4231
  }
4232
  {
4233
    EXPECT_TRUE(matchesConditionally(
4234
        Code,
4235
        traverse(TK_AsIs,
4236
                 cxxRewrittenBinaryOperator(
4237
                     hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4238
                     isComparisonOperator(),
4239
                     hasLHS(ignoringImplicit(
4240
                         declRefExpr(to(varDecl(hasName("s1")))))),
4241
                     hasRHS(ignoringImplicit(
4242
                         declRefExpr(to(varDecl(hasName("s2")))))),
4243
                     hasEitherOperand(ignoringImplicit(
4244
                         declRefExpr(to(varDecl(hasName("s2")))))),
4245
                     hasOperands(ignoringImplicit(
4246
                                     declRefExpr(to(varDecl(hasName("s1"))))),
4247
                                 ignoringImplicit(declRefExpr(
4248
                                     to(varDecl(hasName("s2")))))))),
4249
        true, {"-std=c++20"}));
4250
    EXPECT_TRUE(matchesConditionally(
4251
        Code,
4252
        traverse(TK_IgnoreUnlessSpelledInSource,
4253
                 cxxRewrittenBinaryOperator(
4254
                     hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4255
                     isComparisonOperator(),
4256
                     hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
4257
                     hasRHS(declRefExpr(to(varDecl(hasName("s2"))))),
4258
                     hasEitherOperand(declRefExpr(to(varDecl(hasName("s2"))))),
4259
                     hasOperands(declRefExpr(to(varDecl(hasName("s1")))),
4260
                                 declRefExpr(to(varDecl(hasName("s2"))))))),
4261
        true, {"-std=c++20"}));
4262
  }
4263

4264
  Code = R"cpp(
4265
namespace std {
4266
struct strong_ordering {
4267
  int n;
4268
  constexpr operator int() const { return n; }
4269
  static const strong_ordering equal, greater, less;
4270
};
4271
constexpr strong_ordering strong_ordering::equal = {0};
4272
constexpr strong_ordering strong_ordering::greater = {1};
4273
constexpr strong_ordering strong_ordering::less = {-1};
4274
}
4275

4276
struct HasSpaceshipMem {
4277
  int a;
4278
  constexpr auto operator<=>(const HasSpaceshipMem&) const = default;
4279
};
4280

4281
void binop()
4282
{
4283
    HasSpaceshipMem hs1, hs2;
4284
    if (hs1 == hs2)
4285
        return;
4286

4287
    HasSpaceshipMem hs3, hs4;
4288
    if (hs3 != hs4)
4289
        return;
4290

4291
    HasSpaceshipMem hs5, hs6;
4292
    if (hs5 < hs6)
4293
        return;
4294

4295
    HasSpaceshipMem hs7, hs8;
4296
    if (hs7 > hs8)
4297
        return;
4298

4299
    HasSpaceshipMem hs9, hs10;
4300
    if (hs9 <= hs10)
4301
        return;
4302

4303
    HasSpaceshipMem hs11, hs12;
4304
    if (hs11 >= hs12)
4305
        return;
4306
}
4307
)cpp";
4308
  auto withArgs = [](StringRef lName, StringRef rName) {
4309
    return cxxOperatorCallExpr(
4310
        hasArgument(0, declRefExpr(to(varDecl(hasName(lName))))),
4311
        hasArgument(1, declRefExpr(to(varDecl(hasName(rName))))));
4312
  };
4313
  {
4314
    auto M = ifStmt(hasCondition(cxxOperatorCallExpr(
4315
        hasOverloadedOperatorName("=="), withArgs("hs1", "hs2"))));
4316
    EXPECT_TRUE(
4317
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4318
    EXPECT_TRUE(
4319
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4320
                             true, {"-std=c++20"}));
4321
  }
4322
  {
4323
    auto M =
4324
        unaryOperator(hasOperatorName("!"),
4325
                      has(cxxOperatorCallExpr(hasOverloadedOperatorName("=="),
4326
                                              withArgs("hs3", "hs4"))));
4327
    EXPECT_TRUE(
4328
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4329
    EXPECT_FALSE(
4330
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4331
                             true, {"-std=c++20"}));
4332
  }
4333
  {
4334
    auto M =
4335
        unaryOperator(hasOperatorName("!"),
4336
                      has(cxxOperatorCallExpr(hasOverloadedOperatorName("=="),
4337
                                              withArgs("hs3", "hs4"))));
4338
    EXPECT_TRUE(
4339
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4340
    EXPECT_FALSE(
4341
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4342
                             true, {"-std=c++20"}));
4343
  }
4344
  {
4345
    auto M = binaryOperator(
4346
        hasOperatorName("<"),
4347
        hasLHS(hasDescendant(cxxOperatorCallExpr(
4348
            hasOverloadedOperatorName("<=>"), withArgs("hs5", "hs6")))),
4349
        hasRHS(integerLiteral(equals(0))));
4350
    EXPECT_TRUE(
4351
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4352
    EXPECT_FALSE(
4353
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4354
                             true, {"-std=c++20"}));
4355
  }
4356
  {
4357
    auto M = cxxRewrittenBinaryOperator(withDescendants("hs3", "hs4"));
4358
    EXPECT_TRUE(
4359
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4360
    EXPECT_TRUE(
4361
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4362
                             true, {"-std=c++20"}));
4363
  }
4364
  {
4365
    auto M = declRefExpr(to(varDecl(hasName("hs3"))));
4366
    EXPECT_TRUE(
4367
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4368
    EXPECT_TRUE(
4369
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4370
                             true, {"-std=c++20"}));
4371
  }
4372
  {
4373
    auto M = cxxRewrittenBinaryOperator(has(
4374
        unaryOperator(hasOperatorName("!"), withDescendants("hs3", "hs4"))));
4375
    EXPECT_TRUE(
4376
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4377
    EXPECT_FALSE(
4378
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4379
                             true, {"-std=c++20"}));
4380
  }
4381
  {
4382
    auto M = cxxRewrittenBinaryOperator(
4383
        has(declRefExpr(to(varDecl(hasName("hs3"))))),
4384
        has(declRefExpr(to(varDecl(hasName("hs4"))))));
4385
    EXPECT_FALSE(
4386
        matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4387
    EXPECT_TRUE(
4388
        matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4389
                             true, {"-std=c++20"}));
4390
  }
4391
  {
4392
    EXPECT_TRUE(matchesConditionally(
4393
        Code,
4394
        traverse(TK_AsIs,
4395
                 cxxRewrittenBinaryOperator(
4396
                     hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4397
                     isComparisonOperator(),
4398
                     hasLHS(ignoringImplicit(
4399
                         declRefExpr(to(varDecl(hasName("hs3")))))),
4400
                     hasRHS(ignoringImplicit(
4401
                         declRefExpr(to(varDecl(hasName("hs4")))))),
4402
                     hasEitherOperand(ignoringImplicit(
4403
                         declRefExpr(to(varDecl(hasName("hs3")))))),
4404
                     hasOperands(ignoringImplicit(
4405
                                     declRefExpr(to(varDecl(hasName("hs3"))))),
4406
                                 ignoringImplicit(declRefExpr(
4407
                                     to(varDecl(hasName("hs4")))))))),
4408
        true, {"-std=c++20"}));
4409
    EXPECT_TRUE(matchesConditionally(
4410
        Code,
4411
        traverse(TK_IgnoreUnlessSpelledInSource,
4412
                 cxxRewrittenBinaryOperator(
4413
                     hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4414
                     isComparisonOperator(),
4415
                     hasLHS(declRefExpr(to(varDecl(hasName("hs3"))))),
4416
                     hasRHS(declRefExpr(to(varDecl(hasName("hs4"))))),
4417
                     hasEitherOperand(declRefExpr(to(varDecl(hasName("hs3"))))),
4418
                     hasOperands(declRefExpr(to(varDecl(hasName("hs3")))),
4419
                                 declRefExpr(to(varDecl(hasName("hs4"))))))),
4420
        true, {"-std=c++20"}));
4421
  }
4422
  {
4423
    EXPECT_TRUE(matchesConditionally(
4424
        Code,
4425
        traverse(TK_AsIs,
4426
                 cxxRewrittenBinaryOperator(
4427
                     hasOperatorName("<"), hasAnyOperatorName("<", "!="),
4428
                     isComparisonOperator(),
4429
                     hasLHS(ignoringImplicit(
4430
                         declRefExpr(to(varDecl(hasName("hs5")))))),
4431
                     hasRHS(ignoringImplicit(
4432
                         declRefExpr(to(varDecl(hasName("hs6")))))),
4433
                     hasEitherOperand(ignoringImplicit(
4434
                         declRefExpr(to(varDecl(hasName("hs5")))))),
4435
                     hasOperands(ignoringImplicit(
4436
                                     declRefExpr(to(varDecl(hasName("hs5"))))),
4437
                                 ignoringImplicit(declRefExpr(
4438
                                     to(varDecl(hasName("hs6")))))))),
4439
        true, {"-std=c++20"}));
4440
    EXPECT_TRUE(matchesConditionally(
4441
        Code,
4442
        traverse(TK_IgnoreUnlessSpelledInSource,
4443
                 cxxRewrittenBinaryOperator(
4444
                     hasOperatorName("<"), hasAnyOperatorName("<", "!="),
4445
                     isComparisonOperator(),
4446
                     hasLHS(declRefExpr(to(varDecl(hasName("hs5"))))),
4447
                     hasRHS(declRefExpr(to(varDecl(hasName("hs6"))))),
4448
                     hasEitherOperand(declRefExpr(to(varDecl(hasName("hs5"))))),
4449
                     hasOperands(declRefExpr(to(varDecl(hasName("hs5")))),
4450
                                 declRefExpr(to(varDecl(hasName("hs6"))))))),
4451
        true, {"-std=c++20"}));
4452
  }
4453
  {
4454
    EXPECT_TRUE(matchesConditionally(
4455
        Code,
4456
        traverse(TK_AsIs,
4457
                 cxxRewrittenBinaryOperator(
4458
                     hasOperatorName(">"), hasAnyOperatorName("<", ">"),
4459
                     isComparisonOperator(),
4460
                     hasLHS(ignoringImplicit(
4461
                         declRefExpr(to(varDecl(hasName("hs7")))))),
4462
                     hasRHS(ignoringImplicit(
4463
                         declRefExpr(to(varDecl(hasName("hs8")))))),
4464
                     hasEitherOperand(ignoringImplicit(
4465
                         declRefExpr(to(varDecl(hasName("hs7")))))),
4466
                     hasOperands(ignoringImplicit(
4467
                                     declRefExpr(to(varDecl(hasName("hs7"))))),
4468
                                 ignoringImplicit(declRefExpr(
4469
                                     to(varDecl(hasName("hs8")))))))),
4470
        true, {"-std=c++20"}));
4471
    EXPECT_TRUE(matchesConditionally(
4472
        Code,
4473
        traverse(TK_IgnoreUnlessSpelledInSource,
4474
                 cxxRewrittenBinaryOperator(
4475
                     hasOperatorName(">"), hasAnyOperatorName("<", ">"),
4476
                     isComparisonOperator(),
4477
                     hasLHS(declRefExpr(to(varDecl(hasName("hs7"))))),
4478
                     hasRHS(declRefExpr(to(varDecl(hasName("hs8"))))),
4479
                     hasEitherOperand(declRefExpr(to(varDecl(hasName("hs7"))))),
4480
                     hasOperands(declRefExpr(to(varDecl(hasName("hs7")))),
4481
                                 declRefExpr(to(varDecl(hasName("hs8"))))))),
4482
        true, {"-std=c++20"}));
4483
  }
4484
  {
4485
    EXPECT_TRUE(matchesConditionally(
4486
        Code,
4487
        traverse(TK_AsIs,
4488
                 cxxRewrittenBinaryOperator(
4489
                     hasOperatorName("<="), hasAnyOperatorName("<", "<="),
4490
                     isComparisonOperator(),
4491
                     hasLHS(ignoringImplicit(
4492
                         declRefExpr(to(varDecl(hasName("hs9")))))),
4493
                     hasRHS(ignoringImplicit(
4494
                         declRefExpr(to(varDecl(hasName("hs10")))))),
4495
                     hasEitherOperand(ignoringImplicit(
4496
                         declRefExpr(to(varDecl(hasName("hs9")))))),
4497
                     hasOperands(ignoringImplicit(
4498
                                     declRefExpr(to(varDecl(hasName("hs9"))))),
4499
                                 ignoringImplicit(declRefExpr(
4500
                                     to(varDecl(hasName("hs10")))))))),
4501
        true, {"-std=c++20"}));
4502
    EXPECT_TRUE(matchesConditionally(
4503
        Code,
4504
        traverse(TK_IgnoreUnlessSpelledInSource,
4505
                 cxxRewrittenBinaryOperator(
4506
                     hasOperatorName("<="), hasAnyOperatorName("<", "<="),
4507
                     isComparisonOperator(),
4508
                     hasLHS(declRefExpr(to(varDecl(hasName("hs9"))))),
4509
                     hasRHS(declRefExpr(to(varDecl(hasName("hs10"))))),
4510
                     hasEitherOperand(declRefExpr(to(varDecl(hasName("hs9"))))),
4511
                     hasOperands(declRefExpr(to(varDecl(hasName("hs9")))),
4512
                                 declRefExpr(to(varDecl(hasName("hs10"))))))),
4513
        true, {"-std=c++20"}));
4514
  }
4515
  {
4516
    EXPECT_TRUE(matchesConditionally(
4517
        Code,
4518
        traverse(TK_AsIs,
4519
                 cxxRewrittenBinaryOperator(
4520
                     hasOperatorName(">="), hasAnyOperatorName("<", ">="),
4521
                     isComparisonOperator(),
4522
                     hasLHS(ignoringImplicit(
4523
                         declRefExpr(to(varDecl(hasName("hs11")))))),
4524
                     hasRHS(ignoringImplicit(
4525
                         declRefExpr(to(varDecl(hasName("hs12")))))),
4526
                     hasEitherOperand(ignoringImplicit(
4527
                         declRefExpr(to(varDecl(hasName("hs11")))))),
4528
                     hasOperands(ignoringImplicit(
4529
                                     declRefExpr(to(varDecl(hasName("hs11"))))),
4530
                                 ignoringImplicit(declRefExpr(
4531
                                     to(varDecl(hasName("hs12")))))))),
4532
        true, {"-std=c++20"}));
4533
    EXPECT_TRUE(matchesConditionally(
4534
        Code,
4535
        traverse(
4536
            TK_IgnoreUnlessSpelledInSource,
4537
            cxxRewrittenBinaryOperator(
4538
                hasOperatorName(">="), hasAnyOperatorName("<", ">="),
4539
                isComparisonOperator(),
4540
                hasLHS(declRefExpr(to(varDecl(hasName("hs11"))))),
4541
                hasRHS(declRefExpr(to(varDecl(hasName("hs12"))))),
4542
                hasEitherOperand(declRefExpr(to(varDecl(hasName("hs11"))))),
4543
                hasOperands(declRefExpr(to(varDecl(hasName("hs11")))),
4544
                            declRefExpr(to(varDecl(hasName("hs12"))))))),
4545
        true, {"-std=c++20"}));
4546
  }
4547

4548
  Code = R"cpp(
4549
struct S {};
4550

4551
struct HasOpEq
4552
{
4553
    bool operator==(const S& other) const
4554
    {
4555
        return true;
4556
    }
4557
};
4558

4559
struct HasOpEqMem {
4560
  bool operator==(const HasOpEqMem&) const { return true; }
4561
};
4562

4563
struct HasOpEqFree {
4564
};
4565
bool operator==(const HasOpEqFree&, const HasOpEqFree&) { return true; }
4566

4567
void binop()
4568
{
4569
    {
4570
    HasOpEq s1;
4571
    S s2;
4572
    if (s1 != s2)
4573
        return;
4574
    }
4575

4576
    {
4577
      int i1;
4578
      int i2;
4579
      if (i1 != i2)
4580
          return;
4581
    }
4582

4583
    {
4584
      HasOpEqMem M1;
4585
      HasOpEqMem M2;
4586
      if (M1 == M2)
4587
          return;
4588
    }
4589

4590
    {
4591
      HasOpEqFree F1;
4592
      HasOpEqFree F2;
4593
      if (F1 == F2)
4594
          return;
4595
    }
4596
}
4597
)cpp";
4598
  {
4599
    EXPECT_TRUE(matchesConditionally(
4600
        Code,
4601
        traverse(TK_AsIs,
4602
                 binaryOperation(
4603
                     hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4604
                     isComparisonOperator(),
4605
                     hasLHS(ignoringImplicit(
4606
                         declRefExpr(to(varDecl(hasName("s1")))))),
4607
                     hasRHS(ignoringImplicit(
4608
                         declRefExpr(to(varDecl(hasName("s2")))))),
4609
                     hasEitherOperand(ignoringImplicit(
4610
                         declRefExpr(to(varDecl(hasName("s2")))))),
4611
                     hasOperands(ignoringImplicit(
4612
                                     declRefExpr(to(varDecl(hasName("s1"))))),
4613
                                 ignoringImplicit(declRefExpr(
4614
                                     to(varDecl(hasName("s2")))))))),
4615
        true, {"-std=c++20"}));
4616
    EXPECT_TRUE(matchesConditionally(
4617
        Code,
4618
        traverse(TK_AsIs, binaryOperation(hasOperatorName("!="),
4619
                                          hasLHS(ignoringImplicit(declRefExpr(
4620
                                              to(varDecl(hasName("i1")))))),
4621
                                          hasRHS(ignoringImplicit(declRefExpr(
4622
                                              to(varDecl(hasName("i2")))))))),
4623
        true, {"-std=c++20"}));
4624
    EXPECT_TRUE(matchesConditionally(
4625
        Code,
4626
        traverse(TK_AsIs, binaryOperation(hasOperatorName("=="),
4627
                                          hasLHS(ignoringImplicit(declRefExpr(
4628
                                              to(varDecl(hasName("M1")))))),
4629
                                          hasRHS(ignoringImplicit(declRefExpr(
4630
                                              to(varDecl(hasName("M2")))))))),
4631
        true, {"-std=c++20"}));
4632
    EXPECT_TRUE(matchesConditionally(
4633
        Code,
4634
        traverse(TK_AsIs, binaryOperation(hasOperatorName("=="),
4635
                                          hasLHS(ignoringImplicit(declRefExpr(
4636
                                              to(varDecl(hasName("F1")))))),
4637
                                          hasRHS(ignoringImplicit(declRefExpr(
4638
                                              to(varDecl(hasName("F2")))))))),
4639
        true, {"-std=c++20"}));
4640
    EXPECT_TRUE(matchesConditionally(
4641
        Code,
4642
        traverse(TK_IgnoreUnlessSpelledInSource,
4643
                 binaryOperation(
4644
                     hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4645
                     isComparisonOperator(),
4646
                     hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
4647
                     hasRHS(declRefExpr(to(varDecl(hasName("s2"))))),
4648
                     hasEitherOperand(declRefExpr(to(varDecl(hasName("s2"))))),
4649
                     hasOperands(declRefExpr(to(varDecl(hasName("s1")))),
4650
                                 declRefExpr(to(varDecl(hasName("s2"))))))),
4651
        true, {"-std=c++20"}));
4652
    EXPECT_TRUE(matchesConditionally(
4653
        Code,
4654
        traverse(
4655
            TK_IgnoreUnlessSpelledInSource,
4656
            binaryOperation(hasOperatorName("!="),
4657
                            hasLHS(declRefExpr(to(varDecl(hasName("i1"))))),
4658
                            hasRHS(declRefExpr(to(varDecl(hasName("i2"))))))),
4659
        true, {"-std=c++20"}));
4660
    EXPECT_TRUE(matchesConditionally(
4661
        Code,
4662
        traverse(
4663
            TK_IgnoreUnlessSpelledInSource,
4664
            binaryOperation(hasOperatorName("=="),
4665
                            hasLHS(declRefExpr(to(varDecl(hasName("M1"))))),
4666
                            hasRHS(declRefExpr(to(varDecl(hasName("M2"))))))),
4667
        true, {"-std=c++20"}));
4668
    EXPECT_TRUE(matchesConditionally(
4669
        Code,
4670
        traverse(
4671
            TK_IgnoreUnlessSpelledInSource,
4672
            binaryOperation(hasOperatorName("=="),
4673
                            hasLHS(declRefExpr(to(varDecl(hasName("F1"))))),
4674
                            hasRHS(declRefExpr(to(varDecl(hasName("F2"))))))),
4675
        true, {"-std=c++20"}));
4676
  }
4677
}
4678

4679
TEST(IgnoringImpCasts, PathologicalLambda) {
4680

4681
  // Test that deeply nested lambdas are not a performance penalty
4682
  StringRef Code = R"cpp(
4683
void f() {
4684
  [] {
4685
  [] {
4686
  [] {
4687
  [] {
4688
  [] {
4689
  [] {
4690
  [] {
4691
  [] {
4692
  [] {
4693
  [] {
4694
  [] {
4695
  [] {
4696
  [] {
4697
  [] {
4698
  [] {
4699
  [] {
4700
  [] {
4701
  [] {
4702
  [] {
4703
  [] {
4704
  [] {
4705
  [] {
4706
  [] {
4707
  [] {
4708
  [] {
4709
  [] {
4710
  [] {
4711
  [] {
4712
  [] {
4713
    int i = 42;
4714
    (void)i;
4715
  }();
4716
  }();
4717
  }();
4718
  }();
4719
  }();
4720
  }();
4721
  }();
4722
  }();
4723
  }();
4724
  }();
4725
  }();
4726
  }();
4727
  }();
4728
  }();
4729
  }();
4730
  }();
4731
  }();
4732
  }();
4733
  }();
4734
  }();
4735
  }();
4736
  }();
4737
  }();
4738
  }();
4739
  }();
4740
  }();
4741
  }();
4742
  }();
4743
  }();
4744
}
4745
  )cpp";
4746

4747
  EXPECT_TRUE(matches(Code, integerLiteral(equals(42))));
4748
  EXPECT_TRUE(matches(Code, functionDecl(hasDescendant(integerLiteral(equals(42))))));
4749
}
4750

4751
TEST(IgnoringImpCasts, MatchesImpCasts) {
4752
  // This test checks that ignoringImpCasts matches when implicit casts are
4753
  // present and its inner matcher alone does not match.
4754
  // Note that this test creates an implicit const cast.
4755
  EXPECT_TRUE(matches("int x = 0; const int y = x;",
4756
                      varDecl(hasInitializer(ignoringImpCasts(
4757
                        declRefExpr(to(varDecl(hasName("x")))))))));
4758
  // This test creates an implict cast from int to char.
4759
  EXPECT_TRUE(matches("char x = 0;",
4760
                      varDecl(hasInitializer(ignoringImpCasts(
4761
                        integerLiteral(equals(0)))))));
4762
}
4763

4764
TEST(IgnoringImpCasts, DoesNotMatchIncorrectly) {
4765
  // These tests verify that ignoringImpCasts does not match if the inner
4766
  // matcher does not match.
4767
  // Note that the first test creates an implicit const cast.
4768
  EXPECT_TRUE(notMatches("int x; const int y = x;",
4769
                         varDecl(hasInitializer(ignoringImpCasts(
4770
                           unless(anything()))))));
4771
  EXPECT_TRUE(notMatches("int x; int y = x;",
4772
                         varDecl(hasInitializer(ignoringImpCasts(
4773
                           unless(anything()))))));
4774

4775
  // These tests verify that ignoringImplictCasts does not look through explicit
4776
  // casts or parentheses.
4777
  EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
4778
                         varDecl(hasInitializer(ignoringImpCasts(
4779
                           integerLiteral())))));
4780
  EXPECT_TRUE(notMatches(
4781
      "int i = (0);",
4782
      traverse(TK_AsIs,
4783
               varDecl(hasInitializer(ignoringImpCasts(integerLiteral()))))));
4784
  EXPECT_TRUE(notMatches("float i = (float)0;",
4785
                         varDecl(hasInitializer(ignoringImpCasts(
4786
                           integerLiteral())))));
4787
  EXPECT_TRUE(notMatches("float i = float(0);",
4788
                         varDecl(hasInitializer(ignoringImpCasts(
4789
                           integerLiteral())))));
4790
}
4791

4792
TEST(IgnoringImpCasts, MatchesWithoutImpCasts) {
4793
  // This test verifies that expressions that do not have implicit casts
4794
  // still match the inner matcher.
4795
  EXPECT_TRUE(matches("int x = 0; int &y = x;",
4796
                      varDecl(hasInitializer(ignoringImpCasts(
4797
                        declRefExpr(to(varDecl(hasName("x")))))))));
4798
}
4799

4800
TEST(IgnoringParenCasts, MatchesParenCasts) {
4801
  // This test checks that ignoringParenCasts matches when parentheses and/or
4802
  // casts are present and its inner matcher alone does not match.
4803
  EXPECT_TRUE(matches("int x = (0);",
4804
                      varDecl(hasInitializer(ignoringParenCasts(
4805
                        integerLiteral(equals(0)))))));
4806
  EXPECT_TRUE(matches("int x = (((((0)))));",
4807
                      varDecl(hasInitializer(ignoringParenCasts(
4808
                        integerLiteral(equals(0)))))));
4809

4810
  // This test creates an implict cast from int to char in addition to the
4811
  // parentheses.
4812
  EXPECT_TRUE(matches("char x = (0);",
4813
                      varDecl(hasInitializer(ignoringParenCasts(
4814
                        integerLiteral(equals(0)))))));
4815

4816
  EXPECT_TRUE(matches("char x = (char)0;",
4817
                      varDecl(hasInitializer(ignoringParenCasts(
4818
                        integerLiteral(equals(0)))))));
4819
  EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
4820
                      varDecl(hasInitializer(ignoringParenCasts(
4821
                        integerLiteral(equals(0)))))));
4822
}
4823

4824
TEST(IgnoringParenCasts, MatchesWithoutParenCasts) {
4825
  // This test verifies that expressions that do not have any casts still match.
4826
  EXPECT_TRUE(matches("int x = 0;",
4827
                      varDecl(hasInitializer(ignoringParenCasts(
4828
                        integerLiteral(equals(0)))))));
4829
}
4830

4831
TEST(IgnoringParenCasts, DoesNotMatchIncorrectly) {
4832
  // These tests verify that ignoringImpCasts does not match if the inner
4833
  // matcher does not match.
4834
  EXPECT_TRUE(notMatches("int x = ((0));",
4835
                         varDecl(hasInitializer(ignoringParenCasts(
4836
                           unless(anything()))))));
4837

4838
  // This test creates an implicit cast from int to char in addition to the
4839
  // parentheses.
4840
  EXPECT_TRUE(notMatches("char x = ((0));",
4841
                         varDecl(hasInitializer(ignoringParenCasts(
4842
                           unless(anything()))))));
4843

4844
  EXPECT_TRUE(notMatches("char *x = static_cast<char *>((0));",
4845
                         varDecl(hasInitializer(ignoringParenCasts(
4846
                           unless(anything()))))));
4847
}
4848

4849
TEST(IgnoringParenAndImpCasts, MatchesParenImpCasts) {
4850
  // This test checks that ignoringParenAndImpCasts matches when
4851
  // parentheses and/or implicit casts are present and its inner matcher alone
4852
  // does not match.
4853
  // Note that this test creates an implicit const cast.
4854
  EXPECT_TRUE(matches("int x = 0; const int y = x;",
4855
                      varDecl(hasInitializer(ignoringParenImpCasts(
4856
                        declRefExpr(to(varDecl(hasName("x")))))))));
4857
  // This test creates an implicit cast from int to char.
4858
  EXPECT_TRUE(matches("const char x = (0);",
4859
                      varDecl(hasInitializer(ignoringParenImpCasts(
4860
                        integerLiteral(equals(0)))))));
4861
}
4862

4863
TEST(IgnoringParenAndImpCasts, MatchesWithoutParenImpCasts) {
4864
  // This test verifies that expressions that do not have parentheses or
4865
  // implicit casts still match.
4866
  EXPECT_TRUE(matches("int x = 0; int &y = x;",
4867
                      varDecl(hasInitializer(ignoringParenImpCasts(
4868
                        declRefExpr(to(varDecl(hasName("x")))))))));
4869
  EXPECT_TRUE(matches("int x = 0;",
4870
                      varDecl(hasInitializer(ignoringParenImpCasts(
4871
                        integerLiteral(equals(0)))))));
4872
}
4873

4874
TEST(IgnoringParenAndImpCasts, DoesNotMatchIncorrectly) {
4875
  // These tests verify that ignoringParenImpCasts does not match if
4876
  // the inner matcher does not match.
4877
  // This test creates an implicit cast.
4878
  EXPECT_TRUE(notMatches("char c = ((3));",
4879
                         varDecl(hasInitializer(ignoringParenImpCasts(
4880
                           unless(anything()))))));
4881
  // These tests verify that ignoringParenAndImplictCasts does not look
4882
  // through explicit casts.
4883
  EXPECT_TRUE(notMatches("float y = (float(0));",
4884
                         varDecl(hasInitializer(ignoringParenImpCasts(
4885
                           integerLiteral())))));
4886
  EXPECT_TRUE(notMatches("float y = (float)0;",
4887
                         varDecl(hasInitializer(ignoringParenImpCasts(
4888
                           integerLiteral())))));
4889
  EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
4890
                         varDecl(hasInitializer(ignoringParenImpCasts(
4891
                           integerLiteral())))));
4892
}
4893

4894
TEST(HasSourceExpression, MatchesImplicitCasts) {
4895
  EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
4896
                      "void r() {string a_string; URL url = a_string; }",
4897
                      traverse(TK_AsIs, implicitCastExpr(hasSourceExpression(
4898
                                            cxxConstructExpr())))));
4899
}
4900

4901
TEST(HasSourceExpression, MatchesExplicitCasts) {
4902
  EXPECT_TRUE(
4903
      matches("float x = static_cast<float>(42);",
4904
              traverse(TK_AsIs, explicitCastExpr(hasSourceExpression(
4905
                                    hasDescendant(expr(integerLiteral())))))));
4906
}
4907

4908
TEST(UsingDeclaration, MatchesSpecificTarget) {
4909
  EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
4910
                      usingDecl(hasAnyUsingShadowDecl(
4911
                        hasTargetDecl(functionDecl())))));
4912
  EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
4913
                         usingDecl(hasAnyUsingShadowDecl(
4914
                           hasTargetDecl(functionDecl())))));
4915
}
4916

4917
TEST(UsingDeclaration, ThroughUsingDeclaration) {
4918
  EXPECT_TRUE(matches(
4919
    "namespace a { void f(); } using a::f; void g() { f(); }",
4920
    declRefExpr(throughUsingDecl(anything()))));
4921
  EXPECT_TRUE(notMatches(
4922
    "namespace a { void f(); } using a::f; void g() { a::f(); }",
4923
    declRefExpr(throughUsingDecl(anything()))));
4924
}
4925

4926
TEST(SingleDecl, IsSingleDecl) {
4927
  StatementMatcher SingleDeclStmt =
4928
    declStmt(hasSingleDecl(varDecl(hasInitializer(anything()))));
4929
  EXPECT_TRUE(matches("void f() {int a = 4;}", SingleDeclStmt));
4930
  EXPECT_TRUE(notMatches("void f() {int a;}", SingleDeclStmt));
4931
  EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
4932
                         SingleDeclStmt));
4933
}
4934

4935
TEST(DeclStmt, ContainsDeclaration) {
4936
  DeclarationMatcher MatchesInit = varDecl(hasInitializer(anything()));
4937

4938
  EXPECT_TRUE(matches("void f() {int a = 4;}",
4939
                      declStmt(containsDeclaration(0, MatchesInit))));
4940
  EXPECT_TRUE(matches("void f() {int a = 4, b = 3;}",
4941
                      declStmt(containsDeclaration(0, MatchesInit),
4942
                               containsDeclaration(1, MatchesInit))));
4943
  unsigned WrongIndex = 42;
4944
  EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
4945
                         declStmt(containsDeclaration(WrongIndex,
4946
                                                      MatchesInit))));
4947
}
4948

4949
TEST(SwitchCase, MatchesEachCase) {
4950
  EXPECT_TRUE(notMatches("void x() { switch(42); }",
4951
                         switchStmt(forEachSwitchCase(caseStmt()))));
4952
  EXPECT_TRUE(matches("void x() { switch(42) case 42:; }",
4953
                      switchStmt(forEachSwitchCase(caseStmt()))));
4954
  EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }",
4955
                      switchStmt(forEachSwitchCase(caseStmt()))));
4956
  EXPECT_TRUE(notMatches(
4957
    "void x() { if (1) switch(42) { case 42: switch (42) { default:; } } }",
4958
    ifStmt(has(switchStmt(forEachSwitchCase(defaultStmt()))))));
4959
  EXPECT_TRUE(matches(
4960
      "void x() { switch(42) { case 1+1: case 4:; } }",
4961
      traverse(TK_AsIs, switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant(
4962
                            constantExpr(has(integerLiteral())))))))));
4963
  EXPECT_TRUE(notMatches(
4964
      "void x() { switch(42) { case 1+1: case 2+2:; } }",
4965
      traverse(TK_AsIs, switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant(
4966
                            constantExpr(has(integerLiteral())))))))));
4967
  EXPECT_TRUE(notMatches(
4968
      "void x() { switch(42) { case 1 ... 2:; } }",
4969
      traverse(TK_AsIs, switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant(
4970
                            constantExpr(has(integerLiteral())))))))));
4971
  EXPECT_TRUE(matchAndVerifyResultTrue(
4972
    "void x() { switch (42) { case 1: case 2: case 3: default:; } }",
4973
    switchStmt(forEachSwitchCase(caseStmt().bind("x"))),
4974
    std::make_unique<VerifyIdIsBoundTo<CaseStmt>>("x", 3)));
4975
}
4976

4977
TEST(Declaration, HasExplicitSpecifier) {
4978

4979
  EXPECT_TRUE(notMatches("void f();",
4980
                         functionDecl(hasExplicitSpecifier(constantExpr())),
4981
                         langCxx20OrLater()));
4982
  EXPECT_TRUE(
4983
      notMatches("template<bool b> struct S { explicit operator int(); };",
4984
                 cxxConversionDecl(
4985
                     hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
4986
                 langCxx20OrLater()));
4987
  EXPECT_TRUE(
4988
      notMatches("template<bool b> struct S { explicit(b) operator int(); };",
4989
                 cxxConversionDecl(
4990
                     hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
4991
                 langCxx20OrLater()));
4992
  EXPECT_TRUE(
4993
      matches("struct S { explicit(true) operator int(); };",
4994
              traverse(TK_AsIs, cxxConversionDecl(hasExplicitSpecifier(
4995
                                    constantExpr(has(cxxBoolLiteral()))))),
4996
              langCxx20OrLater()));
4997
  EXPECT_TRUE(
4998
      matches("struct S { explicit(false) operator int(); };",
4999
              traverse(TK_AsIs, cxxConversionDecl(hasExplicitSpecifier(
5000
                                    constantExpr(has(cxxBoolLiteral()))))),
5001
              langCxx20OrLater()));
5002
  EXPECT_TRUE(
5003
      notMatches("template<bool b> struct S { explicit(b) S(int); };",
5004
                 traverse(TK_AsIs, cxxConstructorDecl(hasExplicitSpecifier(
5005
                                       constantExpr(has(cxxBoolLiteral()))))),
5006
                 langCxx20OrLater()));
5007
  EXPECT_TRUE(
5008
      matches("struct S { explicit(true) S(int); };",
5009
              traverse(TK_AsIs, cxxConstructorDecl(hasExplicitSpecifier(
5010
                                    constantExpr(has(cxxBoolLiteral()))))),
5011
              langCxx20OrLater()));
5012
  EXPECT_TRUE(
5013
      matches("struct S { explicit(false) S(int); };",
5014
              traverse(TK_AsIs, cxxConstructorDecl(hasExplicitSpecifier(
5015
                                    constantExpr(has(cxxBoolLiteral()))))),
5016
              langCxx20OrLater()));
5017
  EXPECT_TRUE(
5018
      notMatches("template<typename T> struct S { S(int); };"
5019
                 "template<bool b = true> explicit(b) S(int) -> S<int>;",
5020
                 traverse(TK_AsIs, cxxDeductionGuideDecl(hasExplicitSpecifier(
5021
                                       constantExpr(has(cxxBoolLiteral()))))),
5022
                 langCxx20OrLater()));
5023
  EXPECT_TRUE(
5024
      matches("template<typename T> struct S { S(int); };"
5025
              "explicit(true) S(int) -> S<int>;",
5026
              traverse(TK_AsIs, cxxDeductionGuideDecl(hasExplicitSpecifier(
5027
                                    constantExpr(has(cxxBoolLiteral()))))),
5028
              langCxx20OrLater()));
5029
  EXPECT_TRUE(
5030
      matches("template<typename T> struct S { S(int); };"
5031
              "explicit(false) S(int) -> S<int>;",
5032
              traverse(TK_AsIs, cxxDeductionGuideDecl(hasExplicitSpecifier(
5033
                                    constantExpr(has(cxxBoolLiteral()))))),
5034
              langCxx20OrLater()));
5035
}
5036

5037
TEST(ForEachConstructorInitializer, MatchesInitializers) {
5038
  EXPECT_TRUE(matches(
5039
    "struct X { X() : i(42), j(42) {} int i, j; };",
5040
    cxxConstructorDecl(forEachConstructorInitializer(cxxCtorInitializer()))));
5041
}
5042

5043
TEST(ForEachLambdaCapture, MatchesCaptures) {
5044
  EXPECT_TRUE(matches(
5045
      "int main() { int x, y; auto f = [x, y]() { return x + y; }; }",
5046
      lambdaExpr(forEachLambdaCapture(lambdaCapture())), langCxx11OrLater()));
5047
  auto matcher = lambdaExpr(forEachLambdaCapture(
5048
      lambdaCapture(capturesVar(varDecl(hasType(isInteger())))).bind("LC")));
5049
  EXPECT_TRUE(matchAndVerifyResultTrue(
5050
      "int main() { int x, y; float z; auto f = [=]() { return x + y + z; }; }",
5051
      matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 2)));
5052
  EXPECT_TRUE(matchAndVerifyResultTrue(
5053
      "int main() { int x, y; float z; auto f = [x, y, z]() { return x + y + "
5054
      "z; }; }",
5055
      matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 2)));
5056
}
5057

5058
TEST(ForEachLambdaCapture, IgnoreUnlessSpelledInSource) {
5059
  auto matcher =
5060
      traverse(TK_IgnoreUnlessSpelledInSource,
5061
               lambdaExpr(forEachLambdaCapture(
5062
                   lambdaCapture(capturesVar(varDecl(hasType(isInteger()))))
5063
                       .bind("LC"))));
5064
  EXPECT_TRUE(
5065
      notMatches("int main() { int x, y; auto f = [=]() { return x + y; }; }",
5066
                 matcher, langCxx11OrLater()));
5067
  EXPECT_TRUE(
5068
      notMatches("int main() { int x, y; auto f = [&]() { return x + y; }; }",
5069
                 matcher, langCxx11OrLater()));
5070
  EXPECT_TRUE(matchAndVerifyResultTrue(
5071
      R"cc(
5072
      int main() {
5073
        int x, y;
5074
        float z;
5075
        auto f = [=, &y]() { return x + y + z; };
5076
      }
5077
      )cc",
5078
      matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 1)));
5079
}
5080

5081
TEST(ForEachLambdaCapture, MatchImplicitCapturesOnly) {
5082
  auto matcher =
5083
      lambdaExpr(forEachLambdaCapture(lambdaCapture(isImplicit()).bind("LC")));
5084
  EXPECT_TRUE(matchAndVerifyResultTrue(
5085
      "int main() { int x, y, z; auto f = [=, &z]() { return x + y + z; }; }",
5086
      matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 2)));
5087
  EXPECT_TRUE(matchAndVerifyResultTrue(
5088
      "int main() { int x, y, z; auto f = [&, z]() { return x + y + z; }; }",
5089
      matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 2)));
5090
}
5091

5092
TEST(ForEachLambdaCapture, MatchExplicitCapturesOnly) {
5093
  auto matcher = lambdaExpr(
5094
      forEachLambdaCapture(lambdaCapture(unless(isImplicit())).bind("LC")));
5095
  EXPECT_TRUE(matchAndVerifyResultTrue(
5096
      "int main() { int x, y, z; auto f = [=, &z]() { return x + y + z; }; }",
5097
      matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 1)));
5098
  EXPECT_TRUE(matchAndVerifyResultTrue(
5099
      "int main() { int x, y, z; auto f = [&, z]() { return x + y + z; }; }",
5100
      matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 1)));
5101
}
5102

5103
TEST(HasConditionVariableStatement, DoesNotMatchCondition) {
5104
  EXPECT_TRUE(notMatches(
5105
    "void x() { if(true) {} }",
5106
    ifStmt(hasConditionVariableStatement(declStmt()))));
5107
  EXPECT_TRUE(notMatches(
5108
    "void x() { int x; if((x = 42)) {} }",
5109
    ifStmt(hasConditionVariableStatement(declStmt()))));
5110
}
5111

5112
TEST(HasConditionVariableStatement, MatchesConditionVariables) {
5113
  EXPECT_TRUE(matches(
5114
    "void x() { if(int* a = 0) {} }",
5115
    ifStmt(hasConditionVariableStatement(declStmt()))));
5116
}
5117

5118
TEST(ForEach, BindsOneNode) {
5119
  EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
5120
                                       recordDecl(hasName("C"), forEach(fieldDecl(hasName("x")).bind("x"))),
5121
                                       std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("x", 1)));
5122
}
5123

5124
TEST(ForEach, BindsMultipleNodes) {
5125
  EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
5126
                                       recordDecl(hasName("C"), forEach(fieldDecl().bind("f"))),
5127
                                       std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 3)));
5128
}
5129

5130
TEST(ForEach, BindsRecursiveCombinations) {
5131
  EXPECT_TRUE(matchAndVerifyResultTrue(
5132
    "class C { class D { int x; int y; }; class E { int y; int z; }; };",
5133
    recordDecl(hasName("C"),
5134
               forEach(recordDecl(forEach(fieldDecl().bind("f"))))),
5135
    std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 4)));
5136
}
5137

5138
TEST(ForEach, DoesNotIgnoreImplicit) {
5139
  StringRef Code = R"cpp(
5140
void foo()
5141
{
5142
    int i = 0;
5143
    int b = 4;
5144
    i < b;
5145
}
5146
)cpp";
5147
  EXPECT_TRUE(matchAndVerifyResultFalse(
5148
      Code, binaryOperator(forEach(declRefExpr().bind("dre"))),
5149
      std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 0)));
5150

5151
  EXPECT_TRUE(matchAndVerifyResultTrue(
5152
      Code,
5153
      binaryOperator(forEach(
5154
          implicitCastExpr(hasSourceExpression(declRefExpr().bind("dre"))))),
5155
      std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 2)));
5156

5157
  EXPECT_TRUE(matchAndVerifyResultTrue(
5158
      Code,
5159
      binaryOperator(
5160
          forEach(expr(ignoringImplicit(declRefExpr().bind("dre"))))),
5161
      std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 2)));
5162

5163
  EXPECT_TRUE(matchAndVerifyResultTrue(
5164
      Code,
5165
      traverse(TK_IgnoreUnlessSpelledInSource,
5166
               binaryOperator(forEach(declRefExpr().bind("dre")))),
5167
      std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 2)));
5168
}
5169

5170
TEST(ForEachDescendant, BindsOneNode) {
5171
  EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
5172
                                       recordDecl(hasName("C"),
5173
                                                  forEachDescendant(fieldDecl(hasName("x")).bind("x"))),
5174
                                       std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("x", 1)));
5175
}
5176

5177
TEST(ForEachDescendant, NestedForEachDescendant) {
5178
  DeclarationMatcher m = recordDecl(
5179
    isDefinition(), decl().bind("x"), hasName("C"));
5180
  EXPECT_TRUE(matchAndVerifyResultTrue(
5181
    "class A { class B { class C {}; }; };",
5182
    recordDecl(hasName("A"), anyOf(m, forEachDescendant(m))),
5183
    std::make_unique<VerifyIdIsBoundTo<Decl>>("x", "C")));
5184

5185
  // Check that a partial match of 'm' that binds 'x' in the
5186
  // first part of anyOf(m, anything()) will not overwrite the
5187
  // binding created by the earlier binding in the hasDescendant.
5188
  EXPECT_TRUE(matchAndVerifyResultTrue(
5189
    "class A { class B { class C {}; }; };",
5190
    recordDecl(hasName("A"), allOf(hasDescendant(m), anyOf(m, anything()))),
5191
    std::make_unique<VerifyIdIsBoundTo<Decl>>("x", "C")));
5192
}
5193

5194
TEST(ForEachDescendant, BindsMultipleNodes) {
5195
  EXPECT_TRUE(matchAndVerifyResultTrue(
5196
    "class C { class D { int x; int y; }; "
5197
      "          class E { class F { int y; int z; }; }; };",
5198
    recordDecl(hasName("C"), forEachDescendant(fieldDecl().bind("f"))),
5199
    std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 4)));
5200
}
5201

5202
TEST(ForEachDescendant, BindsRecursiveCombinations) {
5203
  EXPECT_TRUE(matchAndVerifyResultTrue(
5204
    "class C { class D { "
5205
      "          class E { class F { class G { int y; int z; }; }; }; }; };",
5206
    recordDecl(hasName("C"), forEachDescendant(recordDecl(
5207
      forEachDescendant(fieldDecl().bind("f"))))),
5208
    std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 8)));
5209
}
5210

5211
TEST(ForEachDescendant, BindsCombinations) {
5212
  EXPECT_TRUE(matchAndVerifyResultTrue(
5213
    "void f() { if(true) {} if (true) {} while (true) {} if (true) {} while "
5214
      "(true) {} }",
5215
    compoundStmt(forEachDescendant(ifStmt().bind("if")),
5216
                 forEachDescendant(whileStmt().bind("while"))),
5217
    std::make_unique<VerifyIdIsBoundTo<IfStmt>>("if", 6)));
5218
}
5219

5220
TEST(ForEachTemplateArgument, OnFunctionDecl) {
5221
  const std::string Code = R"(
5222
template <typename T, typename U> void f(T, U) {}
5223
void test() {
5224
  int I = 1;
5225
  bool B = false;
5226
  f(I, B);
5227
})";
5228
  EXPECT_TRUE(matches(
5229
      Code, functionDecl(forEachTemplateArgument(refersToType(builtinType()))),
5230
      langCxx11OrLater()));
5231
  auto matcher =
5232
      functionDecl(forEachTemplateArgument(
5233
                       templateArgument(refersToType(builtinType().bind("BT")))
5234
                           .bind("TA")))
5235
          .bind("FN");
5236

5237
  EXPECT_TRUE(matchAndVerifyResultTrue(
5238
      Code, matcher,
5239
      std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("FN", 2)));
5240
  EXPECT_TRUE(matchAndVerifyResultTrue(
5241
      Code, matcher,
5242
      std::make_unique<VerifyIdIsBoundTo<TemplateArgument>>("TA", 2)));
5243
  EXPECT_TRUE(matchAndVerifyResultTrue(
5244
      Code, matcher,
5245
      std::make_unique<VerifyIdIsBoundTo<BuiltinType>>("BT", 2)));
5246
}
5247

5248
TEST(ForEachTemplateArgument, OnClassTemplateSpecialization) {
5249
  const std::string Code = R"(
5250
template <typename T, unsigned N, unsigned M>
5251
struct Matrix {};
5252

5253
static constexpr unsigned R = 2;
5254

5255
Matrix<int, R * 2, R * 4> M;
5256
)";
5257
  EXPECT_TRUE(matches(
5258
      Code, templateSpecializationType(forEachTemplateArgument(isExpr(expr()))),
5259
      langCxx11OrLater()));
5260
  auto matcher = templateSpecializationType(
5261
                     forEachTemplateArgument(
5262
                         templateArgument(isExpr(expr().bind("E"))).bind("TA")))
5263
                     .bind("TST");
5264

5265
  EXPECT_TRUE(matchAndVerifyResultTrue(
5266
      Code, matcher,
5267
      std::make_unique<VerifyIdIsBoundTo<TemplateSpecializationType>>("TST",
5268
                                                                      2)));
5269
  EXPECT_TRUE(matchAndVerifyResultTrue(
5270
      Code, matcher,
5271
      std::make_unique<VerifyIdIsBoundTo<TemplateArgument>>("TA", 2)));
5272
  EXPECT_TRUE(matchAndVerifyResultTrue(
5273
      Code, matcher, std::make_unique<VerifyIdIsBoundTo<Expr>>("E", 2)));
5274
}
5275

5276
TEST(Has, DoesNotDeleteBindings) {
5277
  EXPECT_TRUE(matchAndVerifyResultTrue(
5278
    "class X { int a; };", recordDecl(decl().bind("x"), has(fieldDecl())),
5279
    std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5280
}
5281

5282
TEST(TemplateArgumentLoc, Matches) {
5283
  EXPECT_TRUE(matchAndVerifyResultTrue(
5284
      R"cpp(
5285
        template <typename A, int B, template <typename> class C> class X {};
5286
        class A {};
5287
        const int B = 42;
5288
        template <typename> class C {};
5289
        X<A, B, C> x;
5290
      )cpp",
5291
      templateArgumentLoc().bind("x"),
5292
      std::make_unique<VerifyIdIsBoundTo<TemplateArgumentLoc>>("x", 3)));
5293
}
5294

5295
TEST(LoopingMatchers, DoNotOverwritePreviousMatchResultOnFailure) {
5296
  // Those matchers cover all the cases where an inner matcher is called
5297
  // and there is not a 1:1 relationship between the match of the outer
5298
  // matcher and the match of the inner matcher.
5299
  // The pattern to look for is:
5300
  //   ... return InnerMatcher.matches(...); ...
5301
  // In which case no special handling is needed.
5302
  //
5303
  // On the other hand, if there are multiple alternative matches
5304
  // (for example forEach*) or matches might be discarded (for example has*)
5305
  // the implementation must make sure that the discarded matches do not
5306
  // affect the bindings.
5307
  // When new such matchers are added, add a test here that:
5308
  // - matches a simple node, and binds it as the first thing in the matcher:
5309
  //     recordDecl(decl().bind("x"), hasName("X")))
5310
  // - uses the matcher under test afterwards in a way that not the first
5311
  //   alternative is matched; for anyOf, that means the first branch
5312
  //   would need to return false; for hasAncestor, it means that not
5313
  //   the direct parent matches the inner matcher.
5314

5315
  EXPECT_TRUE(matchAndVerifyResultTrue(
5316
    "class X { int y; };",
5317
    recordDecl(
5318
      recordDecl().bind("x"), hasName("::X"),
5319
      anyOf(forEachDescendant(recordDecl(hasName("Y"))), anything())),
5320
    std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("x", 1)));
5321
  EXPECT_TRUE(matchAndVerifyResultTrue(
5322
    "class X {};", recordDecl(recordDecl().bind("x"), hasName("::X"),
5323
                              anyOf(unless(anything()), anything())),
5324
    std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("x", 1)));
5325
  EXPECT_TRUE(matchAndVerifyResultTrue(
5326
    "template<typename T1, typename T2> class X {}; X<float, int> x;",
5327
    classTemplateSpecializationDecl(
5328
      decl().bind("x"),
5329
      hasAnyTemplateArgument(refersToType(asString("int")))),
5330
    std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5331
  EXPECT_TRUE(matchAndVerifyResultTrue(
5332
    "class X { void f(); void g(); };",
5333
    cxxRecordDecl(decl().bind("x"), hasMethod(hasName("g"))),
5334
    std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5335
  EXPECT_TRUE(matchAndVerifyResultTrue(
5336
    "class X { X() : a(1), b(2) {} double a; int b; };",
5337
    recordDecl(decl().bind("x"),
5338
               has(cxxConstructorDecl(
5339
                 hasAnyConstructorInitializer(forField(hasName("b")))))),
5340
    std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5341
  EXPECT_TRUE(matchAndVerifyResultTrue(
5342
    "void x(int, int) { x(0, 42); }",
5343
    callExpr(expr().bind("x"), hasAnyArgument(integerLiteral(equals(42)))),
5344
    std::make_unique<VerifyIdIsBoundTo<Expr>>("x", 1)));
5345
  EXPECT_TRUE(matchAndVerifyResultTrue(
5346
    "void x(int, int y) {}",
5347
    functionDecl(decl().bind("x"), hasAnyParameter(hasName("y"))),
5348
    std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5349
  EXPECT_TRUE(matchAndVerifyResultTrue(
5350
    "void x() { return; if (true) {} }",
5351
    functionDecl(decl().bind("x"),
5352
                 has(compoundStmt(hasAnySubstatement(ifStmt())))),
5353
    std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5354
  EXPECT_TRUE(matchAndVerifyResultTrue(
5355
    "namespace X { void b(int); void b(); }"
5356
      "using X::b;",
5357
    usingDecl(decl().bind("x"), hasAnyUsingShadowDecl(hasTargetDecl(
5358
      functionDecl(parameterCountIs(1))))),
5359
    std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5360
  EXPECT_TRUE(matchAndVerifyResultTrue(
5361
    "class A{}; class B{}; class C : B, A {};",
5362
    cxxRecordDecl(decl().bind("x"), isDerivedFrom("::A")),
5363
    std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5364
  EXPECT_TRUE(matchAndVerifyResultTrue(
5365
    "class A{}; typedef A B; typedef A C; typedef A D;"
5366
      "class E : A {};",
5367
    cxxRecordDecl(decl().bind("x"), isDerivedFrom("C")),
5368
    std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5369
  EXPECT_TRUE(matchAndVerifyResultTrue(
5370
    "class A { class B { void f() {} }; };",
5371
    functionDecl(decl().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
5372
    std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5373
  EXPECT_TRUE(matchAndVerifyResultTrue(
5374
    "template <typename T> struct A { struct B {"
5375
      "  void f() { if(true) {} }"
5376
      "}; };"
5377
      "void t() { A<int>::B b; b.f(); }",
5378
    ifStmt(stmt().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
5379
    std::make_unique<VerifyIdIsBoundTo<Stmt>>("x", 2)));
5380
  EXPECT_TRUE(matchAndVerifyResultTrue(
5381
    "class A {};",
5382
    recordDecl(hasName("::A"), decl().bind("x"), unless(hasName("fooble"))),
5383
    std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5384
  EXPECT_TRUE(matchAndVerifyResultTrue(
5385
    "class A { A() : s(), i(42) {} const char *s; int i; };",
5386
    cxxConstructorDecl(hasName("::A::A"), decl().bind("x"),
5387
                       forEachConstructorInitializer(forField(hasName("i")))),
5388
    std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5389
}
5390

5391
TEST(ForEachDescendant, BindsCorrectNodes) {
5392
  EXPECT_TRUE(matchAndVerifyResultTrue(
5393
    "class C { void f(); int i; };",
5394
    recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
5395
    std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("decl", 1)));
5396
  EXPECT_TRUE(matchAndVerifyResultTrue(
5397
    "class C { void f() {} int i; };",
5398
    recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
5399
    std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("decl", 1)));
5400
}
5401

5402
TEST(FindAll, BindsNodeOnMatch) {
5403
  EXPECT_TRUE(matchAndVerifyResultTrue(
5404
    "class A {};",
5405
    recordDecl(hasName("::A"), findAll(recordDecl(hasName("::A")).bind("v"))),
5406
    std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("v", 1)));
5407
}
5408

5409
TEST(FindAll, BindsDescendantNodeOnMatch) {
5410
  EXPECT_TRUE(matchAndVerifyResultTrue(
5411
    "class A { int a; int b; };",
5412
    recordDecl(hasName("::A"), findAll(fieldDecl().bind("v"))),
5413
    std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 2)));
5414
}
5415

5416
TEST(FindAll, BindsNodeAndDescendantNodesOnOneMatch) {
5417
  EXPECT_TRUE(matchAndVerifyResultTrue(
5418
    "class A { int a; int b; };",
5419
    recordDecl(hasName("::A"),
5420
               findAll(decl(anyOf(recordDecl(hasName("::A")).bind("v"),
5421
                                  fieldDecl().bind("v"))))),
5422
    std::make_unique<VerifyIdIsBoundTo<Decl>>("v", 3)));
5423

5424
  EXPECT_TRUE(matchAndVerifyResultTrue(
5425
    "class A { class B {}; class C {}; };",
5426
    recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("v"))),
5427
    std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("v", 3)));
5428
}
5429

5430
TEST(HasAncenstor, MatchesDeclarationAncestors) {
5431
  EXPECT_TRUE(matches(
5432
    "class A { class B { class C {}; }; };",
5433
    recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("A"))))));
5434
}
5435

5436
TEST(HasAncenstor, FailsIfNoAncestorMatches) {
5437
  EXPECT_TRUE(notMatches(
5438
    "class A { class B { class C {}; }; };",
5439
    recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("X"))))));
5440
}
5441

5442
TEST(HasAncestor, MatchesDeclarationsThatGetVisitedLater) {
5443
  EXPECT_TRUE(matches(
5444
    "class A { class B { void f() { C c; } class C {}; }; };",
5445
    varDecl(hasName("c"), hasType(recordDecl(hasName("C"),
5446
                                             hasAncestor(recordDecl(hasName("A"))))))));
5447
}
5448

5449
TEST(HasAncenstor, MatchesStatementAncestors) {
5450
  EXPECT_TRUE(matches(
5451
    "void f() { if (true) { while (false) { 42; } } }",
5452
    integerLiteral(equals(42), hasAncestor(ifStmt()))));
5453
}
5454

5455
TEST(HasAncestor, DrillsThroughDifferentHierarchies) {
5456
  EXPECT_TRUE(matches(
5457
    "void f() { if (true) { int x = 42; } }",
5458
    integerLiteral(equals(42), hasAncestor(functionDecl(hasName("f"))))));
5459
}
5460

5461
TEST(HasAncestor, BindsRecursiveCombinations) {
5462
  EXPECT_TRUE(matchAndVerifyResultTrue(
5463
    "class C { class D { class E { class F { int y; }; }; }; };",
5464
    fieldDecl(hasAncestor(recordDecl(hasAncestor(recordDecl().bind("r"))))),
5465
    std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("r", 1)));
5466
}
5467

5468
TEST(HasAncestor, BindsCombinationsWithHasDescendant) {
5469
  EXPECT_TRUE(matchAndVerifyResultTrue(
5470
    "class C { class D { class E { class F { int y; }; }; }; };",
5471
    fieldDecl(hasAncestor(
5472
      decl(
5473
        hasDescendant(recordDecl(isDefinition(),
5474
                                 hasAncestor(recordDecl())))
5475
      ).bind("d")
5476
    )),
5477
    std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("d", "E")));
5478
}
5479

5480
TEST(HasAncestor, MatchesClosestAncestor) {
5481
  EXPECT_TRUE(matchAndVerifyResultTrue(
5482
    "template <typename T> struct C {"
5483
      "  void f(int) {"
5484
      "    struct I { void g(T) { int x; } } i; i.g(42);"
5485
      "  }"
5486
      "};"
5487
      "template struct C<int>;",
5488
    varDecl(hasName("x"),
5489
            hasAncestor(functionDecl(hasParameter(
5490
              0, varDecl(hasType(asString("int"))))).bind("f"))).bind("v"),
5491
    std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("f", "g", 2)));
5492
}
5493

5494
TEST(HasAncestor, MatchesInTemplateInstantiations) {
5495
  EXPECT_TRUE(matches(
5496
    "template <typename T> struct A { struct B { struct C { T t; }; }; }; "
5497
      "A<int>::B::C a;",
5498
    fieldDecl(hasType(asString("int")),
5499
              hasAncestor(recordDecl(hasName("A"))))));
5500
}
5501

5502
TEST(HasAncestor, MatchesInImplicitCode) {
5503
  EXPECT_TRUE(matches(
5504
    "struct X {}; struct A { A() {} X x; };",
5505
    cxxConstructorDecl(
5506
      hasAnyConstructorInitializer(withInitializer(expr(
5507
        hasAncestor(recordDecl(hasName("A")))))))));
5508
}
5509

5510
TEST(HasParent, MatchesOnlyParent) {
5511
  EXPECT_TRUE(matches(
5512
    "void f() { if (true) { int x = 42; } }",
5513
    compoundStmt(hasParent(ifStmt()))));
5514
  EXPECT_TRUE(notMatches(
5515
    "void f() { for (;;) { int x = 42; } }",
5516
    compoundStmt(hasParent(ifStmt()))));
5517
  EXPECT_TRUE(notMatches(
5518
    "void f() { if (true) for (;;) { int x = 42; } }",
5519
    compoundStmt(hasParent(ifStmt()))));
5520
}
5521

5522
TEST(MatcherMemoize, HasParentDiffersFromHas) {
5523
  // Test introduced after detecting a bug in memoization
5524
  constexpr auto code = "void f() { throw 1; }";
5525
  EXPECT_TRUE(notMatches(
5526
    code,
5527
    cxxThrowExpr(hasParent(expr()))));
5528
  EXPECT_TRUE(matches(
5529
    code,
5530
    cxxThrowExpr(has(expr()))));
5531
  EXPECT_TRUE(matches(
5532
    code,
5533
    cxxThrowExpr(anyOf(hasParent(expr()), has(expr())))));
5534
}
5535

5536
TEST(MatcherMemoize, HasDiffersFromHasDescendant) {
5537
  // Test introduced after detecting a bug in memoization
5538
  constexpr auto code = "void f() { throw 1+1; }";
5539
  EXPECT_TRUE(notMatches(
5540
    code,
5541
    cxxThrowExpr(has(integerLiteral()))));
5542
  EXPECT_TRUE(matches(
5543
    code,
5544
    cxxThrowExpr(hasDescendant(integerLiteral()))));
5545
  EXPECT_TRUE(
5546
      notMatches(code, cxxThrowExpr(allOf(hasDescendant(integerLiteral()),
5547
                                          has(integerLiteral())))));
5548
}
5549
TEST(HasAncestor, MatchesAllAncestors) {
5550
  EXPECT_TRUE(matches(
5551
    "template <typename T> struct C { static void f() { 42; } };"
5552
      "void t() { C<int>::f(); }",
5553
    integerLiteral(
5554
      equals(42),
5555
      allOf(
5556
        hasAncestor(cxxRecordDecl(isTemplateInstantiation())),
5557
        hasAncestor(cxxRecordDecl(unless(isTemplateInstantiation())))))));
5558
}
5559

5560
TEST(HasAncestor, ImplicitArrayCopyCtorDeclRefExpr) {
5561
  EXPECT_TRUE(matches("struct MyClass {\n"
5562
                        "  int c[1];\n"
5563
                        "  static MyClass Create() { return MyClass(); }\n"
5564
                        "};",
5565
                      declRefExpr(to(decl(hasAncestor(decl()))))));
5566
}
5567

5568
TEST(HasAncestor, AnonymousUnionMemberExpr) {
5569
  EXPECT_TRUE(matches("int F() {\n"
5570
                        "  union { int i; };\n"
5571
                        "  return i;\n"
5572
                        "}\n",
5573
                      memberExpr(member(hasAncestor(decl())))));
5574
  EXPECT_TRUE(matches("void f() {\n"
5575
                        "  struct {\n"
5576
                        "    struct { int a; int b; };\n"
5577
                        "  } s;\n"
5578
                        "  s.a = 4;\n"
5579
                        "}\n",
5580
                      memberExpr(member(hasAncestor(decl())))));
5581
  EXPECT_TRUE(matches("void f() {\n"
5582
                        "  struct {\n"
5583
                        "    struct { int a; int b; };\n"
5584
                        "  } s;\n"
5585
                        "  s.a = 4;\n"
5586
                        "}\n",
5587
                      declRefExpr(to(decl(hasAncestor(decl()))))));
5588
}
5589
TEST(HasAncestor, NonParmDependentTemplateParmVarDeclRefExpr) {
5590
  EXPECT_TRUE(matches("struct PartitionAllocator {\n"
5591
                        "  template<typename T>\n"
5592
                        "  static int quantizedSize(int count) {\n"
5593
                        "    return count;\n"
5594
                        "  }\n"
5595
                        "  void f() { quantizedSize<int>(10); }\n"
5596
                        "};",
5597
                      declRefExpr(to(decl(hasAncestor(decl()))))));
5598
}
5599

5600
TEST(HasAncestor, AddressOfExplicitSpecializationFunction) {
5601
  EXPECT_TRUE(matches("template <class T> void f();\n"
5602
                        "template <> void f<int>();\n"
5603
                        "void (*get_f())() { return f<int>; }\n",
5604
                      declRefExpr(to(decl(hasAncestor(decl()))))));
5605
}
5606

5607
TEST(HasParent, MatchesAllParents) {
5608
  EXPECT_TRUE(matches(
5609
    "template <typename T> struct C { static void f() { 42; } };"
5610
      "void t() { C<int>::f(); }",
5611
    integerLiteral(
5612
      equals(42),
5613
      hasParent(compoundStmt(hasParent(functionDecl(
5614
        hasParent(cxxRecordDecl(isTemplateInstantiation())))))))));
5615
  EXPECT_TRUE(
5616
    matches("template <typename T> struct C { static void f() { 42; } };"
5617
              "void t() { C<int>::f(); }",
5618
            integerLiteral(
5619
              equals(42),
5620
              hasParent(compoundStmt(hasParent(functionDecl(hasParent(
5621
                cxxRecordDecl(unless(isTemplateInstantiation()))))))))));
5622
  EXPECT_TRUE(matches(
5623
    "template <typename T> struct C { static void f() { 42; } };"
5624
      "void t() { C<int>::f(); }",
5625
    integerLiteral(equals(42),
5626
                   hasParent(compoundStmt(
5627
                     allOf(hasParent(functionDecl(hasParent(
5628
                       cxxRecordDecl(isTemplateInstantiation())))),
5629
                           hasParent(functionDecl(hasParent(cxxRecordDecl(
5630
                             unless(isTemplateInstantiation())))))))))));
5631
  EXPECT_TRUE(
5632
    notMatches("template <typename T> struct C { static void f() {} };"
5633
                 "void t() { C<int>::f(); }",
5634
               compoundStmt(hasParent(recordDecl()))));
5635
}
5636

5637
TEST(HasParent, NoDuplicateParents) {
5638
  class HasDuplicateParents : public BoundNodesCallback {
5639
  public:
5640
    bool run(const BoundNodes *Nodes) override { return false; }
5641
    bool run(const BoundNodes *Nodes, ASTContext *Context) override {
5642
      const Stmt *Node = Nodes->getNodeAs<Stmt>("node");
5643
      std::set<const void *> Parents;
5644
      for (const auto &Parent : Context->getParents(*Node)) {
5645
        if (!Parents.insert(Parent.getMemoizationData()).second) {
5646
          return true;
5647
        }
5648
      }
5649
      return false;
5650
    }
5651
  };
5652
  EXPECT_FALSE(matchAndVerifyResultTrue(
5653
    "template <typename T> int Foo() { return 1 + 2; }\n"
5654
      "int x = Foo<int>() + Foo<unsigned>();",
5655
    stmt().bind("node"), std::make_unique<HasDuplicateParents>()));
5656
}
5657

5658
TEST(HasAnyBase, BindsInnerBoundNodes) {
5659
  EXPECT_TRUE(matchAndVerifyResultTrue(
5660
      "struct Inner {}; struct Proxy : Inner {}; struct Main : public "
5661
      "Proxy {};",
5662
      cxxRecordDecl(hasName("Main"),
5663
                    hasAnyBase(cxxBaseSpecifier(hasType(
5664
                        cxxRecordDecl(hasName("Inner")).bind("base-class")))))
5665
          .bind("class"),
5666
      std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("base-class",
5667
                                                         "Inner")));
5668
}
5669

5670
TEST(TypeMatching, PointeeTypes) {
5671
  EXPECT_TRUE(matches("int b; int &a = b;",
5672
                      referenceType(pointee(builtinType()))));
5673
  EXPECT_TRUE(matches("int *a;", pointerType(pointee(builtinType()))));
5674

5675
  EXPECT_TRUE(matches("int *a;",
5676
                      loc(pointerType(pointee(builtinType())))));
5677

5678
  EXPECT_TRUE(matches(
5679
    "int const *A;",
5680
    pointerType(pointee(isConstQualified(), builtinType()))));
5681
  EXPECT_TRUE(notMatches(
5682
    "int *A;",
5683
    pointerType(pointee(isConstQualified(), builtinType()))));
5684
}
5685

5686
TEST(ElaboratedTypeNarrowing, hasQualifier) {
5687
  EXPECT_TRUE(matches(
5688
    "namespace N {"
5689
      "  namespace M {"
5690
      "    class D {};"
5691
      "  }"
5692
      "}"
5693
      "N::M::D d;",
5694
    elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
5695
  EXPECT_TRUE(notMatches(
5696
    "namespace M {"
5697
      "  class D {};"
5698
      "}"
5699
      "M::D d;",
5700
    elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
5701
  EXPECT_TRUE(notMatches(
5702
    "struct D {"
5703
      "} d;",
5704
    elaboratedType(hasQualifier(nestedNameSpecifier()))));
5705
}
5706

5707
TEST(ElaboratedTypeNarrowing, namesType) {
5708
  EXPECT_TRUE(matches(
5709
    "namespace N {"
5710
      "  namespace M {"
5711
      "    class D {};"
5712
      "  }"
5713
      "}"
5714
      "N::M::D d;",
5715
    elaboratedType(elaboratedType(namesType(recordType(
5716
      hasDeclaration(namedDecl(hasName("D")))))))));
5717
  EXPECT_TRUE(notMatches(
5718
    "namespace M {"
5719
      "  class D {};"
5720
      "}"
5721
      "M::D d;",
5722
    elaboratedType(elaboratedType(namesType(typedefType())))));
5723
}
5724

5725
TEST(NNS, BindsNestedNameSpecifiers) {
5726
  EXPECT_TRUE(matchAndVerifyResultTrue(
5727
    "namespace ns { struct E { struct B {}; }; } ns::E::B b;",
5728
    nestedNameSpecifier(specifiesType(asString("struct ns::E"))).bind("nns"),
5729
    std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>(
5730
      "nns", "ns::struct E::")));
5731
}
5732

5733
TEST(NNS, BindsNestedNameSpecifierLocs) {
5734
  EXPECT_TRUE(matchAndVerifyResultTrue(
5735
    "namespace ns { struct B {}; } ns::B b;",
5736
    loc(nestedNameSpecifier()).bind("loc"),
5737
    std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifierLoc>>("loc", 1)));
5738
}
5739

5740
TEST(NNS, DescendantsOfNestedNameSpecifiers) {
5741
  StringRef Fragment =
5742
      "namespace a { struct A { struct B { struct C {}; }; }; };"
5743
      "void f() { a::A::B::C c; }";
5744
  EXPECT_TRUE(matches(
5745
    Fragment,
5746
    nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
5747
                        hasDescendant(nestedNameSpecifier(
5748
                          specifiesNamespace(hasName("a")))))));
5749
  EXPECT_TRUE(notMatches(
5750
    Fragment,
5751
    nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
5752
                        has(nestedNameSpecifier(
5753
                          specifiesNamespace(hasName("a")))))));
5754
  EXPECT_TRUE(matches(
5755
    Fragment,
5756
    nestedNameSpecifier(specifiesType(asString("struct a::A")),
5757
                        has(nestedNameSpecifier(
5758
                          specifiesNamespace(hasName("a")))))));
5759

5760
  // Not really useful because a NestedNameSpecifier can af at most one child,
5761
  // but to complete the interface.
5762
  EXPECT_TRUE(matchAndVerifyResultTrue(
5763
    Fragment,
5764
    nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
5765
                        forEach(nestedNameSpecifier().bind("x"))),
5766
    std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>("x", 1)));
5767
}
5768

5769
TEST(NNS, NestedNameSpecifiersAsDescendants) {
5770
  StringRef Fragment =
5771
      "namespace a { struct A { struct B { struct C {}; }; }; };"
5772
      "void f() { a::A::B::C c; }";
5773
  EXPECT_TRUE(matches(
5774
    Fragment,
5775
    decl(hasDescendant(nestedNameSpecifier(specifiesType(
5776
      asString("struct a::A")))))));
5777
  EXPECT_TRUE(matchAndVerifyResultTrue(
5778
    Fragment,
5779
    functionDecl(hasName("f"),
5780
                 forEachDescendant(nestedNameSpecifier().bind("x"))),
5781
    // Nested names: a, a::A and a::A::B.
5782
    std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>("x", 3)));
5783
}
5784

5785
TEST(NNSLoc, DescendantsOfNestedNameSpecifierLocs) {
5786
  StringRef Fragment =
5787
      "namespace a { struct A { struct B { struct C {}; }; }; };"
5788
      "void f() { a::A::B::C c; }";
5789
  EXPECT_TRUE(matches(
5790
    Fragment,
5791
    nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5792
                           hasDescendant(loc(nestedNameSpecifier(
5793
                             specifiesNamespace(hasName("a"))))))));
5794
  EXPECT_TRUE(notMatches(
5795
    Fragment,
5796
    nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5797
                           has(loc(nestedNameSpecifier(
5798
                             specifiesNamespace(hasName("a"))))))));
5799
  EXPECT_TRUE(matches(
5800
    Fragment,
5801
    nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A"))),
5802
                           has(loc(nestedNameSpecifier(
5803
                             specifiesNamespace(hasName("a"))))))));
5804

5805
  EXPECT_TRUE(matchAndVerifyResultTrue(
5806
    Fragment,
5807
    nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5808
                           forEach(nestedNameSpecifierLoc().bind("x"))),
5809
    std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifierLoc>>("x", 1)));
5810
}
5811

5812
TEST(NNSLoc, NestedNameSpecifierLocsAsDescendants) {
5813
  StringRef Fragment =
5814
      "namespace a { struct A { struct B { struct C {}; }; }; };"
5815
      "void f() { a::A::B::C c; }";
5816
  EXPECT_TRUE(matches(
5817
    Fragment,
5818
    decl(hasDescendant(loc(nestedNameSpecifier(specifiesType(
5819
      asString("struct a::A"))))))));
5820
  EXPECT_TRUE(matchAndVerifyResultTrue(
5821
    Fragment,
5822
    functionDecl(hasName("f"),
5823
                 forEachDescendant(nestedNameSpecifierLoc().bind("x"))),
5824
    // Nested names: a, a::A and a::A::B.
5825
    std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifierLoc>>("x", 3)));
5826
}
5827

5828
TEST(Attr, AttrsAsDescendants) {
5829
  StringRef Fragment = "namespace a { struct [[clang::warn_unused_result]] "
5830
                       "F{}; [[noreturn]] void foo(); }";
5831
  EXPECT_TRUE(matches(Fragment, namespaceDecl(hasDescendant(attr()))));
5832
  EXPECT_TRUE(matchAndVerifyResultTrue(
5833
      Fragment,
5834
      namespaceDecl(hasName("a"),
5835
                    forEachDescendant(attr(unless(isImplicit())).bind("x"))),
5836
      std::make_unique<VerifyIdIsBoundTo<Attr>>("x", 2)));
5837
}
5838

5839
TEST(Attr, ParentsOfAttrs) {
5840
  StringRef Fragment =
5841
      "namespace a { struct [[clang::warn_unused_result]] F{}; }";
5842
  EXPECT_TRUE(matches(Fragment, attr(hasAncestor(namespaceDecl()))));
5843
}
5844

5845
template <typename T> class VerifyMatchOnNode : public BoundNodesCallback {
5846
public:
5847
  VerifyMatchOnNode(StringRef Id, const internal::Matcher<T> &InnerMatcher,
5848
                    StringRef InnerId)
5849
    : Id(Id), InnerMatcher(InnerMatcher), InnerId(InnerId) {
5850
  }
5851

5852
  bool run(const BoundNodes *Nodes) override { return false; }
5853

5854
  bool run(const BoundNodes *Nodes, ASTContext *Context) override {
5855
    const T *Node = Nodes->getNodeAs<T>(Id);
5856
    return selectFirst<T>(InnerId, match(InnerMatcher, *Node, *Context)) !=
5857
      nullptr;
5858
  }
5859
private:
5860
  std::string Id;
5861
  internal::Matcher<T> InnerMatcher;
5862
  std::string InnerId;
5863
};
5864

5865
TEST(MatchFinder, CanMatchDeclarationsRecursively) {
5866
  EXPECT_TRUE(matchAndVerifyResultTrue(
5867
    "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5868
    std::make_unique<VerifyMatchOnNode<Decl>>(
5869
      "X", decl(hasDescendant(recordDecl(hasName("X::Y")).bind("Y"))),
5870
      "Y")));
5871
  EXPECT_TRUE(matchAndVerifyResultFalse(
5872
    "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5873
    std::make_unique<VerifyMatchOnNode<Decl>>(
5874
      "X", decl(hasDescendant(recordDecl(hasName("X::Z")).bind("Z"))),
5875
      "Z")));
5876
}
5877

5878
TEST(MatchFinder, CanMatchStatementsRecursively) {
5879
  EXPECT_TRUE(matchAndVerifyResultTrue(
5880
    "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
5881
    std::make_unique<VerifyMatchOnNode<Stmt>>(
5882
      "if", stmt(hasDescendant(forStmt().bind("for"))), "for")));
5883
  EXPECT_TRUE(matchAndVerifyResultFalse(
5884
    "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
5885
    std::make_unique<VerifyMatchOnNode<Stmt>>(
5886
      "if", stmt(hasDescendant(declStmt().bind("decl"))), "decl")));
5887
}
5888

5889
TEST(MatchFinder, CanMatchSingleNodesRecursively) {
5890
  EXPECT_TRUE(matchAndVerifyResultTrue(
5891
    "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5892
    std::make_unique<VerifyMatchOnNode<Decl>>(
5893
      "X", recordDecl(has(recordDecl(hasName("X::Y")).bind("Y"))), "Y")));
5894
  EXPECT_TRUE(matchAndVerifyResultFalse(
5895
    "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5896
    std::make_unique<VerifyMatchOnNode<Decl>>(
5897
      "X", recordDecl(has(recordDecl(hasName("X::Z")).bind("Z"))), "Z")));
5898
}
5899

5900
TEST(StatementMatcher, HasReturnValue) {
5901
  StatementMatcher RetVal = returnStmt(hasReturnValue(binaryOperator()));
5902
  EXPECT_TRUE(matches("int F() { int a, b; return a + b; }", RetVal));
5903
  EXPECT_FALSE(matches("int F() { int a; return a; }", RetVal));
5904
  EXPECT_FALSE(matches("void F() { return; }", RetVal));
5905
}
5906

5907
TEST(StatementMatcher, ForFunction) {
5908
  StringRef CppString1 = "struct PosVec {"
5909
                         "  PosVec& operator=(const PosVec&) {"
5910
                         "    auto x = [] { return 1; };"
5911
                         "    return *this;"
5912
                         "  }"
5913
                         "};";
5914
  StringRef CppString2 = "void F() {"
5915
                         "  struct S {"
5916
                         "    void F2() {"
5917
                         "       return;"
5918
                         "    }"
5919
                         "  };"
5920
                         "}";
5921
  EXPECT_TRUE(
5922
    matches(
5923
      CppString1,
5924
      returnStmt(forFunction(hasName("operator=")),
5925
                 has(unaryOperator(hasOperatorName("*"))))));
5926
  EXPECT_TRUE(
5927
    notMatches(
5928
      CppString1,
5929
      returnStmt(forFunction(hasName("operator=")),
5930
                 has(integerLiteral()))));
5931
  EXPECT_TRUE(
5932
    matches(
5933
      CppString1,
5934
      returnStmt(forFunction(hasName("operator()")),
5935
                 has(integerLiteral()))));
5936
  EXPECT_TRUE(matches(CppString2, returnStmt(forFunction(hasName("F2")))));
5937
  EXPECT_TRUE(notMatches(CppString2, returnStmt(forFunction(hasName("F")))));
5938
}
5939

5940
TEST(StatementMatcher, ForCallable) {
5941
  // These tests are copied over from the forFunction() test above.
5942
  StringRef CppString1 = "struct PosVec {"
5943
                         "  PosVec& operator=(const PosVec&) {"
5944
                         "    auto x = [] { return 1; };"
5945
                         "    return *this;"
5946
                         "  }"
5947
                         "};";
5948
  StringRef CppString2 = "void F() {"
5949
                         "  struct S {"
5950
                         "    void F2() {"
5951
                         "       return;"
5952
                         "    }"
5953
                         "  };"
5954
                         "}";
5955

5956
  EXPECT_TRUE(
5957
    matches(
5958
      CppString1,
5959
      returnStmt(forCallable(functionDecl(hasName("operator="))),
5960
                 has(unaryOperator(hasOperatorName("*"))))));
5961
  EXPECT_TRUE(
5962
    notMatches(
5963
      CppString1,
5964
      returnStmt(forCallable(functionDecl(hasName("operator="))),
5965
                 has(integerLiteral()))));
5966
  EXPECT_TRUE(
5967
    matches(
5968
      CppString1,
5969
      returnStmt(forCallable(functionDecl(hasName("operator()"))),
5970
                 has(integerLiteral()))));
5971
  EXPECT_TRUE(matches(CppString2,
5972
                      returnStmt(forCallable(functionDecl(hasName("F2"))))));
5973
  EXPECT_TRUE(notMatches(CppString2,
5974
                         returnStmt(forCallable(functionDecl(hasName("F"))))));
5975

5976
  StringRef CodeWithDeepCallExpr = R"cpp(
5977
void Other();
5978
void Function() {
5979
  {
5980
    (
5981
      Other()
5982
    );
5983
  }
5984
}
5985
)cpp";
5986
  auto ForCallableFirst =
5987
      callExpr(forCallable(functionDecl(hasName("Function"))),
5988
               callee(functionDecl(hasName("Other")).bind("callee")))
5989
          .bind("call");
5990
  auto ForCallableSecond =
5991
      callExpr(callee(functionDecl(hasName("Other")).bind("callee")),
5992
               forCallable(functionDecl(hasName("Function"))))
5993
          .bind("call");
5994
  EXPECT_TRUE(matchAndVerifyResultTrue(
5995
      CodeWithDeepCallExpr, ForCallableFirst,
5996
      std::make_unique<VerifyIdIsBoundTo<CallExpr>>("call")));
5997
  EXPECT_TRUE(matchAndVerifyResultTrue(
5998
      CodeWithDeepCallExpr, ForCallableFirst,
5999
      std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("callee")));
6000
  EXPECT_TRUE(matchAndVerifyResultTrue(
6001
      CodeWithDeepCallExpr, ForCallableSecond,
6002
      std::make_unique<VerifyIdIsBoundTo<CallExpr>>("call")));
6003
  EXPECT_TRUE(matchAndVerifyResultTrue(
6004
      CodeWithDeepCallExpr, ForCallableSecond,
6005
      std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("callee")));
6006

6007
  // These tests are specific to forCallable().
6008
  StringRef ObjCString1 = "@interface I"
6009
                          "-(void) foo;"
6010
                          "@end"
6011
                          "@implementation I"
6012
                          "-(void) foo {"
6013
                          "  void (^block)() = ^{ 0x2b | ~0x2b; };"
6014
                          "}"
6015
                          "@end";
6016

6017
  EXPECT_TRUE(
6018
    matchesObjC(
6019
      ObjCString1,
6020
      binaryOperator(forCallable(blockDecl()))));
6021

6022
  EXPECT_TRUE(
6023
    notMatchesObjC(
6024
      ObjCString1,
6025
      binaryOperator(forCallable(objcMethodDecl()))));
6026

6027
  StringRef ObjCString2 = "@interface I"
6028
                          "-(void) foo;"
6029
                          "@end"
6030
                          "@implementation I"
6031
                          "-(void) foo {"
6032
                          "  0x2b | ~0x2b;"
6033
                          "  void (^block)() = ^{};"
6034
                          "}"
6035
                          "@end";
6036

6037
  EXPECT_TRUE(
6038
    matchesObjC(
6039
      ObjCString2,
6040
      binaryOperator(forCallable(objcMethodDecl()))));
6041

6042
  EXPECT_TRUE(
6043
    notMatchesObjC(
6044
      ObjCString2,
6045
      binaryOperator(forCallable(blockDecl()))));
6046
}
6047

6048
namespace {
6049
class ForCallablePreservesBindingWithMultipleParentsTestCallback
6050
    : public BoundNodesCallback {
6051
public:
6052
  bool run(const BoundNodes *BoundNodes) override {
6053
    FunctionDecl const *FunDecl =
6054
        BoundNodes->getNodeAs<FunctionDecl>("funDecl");
6055
    // Validate test assumptions. This would be expressed as ASSERT_* in
6056
    // a TEST().
6057
    if (!FunDecl) {
6058
      EXPECT_TRUE(false && "Incorrect test setup");
6059
      return false;
6060
    }
6061
    auto const *FunDef = FunDecl->getDefinition();
6062
    if (!FunDef || !FunDef->getBody() ||
6063
        FunDef->getNameAsString() != "Function") {
6064
      EXPECT_TRUE(false && "Incorrect test setup");
6065
      return false;
6066
    }
6067

6068
    ExpectCorrectResult(
6069
        "Baseline",
6070
        callExpr(callee(cxxMethodDecl().bind("callee"))).bind("call"), //
6071
        FunDecl);
6072

6073
    ExpectCorrectResult("ForCallable first",
6074
                        callExpr(forCallable(equalsNode(FunDecl)),
6075
                                 callee(cxxMethodDecl().bind("callee")))
6076
                            .bind("call"),
6077
                        FunDecl);
6078

6079
    ExpectCorrectResult("ForCallable second",
6080
                        callExpr(callee(cxxMethodDecl().bind("callee")),
6081
                                 forCallable(equalsNode(FunDecl)))
6082
                            .bind("call"),
6083
                        FunDecl);
6084

6085
    // This value does not really matter: the EXPECT_* will set the exit code.
6086
    return true;
6087
  }
6088

6089
  bool run(const BoundNodes *BoundNodes, ASTContext *Context) override {
6090
    return run(BoundNodes);
6091
  }
6092

6093
private:
6094
  void ExpectCorrectResult(StringRef LogInfo,
6095
                           ArrayRef<BoundNodes> Results) const {
6096
    EXPECT_EQ(Results.size(), 1u) << LogInfo;
6097
    if (Results.empty())
6098
      return;
6099
    auto const &R = Results.front();
6100
    EXPECT_TRUE(R.getNodeAs<CallExpr>("call")) << LogInfo;
6101
    EXPECT_TRUE(R.getNodeAs<CXXMethodDecl>("callee")) << LogInfo;
6102
  }
6103

6104
  template <typename MatcherT>
6105
  void ExpectCorrectResult(StringRef LogInfo, MatcherT Matcher,
6106
                           FunctionDecl const *FunDef) const {
6107
    auto &Context = FunDef->getASTContext();
6108
    auto const &Results = match(findAll(Matcher), *FunDef->getBody(), Context);
6109
    ExpectCorrectResult(LogInfo, Results);
6110
  }
6111
};
6112
} // namespace
6113

6114
TEST(StatementMatcher, ForCallablePreservesBindingWithMultipleParents) {
6115
  // Tests in this file are fairly simple and therefore can rely on matches,
6116
  // matchAndVerifyResultTrue, etc. This test, however, needs a FunctionDecl* in
6117
  // order to call equalsNode in order to reproduce the observed issue (bindings
6118
  // being removed despite forCallable matching the node).
6119
  //
6120
  // Because of this and because the machinery to compile the code into an
6121
  // ASTUnit is not exposed outside matchAndVerifyResultConditionally, it is
6122
  // cheaper to have a custom BoundNodesCallback for the purpose of this test.
6123
  StringRef codeWithTemplateFunction = R"cpp(
6124
struct Klass {
6125
  void Method();
6126
  template <typename T>
6127
  void Function(T t); // Declaration
6128
};
6129

6130
void Instantiate(Klass k) {
6131
  k.Function(0);
6132
}
6133

6134
template <typename T>
6135
void Klass::Function(T t) { // Definition
6136
  // Compound statement has two parents: the declaration and the definition.
6137
  Method();
6138
}
6139
)cpp";
6140
  EXPECT_TRUE(matchAndVerifyResultTrue(
6141
      codeWithTemplateFunction,
6142
      callExpr(callee(functionDecl(hasName("Function")).bind("funDecl"))),
6143
      std::make_unique<
6144
          ForCallablePreservesBindingWithMultipleParentsTestCallback>()));
6145
}
6146

6147
TEST(Matcher, ForEachOverriden) {
6148
  const auto ForEachOverriddenInClass = [](const char *ClassName) {
6149
    return cxxMethodDecl(ofClass(hasName(ClassName)), isVirtual(),
6150
                         forEachOverridden(cxxMethodDecl().bind("overridden")))
6151
        .bind("override");
6152
  };
6153
  static const char Code1[] = "class A { virtual void f(); };"
6154
                              "class B : public A { void f(); };"
6155
                              "class C : public B { void f(); };";
6156
  // C::f overrides A::f.
6157
  EXPECT_TRUE(matchAndVerifyResultTrue(
6158
      Code1, ForEachOverriddenInClass("C"),
6159
      std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("override", "f", 1)));
6160
  EXPECT_TRUE(matchAndVerifyResultTrue(
6161
      Code1, ForEachOverriddenInClass("C"),
6162
      std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("overridden", "f",
6163
                                                          1)));
6164
  // B::f overrides A::f.
6165
  EXPECT_TRUE(matchAndVerifyResultTrue(
6166
      Code1, ForEachOverriddenInClass("B"),
6167
      std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("override", "f", 1)));
6168
  EXPECT_TRUE(matchAndVerifyResultTrue(
6169
      Code1, ForEachOverriddenInClass("B"),
6170
      std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("overridden", "f",
6171
                                                          1)));
6172
  // A::f overrides nothing.
6173
  EXPECT_TRUE(notMatches(Code1, ForEachOverriddenInClass("A")));
6174

6175
  static const char Code2[] =
6176
      "class A1 { virtual void f(); };"
6177
      "class A2 { virtual void f(); };"
6178
      "class B : public A1, public A2 { void f(); };";
6179
  // B::f overrides A1::f and A2::f. This produces two matches.
6180
  EXPECT_TRUE(matchAndVerifyResultTrue(
6181
      Code2, ForEachOverriddenInClass("B"),
6182
      std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("override", "f", 2)));
6183
  EXPECT_TRUE(matchAndVerifyResultTrue(
6184
      Code2, ForEachOverriddenInClass("B"),
6185
      std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("overridden", "f",
6186
                                                          2)));
6187
  // A1::f overrides nothing.
6188
  EXPECT_TRUE(notMatches(Code2, ForEachOverriddenInClass("A1")));
6189
}
6190

6191
TEST(Matcher, HasAnyDeclaration) {
6192
  StringRef Fragment = "void foo(int p1);"
6193
                       "void foo(int *p2);"
6194
                       "void bar(int p3);"
6195
                       "template <typename T> void baz(T t) { foo(t); }";
6196

6197
  EXPECT_TRUE(
6198
      matches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(functionDecl(
6199
                            hasParameter(0, parmVarDecl(hasName("p1"))))))));
6200
  EXPECT_TRUE(
6201
      matches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(functionDecl(
6202
                            hasParameter(0, parmVarDecl(hasName("p2"))))))));
6203
  EXPECT_TRUE(
6204
      notMatches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(functionDecl(
6205
                               hasParameter(0, parmVarDecl(hasName("p3"))))))));
6206
  EXPECT_TRUE(notMatches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(
6207
                                       functionDecl(hasName("bar"))))));
6208
}
6209

6210
TEST(SubstTemplateTypeParmType, HasReplacementType) {
6211
  StringRef Fragment = "template<typename T>"
6212
                       "double F(T t);"
6213
                       "int i;"
6214
                       "double j = F(i);";
6215
  EXPECT_TRUE(matches(Fragment, substTemplateTypeParmType(hasReplacementType(
6216
                                    qualType(asString("int"))))));
6217
  EXPECT_TRUE(notMatches(Fragment, substTemplateTypeParmType(hasReplacementType(
6218
                                       qualType(asString("double"))))));
6219
  EXPECT_TRUE(
6220
      notMatches("template<int N>"
6221
                 "double F();"
6222
                 "double j = F<5>();",
6223
                 substTemplateTypeParmType(hasReplacementType(qualType()))));
6224
}
6225

6226
TEST(ClassTemplateSpecializationDecl, HasSpecializedTemplate) {
6227
  auto Matcher = classTemplateSpecializationDecl(
6228
      hasSpecializedTemplate(classTemplateDecl()));
6229
  EXPECT_TRUE(
6230
      matches("template<typename T> class A {}; typedef A<int> B;", Matcher));
6231
  EXPECT_TRUE(notMatches("template<typename T> class A {};", Matcher));
6232
}
6233

6234
TEST(CXXNewExpr, Array) {
6235
  StatementMatcher NewArray = cxxNewExpr(isArray());
6236

6237
  EXPECT_TRUE(matches("void foo() { int *Ptr = new int[10]; }", NewArray));
6238
  EXPECT_TRUE(notMatches("void foo() { int *Ptr = new int; }", NewArray));
6239

6240
  StatementMatcher NewArraySize10 =
6241
      cxxNewExpr(hasArraySize(integerLiteral(equals(10))));
6242
  EXPECT_TRUE(
6243
      matches("void foo() { int *Ptr = new int[10]; }", NewArraySize10));
6244
  EXPECT_TRUE(
6245
      notMatches("void foo() { int *Ptr = new int[20]; }", NewArraySize10));
6246
}
6247

6248
TEST(CXXNewExpr, PlacementArgs) {
6249
  StatementMatcher IsPlacementNew = cxxNewExpr(hasAnyPlacementArg(anything()));
6250

6251
  EXPECT_TRUE(matches(R"(
6252
    void* operator new(decltype(sizeof(void*)), void*);
6253
    int *foo(void* Storage) {
6254
      return new (Storage) int;
6255
    })",
6256
                      IsPlacementNew));
6257

6258
  EXPECT_TRUE(matches(R"(
6259
    void* operator new(decltype(sizeof(void*)), void*, unsigned);
6260
    int *foo(void* Storage) {
6261
      return new (Storage, 16) int;
6262
    })",
6263
                      cxxNewExpr(hasPlacementArg(
6264
                          1, ignoringImpCasts(integerLiteral(equals(16)))))));
6265

6266
  EXPECT_TRUE(notMatches(R"(
6267
    void* operator new(decltype(sizeof(void*)), void*);
6268
    int *foo(void* Storage) {
6269
      return new int;
6270
    })",
6271
                         IsPlacementNew));
6272
}
6273

6274
TEST(HasUnqualifiedLoc, BindsToConstIntVarDecl) {
6275
  EXPECT_TRUE(matches(
6276
      "const int x = 0;",
6277
      varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
6278
                                hasUnqualifiedLoc(loc(asString("int"))))))));
6279
}
6280

6281
TEST(HasUnqualifiedLoc, BindsToVolatileIntVarDecl) {
6282
  EXPECT_TRUE(matches(
6283
      "volatile int x = 0;",
6284
      varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
6285
                                hasUnqualifiedLoc(loc(asString("int"))))))));
6286
}
6287

6288
TEST(HasUnqualifiedLoc, BindsToConstVolatileIntVarDecl) {
6289
  EXPECT_TRUE(matches(
6290
      "const volatile int x = 0;",
6291
      varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
6292
                                hasUnqualifiedLoc(loc(asString("int"))))))));
6293
}
6294

6295
TEST(HasUnqualifiedLoc, BindsToConstPointerVarDecl) {
6296
  auto matcher = varDecl(
6297
      hasName("x"),
6298
      hasTypeLoc(qualifiedTypeLoc(hasUnqualifiedLoc(pointerTypeLoc()))));
6299
  EXPECT_TRUE(matches("int* const x = 0;", matcher));
6300
  EXPECT_TRUE(notMatches("int const x = 0;", matcher));
6301
}
6302

6303
TEST(HasUnqualifiedLoc, BindsToPointerToConstVolatileIntVarDecl) {
6304
  EXPECT_TRUE(
6305
      matches("const volatile int* x = 0;",
6306
              varDecl(hasName("x"),
6307
                      hasTypeLoc(pointerTypeLoc(hasPointeeLoc(qualifiedTypeLoc(
6308
                          hasUnqualifiedLoc(loc(asString("int"))))))))));
6309
}
6310

6311
TEST(HasUnqualifiedLoc, BindsToConstIntFunctionDecl) {
6312
  EXPECT_TRUE(
6313
      matches("const int f() { return 5; }",
6314
              functionDecl(hasName("f"),
6315
                           hasReturnTypeLoc(qualifiedTypeLoc(
6316
                               hasUnqualifiedLoc(loc(asString("int"))))))));
6317
}
6318

6319
TEST(HasUnqualifiedLoc, FloatBindsToConstFloatVarDecl) {
6320
  EXPECT_TRUE(matches(
6321
      "const float x = 0;",
6322
      varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
6323
                                hasUnqualifiedLoc(loc(asString("float"))))))));
6324
}
6325

6326
TEST(HasUnqualifiedLoc, FloatDoesNotBindToIntVarDecl) {
6327
  EXPECT_TRUE(notMatches(
6328
      "int x = 0;",
6329
      varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
6330
                                hasUnqualifiedLoc(loc(asString("float"))))))));
6331
}
6332

6333
TEST(HasUnqualifiedLoc, FloatDoesNotBindToConstIntVarDecl) {
6334
  EXPECT_TRUE(notMatches(
6335
      "const int x = 0;",
6336
      varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
6337
                                hasUnqualifiedLoc(loc(asString("float"))))))));
6338
}
6339

6340
TEST(HasReturnTypeLoc, BindsToIntReturnTypeLoc) {
6341
  EXPECT_TRUE(matches(
6342
      "int f() { return 5; }",
6343
      functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("int"))))));
6344
}
6345

6346
TEST(HasReturnTypeLoc, BindsToFloatReturnTypeLoc) {
6347
  EXPECT_TRUE(matches(
6348
      "float f() { return 5.0; }",
6349
      functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("float"))))));
6350
}
6351

6352
TEST(HasReturnTypeLoc, BindsToVoidReturnTypeLoc) {
6353
  EXPECT_TRUE(matches(
6354
      "void f() {}",
6355
      functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("void"))))));
6356
}
6357

6358
TEST(HasReturnTypeLoc, FloatDoesNotBindToIntReturnTypeLoc) {
6359
  EXPECT_TRUE(notMatches(
6360
      "int f() { return 5; }",
6361
      functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("float"))))));
6362
}
6363

6364
TEST(HasReturnTypeLoc, IntDoesNotBindToFloatReturnTypeLoc) {
6365
  EXPECT_TRUE(notMatches(
6366
      "float f() { return 5.0; }",
6367
      functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("int"))))));
6368
}
6369

6370
TEST(HasPointeeLoc, BindsToAnyPointeeTypeLoc) {
6371
  auto matcher = varDecl(hasName("x"),
6372
                         hasTypeLoc(pointerTypeLoc(hasPointeeLoc(typeLoc()))));
6373
  EXPECT_TRUE(matches("int* x;", matcher));
6374
  EXPECT_TRUE(matches("float* x;", matcher));
6375
  EXPECT_TRUE(matches("char* x;", matcher));
6376
  EXPECT_TRUE(matches("void* x;", matcher));
6377
}
6378

6379
TEST(HasPointeeLoc, DoesNotBindToTypeLocWithoutPointee) {
6380
  auto matcher = varDecl(hasName("x"),
6381
                         hasTypeLoc(pointerTypeLoc(hasPointeeLoc(typeLoc()))));
6382
  EXPECT_TRUE(notMatches("int x;", matcher));
6383
  EXPECT_TRUE(notMatches("float x;", matcher));
6384
  EXPECT_TRUE(notMatches("char x;", matcher));
6385
}
6386

6387
TEST(HasPointeeLoc, BindsToTypeLocPointingToInt) {
6388
  EXPECT_TRUE(
6389
      matches("int* x;", pointerTypeLoc(hasPointeeLoc(loc(asString("int"))))));
6390
}
6391

6392
TEST(HasPointeeLoc, BindsToTypeLocPointingToIntPointer) {
6393
  EXPECT_TRUE(matches("int** x;",
6394
                      pointerTypeLoc(hasPointeeLoc(loc(asString("int *"))))));
6395
}
6396

6397
TEST(HasPointeeLoc, BindsToTypeLocPointingToTypeLocPointingToInt) {
6398
  EXPECT_TRUE(matches("int** x;", pointerTypeLoc(hasPointeeLoc(pointerTypeLoc(
6399
                                      hasPointeeLoc(loc(asString("int"))))))));
6400
}
6401

6402
TEST(HasPointeeLoc, BindsToTypeLocPointingToFloat) {
6403
  EXPECT_TRUE(matches("float* x;",
6404
                      pointerTypeLoc(hasPointeeLoc(loc(asString("float"))))));
6405
}
6406

6407
TEST(HasPointeeLoc, IntPointeeDoesNotBindToTypeLocPointingToFloat) {
6408
  EXPECT_TRUE(notMatches("float* x;",
6409
                         pointerTypeLoc(hasPointeeLoc(loc(asString("int"))))));
6410
}
6411

6412
TEST(HasPointeeLoc, FloatPointeeDoesNotBindToTypeLocPointingToInt) {
6413
  EXPECT_TRUE(notMatches(
6414
      "int* x;", pointerTypeLoc(hasPointeeLoc(loc(asString("float"))))));
6415
}
6416

6417
TEST(HasReferentLoc, BindsToAnyReferentTypeLoc) {
6418
  auto matcher = varDecl(
6419
      hasName("r"), hasTypeLoc(referenceTypeLoc(hasReferentLoc(typeLoc()))));
6420
  EXPECT_TRUE(matches("int rr = 3; int& r = rr;", matcher));
6421
  EXPECT_TRUE(matches("int rr = 3; auto& r = rr;", matcher));
6422
  EXPECT_TRUE(matches("int rr = 3; const int& r = rr;", matcher));
6423
  EXPECT_TRUE(matches("float rr = 3.0; float& r = rr;", matcher));
6424
  EXPECT_TRUE(matches("char rr = 'a'; char& r = rr;", matcher));
6425
}
6426

6427
TEST(HasReferentLoc, DoesNotBindToTypeLocWithoutReferent) {
6428
  auto matcher = varDecl(
6429
      hasName("r"), hasTypeLoc(referenceTypeLoc(hasReferentLoc(typeLoc()))));
6430
  EXPECT_TRUE(notMatches("int r;", matcher));
6431
  EXPECT_TRUE(notMatches("int r = 3;", matcher));
6432
  EXPECT_TRUE(notMatches("const int r = 3;", matcher));
6433
  EXPECT_TRUE(notMatches("int* r;", matcher));
6434
  EXPECT_TRUE(notMatches("float r;", matcher));
6435
  EXPECT_TRUE(notMatches("char r;", matcher));
6436
}
6437

6438
TEST(HasReferentLoc, BindsToAnyRvalueReference) {
6439
  auto matcher = varDecl(
6440
      hasName("r"), hasTypeLoc(referenceTypeLoc(hasReferentLoc(typeLoc()))));
6441
  EXPECT_TRUE(matches("int&& r = 3;", matcher));
6442
  EXPECT_TRUE(matches("auto&& r = 3;", matcher));
6443
  EXPECT_TRUE(matches("float&& r = 3.0;", matcher));
6444
}
6445

6446
TEST(HasReferentLoc, BindsToIntReferenceTypeLoc) {
6447
  EXPECT_TRUE(matches("int rr = 3; int& r = rr;",
6448
                      referenceTypeLoc(hasReferentLoc(loc(asString("int"))))));
6449
}
6450

6451
TEST(HasReferentLoc, BindsToIntRvalueReferenceTypeLoc) {
6452
  EXPECT_TRUE(matches("int&& r = 3;",
6453
                      referenceTypeLoc(hasReferentLoc(loc(asString("int"))))));
6454
}
6455

6456
TEST(HasReferentLoc, BindsToFloatReferenceTypeLoc) {
6457
  EXPECT_TRUE(
6458
      matches("float rr = 3.0; float& r = rr;",
6459
              referenceTypeLoc(hasReferentLoc(loc(asString("float"))))));
6460
}
6461

6462
TEST(HasReferentLoc, BindsToParameterWithIntReferenceTypeLoc) {
6463
  EXPECT_TRUE(matches(
6464
      "int f(int& r) { return r; }",
6465
      parmVarDecl(hasName("r"), hasTypeLoc(referenceTypeLoc(
6466
                                    hasReferentLoc(loc(asString("int"))))))));
6467
}
6468

6469
TEST(HasReferentLoc, IntReferenceDoesNotBindToFloatReferenceTypeLoc) {
6470
  EXPECT_TRUE(
6471
      notMatches("float rr = 3.0; float& r = rr;",
6472
                 referenceTypeLoc(hasReferentLoc(loc(asString("int"))))));
6473
}
6474

6475
TEST(HasReferentLoc, FloatReferenceDoesNotBindToIntReferenceTypeLoc) {
6476
  EXPECT_TRUE(
6477
      notMatches("int rr = 3; int& r = rr;",
6478
                 referenceTypeLoc(hasReferentLoc(loc(asString("float"))))));
6479
}
6480

6481
TEST(HasReferentLoc, DoesNotBindToParameterWithoutIntReferenceTypeLoc) {
6482
  EXPECT_TRUE(notMatches(
6483
      "int f(int r) { return r; }",
6484
      parmVarDecl(hasName("r"), hasTypeLoc(referenceTypeLoc(
6485
                                    hasReferentLoc(loc(asString("int"))))))));
6486
}
6487

6488
TEST(HasAnyTemplateArgumentLoc, BindsToSpecializationWithIntArgument) {
6489
  EXPECT_TRUE(matches(
6490
      "template<typename T> class A {}; A<int> a;",
6491
      varDecl(hasName("a"),
6492
              hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc(
6493
                  templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
6494
                      hasTypeLoc(loc(asString("int")))))))))));
6495
}
6496

6497
TEST(HasAnyTemplateArgumentLoc, BindsToSpecializationWithDoubleArgument) {
6498
  EXPECT_TRUE(matches(
6499
      "template<typename T> class A {}; A<double> a;",
6500
      varDecl(hasName("a"),
6501
              hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc(
6502
                  templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
6503
                      hasTypeLoc(loc(asString("double")))))))))));
6504
}
6505

6506
TEST(HasAnyTemplateArgumentLoc, BindsToExplicitSpecializationWithIntArgument) {
6507
  EXPECT_TRUE(matches(
6508
      "template<typename T> class A {}; template<> class A<int> {};",
6509
      classTemplateSpecializationDecl(
6510
          hasName("A"),
6511
          hasAnyTemplateArgumentLoc(hasTypeLoc(loc(asString("int")))))));
6512
}
6513

6514
TEST(HasAnyTemplateArgumentLoc,
6515
     BindsToExplicitSpecializationWithDoubleArgument) {
6516
  EXPECT_TRUE(matches(
6517
      "template<typename T> class A {}; template<> class A<double> {};",
6518
      classTemplateSpecializationDecl(
6519
          hasName("A"),
6520
          hasAnyTemplateArgumentLoc(hasTypeLoc(loc(asString("double")))))));
6521
}
6522

6523
TEST(HasAnyTemplateArgumentLoc, BindsToSpecializationWithMultipleArguments) {
6524
  auto code = R"(
6525
  template<typename T, typename U> class A {};
6526
  template<> class A<double, int> {};
6527
  )";
6528
  EXPECT_TRUE(
6529
      matches(code, classTemplateSpecializationDecl(
6530
                        hasName("A"), hasAnyTemplateArgumentLoc(hasTypeLoc(
6531
                                          loc(asString("double")))))));
6532

6533
  EXPECT_TRUE(matches(
6534
      code, classTemplateSpecializationDecl(
6535
                hasName("A"),
6536
                hasAnyTemplateArgumentLoc(hasTypeLoc(loc(asString("int")))))));
6537
}
6538

6539
TEST(HasAnyTemplateArgumentLoc, DoesNotBindToSpecializationWithIntArgument) {
6540
  EXPECT_TRUE(notMatches("template<typename T> class A {}; A<int> a;",
6541
                         classTemplateSpecializationDecl(
6542
                             hasName("A"), hasAnyTemplateArgumentLoc(hasTypeLoc(
6543
                                               loc(asString("double")))))));
6544
}
6545

6546
TEST(HasAnyTemplateArgumentLoc,
6547
     DoesNotBindToExplicitSpecializationWithIntArgument) {
6548
  EXPECT_TRUE(notMatches(
6549
      "template<typename T> class A {}; template<> class A<int> {};",
6550
      classTemplateSpecializationDecl(
6551
          hasName("A"),
6552
          hasAnyTemplateArgumentLoc(hasTypeLoc(loc(asString("double")))))));
6553
}
6554

6555
TEST(HasTemplateArgumentLoc, BindsToSpecializationWithIntArgument) {
6556
  EXPECT_TRUE(
6557
      matches("template<typename T> class A {}; A<int> a;",
6558
              varDecl(hasName("a"),
6559
                      hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc(
6560
                          templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6561
                              0, hasTypeLoc(loc(asString("int")))))))))));
6562
}
6563

6564
TEST(HasTemplateArgumentLoc, BindsToSpecializationWithDoubleArgument) {
6565
  EXPECT_TRUE(
6566
      matches("template<typename T> class A {}; A<double> a;",
6567
              varDecl(hasName("a"),
6568
                      hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc(
6569
                          templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6570
                              0, hasTypeLoc(loc(asString("double")))))))))));
6571
}
6572

6573
TEST(HasTemplateArgumentLoc, DoesNotBindToSpecializationWithIntArgument) {
6574
  EXPECT_TRUE(notMatches(
6575
      "template<typename T> class A {}; A<int> a;",
6576
      varDecl(hasName("a"),
6577
              hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc(
6578
                  templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6579
                      0, hasTypeLoc(loc(asString("double")))))))))));
6580
}
6581

6582
TEST(HasTemplateArgumentLoc, BindsToExplicitSpecializationWithIntArgument) {
6583
  EXPECT_TRUE(matches(
6584
      "template<typename T> class A {}; template<> class A<int> {};",
6585
      classTemplateSpecializationDecl(
6586
          hasName("A"),
6587
          hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("int")))))));
6588
}
6589

6590
TEST(HasTemplateArgumentLoc, BindsToExplicitSpecializationWithDoubleArgument) {
6591
  EXPECT_TRUE(matches(
6592
      "template<typename T> class A {}; template<> class A<double> {};",
6593
      classTemplateSpecializationDecl(
6594
          hasName("A"),
6595
          hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("double")))))));
6596
}
6597

6598
TEST(HasTemplateArgumentLoc, BindsToSpecializationWithMultipleArguments) {
6599
  auto code = R"(
6600
  template<typename T, typename U> class A {};
6601
  template<> class A<double, int> {};
6602
  )";
6603
  EXPECT_TRUE(matches(
6604
      code, classTemplateSpecializationDecl(
6605
                hasName("A"), hasTemplateArgumentLoc(
6606
                                  0, hasTypeLoc(loc(asString("double")))))));
6607
  EXPECT_TRUE(matches(
6608
      code, classTemplateSpecializationDecl(
6609
                hasName("A"),
6610
                hasTemplateArgumentLoc(1, hasTypeLoc(loc(asString("int")))))));
6611
}
6612

6613
TEST(HasTemplateArgumentLoc,
6614
     DoesNotBindToExplicitSpecializationWithIntArgument) {
6615
  EXPECT_TRUE(notMatches(
6616
      "template<typename T> class A {}; template<> class A<int> {};",
6617
      classTemplateSpecializationDecl(
6618
          hasName("A"),
6619
          hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("double")))))));
6620
}
6621

6622
TEST(HasTemplateArgumentLoc,
6623
     DoesNotBindToSpecializationWithMisplacedArguments) {
6624
  auto code = R"(
6625
  template<typename T, typename U> class A {};
6626
  template<> class A<double, int> {};
6627
  )";
6628
  EXPECT_TRUE(notMatches(
6629
      code, classTemplateSpecializationDecl(
6630
                hasName("A"), hasTemplateArgumentLoc(
6631
                                  1, hasTypeLoc(loc(asString("double")))))));
6632
  EXPECT_TRUE(notMatches(
6633
      code, classTemplateSpecializationDecl(
6634
                hasName("A"),
6635
                hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("int")))))));
6636
}
6637

6638
TEST(HasTemplateArgumentLoc, DoesNotBindWithBadIndex) {
6639
  auto code = R"(
6640
  template<typename T, typename U> class A {};
6641
  template<> class A<double, int> {};
6642
  )";
6643
  EXPECT_TRUE(notMatches(
6644
      code, classTemplateSpecializationDecl(
6645
                hasName("A"), hasTemplateArgumentLoc(
6646
                                  -1, hasTypeLoc(loc(asString("double")))))));
6647
  EXPECT_TRUE(notMatches(
6648
      code, classTemplateSpecializationDecl(
6649
                hasName("A"), hasTemplateArgumentLoc(
6650
                                  100, hasTypeLoc(loc(asString("int")))))));
6651
}
6652

6653
TEST(HasTemplateArgumentLoc, BindsToDeclRefExprWithIntArgument) {
6654
  EXPECT_TRUE(matches(R"(
6655
      template<typename T> T f(T t) { return t; }
6656
      int g() { int i = f<int>(3); return i; }
6657
      )",
6658
                      declRefExpr(to(functionDecl(hasName("f"))),
6659
                                  hasTemplateArgumentLoc(
6660
                                      0, hasTypeLoc(loc(asString("int")))))));
6661
}
6662

6663
TEST(HasTemplateArgumentLoc, BindsToDeclRefExprWithDoubleArgument) {
6664
  EXPECT_TRUE(matches(
6665
      R"(
6666
      template<typename T> T f(T t) { return t; }
6667
      double g() { double i = f<double>(3.0); return i; }
6668
      )",
6669
      declRefExpr(
6670
          to(functionDecl(hasName("f"))),
6671
          hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("double")))))));
6672
}
6673

6674
TEST(HasTemplateArgumentLoc, DoesNotBindToDeclRefExprWithDoubleArgument) {
6675
  EXPECT_TRUE(notMatches(
6676
      R"(
6677
      template<typename T> T f(T t) { return t; }
6678
      double g() { double i = f<double>(3.0); return i; }
6679
      )",
6680
      declRefExpr(
6681
          to(functionDecl(hasName("f"))),
6682
          hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("int")))))));
6683
}
6684

6685
TEST(HasNamedTypeLoc, BindsToElaboratedObjectDeclaration) {
6686
  EXPECT_TRUE(matches(
6687
      R"(
6688
      template <typename T>
6689
      class C {};
6690
      class C<int> c;
6691
      )",
6692
      varDecl(hasName("c"),
6693
              hasTypeLoc(elaboratedTypeLoc(
6694
                  hasNamedTypeLoc(templateSpecializationTypeLoc(
6695
                      hasAnyTemplateArgumentLoc(templateArgumentLoc()))))))));
6696
}
6697

6698
TEST(HasNamedTypeLoc, DoesNotBindToNonElaboratedObjectDeclaration) {
6699
  EXPECT_TRUE(matches(
6700
      R"(
6701
      template <typename T>
6702
      class C {};
6703
      C<int> c;
6704
      )",
6705
      varDecl(hasName("c"),
6706
              hasTypeLoc(elaboratedTypeLoc(
6707
                  hasNamedTypeLoc(templateSpecializationTypeLoc(
6708
                      hasAnyTemplateArgumentLoc(templateArgumentLoc()))))))));
6709
}
6710

6711
} // namespace ast_matchers
6712
} // namespace clang
6713

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.