Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / unittests / ASTMatchers / ASTMatchersTraversalTest.cpp
blobd4a695b974bf0e5283af77bd63e4f35e7eca18d5
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 //===----------------------------------------------------------------------===//
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"
21 namespace clang {
22 namespace ast_matchers {
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()))));
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()))));
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"))))));
57 EXPECT_TRUE(matches("namespace {"
58 " namespace M {"
59 " class D {};"
60 " }"
61 "}",
62 recordDecl(hasDeclContext(namespaceDecl(
63 hasName("M"), hasDeclContext(namespaceDecl()))))));
65 EXPECT_TRUE(matches("class D{};", decl(hasDeclContext(decl()))));
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()))));
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())))));
79 EXPECT_TRUE(notMatches("void f() { float f = 2.0f; }",
80 stmt(hasDescendant(isInteger()))));
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)));
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())))));
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)));
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)));
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()))))));
125 TEST(StatementMatcher, Has) {
126 StatementMatcher HasVariableI =
127 expr(hasType(pointsTo(recordDecl(hasName("X")))),
128 has(ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("i")))))));
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));
136 TEST(StatementMatcher, HasDescendant) {
137 StatementMatcher HasDescendantVariableI =
138 expr(hasType(pointsTo(recordDecl(hasName("X")))),
139 hasDescendant(declRefExpr(to(varDecl(hasName("i"))))));
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));
149 TEST(TypeMatcher, MatchesClassType) {
150 TypeMatcher TypeA = hasDeclaration(recordDecl(hasName("A")));
152 EXPECT_TRUE(matches("class A { public: A *a; };", TypeA));
153 EXPECT_TRUE(notMatches("class A {};", TypeA));
155 TypeMatcher TypeDerivedFromA =
156 hasDeclaration(cxxRecordDecl(isDerivedFrom("A")));
158 EXPECT_TRUE(matches("class A {}; class B : public A { public: B *b; };",
159 TypeDerivedFromA));
160 EXPECT_TRUE(notMatches("class A {};", TypeA));
162 TypeMatcher TypeAHasClassB = hasDeclaration(
163 recordDecl(hasName("A"), has(recordDecl(hasName("B")))));
165 EXPECT_TRUE(
166 matches("class A { public: A *a; class B {}; };", TypeAHasClassB));
168 EXPECT_TRUE(matchesC("struct S {}; void f(void) { struct S s; }",
169 varDecl(hasType(namedDecl(hasName("S"))))));
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"))))));
206 static const char Using[] = "template <typename T>"
207 "struct Base {"
208 " typedef T Foo;"
209 "};"
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"))))));
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")))))))));
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.");
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()))))));
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()))))))));
254 // FIXME: Add tests for other types with getDecl() (e.g. RecordType)
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()))))))));
273 TEST(HasDeclaration, HasDeclarationOfCXXNewExpr) {
274 EXPECT_TRUE(
275 matches("int *A = new int();",
276 cxxNewExpr(hasDeclaration(functionDecl(parameterCountIs(1))))));
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()))))))));
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())))));
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"))))));
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)))));
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)))));
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));
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))));
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))));
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));
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"))));
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"))));
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"}));
395 TEST(HasTypeLoc, MatchesCXXBaseSpecifierAndCtorInitializer) {
396 llvm::StringRef code = R"cpp(
397 class Foo {};
398 class Bar : public Foo {
399 Bar() : Foo() {}
401 )cpp";
403 EXPECT_TRUE(matches(
404 code, cxxRecordDecl(hasAnyBase(hasTypeLoc(loc(asString("Foo")))))));
405 EXPECT_TRUE(
406 matches(code, cxxCtorInitializer(hasTypeLoc(loc(asString("Foo"))))));
409 TEST(HasTypeLoc, MatchesCXXFunctionalCastExpr) {
410 EXPECT_TRUE(matches("auto x = int(3);",
411 cxxFunctionalCastExpr(hasTypeLoc(loc(asString("int"))))));
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"))))));
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"))))));
427 TEST(HasTypeLoc, MatchesCXXUnresolvedConstructExpr) {
428 EXPECT_TRUE(
429 matches("template <typename T> T make() { return T(); }",
430 cxxUnresolvedConstructExpr(hasTypeLoc(loc(asString("T"))))));
433 TEST(HasTypeLoc, MatchesClassTemplateSpecializationDecl) {
434 EXPECT_TRUE(matches(
435 "template <typename T> class Foo; template <> class Foo<int> {};",
436 classTemplateSpecializationDecl(hasTypeLoc(loc(asString("Foo<int>"))))));
439 TEST(HasTypeLoc, MatchesCompoundLiteralExpr) {
440 EXPECT_TRUE(
441 matches("int* x = (int[2]) { 0, 1 };",
442 compoundLiteralExpr(hasTypeLoc(loc(asString("int[2]"))))));
445 TEST(HasTypeLoc, MatchesDeclaratorDecl) {
446 EXPECT_TRUE(matches("int x;",
447 varDecl(hasName("x"), hasTypeLoc(loc(asString("int"))))));
448 EXPECT_TRUE(matches("int x(3);",
449 varDecl(hasName("x"), hasTypeLoc(loc(asString("int"))))));
450 EXPECT_TRUE(matches("struct Foo { Foo(int, int); }; Foo x(1, 2);",
451 varDecl(hasName("x"), hasTypeLoc(loc(asString("Foo"))))));
453 // Make sure we don't crash on implicit constructors.
454 EXPECT_TRUE(notMatches("class X {}; X x;",
455 declaratorDecl(hasTypeLoc(loc(asString("int"))))));
458 TEST(HasTypeLoc, MatchesExplicitCastExpr) {
459 EXPECT_TRUE(matches("auto x = (int) 3;",
460 explicitCastExpr(hasTypeLoc(loc(asString("int"))))));
461 EXPECT_TRUE(matches("auto x = static_cast<int>(3);",
462 explicitCastExpr(hasTypeLoc(loc(asString("int"))))));
465 TEST(HasTypeLoc, MatchesObjCPropertyDecl) {
466 EXPECT_TRUE(matchesObjC(R"objc(
467 @interface Foo
468 @property int enabled;
469 @end
470 )objc",
471 objcPropertyDecl(hasTypeLoc(loc(asString("int"))))));
474 TEST(HasTypeLoc, MatchesTemplateArgumentLoc) {
475 EXPECT_TRUE(matches("template <typename T> class Foo {}; Foo<int> x;",
476 templateArgumentLoc(hasTypeLoc(loc(asString("int"))))));
479 TEST(HasTypeLoc, MatchesTypedefNameDecl) {
480 EXPECT_TRUE(matches("typedef int X;",
481 typedefNameDecl(hasTypeLoc(loc(asString("int"))))));
482 EXPECT_TRUE(matches("using X = int;",
483 typedefNameDecl(hasTypeLoc(loc(asString("int"))))));
486 TEST(Callee, MatchesDeclarations) {
487 StatementMatcher CallMethodX = callExpr(callee(cxxMethodDecl(hasName("x"))));
489 EXPECT_TRUE(matches("class Y { void x() { x(); } };", CallMethodX));
490 EXPECT_TRUE(notMatches("class Y { void x() {} };", CallMethodX));
492 CallMethodX = traverse(TK_AsIs, callExpr(callee(cxxConversionDecl())));
493 EXPECT_TRUE(
494 matches("struct Y { operator int() const; }; int i = Y();", CallMethodX));
495 EXPECT_TRUE(notMatches("struct Y { operator int() const; }; Y y = Y();",
496 CallMethodX));
499 TEST(Callee, MatchesMemberExpressions) {
500 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
501 callExpr(callee(memberExpr()))));
502 EXPECT_TRUE(
503 notMatches("class Y { void x() { this->x(); } };", callExpr(callee(callExpr()))));
506 TEST(Matcher, Argument) {
507 StatementMatcher CallArgumentY = callExpr(
508 hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
510 EXPECT_TRUE(matches("void x(int) { int y; x(y); }", CallArgumentY));
511 EXPECT_TRUE(
512 matches("class X { void x(int) { int y; x(y); } };", CallArgumentY));
513 EXPECT_TRUE(notMatches("void x(int) { int z; x(z); }", CallArgumentY));
515 StatementMatcher WrongIndex = callExpr(
516 hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
517 EXPECT_TRUE(notMatches("void x(int) { int y; x(y); }", WrongIndex));
520 TEST(Matcher, AnyArgument) {
521 auto HasArgumentY = hasAnyArgument(
522 ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("y"))))));
523 StatementMatcher CallArgumentY = callExpr(HasArgumentY);
524 StatementMatcher CtorArgumentY = cxxConstructExpr(HasArgumentY);
525 StatementMatcher UnresolvedCtorArgumentY =
526 cxxUnresolvedConstructExpr(HasArgumentY);
527 StatementMatcher ObjCCallArgumentY = objcMessageExpr(HasArgumentY);
528 EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
529 EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
530 EXPECT_TRUE(matches("struct Y { Y(int, int); };"
531 "void x() { int y; (void)Y(1, y); }",
532 CtorArgumentY));
533 EXPECT_TRUE(matches("struct Y { Y(int, int); };"
534 "void x() { int y; (void)Y(y, 42); }",
535 CtorArgumentY));
536 EXPECT_TRUE(matches("template <class Y> void x() { int y; (void)Y(1, y); }",
537 UnresolvedCtorArgumentY));
538 EXPECT_TRUE(matches("template <class Y> void x() { int y; (void)Y(y, 42); }",
539 UnresolvedCtorArgumentY));
540 EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) y; @end "
541 "void x(I* i) { int y; [i f:y]; }",
542 ObjCCallArgumentY));
543 EXPECT_FALSE(matchesObjC("@interface I -(void)f:(int) z; @end "
544 "void x(I* i) { int z; [i f:z]; }",
545 ObjCCallArgumentY));
546 EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
547 EXPECT_TRUE(notMatches("struct Y { Y(int, int); };"
548 "void x() { int y; (void)Y(1, 2); }",
549 CtorArgumentY));
550 EXPECT_TRUE(notMatches("template <class Y>"
551 "void x() { int y; (void)Y(1, 2); }",
552 UnresolvedCtorArgumentY));
554 StatementMatcher ImplicitCastedArgument =
555 traverse(TK_AsIs, callExpr(hasAnyArgument(implicitCastExpr())));
556 EXPECT_TRUE(matches("void x(long) { int y; x(y); }", ImplicitCastedArgument));
559 TEST(Matcher, HasReceiver) {
560 EXPECT_TRUE(matchesObjC(
561 "@interface NSString @end "
562 "void f(NSString *x) {"
563 "[x containsString];"
564 "}",
565 objcMessageExpr(hasReceiver(declRefExpr(to(varDecl(hasName("x"))))))));
567 EXPECT_FALSE(matchesObjC(
568 "@interface NSString +(NSString *) stringWithFormat; @end "
569 "void f() { [NSString stringWithFormat]; }",
570 objcMessageExpr(hasReceiver(declRefExpr(to(varDecl(hasName("x"))))))));
573 TEST(Matcher, MatchesMethodsOnLambda) {
574 StringRef Code = R"cpp(
575 struct A {
576 ~A() {}
578 void foo()
580 A a;
581 auto l = [a] { };
582 auto lCopy = l;
583 auto lPtrDecay = +[] { };
584 (void)lPtrDecay;
586 )cpp";
588 EXPECT_TRUE(matches(
589 Code, cxxConstructorDecl(
590 hasBody(compoundStmt()),
591 hasAncestor(lambdaExpr(hasAncestor(varDecl(hasName("l"))))),
592 isCopyConstructor())));
593 EXPECT_TRUE(matches(
594 Code, cxxConstructorDecl(
595 hasBody(compoundStmt()),
596 hasAncestor(lambdaExpr(hasAncestor(varDecl(hasName("l"))))),
597 isMoveConstructor())));
598 EXPECT_TRUE(matches(
599 Code, cxxDestructorDecl(
600 hasBody(compoundStmt()),
601 hasAncestor(lambdaExpr(hasAncestor(varDecl(hasName("l"))))))));
602 EXPECT_TRUE(matches(
603 Code, cxxConversionDecl(hasBody(compoundStmt(has(returnStmt(
604 hasReturnValue(implicitCastExpr()))))),
605 hasAncestor(lambdaExpr(hasAncestor(
606 varDecl(hasName("lPtrDecay"))))))));
609 TEST(Matcher, MatchesCoroutine) {
610 FileContentMappings M;
611 M.push_back(std::make_pair("/coro_header", R"cpp(
612 namespace std {
614 template <class... Args>
615 struct void_t_imp {
616 using type = void;
618 template <class... Args>
619 using void_t = typename void_t_imp<Args...>::type;
621 template <class T, class = void>
622 struct traits_sfinae_base {};
624 template <class T>
625 struct traits_sfinae_base<T, void_t<typename T::promise_type>> {
626 using promise_type = typename T::promise_type;
629 template <class Ret, class... Args>
630 struct coroutine_traits : public traits_sfinae_base<Ret> {};
631 } // namespace std
632 struct awaitable {
633 bool await_ready() noexcept;
634 template <typename F>
635 void await_suspend(F) noexcept;
636 void await_resume() noexcept;
637 } a;
638 struct promise {
639 void get_return_object();
640 awaitable initial_suspend();
641 awaitable final_suspend() noexcept;
642 awaitable yield_value(int); // expected-note 2{{candidate}}
643 void return_value(int); // expected-note 2{{here}}
644 void unhandled_exception();
646 template <typename... T>
647 struct std::coroutine_traits<void, T...> { using promise_type = promise; };
648 namespace std {
649 template <class PromiseType = void>
650 struct coroutine_handle {
651 static coroutine_handle from_address(void *) noexcept;
653 } // namespace std
654 )cpp"));
655 StringRef CoReturnCode = R"cpp(
656 #include <coro_header>
657 void check_match_co_return() {
658 co_return 1;
660 )cpp";
661 EXPECT_TRUE(matchesConditionally(CoReturnCode,
662 coreturnStmt(isExpansionInMainFile()),
663 true, {"-std=c++20", "-I/"}, M));
664 StringRef CoAwaitCode = R"cpp(
665 #include <coro_header>
666 void check_match_co_await() {
667 co_await a;
669 )cpp";
670 EXPECT_TRUE(matchesConditionally(CoAwaitCode,
671 coawaitExpr(isExpansionInMainFile()),
672 true, {"-std=c++20", "-I/"}, M));
673 StringRef CoYieldCode = R"cpp(
674 #include <coro_header>
675 void check_match_co_yield() {
676 co_yield 1.0;
678 )cpp";
679 EXPECT_TRUE(matchesConditionally(CoYieldCode,
680 coyieldExpr(isExpansionInMainFile()),
681 true, {"-std=c++20", "-I/"}, M));
683 StringRef NonCoroCode = R"cpp(
684 #include <coro_header>
685 void non_coro_function() {
687 )cpp";
689 EXPECT_TRUE(matchesConditionally(CoReturnCode, coroutineBodyStmt(), true,
690 {"-std=c++20", "-I/"}, M));
691 EXPECT_TRUE(matchesConditionally(CoAwaitCode, coroutineBodyStmt(), true,
692 {"-std=c++20", "-I/"}, M));
693 EXPECT_TRUE(matchesConditionally(CoYieldCode, coroutineBodyStmt(), true,
694 {"-std=c++20", "-I/"}, M));
696 EXPECT_FALSE(matchesConditionally(NonCoroCode, coroutineBodyStmt(), true,
697 {"-std=c++20", "-I/"}, M));
699 StringRef CoroWithDeclCode = R"cpp(
700 #include <coro_header>
701 void coro() {
702 int thevar;
703 co_return 1;
705 )cpp";
706 EXPECT_TRUE(matchesConditionally(
707 CoroWithDeclCode,
708 coroutineBodyStmt(hasBody(compoundStmt(
709 has(declStmt(containsDeclaration(0, varDecl(hasName("thevar")))))))),
710 true, {"-std=c++20", "-I/"}, M));
712 StringRef CoroWithTryCatchDeclCode = R"cpp(
713 #include <coro_header>
714 void coro() try {
715 int thevar;
716 co_return 1;
717 } catch (...) {}
718 )cpp";
719 EXPECT_TRUE(matchesConditionally(
720 CoroWithTryCatchDeclCode,
721 coroutineBodyStmt(hasBody(compoundStmt(has(cxxTryStmt(has(compoundStmt(has(
722 declStmt(containsDeclaration(0, varDecl(hasName("thevar")))))))))))),
723 true, {"-std=c++20", "-I/"}, M));
726 TEST(Matcher, isClassMessage) {
727 EXPECT_TRUE(matchesObjC(
728 "@interface NSString +(NSString *) stringWithFormat; @end "
729 "void f() { [NSString stringWithFormat]; }",
730 objcMessageExpr(isClassMessage())));
732 EXPECT_FALSE(matchesObjC(
733 "@interface NSString @end "
734 "void f(NSString *x) {"
735 "[x containsString];"
736 "}",
737 objcMessageExpr(isClassMessage())));
740 TEST(Matcher, isInstanceMessage) {
741 EXPECT_TRUE(matchesObjC(
742 "@interface NSString @end "
743 "void f(NSString *x) {"
744 "[x containsString];"
745 "}",
746 objcMessageExpr(isInstanceMessage())));
748 EXPECT_FALSE(matchesObjC(
749 "@interface NSString +(NSString *) stringWithFormat; @end "
750 "void f() { [NSString stringWithFormat]; }",
751 objcMessageExpr(isInstanceMessage())));
755 TEST(Matcher, isClassMethod) {
756 EXPECT_TRUE(matchesObjC(
757 "@interface Bar + (void)bar; @end",
758 objcMethodDecl(isClassMethod())));
760 EXPECT_TRUE(matchesObjC(
761 "@interface Bar @end"
762 "@implementation Bar + (void)bar {} @end",
763 objcMethodDecl(isClassMethod())));
765 EXPECT_FALSE(matchesObjC(
766 "@interface Foo - (void)foo; @end",
767 objcMethodDecl(isClassMethod())));
769 EXPECT_FALSE(matchesObjC(
770 "@interface Foo @end "
771 "@implementation Foo - (void)foo {} @end",
772 objcMethodDecl(isClassMethod())));
775 TEST(Matcher, isInstanceMethod) {
776 EXPECT_TRUE(matchesObjC(
777 "@interface Foo - (void)foo; @end",
778 objcMethodDecl(isInstanceMethod())));
780 EXPECT_TRUE(matchesObjC(
781 "@interface Foo @end "
782 "@implementation Foo - (void)foo {} @end",
783 objcMethodDecl(isInstanceMethod())));
785 EXPECT_FALSE(matchesObjC(
786 "@interface Bar + (void)bar; @end",
787 objcMethodDecl(isInstanceMethod())));
789 EXPECT_FALSE(matchesObjC(
790 "@interface Bar @end"
791 "@implementation Bar + (void)bar {} @end",
792 objcMethodDecl(isInstanceMethod())));
795 TEST(MatcherCXXMemberCallExpr, On) {
796 StringRef Snippet1 = R"cc(
797 struct Y {
798 void m();
800 void z(Y y) { y.m(); }
801 )cc";
802 StringRef Snippet2 = R"cc(
803 struct Y {
804 void m();
806 struct X : public Y {};
807 void z(X x) { x.m(); }
808 )cc";
809 auto MatchesY = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y")))));
810 EXPECT_TRUE(matches(Snippet1, MatchesY));
811 EXPECT_TRUE(notMatches(Snippet2, MatchesY));
813 auto MatchesX = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("X")))));
814 EXPECT_TRUE(matches(Snippet2, MatchesX));
816 // Parens are ignored.
817 StringRef Snippet3 = R"cc(
818 struct Y {
819 void m();
821 Y g();
822 void z(Y y) { (g()).m(); }
823 )cc";
824 auto MatchesCall = cxxMemberCallExpr(on(callExpr()));
825 EXPECT_TRUE(matches(Snippet3, MatchesCall));
828 TEST(MatcherCXXMemberCallExpr, OnImplicitObjectArgument) {
829 StringRef Snippet1 = R"cc(
830 struct Y {
831 void m();
833 void z(Y y) { y.m(); }
834 )cc";
835 StringRef Snippet2 = R"cc(
836 struct Y {
837 void m();
839 struct X : public Y {};
840 void z(X x) { x.m(); }
841 )cc";
842 auto MatchesY = traverse(TK_AsIs, cxxMemberCallExpr(onImplicitObjectArgument(
843 hasType(cxxRecordDecl(hasName("Y"))))));
844 EXPECT_TRUE(matches(Snippet1, MatchesY));
845 EXPECT_TRUE(matches(Snippet2, MatchesY));
847 auto MatchesX = traverse(TK_AsIs, cxxMemberCallExpr(onImplicitObjectArgument(
848 hasType(cxxRecordDecl(hasName("X"))))));
849 EXPECT_TRUE(notMatches(Snippet2, MatchesX));
851 // Parens are not ignored.
852 StringRef Snippet3 = R"cc(
853 struct Y {
854 void m();
856 Y g();
857 void z(Y y) { (g()).m(); }
858 )cc";
859 auto MatchesCall = traverse(
860 TK_AsIs, cxxMemberCallExpr(onImplicitObjectArgument(callExpr())));
861 EXPECT_TRUE(notMatches(Snippet3, MatchesCall));
864 TEST(Matcher, HasObjectExpr) {
865 StringRef Snippet1 = R"cc(
866 struct X {
867 int m;
868 int f(X x) { return x.m; }
870 )cc";
871 StringRef Snippet2 = R"cc(
872 struct X {
873 int m;
874 int f(X x) { return m; }
876 )cc";
877 auto MatchesX =
878 memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))));
879 EXPECT_TRUE(matches(Snippet1, MatchesX));
880 EXPECT_TRUE(notMatches(Snippet2, MatchesX));
882 auto MatchesXPointer = memberExpr(
883 hasObjectExpression(hasType(pointsTo(cxxRecordDecl(hasName("X"))))));
884 EXPECT_TRUE(notMatches(Snippet1, MatchesXPointer));
885 EXPECT_TRUE(matches(Snippet2, MatchesXPointer));
888 TEST(ForEachArgumentWithParam, ReportsNoFalsePositives) {
889 StatementMatcher ArgumentY =
890 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
891 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
892 StatementMatcher CallExpr =
893 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
895 // IntParam does not match.
896 EXPECT_TRUE(notMatches("void f(int* i) { int* y; f(y); }", CallExpr));
897 // ArgumentY does not match.
898 EXPECT_TRUE(notMatches("void f(int i) { int x; f(x); }", CallExpr));
901 TEST(ForEachArgumentWithParam, MatchesCXXMemberCallExpr) {
902 StatementMatcher ArgumentY =
903 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
904 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
905 StatementMatcher CallExpr =
906 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
907 EXPECT_TRUE(matchAndVerifyResultTrue(
908 "struct S {"
909 " const S& operator[](int i) { return *this; }"
910 "};"
911 "void f(S S1) {"
912 " int y = 1;"
913 " S1[y];"
914 "}",
915 CallExpr, std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param", 1)));
917 StatementMatcher CallExpr2 =
918 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
919 EXPECT_TRUE(matchAndVerifyResultTrue(
920 "struct S {"
921 " static void g(int i);"
922 "};"
923 "void f() {"
924 " int y = 1;"
925 " S::g(y);"
926 "}",
927 CallExpr2, std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param", 1)));
930 TEST(ForEachArgumentWithParam, MatchesCallExpr) {
931 StatementMatcher ArgumentY =
932 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
933 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
934 StatementMatcher CallExpr =
935 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
937 EXPECT_TRUE(
938 matchAndVerifyResultTrue("void f(int i) { int y; f(y); }", CallExpr,
939 std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>(
940 "param")));
941 EXPECT_TRUE(
942 matchAndVerifyResultTrue("void f(int i) { int y; f(y); }", CallExpr,
943 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>(
944 "arg")));
946 EXPECT_TRUE(matchAndVerifyResultTrue(
947 "void f(int i, int j) { int y; f(y, y); }", CallExpr,
948 std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param", 2)));
949 EXPECT_TRUE(matchAndVerifyResultTrue(
950 "void f(int i, int j) { int y; f(y, y); }", CallExpr,
951 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg", 2)));
954 TEST(ForEachArgumentWithParam, MatchesConstructExpr) {
955 StatementMatcher ArgumentY =
956 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
957 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
958 StatementMatcher ConstructExpr = traverse(
959 TK_AsIs, cxxConstructExpr(forEachArgumentWithParam(ArgumentY, IntParam)));
961 EXPECT_TRUE(matchAndVerifyResultTrue(
962 "struct C {"
963 " C(int i) {}"
964 "};"
965 "int y = 0;"
966 "C Obj(y);",
967 ConstructExpr,
968 std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param")));
971 TEST(ForEachArgumentWithParam, HandlesBoundNodesForNonMatches) {
972 EXPECT_TRUE(matchAndVerifyResultTrue(
973 "void g(int i, int j) {"
974 " int a;"
975 " int b;"
976 " int c;"
977 " g(a, 0);"
978 " g(a, b);"
979 " g(0, b);"
980 "}",
981 functionDecl(
982 forEachDescendant(varDecl().bind("v")),
983 forEachDescendant(callExpr(forEachArgumentWithParam(
984 declRefExpr(to(decl(equalsBoundNode("v")))), parmVarDecl())))),
985 std::make_unique<VerifyIdIsBoundTo<VarDecl>>("v", 4)));
988 TEST(ForEachArgumentWithParamType, ReportsNoFalsePositives) {
989 StatementMatcher ArgumentY =
990 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
991 TypeMatcher IntType = qualType(isInteger()).bind("type");
992 StatementMatcher CallExpr =
993 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
995 // IntParam does not match.
996 EXPECT_TRUE(notMatches("void f(int* i) { int* y; f(y); }", CallExpr));
997 // ArgumentY does not match.
998 EXPECT_TRUE(notMatches("void f(int i) { int x; f(x); }", CallExpr));
1001 TEST(ForEachArgumentWithParamType, MatchesCXXMemberCallExpr) {
1002 StatementMatcher ArgumentY =
1003 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1004 TypeMatcher IntType = qualType(isInteger()).bind("type");
1005 StatementMatcher CallExpr =
1006 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1007 EXPECT_TRUE(matchAndVerifyResultTrue(
1008 "struct S {"
1009 " const S& operator[](int i) { return *this; }"
1010 "};"
1011 "void f(S S1) {"
1012 " int y = 1;"
1013 " S1[y];"
1014 "}",
1015 CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type", 1)));
1017 StatementMatcher CallExpr2 =
1018 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1019 EXPECT_TRUE(matchAndVerifyResultTrue(
1020 "struct S {"
1021 " static void g(int i);"
1022 "};"
1023 "void f() {"
1024 " int y = 1;"
1025 " S::g(y);"
1026 "}",
1027 CallExpr2, std::make_unique<VerifyIdIsBoundTo<QualType>>("type", 1)));
1030 TEST(ForEachArgumentWithParamType, MatchesCallExpr) {
1031 StatementMatcher ArgumentY =
1032 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1033 TypeMatcher IntType = qualType(isInteger()).bind("type");
1034 StatementMatcher CallExpr =
1035 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1037 EXPECT_TRUE(matchAndVerifyResultTrue(
1038 "void f(int i) { int y; f(y); }", CallExpr,
1039 std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
1040 EXPECT_TRUE(matchAndVerifyResultTrue(
1041 "void f(int i) { int y; f(y); }", CallExpr,
1042 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
1044 EXPECT_TRUE(matchAndVerifyResultTrue(
1045 "void f(int i, int j) { int y; f(y, y); }", CallExpr,
1046 std::make_unique<VerifyIdIsBoundTo<QualType>>("type", 2)));
1047 EXPECT_TRUE(matchAndVerifyResultTrue(
1048 "void f(int i, int j) { int y; f(y, y); }", CallExpr,
1049 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg", 2)));
1052 TEST(ForEachArgumentWithParamType, MatchesConstructExpr) {
1053 StatementMatcher ArgumentY =
1054 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1055 TypeMatcher IntType = qualType(isInteger()).bind("type");
1056 StatementMatcher ConstructExpr =
1057 cxxConstructExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1059 EXPECT_TRUE(matchAndVerifyResultTrue(
1060 "struct C {"
1061 " C(int i) {}"
1062 "};"
1063 "int y = 0;"
1064 "C Obj(y);",
1065 ConstructExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
1066 EXPECT_TRUE(matchAndVerifyResultTrue(
1067 "struct C {"
1068 " C(int i) {}"
1069 "};"
1070 "int y = 0;"
1071 "C Obj(y);",
1072 ConstructExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
1075 TEST(ForEachArgumentWithParamType, HandlesKandRFunctions) {
1076 StatementMatcher ArgumentY =
1077 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1078 TypeMatcher IntType = qualType(isInteger()).bind("type");
1079 StatementMatcher CallExpr =
1080 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1082 EXPECT_TRUE(matchesC("void f();\n"
1083 "void call_it(void) { int x, y; f(x, y); }\n"
1084 "void f(a, b) int a, b; {}\n"
1085 "void call_it2(void) { int x, y; f(x, y); }",
1086 CallExpr));
1089 TEST(ForEachArgumentWithParamType, HandlesBoundNodesForNonMatches) {
1090 EXPECT_TRUE(matchAndVerifyResultTrue(
1091 "void g(int i, int j) {"
1092 " int a;"
1093 " int b;"
1094 " int c;"
1095 " g(a, 0);"
1096 " g(a, b);"
1097 " g(0, b);"
1098 "}",
1099 functionDecl(
1100 forEachDescendant(varDecl().bind("v")),
1101 forEachDescendant(callExpr(forEachArgumentWithParamType(
1102 declRefExpr(to(decl(equalsBoundNode("v")))), qualType())))),
1103 std::make_unique<VerifyIdIsBoundTo<VarDecl>>("v", 4)));
1106 TEST(ForEachArgumentWithParamType, MatchesFunctionPtrCalls) {
1107 StatementMatcher ArgumentY =
1108 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1109 TypeMatcher IntType = qualType(builtinType()).bind("type");
1110 StatementMatcher CallExpr =
1111 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1113 EXPECT_TRUE(matchAndVerifyResultTrue(
1114 "void f(int i) {"
1115 "void (*f_ptr)(int) = f; int y; f_ptr(y); }",
1116 CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
1117 EXPECT_TRUE(matchAndVerifyResultTrue(
1118 "void f(int i) {"
1119 "void (*f_ptr)(int) = f; int y; f_ptr(y); }",
1120 CallExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
1123 TEST(ForEachArgumentWithParamType, MatchesMemberFunctionPtrCalls) {
1124 StatementMatcher ArgumentY =
1125 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1126 TypeMatcher IntType = qualType(builtinType()).bind("type");
1127 StatementMatcher CallExpr =
1128 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1130 StringRef S = "struct A {\n"
1131 " int f(int i) { return i + 1; }\n"
1132 " int (A::*x)(int);\n"
1133 "};\n"
1134 "void f() {\n"
1135 " int y = 42;\n"
1136 " A a;\n"
1137 " a.x = &A::f;\n"
1138 " (a.*(a.x))(y);\n"
1139 "}";
1140 EXPECT_TRUE(matchAndVerifyResultTrue(
1141 S, CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
1142 EXPECT_TRUE(matchAndVerifyResultTrue(
1143 S, CallExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
1146 TEST(ForEachArgumentWithParamType, MatchesVariadicFunctionPtrCalls) {
1147 StatementMatcher ArgumentY =
1148 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1149 TypeMatcher IntType = qualType(builtinType()).bind("type");
1150 StatementMatcher CallExpr =
1151 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1153 StringRef S = R"cpp(
1154 void fcntl(int fd, int cmd, ...) {}
1156 template <typename Func>
1157 void f(Func F) {
1158 int y = 42;
1159 F(y, 1, 3);
1162 void g() { f(fcntl); }
1163 )cpp";
1165 EXPECT_TRUE(matchAndVerifyResultTrue(
1166 S, CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
1167 EXPECT_TRUE(matchAndVerifyResultTrue(
1168 S, CallExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
1171 TEST(QualType, hasCanonicalType) {
1172 EXPECT_TRUE(notMatches("typedef int &int_ref;"
1173 "int a;"
1174 "int_ref b = a;",
1175 varDecl(hasType(qualType(referenceType())))));
1176 EXPECT_TRUE(
1177 matches("typedef int &int_ref;"
1178 "int a;"
1179 "int_ref b = a;",
1180 varDecl(hasType(qualType(hasCanonicalType(referenceType()))))));
1183 TEST(HasParameter, CallsInnerMatcher) {
1184 EXPECT_TRUE(matches("class X { void x(int) {} };",
1185 cxxMethodDecl(hasParameter(0, varDecl()))));
1186 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
1187 cxxMethodDecl(hasParameter(0, hasName("x")))));
1188 EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) x; @end",
1189 objcMethodDecl(hasParameter(0, hasName("x")))));
1190 EXPECT_TRUE(matchesObjC("int main() { void (^b)(int) = ^(int p) {}; }",
1191 blockDecl(hasParameter(0, hasName("p")))));
1194 TEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) {
1195 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
1196 cxxMethodDecl(hasParameter(42, varDecl()))));
1199 TEST(HasType, MatchesParameterVariableTypesStrictly) {
1200 EXPECT_TRUE(matches(
1201 "class X { void x(X x) {} };",
1202 cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
1203 EXPECT_TRUE(notMatches(
1204 "class X { void x(const X &x) {} };",
1205 cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
1206 EXPECT_TRUE(matches("class X { void x(const X *x) {} };",
1207 cxxMethodDecl(hasParameter(
1208 0, hasType(pointsTo(recordDecl(hasName("X"))))))));
1209 EXPECT_TRUE(matches("class X { void x(const X &x) {} };",
1210 cxxMethodDecl(hasParameter(
1211 0, hasType(references(recordDecl(hasName("X"))))))));
1214 TEST(HasAnyParameter, MatchesIndependentlyOfPosition) {
1215 EXPECT_TRUE(matches(
1216 "class Y {}; class X { void x(X x, Y y) {} };",
1217 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
1218 EXPECT_TRUE(matches(
1219 "class Y {}; class X { void x(Y y, X x) {} };",
1220 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
1221 EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) x; @end",
1222 objcMethodDecl(hasAnyParameter(hasName("x")))));
1223 EXPECT_TRUE(matchesObjC("int main() { void (^b)(int) = ^(int p) {}; }",
1224 blockDecl(hasAnyParameter(hasName("p")))));
1227 TEST(Returns, MatchesReturnTypes) {
1228 EXPECT_TRUE(matches("class Y { int f() { return 1; } };",
1229 functionDecl(returns(asString("int")))));
1230 EXPECT_TRUE(notMatches("class Y { int f() { return 1; } };",
1231 functionDecl(returns(asString("float")))));
1232 EXPECT_TRUE(matches("class Y { Y getMe() { return *this; } };",
1233 functionDecl(returns(hasDeclaration(
1234 recordDecl(hasName("Y")))))));
1237 TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
1238 EXPECT_TRUE(notMatches(
1239 "class Y {}; class X { void x(int) {} };",
1240 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
1243 TEST(HasAnyParameter, DoesNotMatchThisPointer) {
1244 EXPECT_TRUE(notMatches("class Y {}; class X { void x() {} };",
1245 cxxMethodDecl(hasAnyParameter(
1246 hasType(pointsTo(recordDecl(hasName("X"))))))));
1249 TEST(HasName, MatchesParameterVariableDeclarations) {
1250 EXPECT_TRUE(matches("class Y {}; class X { void x(int x) {} };",
1251 cxxMethodDecl(hasAnyParameter(hasName("x")))));
1252 EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
1253 cxxMethodDecl(hasAnyParameter(hasName("x")))));
1256 TEST(Matcher, MatchesTypeTemplateArgument) {
1257 EXPECT_TRUE(matches(
1258 "template<typename T> struct B {};"
1259 "B<int> b;",
1260 classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToType(
1261 asString("int"))))));
1264 TEST(Matcher, MatchesTemplateTemplateArgument) {
1265 EXPECT_TRUE(matches("template<template <typename> class S> class X {};"
1266 "template<typename T> class Y {};"
1267 "X<Y> xi;",
1268 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1269 refersToTemplate(templateName())))));
1272 TEST(Matcher, MatchesDeclarationReferenceTemplateArgument) {
1273 EXPECT_TRUE(matches(
1274 "struct B { int next; };"
1275 "template<int(B::*next_ptr)> struct A {};"
1276 "A<&B::next> a;",
1277 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1278 refersToDeclaration(fieldDecl(hasName("next")))))));
1280 EXPECT_TRUE(notMatches(
1281 "template <typename T> struct A {};"
1282 "A<int> a;",
1283 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1284 refersToDeclaration(decl())))));
1286 EXPECT_TRUE(matches(
1287 "struct B { int next; };"
1288 "template<int(B::*next_ptr)> struct A {};"
1289 "A<&B::next> a;",
1290 templateSpecializationType(hasAnyTemplateArgument(isExpr(
1291 hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))));
1293 EXPECT_TRUE(notMatches(
1294 "template <typename T> struct A {};"
1295 "A<int> a;",
1296 templateSpecializationType(hasAnyTemplateArgument(
1297 refersToDeclaration(decl())))));
1301 TEST(Matcher, MatchesSpecificArgument) {
1302 EXPECT_TRUE(matches(
1303 "template<typename T, typename U> class A {};"
1304 "A<bool, int> a;",
1305 classTemplateSpecializationDecl(hasTemplateArgument(
1306 1, refersToType(asString("int"))))));
1307 EXPECT_TRUE(notMatches(
1308 "template<typename T, typename U> class A {};"
1309 "A<int, bool> a;",
1310 classTemplateSpecializationDecl(hasTemplateArgument(
1311 1, refersToType(asString("int"))))));
1313 EXPECT_TRUE(matches(
1314 "template<typename T, typename U> class A {};"
1315 "A<bool, int> a;",
1316 templateSpecializationType(hasTemplateArgument(
1317 1, refersToType(asString("int"))))));
1318 EXPECT_TRUE(notMatches(
1319 "template<typename T, typename U> class A {};"
1320 "A<int, bool> a;",
1321 templateSpecializationType(hasTemplateArgument(
1322 1, refersToType(asString("int"))))));
1324 EXPECT_TRUE(matches(
1325 "template<typename T> void f() {};"
1326 "void func() { f<int>(); }",
1327 functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))));
1328 EXPECT_TRUE(notMatches(
1329 "template<typename T> void f() {};",
1330 functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))));
1333 TEST(TemplateArgument, Matches) {
1334 EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
1335 classTemplateSpecializationDecl(
1336 hasAnyTemplateArgument(templateArgument()))));
1337 EXPECT_TRUE(matches(
1338 "template<typename T> struct C {}; C<int> c;",
1339 templateSpecializationType(hasAnyTemplateArgument(templateArgument()))));
1341 EXPECT_TRUE(matches(
1342 "template<typename T> void f() {};"
1343 "void func() { f<int>(); }",
1344 functionDecl(hasAnyTemplateArgument(templateArgument()))));
1347 TEST(TemplateTypeParmDecl, CXXMethodDecl) {
1348 const char input[] =
1349 "template<typename T>\n"
1350 "class Class {\n"
1351 " void method();\n"
1352 "};\n"
1353 "template<typename U>\n"
1354 "void Class<U>::method() {}\n";
1355 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1356 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1359 TEST(TemplateTypeParmDecl, VarDecl) {
1360 const char input[] =
1361 "template<typename T>\n"
1362 "class Class {\n"
1363 " static T pi;\n"
1364 "};\n"
1365 "template<typename U>\n"
1366 "U Class<U>::pi = U(3.1415926535897932385);\n";
1367 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1368 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1371 TEST(TemplateTypeParmDecl, VarTemplatePartialSpecializationDecl) {
1372 const char input[] =
1373 "template<typename T>\n"
1374 "struct Struct {\n"
1375 " template<typename T2> static int field;\n"
1376 "};\n"
1377 "template<typename U>\n"
1378 "template<typename U2>\n"
1379 "int Struct<U>::field<U2*> = 123;\n";
1380 EXPECT_TRUE(
1381 matches(input, templateTypeParmDecl(hasName("T")), langCxx14OrLater()));
1382 EXPECT_TRUE(
1383 matches(input, templateTypeParmDecl(hasName("T2")), langCxx14OrLater()));
1384 EXPECT_TRUE(
1385 matches(input, templateTypeParmDecl(hasName("U")), langCxx14OrLater()));
1386 EXPECT_TRUE(
1387 matches(input, templateTypeParmDecl(hasName("U2")), langCxx14OrLater()));
1390 TEST(TemplateTypeParmDecl, ClassTemplatePartialSpecializationDecl) {
1391 const char input[] =
1392 "template<typename T>\n"
1393 "class Class {\n"
1394 " template<typename T2> struct Struct;\n"
1395 "};\n"
1396 "template<typename U>\n"
1397 "template<typename U2>\n"
1398 "struct Class<U>::Struct<U2*> {};\n";
1399 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1400 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T2"))));
1401 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1402 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U2"))));
1405 TEST(TemplateTypeParmDecl, EnumDecl) {
1406 const char input[] =
1407 "template<typename T>\n"
1408 "struct Struct {\n"
1409 " enum class Enum : T;\n"
1410 "};\n"
1411 "template<typename U>\n"
1412 "enum class Struct<U>::Enum : U {\n"
1413 " e1,\n"
1414 " e2\n"
1415 "};\n";
1416 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1417 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1420 TEST(TemplateTypeParmDecl, RecordDecl) {
1421 const char input[] =
1422 "template<typename T>\n"
1423 "class Class {\n"
1424 " struct Struct;\n"
1425 "};\n"
1426 "template<typename U>\n"
1427 "struct Class<U>::Struct {\n"
1428 " U field;\n"
1429 "};\n";
1430 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1431 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1434 TEST(RefersToIntegralType, Matches) {
1435 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
1436 classTemplateSpecializationDecl(
1437 hasAnyTemplateArgument(refersToIntegralType(
1438 asString("int"))))));
1439 EXPECT_TRUE(notMatches("template<unsigned T> struct C {}; C<42> c;",
1440 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1441 refersToIntegralType(asString("int"))))));
1444 TEST(ConstructorDeclaration, SimpleCase) {
1445 EXPECT_TRUE(matches("class Foo { Foo(int i); };",
1446 cxxConstructorDecl(ofClass(hasName("Foo")))));
1447 EXPECT_TRUE(notMatches("class Foo { Foo(int i); };",
1448 cxxConstructorDecl(ofClass(hasName("Bar")))));
1451 TEST(DestructorDeclaration, MatchesVirtualDestructor) {
1452 EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };",
1453 cxxDestructorDecl(ofClass(hasName("Foo")))));
1456 TEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) {
1457 EXPECT_TRUE(notMatches("class Foo {};",
1458 cxxDestructorDecl(ofClass(hasName("Foo")))));
1461 TEST(HasAnyConstructorInitializer, SimpleCase) {
1462 EXPECT_TRUE(
1463 notMatches("class Foo { Foo() { } };",
1464 cxxConstructorDecl(hasAnyConstructorInitializer(anything()))));
1465 EXPECT_TRUE(
1466 matches("class Foo {"
1467 " Foo() : foo_() { }"
1468 " int foo_;"
1469 "};",
1470 cxxConstructorDecl(hasAnyConstructorInitializer(anything()))));
1473 TEST(HasAnyConstructorInitializer, ForField) {
1474 static const char Code[] =
1475 "class Baz { };"
1476 "class Foo {"
1477 " Foo() : foo_(), bar_() { }"
1478 " Baz foo_;"
1479 " struct {"
1480 " Baz bar_;"
1481 " };"
1482 "};";
1483 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1484 forField(hasType(recordDecl(hasName("Baz"))))))));
1485 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1486 forField(hasName("foo_"))))));
1487 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1488 forField(hasName("bar_"))))));
1489 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1490 forField(hasType(recordDecl(hasName("Bar"))))))));
1493 TEST(HasAnyConstructorInitializer, WithInitializer) {
1494 static const char Code[] =
1495 "class Foo {"
1496 " Foo() : foo_(0) { }"
1497 " int foo_;"
1498 "};";
1499 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1500 withInitializer(integerLiteral(equals(0)))))));
1501 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1502 withInitializer(integerLiteral(equals(1)))))));
1505 TEST(HasAnyConstructorInitializer, IsWritten) {
1506 static const char Code[] =
1507 "struct Bar { Bar(){} };"
1508 "class Foo {"
1509 " Foo() : foo_() { }"
1510 " Bar foo_;"
1511 " Bar bar_;"
1512 "};";
1513 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1514 allOf(forField(hasName("foo_")), isWritten())))));
1515 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1516 allOf(forField(hasName("bar_")), isWritten())))));
1517 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1518 allOf(forField(hasName("bar_")), unless(isWritten()))))));
1521 TEST(HasAnyConstructorInitializer, IsBaseInitializer) {
1522 static const char Code[] =
1523 "struct B {};"
1524 "struct D : B {"
1525 " int I;"
1526 " D(int i) : I(i) {}"
1527 "};"
1528 "struct E : B {"
1529 " E() : B() {}"
1530 "};";
1531 EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf(
1532 hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())),
1533 hasName("E")))));
1534 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf(
1535 hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())),
1536 hasName("D")))));
1537 EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf(
1538 hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())),
1539 hasName("D")))));
1540 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf(
1541 hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())),
1542 hasName("E")))));
1545 TEST(IfStmt, ChildTraversalMatchers) {
1546 EXPECT_TRUE(matches("void f() { if (false) true; else false; }",
1547 ifStmt(hasThen(cxxBoolLiteral(equals(true))))));
1548 EXPECT_TRUE(notMatches("void f() { if (false) false; else true; }",
1549 ifStmt(hasThen(cxxBoolLiteral(equals(true))))));
1550 EXPECT_TRUE(matches("void f() { if (false) false; else true; }",
1551 ifStmt(hasElse(cxxBoolLiteral(equals(true))))));
1552 EXPECT_TRUE(notMatches("void f() { if (false) true; else false; }",
1553 ifStmt(hasElse(cxxBoolLiteral(equals(true))))));
1556 TEST(MatchBinaryOperator, HasOperatorName) {
1557 StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
1559 EXPECT_TRUE(matches("void x() { true || false; }", OperatorOr));
1560 EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
1563 TEST(MatchBinaryOperator, HasAnyOperatorName) {
1564 StatementMatcher Matcher =
1565 binaryOperator(hasAnyOperatorName("+", "-", "*", "/"));
1567 EXPECT_TRUE(matches("int x(int I) { return I + 2; }", Matcher));
1568 EXPECT_TRUE(matches("int x(int I) { return I - 2; }", Matcher));
1569 EXPECT_TRUE(matches("int x(int I) { return I * 2; }", Matcher));
1570 EXPECT_TRUE(matches("int x(int I) { return I / 2; }", Matcher));
1571 EXPECT_TRUE(notMatches("int x(int I) { return I % 2; }", Matcher));
1572 // Ensure '+= isn't mistaken.
1573 EXPECT_TRUE(notMatches("void x(int &I) { I += 1; }", Matcher));
1576 TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
1577 StatementMatcher OperatorTrueFalse =
1578 binaryOperator(hasLHS(cxxBoolLiteral(equals(true))),
1579 hasRHS(cxxBoolLiteral(equals(false))));
1581 EXPECT_TRUE(matches("void x() { true || false; }", OperatorTrueFalse));
1582 EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse));
1583 EXPECT_TRUE(notMatches("void x() { false || true; }", OperatorTrueFalse));
1585 StatementMatcher OperatorIntPointer = arraySubscriptExpr(
1586 hasLHS(hasType(isInteger())),
1587 traverse(TK_AsIs, hasRHS(hasType(pointsTo(qualType())))));
1588 EXPECT_TRUE(matches("void x() { 1[\"abc\"]; }", OperatorIntPointer));
1589 EXPECT_TRUE(notMatches("void x() { \"abc\"[1]; }", OperatorIntPointer));
1591 StringRef Code = R"cpp(
1592 struct HasOpEqMem
1594 bool operator==(const HasOpEqMem& other) const
1596 return true;
1600 struct HasOpFree
1603 bool operator==(const HasOpFree& lhs, const HasOpFree& rhs)
1605 return true;
1608 void opMem()
1610 HasOpEqMem s1;
1611 HasOpEqMem s2;
1612 if (s1 == s2)
1613 return;
1616 void opFree()
1618 HasOpFree s1;
1619 HasOpFree s2;
1620 if (s1 == s2)
1621 return;
1623 )cpp";
1624 auto s1Expr = declRefExpr(to(varDecl(hasName("s1"))));
1625 auto s2Expr = declRefExpr(to(varDecl(hasName("s2"))));
1626 EXPECT_TRUE(matches(
1627 Code,
1628 traverse(TK_IgnoreUnlessSpelledInSource,
1629 cxxOperatorCallExpr(forFunction(functionDecl(hasName("opMem"))),
1630 hasOperatorName("=="), hasLHS(s1Expr),
1631 hasRHS(s2Expr)))));
1632 EXPECT_TRUE(matches(
1633 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1634 cxxOperatorCallExpr(
1635 forFunction(functionDecl(hasName("opMem"))),
1636 hasAnyOperatorName("!=", "=="), hasLHS(s1Expr)))));
1637 EXPECT_TRUE(matches(
1638 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1639 cxxOperatorCallExpr(
1640 forFunction(functionDecl(hasName("opMem"))),
1641 hasOperatorName("=="), hasOperands(s1Expr, s2Expr)))));
1642 EXPECT_TRUE(matches(
1643 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1644 cxxOperatorCallExpr(
1645 forFunction(functionDecl(hasName("opMem"))),
1646 hasOperatorName("=="), hasEitherOperand(s2Expr)))));
1648 EXPECT_TRUE(matches(
1649 Code,
1650 traverse(TK_IgnoreUnlessSpelledInSource,
1651 cxxOperatorCallExpr(forFunction(functionDecl(hasName("opFree"))),
1652 hasOperatorName("=="), hasLHS(s1Expr),
1653 hasRHS(s2Expr)))));
1654 EXPECT_TRUE(matches(
1655 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1656 cxxOperatorCallExpr(
1657 forFunction(functionDecl(hasName("opFree"))),
1658 hasAnyOperatorName("!=", "=="), hasLHS(s1Expr)))));
1659 EXPECT_TRUE(matches(
1660 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1661 cxxOperatorCallExpr(
1662 forFunction(functionDecl(hasName("opFree"))),
1663 hasOperatorName("=="), hasOperands(s1Expr, s2Expr)))));
1664 EXPECT_TRUE(matches(
1665 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1666 cxxOperatorCallExpr(
1667 forFunction(functionDecl(hasName("opFree"))),
1668 hasOperatorName("=="), hasEitherOperand(s2Expr)))));
1671 TEST(MatchBinaryOperator, HasEitherOperand) {
1672 StatementMatcher HasOperand =
1673 binaryOperator(hasEitherOperand(cxxBoolLiteral(equals(false))));
1675 EXPECT_TRUE(matches("void x() { true || false; }", HasOperand));
1676 EXPECT_TRUE(matches("void x() { false && true; }", HasOperand));
1677 EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand));
1680 TEST(MatchBinaryOperator, HasOperands) {
1681 StatementMatcher HasOperands = binaryOperator(
1682 hasOperands(integerLiteral(equals(1)), integerLiteral(equals(2))));
1683 EXPECT_TRUE(matches("void x() { 1 + 2; }", HasOperands));
1684 EXPECT_TRUE(matches("void x() { 2 + 1; }", HasOperands));
1685 EXPECT_TRUE(notMatches("void x() { 1 + 1; }", HasOperands));
1686 EXPECT_TRUE(notMatches("void x() { 2 + 2; }", HasOperands));
1687 EXPECT_TRUE(notMatches("void x() { 0 + 0; }", HasOperands));
1688 EXPECT_TRUE(notMatches("void x() { 0 + 1; }", HasOperands));
1691 TEST(Matcher, BinaryOperatorTypes) {
1692 // Integration test that verifies the AST provides all binary operators in
1693 // a way we expect.
1694 // FIXME: Operator ','
1695 EXPECT_TRUE(
1696 matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(","))));
1697 EXPECT_TRUE(
1698 matches("bool b; bool c = (b = true);",
1699 binaryOperator(hasOperatorName("="))));
1700 EXPECT_TRUE(
1701 matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!="))));
1702 EXPECT_TRUE(
1703 matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("=="))));
1704 EXPECT_TRUE(matches("bool b = 1 < 2;", binaryOperator(hasOperatorName("<"))));
1705 EXPECT_TRUE(
1706 matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<="))));
1707 EXPECT_TRUE(
1708 matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<"))));
1709 EXPECT_TRUE(
1710 matches("int i = 1; int j = (i <<= 2);",
1711 binaryOperator(hasOperatorName("<<="))));
1712 EXPECT_TRUE(matches("bool b = 1 > 2;", binaryOperator(hasOperatorName(">"))));
1713 EXPECT_TRUE(
1714 matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">="))));
1715 EXPECT_TRUE(
1716 matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>"))));
1717 EXPECT_TRUE(
1718 matches("int i = 1; int j = (i >>= 2);",
1719 binaryOperator(hasOperatorName(">>="))));
1720 EXPECT_TRUE(
1721 matches("int i = 42 ^ 23;", binaryOperator(hasOperatorName("^"))));
1722 EXPECT_TRUE(
1723 matches("int i = 42; int j = (i ^= 42);",
1724 binaryOperator(hasOperatorName("^="))));
1725 EXPECT_TRUE(
1726 matches("int i = 42 % 23;", binaryOperator(hasOperatorName("%"))));
1727 EXPECT_TRUE(
1728 matches("int i = 42; int j = (i %= 42);",
1729 binaryOperator(hasOperatorName("%="))));
1730 EXPECT_TRUE(
1731 matches("bool b = 42 &23;", binaryOperator(hasOperatorName("&"))));
1732 EXPECT_TRUE(
1733 matches("bool b = true && false;",
1734 binaryOperator(hasOperatorName("&&"))));
1735 EXPECT_TRUE(
1736 matches("bool b = true; bool c = (b &= false);",
1737 binaryOperator(hasOperatorName("&="))));
1738 EXPECT_TRUE(
1739 matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|"))));
1740 EXPECT_TRUE(
1741 matches("bool b = true || false;",
1742 binaryOperator(hasOperatorName("||"))));
1743 EXPECT_TRUE(
1744 matches("bool b = true; bool c = (b |= false);",
1745 binaryOperator(hasOperatorName("|="))));
1746 EXPECT_TRUE(
1747 matches("int i = 42 *23;", binaryOperator(hasOperatorName("*"))));
1748 EXPECT_TRUE(
1749 matches("int i = 42; int j = (i *= 23);",
1750 binaryOperator(hasOperatorName("*="))));
1751 EXPECT_TRUE(
1752 matches("int i = 42 / 23;", binaryOperator(hasOperatorName("/"))));
1753 EXPECT_TRUE(
1754 matches("int i = 42; int j = (i /= 23);",
1755 binaryOperator(hasOperatorName("/="))));
1756 EXPECT_TRUE(
1757 matches("int i = 42 + 23;", binaryOperator(hasOperatorName("+"))));
1758 EXPECT_TRUE(
1759 matches("int i = 42; int j = (i += 23);",
1760 binaryOperator(hasOperatorName("+="))));
1761 EXPECT_TRUE(
1762 matches("int i = 42 - 23;", binaryOperator(hasOperatorName("-"))));
1763 EXPECT_TRUE(
1764 matches("int i = 42; int j = (i -= 23);",
1765 binaryOperator(hasOperatorName("-="))));
1766 EXPECT_TRUE(
1767 matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };",
1768 binaryOperator(hasOperatorName("->*"))));
1769 EXPECT_TRUE(
1770 matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };",
1771 binaryOperator(hasOperatorName(".*"))));
1773 // Member expressions as operators are not supported in matches.
1774 EXPECT_TRUE(
1775 notMatches("struct A { void x(A *a) { a->x(this); } };",
1776 binaryOperator(hasOperatorName("->"))));
1778 // Initializer assignments are not represented as operator equals.
1779 EXPECT_TRUE(
1780 notMatches("bool b = true;", binaryOperator(hasOperatorName("="))));
1782 // Array indexing is not represented as operator.
1783 EXPECT_TRUE(notMatches("int a[42]; void x() { a[23]; }", unaryOperator()));
1785 // Overloaded operators do not match at all.
1786 EXPECT_TRUE(notMatches(
1787 "struct A { bool operator&&(const A &a) const { return false; } };"
1788 "void x() { A a, b; a && b; }",
1789 binaryOperator()));
1792 TEST(MatchUnaryOperator, HasOperatorName) {
1793 StatementMatcher OperatorNot = unaryOperator(hasOperatorName("!"));
1795 EXPECT_TRUE(matches("void x() { !true; } ", OperatorNot));
1796 EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
1799 TEST(MatchUnaryOperator, HasAnyOperatorName) {
1800 StatementMatcher Matcher = unaryOperator(hasAnyOperatorName("-", "*", "++"));
1802 EXPECT_TRUE(matches("int x(int *I) { return *I; }", Matcher));
1803 EXPECT_TRUE(matches("int x(int I) { return -I; }", Matcher));
1804 EXPECT_TRUE(matches("void x(int &I) { I++; }", Matcher));
1805 EXPECT_TRUE(matches("void x(int &I) { ++I; }", Matcher));
1806 EXPECT_TRUE(notMatches("void x(int &I) { I--; }", Matcher));
1807 EXPECT_TRUE(notMatches("void x(int &I) { --I; }", Matcher));
1808 EXPECT_TRUE(notMatches("int *x(int &I) { return &I; }", Matcher));
1811 TEST(MatchUnaryOperator, HasUnaryOperand) {
1812 StatementMatcher OperatorOnFalse =
1813 unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false))));
1815 EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse));
1816 EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse));
1818 StringRef Code = R"cpp(
1819 struct HasOpBangMem
1821 bool operator!() const
1823 return false;
1826 struct HasOpBangFree
1829 bool operator!(HasOpBangFree const&)
1831 return false;
1834 void opMem()
1836 HasOpBangMem s1;
1837 if (!s1)
1838 return;
1840 void opFree()
1842 HasOpBangFree s1;
1843 if (!s1)
1844 return;
1846 )cpp";
1847 auto s1Expr = declRefExpr(to(varDecl(hasName("s1"))));
1848 EXPECT_TRUE(matches(
1849 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1850 cxxOperatorCallExpr(
1851 forFunction(functionDecl(hasName("opMem"))),
1852 hasOperatorName("!"), hasUnaryOperand(s1Expr)))));
1853 EXPECT_TRUE(matches(
1854 Code,
1855 traverse(TK_IgnoreUnlessSpelledInSource,
1856 cxxOperatorCallExpr(forFunction(functionDecl(hasName("opMem"))),
1857 hasAnyOperatorName("+", "!"),
1858 hasUnaryOperand(s1Expr)))));
1860 EXPECT_TRUE(matches(
1861 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1862 cxxOperatorCallExpr(
1863 forFunction(functionDecl(hasName("opFree"))),
1864 hasOperatorName("!"), hasUnaryOperand(s1Expr)))));
1865 EXPECT_TRUE(matches(
1866 Code,
1867 traverse(TK_IgnoreUnlessSpelledInSource,
1868 cxxOperatorCallExpr(forFunction(functionDecl(hasName("opFree"))),
1869 hasAnyOperatorName("+", "!"),
1870 hasUnaryOperand(s1Expr)))));
1872 Code = R"cpp(
1873 struct HasIncOperatorsMem
1875 HasIncOperatorsMem& operator++();
1876 HasIncOperatorsMem operator++(int);
1878 struct HasIncOperatorsFree
1881 HasIncOperatorsFree& operator++(HasIncOperatorsFree&);
1882 HasIncOperatorsFree operator++(HasIncOperatorsFree&, int);
1884 void prefixIncOperatorMem()
1886 HasIncOperatorsMem s1;
1887 ++s1;
1889 void prefixIncOperatorFree()
1891 HasIncOperatorsFree s1;
1892 ++s1;
1894 void postfixIncOperatorMem()
1896 HasIncOperatorsMem s1;
1897 s1++;
1899 void postfixIncOperatorFree()
1901 HasIncOperatorsFree s1;
1902 s1++;
1905 struct HasOpPlusInt
1907 HasOpPlusInt& operator+(int);
1909 void plusIntOperator()
1911 HasOpPlusInt s1;
1912 s1+1;
1914 )cpp";
1916 EXPECT_TRUE(matches(
1917 Code,
1918 traverse(TK_IgnoreUnlessSpelledInSource,
1919 cxxOperatorCallExpr(
1920 forFunction(functionDecl(hasName("prefixIncOperatorMem"))),
1921 hasOperatorName("++"), hasUnaryOperand(declRefExpr())))));
1923 EXPECT_TRUE(matches(
1924 Code,
1925 traverse(TK_IgnoreUnlessSpelledInSource,
1926 cxxOperatorCallExpr(
1927 forFunction(functionDecl(hasName("prefixIncOperatorFree"))),
1928 hasOperatorName("++"), hasUnaryOperand(declRefExpr())))));
1930 EXPECT_TRUE(matches(
1931 Code,
1932 traverse(TK_IgnoreUnlessSpelledInSource,
1933 cxxOperatorCallExpr(
1934 forFunction(functionDecl(hasName("postfixIncOperatorMem"))),
1935 hasOperatorName("++"), hasUnaryOperand(declRefExpr())))));
1937 EXPECT_TRUE(matches(
1938 Code,
1939 traverse(TK_IgnoreUnlessSpelledInSource,
1940 cxxOperatorCallExpr(
1941 forFunction(functionDecl(hasName("postfixIncOperatorFree"))),
1942 hasOperatorName("++"), hasUnaryOperand(declRefExpr())))));
1944 EXPECT_FALSE(matches(
1945 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1946 cxxOperatorCallExpr(
1947 forFunction(functionDecl(hasName("plusIntOperator"))),
1948 hasOperatorName("+"), hasUnaryOperand(expr())))));
1950 Code = R"cpp(
1951 struct HasOpArrow
1953 int& operator*();
1955 void foo()
1957 HasOpArrow s1;
1958 *s1;
1960 )cpp";
1962 EXPECT_TRUE(
1963 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
1964 cxxOperatorCallExpr(hasOperatorName("*"),
1965 hasUnaryOperand(expr())))));
1968 TEST(Matcher, UnaryOperatorTypes) {
1969 // Integration test that verifies the AST provides all unary operators in
1970 // a way we expect.
1971 EXPECT_TRUE(matches("bool b = !true;", unaryOperator(hasOperatorName("!"))));
1972 EXPECT_TRUE(
1973 matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&"))));
1974 EXPECT_TRUE(matches("int i = ~ 1;", unaryOperator(hasOperatorName("~"))));
1975 EXPECT_TRUE(
1976 matches("bool *p; bool b = *p;", unaryOperator(hasOperatorName("*"))));
1977 EXPECT_TRUE(
1978 matches("int i; int j = +i;", unaryOperator(hasOperatorName("+"))));
1979 EXPECT_TRUE(
1980 matches("int i; int j = -i;", unaryOperator(hasOperatorName("-"))));
1981 EXPECT_TRUE(
1982 matches("int i; int j = ++i;", unaryOperator(hasOperatorName("++"))));
1983 EXPECT_TRUE(
1984 matches("int i; int j = i++;", unaryOperator(hasOperatorName("++"))));
1985 EXPECT_TRUE(
1986 matches("int i; int j = --i;", unaryOperator(hasOperatorName("--"))));
1987 EXPECT_TRUE(
1988 matches("int i; int j = i--;", unaryOperator(hasOperatorName("--"))));
1990 // We don't match conversion operators.
1991 EXPECT_TRUE(notMatches("int i; double d = (double)i;", unaryOperator()));
1993 // Function calls are not represented as operator.
1994 EXPECT_TRUE(notMatches("void f(); void x() { f(); }", unaryOperator()));
1996 // Overloaded operators do not match at all.
1997 // FIXME: We probably want to add that.
1998 EXPECT_TRUE(notMatches(
1999 "struct A { bool operator!() const { return false; } };"
2000 "void x() { A a; !a; }", unaryOperator(hasOperatorName("!"))));
2003 TEST(ArraySubscriptMatchers, ArrayIndex) {
2004 EXPECT_TRUE(matches(
2005 "int i[2]; void f() { i[1] = 1; }",
2006 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
2007 EXPECT_TRUE(matches(
2008 "int i[2]; void f() { 1[i] = 1; }",
2009 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
2010 EXPECT_TRUE(notMatches(
2011 "int i[2]; void f() { i[1] = 1; }",
2012 arraySubscriptExpr(hasIndex(integerLiteral(equals(0))))));
2015 TEST(ArraySubscriptMatchers, MatchesArrayBase) {
2016 EXPECT_TRUE(
2017 matches("int i[2]; void f() { i[1] = 2; }",
2018 traverse(TK_AsIs, arraySubscriptExpr(hasBase(implicitCastExpr(
2019 hasSourceExpression(declRefExpr())))))));
2022 TEST(Matcher, OfClass) {
2023 StatementMatcher Constructor = cxxConstructExpr(hasDeclaration(cxxMethodDecl(
2024 ofClass(hasName("X")))));
2026 EXPECT_TRUE(
2027 matches("class X { public: X(); }; void x(int) { X x; }", Constructor));
2028 EXPECT_TRUE(
2029 matches("class X { public: X(); }; void x(int) { X x = X(); }",
2030 Constructor));
2031 EXPECT_TRUE(
2032 notMatches("class Y { public: Y(); }; void x(int) { Y y; }",
2033 Constructor));
2036 TEST(Matcher, VisitsTemplateInstantiations) {
2037 EXPECT_TRUE(matches(
2038 "class A { public: void x(); };"
2039 "template <typename T> class B { public: void y() { T t; t.x(); } };"
2040 "void f() { B<A> b; b.y(); }",
2041 callExpr(callee(cxxMethodDecl(hasName("x"))))));
2043 EXPECT_TRUE(matches(
2044 "class A { public: void x(); };"
2045 "class C {"
2046 " public:"
2047 " template <typename T> class B { public: void y() { T t; t.x(); } };"
2048 "};"
2049 "void f() {"
2050 " C::B<A> b; b.y();"
2051 "}",
2052 recordDecl(hasName("C"), hasDescendant(callExpr(
2053 callee(cxxMethodDecl(hasName("x"))))))));
2056 TEST(Matcher, HasCondition) {
2057 StatementMatcher IfStmt =
2058 ifStmt(hasCondition(cxxBoolLiteral(equals(true))));
2059 EXPECT_TRUE(matches("void x() { if (true) {} }", IfStmt));
2060 EXPECT_TRUE(notMatches("void x() { if (false) {} }", IfStmt));
2062 StatementMatcher ForStmt =
2063 forStmt(hasCondition(cxxBoolLiteral(equals(true))));
2064 EXPECT_TRUE(matches("void x() { for (;true;) {} }", ForStmt));
2065 EXPECT_TRUE(notMatches("void x() { for (;false;) {} }", ForStmt));
2067 StatementMatcher WhileStmt =
2068 whileStmt(hasCondition(cxxBoolLiteral(equals(true))));
2069 EXPECT_TRUE(matches("void x() { while (true) {} }", WhileStmt));
2070 EXPECT_TRUE(notMatches("void x() { while (false) {} }", WhileStmt));
2072 StatementMatcher SwitchStmt =
2073 switchStmt(hasCondition(integerLiteral(equals(42))));
2074 EXPECT_TRUE(matches("void x() { switch (42) {case 42:;} }", SwitchStmt));
2075 EXPECT_TRUE(notMatches("void x() { switch (43) {case 43:;} }", SwitchStmt));
2078 TEST(For, ForLoopInternals) {
2079 EXPECT_TRUE(matches("void f(){ int i; for (; i < 3 ; ); }",
2080 forStmt(hasCondition(anything()))));
2081 EXPECT_TRUE(matches("void f() { for (int i = 0; ;); }",
2082 forStmt(hasLoopInit(anything()))));
2085 TEST(For, ForRangeLoopInternals) {
2086 EXPECT_TRUE(matches("void f(){ int a[] {1, 2}; for (int i : a); }",
2087 cxxForRangeStmt(hasLoopVariable(anything()))));
2088 EXPECT_TRUE(matches(
2089 "void f(){ int a[] {1, 2}; for (int i : a); }",
2090 cxxForRangeStmt(hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))))));
2093 TEST(For, NegativeForLoopInternals) {
2094 EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }",
2095 forStmt(hasCondition(expr()))));
2096 EXPECT_TRUE(notMatches("void f() {int i; for (; i < 4; ++i) {} }",
2097 forStmt(hasLoopInit(anything()))));
2100 TEST(HasBody, FindsBodyOfForWhileDoLoops) {
2101 EXPECT_TRUE(matches("void f() { for(;;) {} }",
2102 forStmt(hasBody(compoundStmt()))));
2103 EXPECT_TRUE(notMatches("void f() { for(;;); }",
2104 forStmt(hasBody(compoundStmt()))));
2105 EXPECT_TRUE(matches("void f() { while(true) {} }",
2106 whileStmt(hasBody(compoundStmt()))));
2107 EXPECT_TRUE(matches("void f() { do {} while(true); }",
2108 doStmt(hasBody(compoundStmt()))));
2109 EXPECT_TRUE(matches("void f() { int p[2]; for (auto x : p) {} }",
2110 cxxForRangeStmt(hasBody(compoundStmt()))));
2113 TEST(HasBody, FindsBodyOfFunctions) {
2114 EXPECT_TRUE(matches("void f() {}", functionDecl(hasBody(compoundStmt()))));
2115 EXPECT_TRUE(notMatches("void f();", functionDecl(hasBody(compoundStmt()))));
2116 EXPECT_TRUE(matchAndVerifyResultTrue(
2117 "void f(); void f() {}",
2118 functionDecl(hasBody(compoundStmt())).bind("func"),
2119 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("func", 1)));
2120 EXPECT_TRUE(matchAndVerifyResultTrue(
2121 "class C { void f(); }; void C::f() {}",
2122 cxxMethodDecl(hasBody(compoundStmt())).bind("met"),
2123 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("met", 1)));
2124 EXPECT_TRUE(matchAndVerifyResultTrue(
2125 "class C { C(); }; C::C() {}",
2126 cxxConstructorDecl(hasBody(compoundStmt())).bind("ctr"),
2127 std::make_unique<VerifyIdIsBoundTo<CXXConstructorDecl>>("ctr", 1)));
2128 EXPECT_TRUE(matchAndVerifyResultTrue(
2129 "class C { ~C(); }; C::~C() {}",
2130 cxxDestructorDecl(hasBody(compoundStmt())).bind("dtr"),
2131 std::make_unique<VerifyIdIsBoundTo<CXXDestructorDecl>>("dtr", 1)));
2134 TEST(HasAnyBody, FindsAnyBodyOfFunctions) {
2135 EXPECT_TRUE(matches("void f() {}", functionDecl(hasAnyBody(compoundStmt()))));
2136 EXPECT_TRUE(notMatches("void f();",
2137 functionDecl(hasAnyBody(compoundStmt()))));
2138 EXPECT_TRUE(matchAndVerifyResultTrue(
2139 "void f(); void f() {}",
2140 functionDecl(hasAnyBody(compoundStmt())).bind("func"),
2141 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("func", 2)));
2142 EXPECT_TRUE(matchAndVerifyResultTrue(
2143 "class C { void f(); }; void C::f() {}",
2144 cxxMethodDecl(hasAnyBody(compoundStmt())).bind("met"),
2145 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("met", 2)));
2146 EXPECT_TRUE(matchAndVerifyResultTrue(
2147 "class C { C(); }; C::C() {}",
2148 cxxConstructorDecl(hasAnyBody(compoundStmt())).bind("ctr"),
2149 std::make_unique<VerifyIdIsBoundTo<CXXConstructorDecl>>("ctr", 2)));
2150 EXPECT_TRUE(matchAndVerifyResultTrue(
2151 "class C { ~C(); }; C::~C() {}",
2152 cxxDestructorDecl(hasAnyBody(compoundStmt())).bind("dtr"),
2153 std::make_unique<VerifyIdIsBoundTo<CXXDestructorDecl>>("dtr", 2)));
2156 TEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
2157 // The simplest case: every compound statement is in a function
2158 // definition, and the function body itself must be a compound
2159 // statement.
2160 EXPECT_TRUE(matches("void f() { for (;;); }",
2161 compoundStmt(hasAnySubstatement(forStmt()))));
2164 TEST(HasAnySubstatement, IsNotRecursive) {
2165 // It's really "has any immediate substatement".
2166 EXPECT_TRUE(notMatches("void f() { if (true) for (;;); }",
2167 compoundStmt(hasAnySubstatement(forStmt()))));
2170 TEST(HasAnySubstatement, MatchesInNestedCompoundStatements) {
2171 EXPECT_TRUE(matches("void f() { if (true) { for (;;); } }",
2172 compoundStmt(hasAnySubstatement(forStmt()))));
2175 TEST(HasAnySubstatement, FindsSubstatementBetweenOthers) {
2176 EXPECT_TRUE(matches("void f() { 1; 2; 3; for (;;); 4; 5; 6; }",
2177 compoundStmt(hasAnySubstatement(forStmt()))));
2180 TEST(Member, MatchesMemberAllocationFunction) {
2181 // Fails in C++11 mode
2182 EXPECT_TRUE(matchesConditionally(
2183 "namespace std { typedef typeof(sizeof(int)) size_t; }"
2184 "class X { void *operator new(std::size_t); };",
2185 cxxMethodDecl(ofClass(hasName("X"))), true, {"-std=gnu++03"}));
2187 EXPECT_TRUE(matches("class X { void operator delete(void*); };",
2188 cxxMethodDecl(ofClass(hasName("X")))));
2190 // Fails in C++11 mode
2191 EXPECT_TRUE(matchesConditionally(
2192 "namespace std { typedef typeof(sizeof(int)) size_t; }"
2193 "class X { void operator delete[](void*, std::size_t); };",
2194 cxxMethodDecl(ofClass(hasName("X"))), true, {"-std=gnu++03"}));
2197 TEST(HasDestinationType, MatchesSimpleCase) {
2198 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
2199 cxxStaticCastExpr(hasDestinationType(
2200 pointsTo(TypeMatcher(anything()))))));
2203 TEST(HasImplicitDestinationType, MatchesSimpleCase) {
2204 // This test creates an implicit const cast.
2205 EXPECT_TRUE(matches(
2206 "int x; const int i = x;",
2207 traverse(TK_AsIs,
2208 implicitCastExpr(hasImplicitDestinationType(isInteger())))));
2209 // This test creates an implicit array-to-pointer cast.
2210 EXPECT_TRUE(
2211 matches("int arr[3]; int *p = arr;",
2212 traverse(TK_AsIs, implicitCastExpr(hasImplicitDestinationType(
2213 pointsTo(TypeMatcher(anything())))))));
2216 TEST(HasImplicitDestinationType, DoesNotMatchIncorrectly) {
2217 // This test creates an implicit cast from int to char.
2218 EXPECT_TRUE(notMatches("char c = 0;",
2219 implicitCastExpr(hasImplicitDestinationType(
2220 unless(anything())))));
2221 // This test creates an implicit array-to-pointer cast.
2222 EXPECT_TRUE(notMatches("int arr[3]; int *p = arr;",
2223 implicitCastExpr(hasImplicitDestinationType(
2224 unless(anything())))));
2227 TEST(Matcher, IgnoresElidableConstructors) {
2228 EXPECT_TRUE(
2229 matches("struct H {};"
2230 "template<typename T> H B(T A);"
2231 "void f() {"
2232 " H D1;"
2233 " D1 = B(B(1));"
2234 "}",
2235 cxxOperatorCallExpr(hasArgument(
2236 1, callExpr(hasArgument(
2237 0, ignoringElidableConstructorCall(callExpr()))))),
2238 langCxx11OrLater()));
2239 EXPECT_TRUE(
2240 matches("struct H {};"
2241 "template<typename T> H B(T A);"
2242 "void f() {"
2243 " H D1;"
2244 " D1 = B(1);"
2245 "}",
2246 cxxOperatorCallExpr(hasArgument(
2247 1, callExpr(hasArgument(0, ignoringElidableConstructorCall(
2248 integerLiteral()))))),
2249 langCxx11OrLater()));
2250 EXPECT_TRUE(matches(
2251 "struct H {};"
2252 "H G();"
2253 "void f() {"
2254 " H D = G();"
2255 "}",
2256 varDecl(hasInitializer(anyOf(
2257 ignoringElidableConstructorCall(callExpr()),
2258 exprWithCleanups(has(ignoringElidableConstructorCall(callExpr())))))),
2259 langCxx11OrLater()));
2262 TEST(Matcher, IgnoresElidableInReturn) {
2263 auto matcher = expr(ignoringElidableConstructorCall(declRefExpr()));
2264 EXPECT_TRUE(matches("struct H {};"
2265 "H f() {"
2266 " H g;"
2267 " return g;"
2268 "}",
2269 matcher, langCxx11OrLater()));
2270 EXPECT_TRUE(notMatches("struct H {};"
2271 "H f() {"
2272 " return H();"
2273 "}",
2274 matcher, langCxx11OrLater()));
2277 TEST(Matcher, IgnoreElidableConstructorDoesNotMatchConstructors) {
2278 EXPECT_TRUE(matches("struct H {};"
2279 "void f() {"
2280 " H D;"
2281 "}",
2282 varDecl(hasInitializer(
2283 ignoringElidableConstructorCall(cxxConstructExpr()))),
2284 langCxx11OrLater()));
2287 TEST(Matcher, IgnoresElidableDoesNotPreventMatches) {
2288 EXPECT_TRUE(matches("void f() {"
2289 " int D = 10;"
2290 "}",
2291 expr(ignoringElidableConstructorCall(integerLiteral())),
2292 langCxx11OrLater()));
2295 TEST(Matcher, IgnoresElidableInVarInit) {
2296 auto matcher =
2297 varDecl(hasInitializer(ignoringElidableConstructorCall(callExpr())));
2298 EXPECT_TRUE(matches("struct H {};"
2299 "H G();"
2300 "void f(H D = G()) {"
2301 " return;"
2302 "}",
2303 matcher, langCxx11OrLater()));
2304 EXPECT_TRUE(matches("struct H {};"
2305 "H G();"
2306 "void f() {"
2307 " H D = G();"
2308 "}",
2309 matcher, langCxx11OrLater()));
2312 TEST(IgnoringImplicit, MatchesImplicit) {
2313 EXPECT_TRUE(matches("class C {}; C a = C();",
2314 varDecl(has(ignoringImplicit(cxxConstructExpr())))));
2317 TEST(IgnoringImplicit, MatchesNestedImplicit) {
2318 StringRef Code = R"(
2320 struct OtherType;
2322 struct SomeType
2324 SomeType() {}
2325 SomeType(const OtherType&) {}
2326 SomeType& operator=(OtherType const&) { return *this; }
2329 struct OtherType
2331 OtherType() {}
2332 ~OtherType() {}
2335 OtherType something()
2337 return {};
2340 int main()
2342 SomeType i = something();
2345 EXPECT_TRUE(matches(
2346 Code,
2347 traverse(TK_AsIs,
2348 varDecl(hasName("i"),
2349 hasInitializer(exprWithCleanups(has(cxxConstructExpr(
2350 has(expr(ignoringImplicit(cxxConstructExpr(has(
2351 expr(ignoringImplicit(callExpr())))))))))))))));
2354 TEST(IgnoringImplicit, DoesNotMatchIncorrectly) {
2355 EXPECT_TRUE(notMatches("class C {}; C a = C();",
2356 traverse(TK_AsIs, varDecl(has(cxxConstructExpr())))));
2359 TEST(Traversal, traverseMatcher) {
2361 StringRef VarDeclCode = R"cpp(
2362 void foo()
2364 int i = 3.0;
2366 )cpp";
2368 auto Matcher = varDecl(hasInitializer(floatLiteral()));
2370 EXPECT_TRUE(notMatches(VarDeclCode, traverse(TK_AsIs, Matcher)));
2371 EXPECT_TRUE(
2372 matches(VarDeclCode, traverse(TK_IgnoreUnlessSpelledInSource, Matcher)));
2374 auto ParentMatcher = floatLiteral(hasParent(varDecl(hasName("i"))));
2376 EXPECT_TRUE(notMatches(VarDeclCode, traverse(TK_AsIs, ParentMatcher)));
2377 EXPECT_TRUE(matches(VarDeclCode,
2378 traverse(TK_IgnoreUnlessSpelledInSource, ParentMatcher)));
2380 EXPECT_TRUE(matches(
2381 VarDeclCode, decl(traverse(TK_AsIs, anyOf(cxxRecordDecl(), varDecl())))));
2383 EXPECT_TRUE(
2384 matches(VarDeclCode,
2385 floatLiteral(traverse(TK_AsIs, hasParent(implicitCastExpr())))));
2387 EXPECT_TRUE(
2388 matches(VarDeclCode, floatLiteral(traverse(TK_IgnoreUnlessSpelledInSource,
2389 hasParent(varDecl())))));
2391 EXPECT_TRUE(
2392 matches(VarDeclCode, varDecl(traverse(TK_IgnoreUnlessSpelledInSource,
2393 unless(parmVarDecl())))));
2395 EXPECT_TRUE(
2396 notMatches(VarDeclCode, varDecl(traverse(TK_IgnoreUnlessSpelledInSource,
2397 has(implicitCastExpr())))));
2399 EXPECT_TRUE(matches(VarDeclCode,
2400 varDecl(traverse(TK_AsIs, has(implicitCastExpr())))));
2402 EXPECT_TRUE(matches(
2403 VarDeclCode, traverse(TK_IgnoreUnlessSpelledInSource,
2404 // The has() below strips away the ImplicitCastExpr
2405 // before the traverse(AsIs) gets to process it.
2406 varDecl(has(traverse(TK_AsIs, floatLiteral()))))));
2408 EXPECT_TRUE(
2409 matches(VarDeclCode, functionDecl(traverse(TK_AsIs, hasName("foo")))));
2411 EXPECT_TRUE(matches(
2412 VarDeclCode,
2413 functionDecl(traverse(TK_IgnoreUnlessSpelledInSource, hasName("foo")))));
2415 EXPECT_TRUE(matches(
2416 VarDeclCode, functionDecl(traverse(TK_AsIs, hasAnyName("foo", "bar")))));
2418 EXPECT_TRUE(
2419 matches(VarDeclCode, functionDecl(traverse(TK_IgnoreUnlessSpelledInSource,
2420 hasAnyName("foo", "bar")))));
2422 StringRef Code = R"cpp(
2423 void foo(int a)
2425 int i = 3.0 + a;
2427 void bar()
2429 foo(7.0);
2431 )cpp";
2432 EXPECT_TRUE(
2433 matches(Code, callExpr(traverse(TK_IgnoreUnlessSpelledInSource,
2434 hasArgument(0, floatLiteral())))));
2436 EXPECT_TRUE(
2437 matches(Code, callExpr(traverse(TK_IgnoreUnlessSpelledInSource,
2438 hasAnyArgument(floatLiteral())))));
2440 EXPECT_TRUE(matches(
2441 R"cpp(
2442 void takesBool(bool){}
2444 template <typename T>
2445 void neverInstantiatedTemplate() {
2446 takesBool(T{});
2448 )cpp",
2449 traverse(TK_IgnoreUnlessSpelledInSource,
2450 callExpr(unless(callExpr(hasDeclaration(functionDecl())))))));
2452 EXPECT_TRUE(
2453 matches(VarDeclCode, varDecl(traverse(TK_IgnoreUnlessSpelledInSource,
2454 hasType(builtinType())))));
2456 EXPECT_TRUE(
2457 matches(VarDeclCode,
2458 functionDecl(hasName("foo"),
2459 traverse(TK_AsIs, hasDescendant(floatLiteral())))));
2461 EXPECT_TRUE(notMatches(
2462 Code, traverse(TK_AsIs, floatLiteral(hasParent(callExpr(
2463 callee(functionDecl(hasName("foo")))))))));
2464 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
2465 floatLiteral(hasParent(callExpr(callee(
2466 functionDecl(hasName("foo")))))))));
2468 Code = R"cpp(
2469 void foo()
2471 int i = (3);
2473 )cpp";
2474 EXPECT_TRUE(matches(
2475 Code, traverse(TK_IgnoreUnlessSpelledInSource,
2476 varDecl(hasInitializer(integerLiteral(equals(3)))))));
2477 EXPECT_TRUE(matches(
2478 Code,
2479 traverse(TK_IgnoreUnlessSpelledInSource,
2480 integerLiteral(equals(3), hasParent(varDecl(hasName("i")))))));
2482 Code = R"cpp(
2483 const char *SomeString{"str"};
2484 )cpp";
2485 EXPECT_TRUE(
2486 matches(Code, traverse(TK_AsIs, stringLiteral(hasParent(implicitCastExpr(
2487 hasParent(initListExpr())))))));
2488 EXPECT_TRUE(
2489 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
2490 stringLiteral(hasParent(initListExpr())))));
2492 Code = R"cpp(
2493 struct String
2495 String(const char*, int = -1) {}
2498 void stringConstruct()
2500 String s = "foo";
2501 s = "bar";
2503 )cpp";
2504 EXPECT_TRUE(matches(
2505 Code,
2506 traverse(
2507 TK_AsIs,
2508 functionDecl(
2509 hasName("stringConstruct"),
2510 hasDescendant(varDecl(
2511 hasName("s"),
2512 hasInitializer(ignoringImplicit(cxxConstructExpr(hasArgument(
2513 0, ignoringImplicit(cxxConstructExpr(hasArgument(
2514 0, ignoringImplicit(stringLiteral()))))))))))))));
2516 EXPECT_TRUE(matches(
2517 Code,
2518 traverse(
2519 TK_AsIs,
2520 functionDecl(hasName("stringConstruct"),
2521 hasDescendant(cxxOperatorCallExpr(
2522 isAssignmentOperator(),
2523 hasArgument(1, ignoringImplicit(
2524 cxxConstructExpr(hasArgument(
2525 0, ignoringImplicit(stringLiteral())))))
2526 ))))));
2528 EXPECT_TRUE(matches(
2529 Code, traverse(TK_IgnoreUnlessSpelledInSource,
2530 functionDecl(hasName("stringConstruct"),
2531 hasDescendant(varDecl(
2532 hasName("s"),
2533 hasInitializer(stringLiteral())))))));
2535 EXPECT_TRUE(
2536 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
2537 functionDecl(hasName("stringConstruct"),
2538 hasDescendant(cxxOperatorCallExpr(
2539 isAssignmentOperator(),
2540 hasArgument(1, stringLiteral())))))));
2542 Code = R"cpp(
2544 struct C1 {};
2545 struct C2 { operator C1(); };
2547 void conversionOperator()
2549 C2* c2;
2550 C1 c1 = (*c2);
2553 )cpp";
2554 EXPECT_TRUE(matches(
2555 Code,
2556 traverse(
2557 TK_AsIs,
2558 functionDecl(
2559 hasName("conversionOperator"),
2560 hasDescendant(
2561 varDecl(
2562 hasName("c1"),
2563 hasInitializer(
2564 ignoringImplicit(cxxConstructExpr(hasArgument(
2565 0, ignoringImplicit(
2566 cxxMemberCallExpr(onImplicitObjectArgument(
2567 ignoringParenImpCasts(unaryOperator(
2568 hasOperatorName("*")))))))))))
2569 .bind("c1"))))));
2571 EXPECT_TRUE(matches(
2572 Code,
2573 traverse(TK_IgnoreUnlessSpelledInSource,
2574 functionDecl(hasName("conversionOperator"),
2575 hasDescendant(varDecl(
2576 hasName("c1"), hasInitializer(unaryOperator(
2577 hasOperatorName("*")))))))));
2579 Code = R"cpp(
2581 template <unsigned alignment>
2582 void template_test() {
2583 static_assert(alignment, "");
2585 void actual_template_test() {
2586 template_test<4>();
2589 )cpp";
2590 EXPECT_TRUE(matches(
2591 Code,
2592 traverse(TK_AsIs,
2593 staticAssertDecl(has(implicitCastExpr(has(
2594 substNonTypeTemplateParmExpr(has(integerLiteral())))))))));
2595 EXPECT_TRUE(matches(
2596 Code, traverse(TK_IgnoreUnlessSpelledInSource,
2597 staticAssertDecl(has(declRefExpr(
2598 to(nonTypeTemplateParmDecl(hasName("alignment"))),
2599 hasType(asString("unsigned int"))))))));
2601 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, staticAssertDecl(hasDescendant(
2602 integerLiteral())))));
2603 EXPECT_FALSE(matches(
2604 Code, traverse(TK_IgnoreUnlessSpelledInSource,
2605 staticAssertDecl(hasDescendant(integerLiteral())))));
2607 Code = R"cpp(
2609 struct OneParamCtor {
2610 explicit OneParamCtor(int);
2612 struct TwoParamCtor {
2613 explicit TwoParamCtor(int, int);
2616 void varDeclCtors() {
2618 auto var1 = OneParamCtor(5);
2619 auto var2 = TwoParamCtor(6, 7);
2622 OneParamCtor var3(5);
2623 TwoParamCtor var4(6, 7);
2625 int i = 0;
2627 auto var5 = OneParamCtor(i);
2628 auto var6 = TwoParamCtor(i, 7);
2631 OneParamCtor var7(i);
2632 TwoParamCtor var8(i, 7);
2636 )cpp";
2637 EXPECT_TRUE(matches(
2638 Code,
2639 traverse(TK_AsIs, varDecl(hasName("var1"), hasInitializer(hasDescendant(
2640 cxxConstructExpr()))))));
2641 EXPECT_TRUE(matches(
2642 Code,
2643 traverse(TK_AsIs, varDecl(hasName("var2"), hasInitializer(hasDescendant(
2644 cxxConstructExpr()))))));
2645 EXPECT_TRUE(matches(
2646 Code, traverse(TK_AsIs, varDecl(hasName("var3"),
2647 hasInitializer(cxxConstructExpr())))));
2648 EXPECT_TRUE(matches(
2649 Code, traverse(TK_AsIs, varDecl(hasName("var4"),
2650 hasInitializer(cxxConstructExpr())))));
2651 EXPECT_TRUE(matches(
2652 Code,
2653 traverse(TK_AsIs, varDecl(hasName("var5"), hasInitializer(hasDescendant(
2654 cxxConstructExpr()))))));
2655 EXPECT_TRUE(matches(
2656 Code,
2657 traverse(TK_AsIs, varDecl(hasName("var6"), hasInitializer(hasDescendant(
2658 cxxConstructExpr()))))));
2659 EXPECT_TRUE(matches(
2660 Code, traverse(TK_AsIs, varDecl(hasName("var7"),
2661 hasInitializer(cxxConstructExpr())))));
2662 EXPECT_TRUE(matches(
2663 Code, traverse(TK_AsIs, varDecl(hasName("var8"),
2664 hasInitializer(cxxConstructExpr())))));
2666 EXPECT_TRUE(matches(
2667 Code,
2668 traverse(TK_IgnoreUnlessSpelledInSource,
2669 varDecl(hasName("var1"), hasInitializer(cxxConstructExpr())))));
2670 EXPECT_TRUE(matches(
2671 Code,
2672 traverse(TK_IgnoreUnlessSpelledInSource,
2673 varDecl(hasName("var2"), hasInitializer(cxxConstructExpr())))));
2674 EXPECT_TRUE(matches(
2675 Code,
2676 traverse(TK_IgnoreUnlessSpelledInSource,
2677 varDecl(hasName("var3"), hasInitializer(cxxConstructExpr())))));
2678 EXPECT_TRUE(matches(
2679 Code,
2680 traverse(TK_IgnoreUnlessSpelledInSource,
2681 varDecl(hasName("var4"), hasInitializer(cxxConstructExpr())))));
2682 EXPECT_TRUE(matches(
2683 Code,
2684 traverse(TK_IgnoreUnlessSpelledInSource,
2685 varDecl(hasName("var5"), hasInitializer(cxxConstructExpr())))));
2686 EXPECT_TRUE(matches(
2687 Code,
2688 traverse(TK_IgnoreUnlessSpelledInSource,
2689 varDecl(hasName("var6"), hasInitializer(cxxConstructExpr())))));
2690 EXPECT_TRUE(matches(
2691 Code,
2692 traverse(TK_IgnoreUnlessSpelledInSource,
2693 varDecl(hasName("var7"), hasInitializer(cxxConstructExpr())))));
2694 EXPECT_TRUE(matches(
2695 Code,
2696 traverse(TK_IgnoreUnlessSpelledInSource,
2697 varDecl(hasName("var8"), hasInitializer(cxxConstructExpr())))));
2699 Code = R"cpp(
2701 template<typename T>
2702 struct TemplStruct {
2703 TemplStruct() {}
2704 ~TemplStruct() {}
2706 void outOfLine(T);
2708 private:
2709 T m_t;
2712 template<typename T>
2713 void TemplStruct<T>::outOfLine(T)
2718 template<typename T>
2719 T timesTwo(T input)
2721 return input * 2;
2724 void instantiate()
2726 TemplStruct<int> ti;
2727 TemplStruct<double> td;
2728 (void)timesTwo<int>(2);
2729 (void)timesTwo<double>(2);
2732 template class TemplStruct<float>;
2734 extern template class TemplStruct<long>;
2736 template<> class TemplStruct<bool> {
2737 TemplStruct() {}
2738 ~TemplStruct() {}
2740 void boolSpecializationMethodOnly() {}
2741 private:
2742 bool m_t;
2745 template float timesTwo(float);
2746 template<> bool timesTwo<bool>(bool){
2747 return true;
2749 )cpp";
2751 auto M = cxxRecordDecl(hasName("TemplStruct"),
2752 has(fieldDecl(hasType(asString("int")))));
2753 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2754 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2757 auto M = cxxRecordDecl(hasName("TemplStruct"),
2758 has(fieldDecl(hasType(asString("double")))));
2759 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2760 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2763 auto M =
2764 functionDecl(hasName("timesTwo"),
2765 hasParameter(0, parmVarDecl(hasType(asString("int")))));
2766 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2767 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2770 auto M =
2771 functionDecl(hasName("timesTwo"),
2772 hasParameter(0, parmVarDecl(hasType(asString("double")))));
2773 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2774 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2777 // Match on the integer literal in the explicit instantiation:
2778 auto MDef =
2779 functionDecl(hasName("timesTwo"),
2780 hasParameter(0, parmVarDecl(hasType(asString("float")))),
2781 hasDescendant(integerLiteral(equals(2))));
2782 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MDef)));
2783 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MDef)));
2785 auto MTempl =
2786 functionDecl(hasName("timesTwo"),
2787 hasTemplateArgument(0, refersToType(asString("float"))));
2788 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MTempl)));
2789 // TODO: If we could match on explicit instantiations of function templates,
2790 // this would be EXPECT_TRUE. See Sema::ActOnExplicitInstantiation.
2791 EXPECT_FALSE(
2792 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MTempl)));
2795 auto M = functionDecl(hasName("timesTwo"),
2796 hasParameter(0, parmVarDecl(hasType(booleanType()))));
2797 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2798 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2801 // Match on the field within the explicit instantiation:
2802 auto MRecord = cxxRecordDecl(hasName("TemplStruct"),
2803 has(fieldDecl(hasType(asString("float")))));
2804 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MRecord)));
2805 EXPECT_FALSE(
2806 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MRecord)));
2808 // Match on the explicit template instantiation itself:
2809 auto MTempl = classTemplateSpecializationDecl(
2810 hasName("TemplStruct"),
2811 hasTemplateArgument(0,
2812 templateArgument(refersToType(asString("float")))));
2813 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MTempl)));
2814 EXPECT_TRUE(
2815 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MTempl)));
2818 // The template argument is matchable, but the instantiation is not:
2819 auto M = classTemplateSpecializationDecl(
2820 hasName("TemplStruct"),
2821 hasTemplateArgument(0,
2822 templateArgument(refersToType(asString("float")))),
2823 has(cxxConstructorDecl(hasName("TemplStruct"))));
2824 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2825 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2828 // The template argument is matchable, but the instantiation is not:
2829 auto M = classTemplateSpecializationDecl(
2830 hasName("TemplStruct"),
2831 hasTemplateArgument(0,
2832 templateArgument(refersToType(asString("long")))),
2833 has(cxxConstructorDecl(hasName("TemplStruct"))));
2834 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2835 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2838 // Instantiated, out-of-line methods are not matchable.
2839 auto M =
2840 cxxMethodDecl(hasName("outOfLine"), isDefinition(),
2841 hasParameter(0, parmVarDecl(hasType(asString("float")))));
2842 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2843 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2846 // Explicit specialization is written in source and it matches:
2847 auto M = classTemplateSpecializationDecl(
2848 hasName("TemplStruct"),
2849 hasTemplateArgument(0, templateArgument(refersToType(booleanType()))),
2850 has(cxxConstructorDecl(hasName("TemplStruct"))),
2851 has(cxxMethodDecl(hasName("boolSpecializationMethodOnly"))));
2852 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2853 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2856 Code = R"cpp(
2857 struct B {
2858 B(int);
2861 B func1() { return 42; }
2862 )cpp";
2864 auto M = expr(ignoringImplicit(integerLiteral(equals(42)).bind("intLit")));
2865 EXPECT_TRUE(matchAndVerifyResultTrue(
2866 Code, traverse(TK_AsIs, M),
2867 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2868 EXPECT_TRUE(matchAndVerifyResultTrue(
2869 Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2870 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2873 auto M = expr(unless(integerLiteral(equals(24)))).bind("intLit");
2874 EXPECT_TRUE(matchAndVerifyResultTrue(
2875 Code, traverse(TK_AsIs, M),
2876 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 6)));
2877 EXPECT_TRUE(matchAndVerifyResultTrue(
2878 Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2879 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2882 auto M =
2883 expr(anyOf(integerLiteral(equals(42)).bind("intLit"), unless(expr())));
2884 EXPECT_TRUE(matchAndVerifyResultTrue(
2885 Code, traverse(TK_AsIs, M),
2886 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2887 EXPECT_TRUE(matchAndVerifyResultTrue(
2888 Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2889 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2892 auto M = expr(allOf(integerLiteral(equals(42)).bind("intLit"), expr()));
2893 EXPECT_TRUE(matchAndVerifyResultTrue(
2894 Code, traverse(TK_AsIs, M),
2895 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2896 EXPECT_TRUE(matchAndVerifyResultTrue(
2897 Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2898 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2901 auto M = expr(integerLiteral(equals(42)).bind("intLit"), expr());
2902 EXPECT_TRUE(matchAndVerifyResultTrue(
2903 Code, traverse(TK_AsIs, M),
2904 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2905 EXPECT_TRUE(matchAndVerifyResultTrue(
2906 Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2907 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2910 auto M = expr(optionally(integerLiteral(equals(42)).bind("intLit")));
2911 EXPECT_TRUE(matchAndVerifyResultTrue(
2912 Code, traverse(TK_AsIs, M),
2913 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2914 EXPECT_TRUE(matchAndVerifyResultTrue(
2915 Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2916 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
2919 auto M = expr().bind("allExprs");
2920 EXPECT_TRUE(matchAndVerifyResultTrue(
2921 Code, traverse(TK_AsIs, M),
2922 std::make_unique<VerifyIdIsBoundTo<Expr>>("allExprs", 6)));
2923 EXPECT_TRUE(matchAndVerifyResultTrue(
2924 Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2925 std::make_unique<VerifyIdIsBoundTo<Expr>>("allExprs", 1)));
2928 Code = R"cpp(
2929 void foo()
2931 int arr[3];
2932 auto &[f, s, t] = arr;
2934 f = 42;
2936 )cpp";
2938 auto M = bindingDecl(hasName("f"));
2939 EXPECT_TRUE(
2940 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++17"}));
2941 EXPECT_TRUE(
2942 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2943 true, {"-std=c++17"}));
2946 auto M = bindingDecl(hasName("f"), has(expr()));
2947 EXPECT_TRUE(
2948 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++17"}));
2949 EXPECT_FALSE(
2950 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2951 true, {"-std=c++17"}));
2954 auto M = integerLiteral(hasAncestor(bindingDecl(hasName("f"))));
2955 EXPECT_TRUE(
2956 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++17"}));
2957 EXPECT_FALSE(
2958 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2959 true, {"-std=c++17"}));
2962 auto M = declRefExpr(hasAncestor(bindingDecl(hasName("f"))));
2963 EXPECT_TRUE(
2964 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++17"}));
2965 EXPECT_FALSE(
2966 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
2967 true, {"-std=c++17"}));
2971 TEST(Traversal, traverseNoImplicit) {
2972 StringRef Code = R"cpp(
2973 struct NonTrivial {
2974 NonTrivial() {}
2975 NonTrivial(const NonTrivial&) {}
2976 NonTrivial& operator=(const NonTrivial&) { return *this; }
2978 ~NonTrivial() {}
2981 struct NoSpecialMethods {
2982 NonTrivial nt;
2985 struct ContainsArray {
2986 NonTrivial arr[2];
2987 ContainsArray& operator=(const ContainsArray &other) = default;
2990 void copyIt()
2992 NoSpecialMethods nc1;
2993 NoSpecialMethods nc2(nc1);
2994 nc2 = nc1;
2996 ContainsArray ca;
2997 ContainsArray ca2;
2998 ca2 = ca;
3001 struct HasCtorInits : NoSpecialMethods, NonTrivial
3003 int m_i;
3004 NonTrivial m_nt;
3005 HasCtorInits() : NoSpecialMethods(), m_i(42) {}
3008 struct CtorInitsNonTrivial : NonTrivial
3010 int m_i;
3011 NonTrivial m_nt;
3012 CtorInitsNonTrivial() : NonTrivial(), m_i(42) {}
3015 )cpp";
3017 auto M = cxxRecordDecl(hasName("NoSpecialMethods"),
3018 has(cxxRecordDecl(hasName("NoSpecialMethods"))));
3019 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3020 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3022 M = cxxRecordDecl(hasName("NoSpecialMethods"),
3023 has(cxxConstructorDecl(isCopyConstructor())));
3024 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3025 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3027 M = cxxRecordDecl(hasName("NoSpecialMethods"),
3028 has(cxxMethodDecl(isCopyAssignmentOperator())));
3029 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3030 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3032 M = cxxRecordDecl(hasName("NoSpecialMethods"),
3033 has(cxxConstructorDecl(isDefaultConstructor())));
3034 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3035 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3037 M = cxxRecordDecl(hasName("NoSpecialMethods"), has(cxxDestructorDecl()));
3038 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3039 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3041 M = cxxRecordDecl(hasName("NoSpecialMethods"),
3042 hasMethod(cxxConstructorDecl(isCopyConstructor())));
3043 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3044 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3046 M = cxxRecordDecl(hasName("NoSpecialMethods"),
3047 hasMethod(cxxMethodDecl(isCopyAssignmentOperator())));
3048 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3049 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3051 M = cxxRecordDecl(hasName("NoSpecialMethods"),
3052 hasMethod(cxxConstructorDecl(isDefaultConstructor())));
3053 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3054 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3056 M = cxxRecordDecl(hasName("NoSpecialMethods"),
3057 hasMethod(cxxDestructorDecl()));
3058 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3059 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3062 // Because the copy-assignment operator is not spelled in the
3063 // source (ie, isImplicit()), we don't match it
3064 auto M =
3065 cxxOperatorCallExpr(hasType(cxxRecordDecl(hasName("NoSpecialMethods"))),
3066 callee(cxxMethodDecl(isCopyAssignmentOperator())));
3067 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3068 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3071 // Compiler generates a forStmt to copy the array
3072 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, forStmt())));
3073 EXPECT_FALSE(
3074 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, forStmt())));
3077 // The defaulted method declaration can be matched, but not its
3078 // definition, in IgnoreUnlessSpelledInSource mode
3079 auto MDecl = cxxMethodDecl(ofClass(cxxRecordDecl(hasName("ContainsArray"))),
3080 isCopyAssignmentOperator(), isDefaulted());
3082 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MDecl)));
3083 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MDecl)));
3085 auto MDef = cxxMethodDecl(MDecl, has(compoundStmt()));
3087 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MDef)));
3088 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MDef)));
3090 auto MBody = cxxMethodDecl(MDecl, hasBody(compoundStmt()));
3092 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MBody)));
3093 EXPECT_FALSE(
3094 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MBody)));
3096 auto MIsDefn = cxxMethodDecl(MDecl, isDefinition());
3098 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MIsDefn)));
3099 EXPECT_TRUE(
3100 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MIsDefn)));
3102 auto MIsInline = cxxMethodDecl(MDecl, isInline());
3104 EXPECT_FALSE(matches(Code, traverse(TK_AsIs, MIsInline)));
3105 EXPECT_FALSE(
3106 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MIsInline)));
3108 // The parameter of the defaulted method can still be matched.
3109 auto MParm =
3110 cxxMethodDecl(MDecl, hasParameter(0, parmVarDecl(hasName("other"))));
3112 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MParm)));
3113 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MParm)));
3116 auto M =
3117 cxxConstructorDecl(hasName("HasCtorInits"),
3118 has(cxxCtorInitializer(forField(hasName("m_i")))));
3119 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3120 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3123 auto M =
3124 cxxConstructorDecl(hasName("HasCtorInits"),
3125 has(cxxCtorInitializer(forField(hasName("m_nt")))));
3126 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3127 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3130 auto M = cxxConstructorDecl(hasName("HasCtorInits"),
3131 hasAnyConstructorInitializer(cxxCtorInitializer(
3132 forField(hasName("m_nt")))));
3133 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3134 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3137 auto M =
3138 cxxConstructorDecl(hasName("HasCtorInits"),
3139 forEachConstructorInitializer(
3140 cxxCtorInitializer(forField(hasName("m_nt")))));
3141 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3142 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3145 auto M = cxxConstructorDecl(
3146 hasName("CtorInitsNonTrivial"),
3147 has(cxxCtorInitializer(withInitializer(cxxConstructExpr(
3148 hasDeclaration(cxxConstructorDecl(hasName("NonTrivial"))))))));
3149 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3150 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3153 auto M = cxxConstructorDecl(
3154 hasName("HasCtorInits"),
3155 has(cxxCtorInitializer(withInitializer(cxxConstructExpr(hasDeclaration(
3156 cxxConstructorDecl(hasName("NoSpecialMethods"))))))));
3157 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3158 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3161 auto M = cxxCtorInitializer(forField(hasName("m_nt")));
3162 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3163 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3166 Code = R"cpp(
3167 void rangeFor()
3169 int arr[2];
3170 for (auto i : arr)
3172 if (true)
3177 )cpp";
3179 auto M = cxxForRangeStmt(has(binaryOperator(hasOperatorName("!="))));
3180 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3181 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3184 auto M =
3185 cxxForRangeStmt(hasDescendant(binaryOperator(hasOperatorName("+"))));
3186 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3187 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3190 auto M =
3191 cxxForRangeStmt(hasDescendant(unaryOperator(hasOperatorName("++"))));
3192 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3193 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3196 auto M = cxxForRangeStmt(has(declStmt()));
3197 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3198 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3201 auto M =
3202 cxxForRangeStmt(hasLoopVariable(varDecl(hasName("i"))),
3203 hasRangeInit(declRefExpr(to(varDecl(hasName("arr"))))));
3204 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3205 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3208 auto M = cxxForRangeStmt(unless(hasInitStatement(stmt())));
3209 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3210 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3213 auto M = cxxForRangeStmt(hasBody(stmt()));
3214 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3215 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3218 auto M = cxxForRangeStmt(hasDescendant(ifStmt()));
3219 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3220 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3223 EXPECT_TRUE(matches(
3224 Code, traverse(TK_AsIs, cxxForRangeStmt(has(declStmt(
3225 hasSingleDecl(varDecl(hasName("i")))))))));
3226 EXPECT_TRUE(
3227 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
3228 cxxForRangeStmt(has(varDecl(hasName("i")))))));
3231 EXPECT_TRUE(matches(
3232 Code, traverse(TK_AsIs, cxxForRangeStmt(has(declStmt(hasSingleDecl(
3233 varDecl(hasInitializer(declRefExpr(
3234 to(varDecl(hasName("arr")))))))))))));
3235 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
3236 cxxForRangeStmt(has(declRefExpr(
3237 to(varDecl(hasName("arr")))))))));
3240 auto M = cxxForRangeStmt(has(compoundStmt()));
3241 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3242 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3245 auto M = binaryOperator(hasOperatorName("!="));
3246 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3247 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3250 auto M = unaryOperator(hasOperatorName("++"));
3251 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3252 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3255 auto M = declStmt(hasSingleDecl(varDecl(matchesName("__range"))));
3256 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3257 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3260 auto M = declStmt(hasSingleDecl(varDecl(matchesName("__begin"))));
3261 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3262 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3265 auto M = declStmt(hasSingleDecl(varDecl(matchesName("__end"))));
3266 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3267 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3270 auto M = ifStmt(hasParent(compoundStmt(hasParent(cxxForRangeStmt()))));
3271 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3272 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3275 auto M = cxxForRangeStmt(
3276 has(varDecl(hasName("i"), hasParent(cxxForRangeStmt()))));
3277 EXPECT_FALSE(matches(Code, traverse(TK_AsIs, M)));
3278 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3281 auto M = cxxForRangeStmt(hasDescendant(varDecl(
3282 hasName("i"), hasParent(declStmt(hasParent(cxxForRangeStmt()))))));
3283 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3284 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3287 auto M = cxxForRangeStmt(hasRangeInit(declRefExpr(
3288 to(varDecl(hasName("arr"))), hasParent(cxxForRangeStmt()))));
3289 EXPECT_FALSE(matches(Code, traverse(TK_AsIs, M)));
3290 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3294 auto M = cxxForRangeStmt(hasRangeInit(declRefExpr(
3295 to(varDecl(hasName("arr"))), hasParent(varDecl(hasParent(declStmt(
3296 hasParent(cxxForRangeStmt()))))))));
3297 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3298 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3301 Code = R"cpp(
3302 struct Range {
3303 int* begin() const;
3304 int* end() const;
3306 Range getRange(int);
3308 void rangeFor()
3310 for (auto i : getRange(42))
3314 )cpp";
3316 auto M = integerLiteral(equals(42));
3317 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3318 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3321 auto M = callExpr(hasDescendant(integerLiteral(equals(42))));
3322 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3323 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3326 auto M = compoundStmt(hasDescendant(integerLiteral(equals(42))));
3327 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3328 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3331 Code = R"cpp(
3332 void rangeFor()
3334 int arr[2];
3335 for (auto& a = arr; auto i : a)
3340 )cpp";
3342 auto M = cxxForRangeStmt(has(binaryOperator(hasOperatorName("!="))));
3343 EXPECT_TRUE(
3344 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3345 EXPECT_FALSE(
3346 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3347 true, {"-std=c++20"}));
3350 auto M =
3351 cxxForRangeStmt(hasDescendant(binaryOperator(hasOperatorName("+"))));
3352 EXPECT_TRUE(
3353 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3354 EXPECT_FALSE(
3355 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3356 true, {"-std=c++20"}));
3359 auto M =
3360 cxxForRangeStmt(hasDescendant(unaryOperator(hasOperatorName("++"))));
3361 EXPECT_TRUE(
3362 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3363 EXPECT_FALSE(
3364 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3365 true, {"-std=c++20"}));
3368 auto M =
3369 cxxForRangeStmt(has(declStmt(hasSingleDecl(varDecl(hasName("i"))))));
3370 EXPECT_TRUE(
3371 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3372 EXPECT_FALSE(
3373 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3374 true, {"-std=c++20"}));
3377 auto M = cxxForRangeStmt(
3378 hasInitStatement(declStmt(hasSingleDecl(varDecl(
3379 hasName("a"),
3380 hasInitializer(declRefExpr(to(varDecl(hasName("arr"))))))))),
3381 hasLoopVariable(varDecl(hasName("i"))),
3382 hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))));
3383 EXPECT_TRUE(
3384 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3385 EXPECT_TRUE(
3386 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3387 true, {"-std=c++20"}));
3390 auto M = cxxForRangeStmt(
3391 has(declStmt(hasSingleDecl(varDecl(
3392 hasName("a"),
3393 hasInitializer(declRefExpr(to(varDecl(hasName("arr"))))))))),
3394 hasLoopVariable(varDecl(hasName("i"))),
3395 hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))));
3396 EXPECT_TRUE(
3397 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3398 EXPECT_TRUE(
3399 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3400 true, {"-std=c++20"}));
3403 auto M = cxxForRangeStmt(hasInitStatement(declStmt(
3404 hasSingleDecl(varDecl(hasName("a"))), hasParent(cxxForRangeStmt()))));
3405 EXPECT_TRUE(
3406 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3407 EXPECT_TRUE(
3408 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3409 true, {"-std=c++20"}));
3412 Code = R"cpp(
3413 struct Range {
3414 int* begin() const;
3415 int* end() const;
3417 Range getRange(int);
3419 int getNum(int);
3421 void rangeFor()
3423 for (auto j = getNum(42); auto i : getRange(j))
3427 )cpp";
3429 auto M = integerLiteral(equals(42));
3430 EXPECT_TRUE(
3431 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3432 EXPECT_TRUE(
3433 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3434 true, {"-std=c++20"}));
3437 auto M = compoundStmt(hasDescendant(integerLiteral(equals(42))));
3438 EXPECT_TRUE(
3439 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3440 EXPECT_TRUE(
3441 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3442 true, {"-std=c++20"}));
3445 Code = R"cpp(
3446 void hasDefaultArg(int i, int j = 0)
3449 void callDefaultArg()
3451 hasDefaultArg(42);
3453 )cpp";
3454 auto hasDefaultArgCall = [](auto InnerMatcher) {
3455 return callExpr(callee(functionDecl(hasName("hasDefaultArg"))),
3456 InnerMatcher);
3459 auto M = hasDefaultArgCall(has(integerLiteral(equals(42))));
3460 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3461 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3464 auto M = hasDefaultArgCall(has(cxxDefaultArgExpr()));
3465 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3466 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3469 auto M = hasDefaultArgCall(argumentCountIs(2));
3470 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3471 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3474 auto M = hasDefaultArgCall(argumentCountIs(1));
3475 EXPECT_FALSE(matches(Code, traverse(TK_AsIs, M)));
3476 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3479 auto M = hasDefaultArgCall(hasArgument(1, cxxDefaultArgExpr()));
3480 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3481 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3484 auto M = hasDefaultArgCall(hasAnyArgument(cxxDefaultArgExpr()));
3485 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3486 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3488 Code = R"cpp(
3489 struct A
3491 ~A();
3492 private:
3493 int i;
3496 A::~A() = default;
3497 )cpp";
3499 auto M = cxxDestructorDecl(isDefaulted(),
3500 ofClass(cxxRecordDecl(has(fieldDecl()))));
3501 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3502 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3504 Code = R"cpp(
3505 struct S
3507 static constexpr bool getTrue() { return true; }
3510 struct A
3512 explicit(S::getTrue()) A();
3515 A::A() = default;
3516 )cpp";
3518 EXPECT_TRUE(matchesConditionally(
3519 Code,
3520 traverse(TK_AsIs,
3521 cxxConstructorDecl(
3522 isDefaulted(),
3523 hasExplicitSpecifier(expr(ignoringImplicit(
3524 callExpr(has(ignoringImplicit(declRefExpr())))))))),
3525 true, {"-std=c++20"}));
3526 EXPECT_TRUE(matchesConditionally(
3527 Code,
3528 traverse(TK_IgnoreUnlessSpelledInSource,
3529 cxxConstructorDecl(
3530 isDefaulted(),
3531 hasExplicitSpecifier(callExpr(has(declRefExpr()))))),
3532 true, {"-std=c++20"}));
3536 template <typename MatcherT>
3537 bool matcherTemplateWithBinding(StringRef Code, const MatcherT &M) {
3538 return matchAndVerifyResultTrue(
3539 Code, M.bind("matchedStmt"),
3540 std::make_unique<VerifyIdIsBoundTo<ReturnStmt>>("matchedStmt", 1));
3543 TEST(Traversal, traverseWithBinding) {
3544 // Some existing matcher code expects to take a matcher as a
3545 // template arg and bind to it. Verify that that works.
3547 llvm::StringRef Code = R"cpp(
3548 int foo()
3550 return 42.0;
3552 )cpp";
3553 EXPECT_TRUE(matcherTemplateWithBinding(
3554 Code, traverse(TK_AsIs,
3555 returnStmt(has(implicitCastExpr(has(floatLiteral())))))));
3558 TEST(Traversal, traverseMatcherNesting) {
3560 StringRef Code = R"cpp(
3561 float bar(int i)
3563 return i;
3566 void foo()
3568 bar(bar(3.0));
3570 )cpp";
3572 EXPECT_TRUE(
3573 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
3574 callExpr(has(callExpr(traverse(
3575 TK_AsIs, callExpr(has(implicitCastExpr(
3576 has(floatLiteral())))))))))));
3578 EXPECT_TRUE(matches(
3579 Code,
3580 traverse(TK_IgnoreUnlessSpelledInSource,
3581 traverse(TK_AsIs, implicitCastExpr(has(floatLiteral()))))));
3584 TEST(Traversal, traverseMatcherThroughImplicit) {
3585 StringRef Code = R"cpp(
3586 struct S {
3587 S(int x);
3590 void constructImplicit() {
3591 int a = 8;
3592 S s(a);
3594 )cpp";
3596 auto Matcher = traverse(TK_IgnoreUnlessSpelledInSource, implicitCastExpr());
3598 // Verfiy that it does not segfault
3599 EXPECT_FALSE(matches(Code, Matcher));
3602 TEST(Traversal, traverseMatcherThroughMemoization) {
3604 StringRef Code = R"cpp(
3605 void foo()
3607 int i = 3.0;
3609 )cpp";
3611 auto Matcher = varDecl(hasInitializer(floatLiteral()));
3613 // Matchers such as hasDescendant memoize their result regarding AST
3614 // nodes. In the matcher below, the first use of hasDescendant(Matcher)
3615 // fails, and the use of it inside the traverse() matcher should pass
3616 // causing the overall matcher to be a true match.
3617 // This test verifies that the first false result is not re-used, which
3618 // would cause the overall matcher to be incorrectly false.
3620 EXPECT_TRUE(matches(
3621 Code,
3622 functionDecl(anyOf(hasDescendant(Matcher),
3623 traverse(TK_IgnoreUnlessSpelledInSource,
3624 functionDecl(hasDescendant(Matcher)))))));
3627 TEST(Traversal, traverseUnlessSpelledInSource) {
3629 StringRef Code = R"cpp(
3631 struct A
3635 struct B
3637 B(int);
3638 B(A const& a);
3639 B();
3642 struct C
3644 operator B();
3647 B func1() {
3648 return 42;
3651 B func2() {
3652 return B{42};
3655 B func3() {
3656 return B(42);
3659 B func4() {
3660 return B();
3663 B func5() {
3664 return B{};
3667 B func6() {
3668 return C();
3671 B func7() {
3672 return A();
3675 B func8() {
3676 return C{};
3679 B func9() {
3680 return A{};
3683 B func10() {
3684 A a;
3685 return a;
3688 B func11() {
3689 B b;
3690 return b;
3693 B func12() {
3694 C c;
3695 return c;
3698 void func13() {
3699 int a = 0;
3700 int c = 0;
3702 [a, b = c](int d) { int e = d; };
3705 void func14() {
3706 [] <typename TemplateType> (TemplateType t, TemplateType u) { int e = t + u; };
3707 float i = 42.0;
3710 void func15() {
3711 int count = 0;
3712 auto l = [&] { ++count; };
3713 (void)l;
3716 )cpp";
3718 EXPECT_TRUE(
3719 matches(Code,
3720 traverse(TK_IgnoreUnlessSpelledInSource,
3721 returnStmt(forFunction(functionDecl(hasName("func1"))),
3722 hasReturnValue(integerLiteral(equals(42))))),
3723 langCxx20OrLater()));
3725 EXPECT_TRUE(
3726 matches(Code,
3727 traverse(TK_IgnoreUnlessSpelledInSource,
3728 integerLiteral(equals(42),
3729 hasParent(returnStmt(forFunction(
3730 functionDecl(hasName("func1"))))))),
3731 langCxx20OrLater()));
3733 EXPECT_TRUE(matches(
3734 Code,
3735 traverse(TK_IgnoreUnlessSpelledInSource,
3736 returnStmt(forFunction(functionDecl(hasName("func2"))),
3737 hasReturnValue(cxxTemporaryObjectExpr(
3738 hasArgument(0, integerLiteral(equals(42))))))),
3739 langCxx20OrLater()));
3740 EXPECT_TRUE(matches(
3741 Code,
3742 traverse(
3743 TK_IgnoreUnlessSpelledInSource,
3744 integerLiteral(equals(42),
3745 hasParent(cxxTemporaryObjectExpr(hasParent(returnStmt(
3746 forFunction(functionDecl(hasName("func2"))))))))),
3747 langCxx20OrLater()));
3749 EXPECT_TRUE(
3750 matches(Code,
3751 traverse(TK_IgnoreUnlessSpelledInSource,
3752 returnStmt(forFunction(functionDecl(hasName("func3"))),
3753 hasReturnValue(cxxConstructExpr(hasArgument(
3754 0, integerLiteral(equals(42))))))),
3755 langCxx20OrLater()));
3757 EXPECT_TRUE(matches(
3758 Code,
3759 traverse(
3760 TK_IgnoreUnlessSpelledInSource,
3761 integerLiteral(equals(42),
3762 hasParent(cxxConstructExpr(hasParent(returnStmt(
3763 forFunction(functionDecl(hasName("func3"))))))))),
3764 langCxx20OrLater()));
3766 EXPECT_TRUE(
3767 matches(Code,
3768 traverse(TK_IgnoreUnlessSpelledInSource,
3769 returnStmt(forFunction(functionDecl(hasName("func4"))),
3770 hasReturnValue(cxxTemporaryObjectExpr()))),
3771 langCxx20OrLater()));
3773 EXPECT_TRUE(
3774 matches(Code,
3775 traverse(TK_IgnoreUnlessSpelledInSource,
3776 returnStmt(forFunction(functionDecl(hasName("func5"))),
3777 hasReturnValue(cxxTemporaryObjectExpr()))),
3778 langCxx20OrLater()));
3780 EXPECT_TRUE(
3781 matches(Code,
3782 traverse(TK_IgnoreUnlessSpelledInSource,
3783 returnStmt(forFunction(functionDecl(hasName("func6"))),
3784 hasReturnValue(cxxTemporaryObjectExpr()))),
3785 langCxx20OrLater()));
3787 EXPECT_TRUE(
3788 matches(Code,
3789 traverse(TK_IgnoreUnlessSpelledInSource,
3790 returnStmt(forFunction(functionDecl(hasName("func7"))),
3791 hasReturnValue(cxxTemporaryObjectExpr()))),
3792 langCxx20OrLater()));
3794 EXPECT_TRUE(
3795 matches(Code,
3796 traverse(TK_IgnoreUnlessSpelledInSource,
3797 returnStmt(forFunction(functionDecl(hasName("func8"))),
3798 hasReturnValue(cxxFunctionalCastExpr(
3799 hasSourceExpression(initListExpr()))))),
3800 langCxx20OrLater()));
3802 EXPECT_TRUE(
3803 matches(Code,
3804 traverse(TK_IgnoreUnlessSpelledInSource,
3805 returnStmt(forFunction(functionDecl(hasName("func9"))),
3806 hasReturnValue(cxxFunctionalCastExpr(
3807 hasSourceExpression(initListExpr()))))),
3808 langCxx20OrLater()));
3810 EXPECT_TRUE(matches(
3811 Code,
3812 traverse(
3813 TK_IgnoreUnlessSpelledInSource,
3814 returnStmt(forFunction(functionDecl(hasName("func10"))),
3815 hasReturnValue(declRefExpr(to(varDecl(hasName("a"))))))),
3816 langCxx20OrLater()));
3818 EXPECT_TRUE(
3819 matches(Code,
3820 traverse(TK_IgnoreUnlessSpelledInSource,
3821 declRefExpr(to(varDecl(hasName("a"))),
3822 hasParent(returnStmt(forFunction(
3823 functionDecl(hasName("func10"))))))),
3824 langCxx20OrLater()));
3826 EXPECT_TRUE(matches(
3827 Code,
3828 traverse(
3829 TK_IgnoreUnlessSpelledInSource,
3830 returnStmt(forFunction(functionDecl(hasName("func11"))),
3831 hasReturnValue(declRefExpr(to(varDecl(hasName("b"))))))),
3832 langCxx20OrLater()));
3834 EXPECT_TRUE(
3835 matches(Code,
3836 traverse(TK_IgnoreUnlessSpelledInSource,
3837 declRefExpr(to(varDecl(hasName("b"))),
3838 hasParent(returnStmt(forFunction(
3839 functionDecl(hasName("func11"))))))),
3840 langCxx20OrLater()));
3842 EXPECT_TRUE(matches(
3843 Code,
3844 traverse(
3845 TK_IgnoreUnlessSpelledInSource,
3846 returnStmt(forFunction(functionDecl(hasName("func12"))),
3847 hasReturnValue(declRefExpr(to(varDecl(hasName("c"))))))),
3848 langCxx20OrLater()));
3850 EXPECT_TRUE(
3851 matches(Code,
3852 traverse(TK_IgnoreUnlessSpelledInSource,
3853 declRefExpr(to(varDecl(hasName("c"))),
3854 hasParent(returnStmt(forFunction(
3855 functionDecl(hasName("func12"))))))),
3856 langCxx20OrLater()));
3858 EXPECT_TRUE(matches(
3859 Code,
3860 traverse(
3861 TK_IgnoreUnlessSpelledInSource,
3862 lambdaExpr(forFunction(functionDecl(hasName("func13"))),
3863 has(compoundStmt(hasDescendant(varDecl(hasName("e"))))),
3864 has(declRefExpr(to(varDecl(hasName("a"))))),
3865 has(varDecl(hasName("b"), hasInitializer(declRefExpr(to(
3866 varDecl(hasName("c"))))))),
3867 has(parmVarDecl(hasName("d"))))),
3868 langCxx20OrLater()));
3870 EXPECT_TRUE(
3871 matches(Code,
3872 traverse(TK_IgnoreUnlessSpelledInSource,
3873 declRefExpr(to(varDecl(hasName("a"))),
3874 hasParent(lambdaExpr(forFunction(
3875 functionDecl(hasName("func13"))))))),
3876 langCxx20OrLater()));
3878 EXPECT_TRUE(matches(
3879 Code,
3880 traverse(TK_IgnoreUnlessSpelledInSource,
3881 varDecl(hasName("b"),
3882 hasInitializer(declRefExpr(to(varDecl(hasName("c"))))),
3883 hasParent(lambdaExpr(
3884 forFunction(functionDecl(hasName("func13"))))))),
3885 langCxx20OrLater()));
3887 EXPECT_TRUE(matches(Code,
3888 traverse(TK_IgnoreUnlessSpelledInSource,
3889 compoundStmt(hasParent(lambdaExpr(forFunction(
3890 functionDecl(hasName("func13"))))))),
3891 langCxx20OrLater()));
3893 EXPECT_TRUE(matches(
3894 Code,
3895 traverse(TK_IgnoreUnlessSpelledInSource,
3896 templateTypeParmDecl(hasName("TemplateType"),
3897 hasParent(lambdaExpr(forFunction(
3898 functionDecl(hasName("func14"))))))),
3899 langCxx20OrLater()));
3901 EXPECT_TRUE(matches(
3902 Code,
3903 traverse(TK_IgnoreUnlessSpelledInSource,
3904 lambdaExpr(forFunction(functionDecl(hasName("func14"))),
3905 has(templateTypeParmDecl(hasName("TemplateType"))))),
3906 langCxx20OrLater()));
3908 EXPECT_TRUE(matches(
3909 Code,
3910 traverse(TK_IgnoreUnlessSpelledInSource,
3911 functionDecl(hasName("func14"), hasDescendant(floatLiteral()))),
3912 langCxx20OrLater()));
3914 EXPECT_TRUE(matches(
3915 Code,
3916 traverse(TK_IgnoreUnlessSpelledInSource,
3917 compoundStmt(
3918 hasDescendant(varDecl(hasName("count")).bind("countVar")),
3919 hasDescendant(
3920 declRefExpr(to(varDecl(equalsBoundNode("countVar"))))))),
3921 langCxx20OrLater()));
3923 Code = R"cpp(
3924 void foo() {
3925 int explicit_captured = 0;
3926 int implicit_captured = 0;
3927 auto l = [&, explicit_captured](int i) {
3928 if (i || explicit_captured || implicit_captured) return;
3931 )cpp";
3933 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, ifStmt())));
3934 EXPECT_TRUE(
3935 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, ifStmt())));
3937 auto lambdaExplicitCapture = declRefExpr(
3938 to(varDecl(hasName("explicit_captured"))), unless(hasAncestor(ifStmt())));
3939 auto lambdaImplicitCapture = declRefExpr(
3940 to(varDecl(hasName("implicit_captured"))), unless(hasAncestor(ifStmt())));
3942 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, lambdaExplicitCapture)));
3943 EXPECT_TRUE(matches(
3944 Code, traverse(TK_IgnoreUnlessSpelledInSource, lambdaExplicitCapture)));
3946 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, lambdaImplicitCapture)));
3947 EXPECT_FALSE(matches(
3948 Code, traverse(TK_IgnoreUnlessSpelledInSource, lambdaImplicitCapture)));
3950 Code = R"cpp(
3951 struct S {};
3953 struct HasOpEq
3955 bool operator==(const S& other)
3957 return true;
3961 void binop()
3963 HasOpEq s1;
3964 S s2;
3965 if (s1 != s2)
3966 return;
3968 )cpp";
3970 auto M = unaryOperator(
3971 hasOperatorName("!"),
3972 has(cxxOperatorCallExpr(hasOverloadedOperatorName("=="))));
3973 EXPECT_TRUE(
3974 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3975 EXPECT_FALSE(
3976 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3977 true, {"-std=c++20"}));
3980 auto M = declRefExpr(to(varDecl(hasName("s1"))));
3981 EXPECT_TRUE(
3982 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3983 EXPECT_TRUE(
3984 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3985 true, {"-std=c++20"}));
3988 auto M = cxxOperatorCallExpr(hasOverloadedOperatorName("=="));
3989 EXPECT_TRUE(
3990 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3991 EXPECT_FALSE(
3992 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3993 true, {"-std=c++20"}));
3996 auto M = cxxOperatorCallExpr(hasOverloadedOperatorName("!="));
3997 EXPECT_FALSE(
3998 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3999 EXPECT_FALSE(
4000 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4001 true, {"-std=c++20"}));
4003 auto withDescendants = [](StringRef lName, StringRef rName) {
4004 return stmt(hasDescendant(declRefExpr(to(varDecl(hasName(lName))))),
4005 hasDescendant(declRefExpr(to(varDecl(hasName(rName))))));
4008 auto M = cxxRewrittenBinaryOperator(withDescendants("s1", "s2"));
4009 EXPECT_TRUE(
4010 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4011 EXPECT_TRUE(
4012 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4013 true, {"-std=c++20"}));
4016 auto M = cxxRewrittenBinaryOperator(
4017 has(declRefExpr(to(varDecl(hasName("s1"))))),
4018 has(declRefExpr(to(varDecl(hasName("s2"))))));
4019 EXPECT_FALSE(
4020 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4021 EXPECT_TRUE(
4022 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4023 true, {"-std=c++20"}));
4026 auto M = cxxRewrittenBinaryOperator(
4027 hasLHS(expr(hasParent(cxxRewrittenBinaryOperator()))),
4028 hasRHS(expr(hasParent(cxxRewrittenBinaryOperator()))));
4029 EXPECT_FALSE(
4030 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4031 EXPECT_TRUE(
4032 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4033 true, {"-std=c++20"}));
4036 EXPECT_TRUE(matchesConditionally(
4037 Code,
4038 traverse(TK_AsIs,
4039 cxxRewrittenBinaryOperator(
4040 hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4041 isComparisonOperator(),
4042 hasLHS(ignoringImplicit(
4043 declRefExpr(to(varDecl(hasName("s1")))))),
4044 hasRHS(ignoringImplicit(
4045 declRefExpr(to(varDecl(hasName("s2")))))),
4046 hasEitherOperand(ignoringImplicit(
4047 declRefExpr(to(varDecl(hasName("s2")))))),
4048 hasOperands(ignoringImplicit(
4049 declRefExpr(to(varDecl(hasName("s1"))))),
4050 ignoringImplicit(declRefExpr(
4051 to(varDecl(hasName("s2")))))))),
4052 true, {"-std=c++20"}));
4053 EXPECT_TRUE(matchesConditionally(
4054 Code,
4055 traverse(TK_IgnoreUnlessSpelledInSource,
4056 cxxRewrittenBinaryOperator(
4057 hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4058 isComparisonOperator(),
4059 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
4060 hasRHS(declRefExpr(to(varDecl(hasName("s2"))))),
4061 hasEitherOperand(declRefExpr(to(varDecl(hasName("s2"))))),
4062 hasOperands(declRefExpr(to(varDecl(hasName("s1")))),
4063 declRefExpr(to(varDecl(hasName("s2"))))))),
4064 true, {"-std=c++20"}));
4067 Code = R"cpp(
4068 namespace std {
4069 struct strong_ordering {
4070 int n;
4071 constexpr operator int() const { return n; }
4072 static const strong_ordering equal, greater, less;
4074 constexpr strong_ordering strong_ordering::equal = {0};
4075 constexpr strong_ordering strong_ordering::greater = {1};
4076 constexpr strong_ordering strong_ordering::less = {-1};
4079 struct HasSpaceshipMem {
4080 int a;
4081 constexpr auto operator<=>(const HasSpaceshipMem&) const = default;
4084 void binop()
4086 HasSpaceshipMem hs1, hs2;
4087 if (hs1 == hs2)
4088 return;
4090 HasSpaceshipMem hs3, hs4;
4091 if (hs3 != hs4)
4092 return;
4094 HasSpaceshipMem hs5, hs6;
4095 if (hs5 < hs6)
4096 return;
4098 HasSpaceshipMem hs7, hs8;
4099 if (hs7 > hs8)
4100 return;
4102 HasSpaceshipMem hs9, hs10;
4103 if (hs9 <= hs10)
4104 return;
4106 HasSpaceshipMem hs11, hs12;
4107 if (hs11 >= hs12)
4108 return;
4110 )cpp";
4111 auto withArgs = [](StringRef lName, StringRef rName) {
4112 return cxxOperatorCallExpr(
4113 hasArgument(0, declRefExpr(to(varDecl(hasName(lName))))),
4114 hasArgument(1, declRefExpr(to(varDecl(hasName(rName))))));
4117 auto M = ifStmt(hasCondition(cxxOperatorCallExpr(
4118 hasOverloadedOperatorName("=="), withArgs("hs1", "hs2"))));
4119 EXPECT_TRUE(
4120 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4121 EXPECT_TRUE(
4122 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4123 true, {"-std=c++20"}));
4126 auto M =
4127 unaryOperator(hasOperatorName("!"),
4128 has(cxxOperatorCallExpr(hasOverloadedOperatorName("=="),
4129 withArgs("hs3", "hs4"))));
4130 EXPECT_TRUE(
4131 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4132 EXPECT_FALSE(
4133 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4134 true, {"-std=c++20"}));
4137 auto M =
4138 unaryOperator(hasOperatorName("!"),
4139 has(cxxOperatorCallExpr(hasOverloadedOperatorName("=="),
4140 withArgs("hs3", "hs4"))));
4141 EXPECT_TRUE(
4142 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4143 EXPECT_FALSE(
4144 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4145 true, {"-std=c++20"}));
4148 auto M = binaryOperator(
4149 hasOperatorName("<"),
4150 hasLHS(hasDescendant(cxxOperatorCallExpr(
4151 hasOverloadedOperatorName("<=>"), withArgs("hs5", "hs6")))),
4152 hasRHS(integerLiteral(equals(0))));
4153 EXPECT_TRUE(
4154 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4155 EXPECT_FALSE(
4156 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4157 true, {"-std=c++20"}));
4160 auto M = cxxRewrittenBinaryOperator(withDescendants("hs3", "hs4"));
4161 EXPECT_TRUE(
4162 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4163 EXPECT_TRUE(
4164 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4165 true, {"-std=c++20"}));
4168 auto M = declRefExpr(to(varDecl(hasName("hs3"))));
4169 EXPECT_TRUE(
4170 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4171 EXPECT_TRUE(
4172 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4173 true, {"-std=c++20"}));
4176 auto M = cxxRewrittenBinaryOperator(has(
4177 unaryOperator(hasOperatorName("!"), withDescendants("hs3", "hs4"))));
4178 EXPECT_TRUE(
4179 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4180 EXPECT_FALSE(
4181 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4182 true, {"-std=c++20"}));
4185 auto M = cxxRewrittenBinaryOperator(
4186 has(declRefExpr(to(varDecl(hasName("hs3"))))),
4187 has(declRefExpr(to(varDecl(hasName("hs4"))))));
4188 EXPECT_FALSE(
4189 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4190 EXPECT_TRUE(
4191 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4192 true, {"-std=c++20"}));
4195 EXPECT_TRUE(matchesConditionally(
4196 Code,
4197 traverse(TK_AsIs,
4198 cxxRewrittenBinaryOperator(
4199 hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4200 isComparisonOperator(),
4201 hasLHS(ignoringImplicit(
4202 declRefExpr(to(varDecl(hasName("hs3")))))),
4203 hasRHS(ignoringImplicit(
4204 declRefExpr(to(varDecl(hasName("hs4")))))),
4205 hasEitherOperand(ignoringImplicit(
4206 declRefExpr(to(varDecl(hasName("hs3")))))),
4207 hasOperands(ignoringImplicit(
4208 declRefExpr(to(varDecl(hasName("hs3"))))),
4209 ignoringImplicit(declRefExpr(
4210 to(varDecl(hasName("hs4")))))))),
4211 true, {"-std=c++20"}));
4212 EXPECT_TRUE(matchesConditionally(
4213 Code,
4214 traverse(TK_IgnoreUnlessSpelledInSource,
4215 cxxRewrittenBinaryOperator(
4216 hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4217 isComparisonOperator(),
4218 hasLHS(declRefExpr(to(varDecl(hasName("hs3"))))),
4219 hasRHS(declRefExpr(to(varDecl(hasName("hs4"))))),
4220 hasEitherOperand(declRefExpr(to(varDecl(hasName("hs3"))))),
4221 hasOperands(declRefExpr(to(varDecl(hasName("hs3")))),
4222 declRefExpr(to(varDecl(hasName("hs4"))))))),
4223 true, {"-std=c++20"}));
4226 EXPECT_TRUE(matchesConditionally(
4227 Code,
4228 traverse(TK_AsIs,
4229 cxxRewrittenBinaryOperator(
4230 hasOperatorName("<"), hasAnyOperatorName("<", "!="),
4231 isComparisonOperator(),
4232 hasLHS(ignoringImplicit(
4233 declRefExpr(to(varDecl(hasName("hs5")))))),
4234 hasRHS(ignoringImplicit(
4235 declRefExpr(to(varDecl(hasName("hs6")))))),
4236 hasEitherOperand(ignoringImplicit(
4237 declRefExpr(to(varDecl(hasName("hs5")))))),
4238 hasOperands(ignoringImplicit(
4239 declRefExpr(to(varDecl(hasName("hs5"))))),
4240 ignoringImplicit(declRefExpr(
4241 to(varDecl(hasName("hs6")))))))),
4242 true, {"-std=c++20"}));
4243 EXPECT_TRUE(matchesConditionally(
4244 Code,
4245 traverse(TK_IgnoreUnlessSpelledInSource,
4246 cxxRewrittenBinaryOperator(
4247 hasOperatorName("<"), hasAnyOperatorName("<", "!="),
4248 isComparisonOperator(),
4249 hasLHS(declRefExpr(to(varDecl(hasName("hs5"))))),
4250 hasRHS(declRefExpr(to(varDecl(hasName("hs6"))))),
4251 hasEitherOperand(declRefExpr(to(varDecl(hasName("hs5"))))),
4252 hasOperands(declRefExpr(to(varDecl(hasName("hs5")))),
4253 declRefExpr(to(varDecl(hasName("hs6"))))))),
4254 true, {"-std=c++20"}));
4257 EXPECT_TRUE(matchesConditionally(
4258 Code,
4259 traverse(TK_AsIs,
4260 cxxRewrittenBinaryOperator(
4261 hasOperatorName(">"), hasAnyOperatorName("<", ">"),
4262 isComparisonOperator(),
4263 hasLHS(ignoringImplicit(
4264 declRefExpr(to(varDecl(hasName("hs7")))))),
4265 hasRHS(ignoringImplicit(
4266 declRefExpr(to(varDecl(hasName("hs8")))))),
4267 hasEitherOperand(ignoringImplicit(
4268 declRefExpr(to(varDecl(hasName("hs7")))))),
4269 hasOperands(ignoringImplicit(
4270 declRefExpr(to(varDecl(hasName("hs7"))))),
4271 ignoringImplicit(declRefExpr(
4272 to(varDecl(hasName("hs8")))))))),
4273 true, {"-std=c++20"}));
4274 EXPECT_TRUE(matchesConditionally(
4275 Code,
4276 traverse(TK_IgnoreUnlessSpelledInSource,
4277 cxxRewrittenBinaryOperator(
4278 hasOperatorName(">"), hasAnyOperatorName("<", ">"),
4279 isComparisonOperator(),
4280 hasLHS(declRefExpr(to(varDecl(hasName("hs7"))))),
4281 hasRHS(declRefExpr(to(varDecl(hasName("hs8"))))),
4282 hasEitherOperand(declRefExpr(to(varDecl(hasName("hs7"))))),
4283 hasOperands(declRefExpr(to(varDecl(hasName("hs7")))),
4284 declRefExpr(to(varDecl(hasName("hs8"))))))),
4285 true, {"-std=c++20"}));
4288 EXPECT_TRUE(matchesConditionally(
4289 Code,
4290 traverse(TK_AsIs,
4291 cxxRewrittenBinaryOperator(
4292 hasOperatorName("<="), hasAnyOperatorName("<", "<="),
4293 isComparisonOperator(),
4294 hasLHS(ignoringImplicit(
4295 declRefExpr(to(varDecl(hasName("hs9")))))),
4296 hasRHS(ignoringImplicit(
4297 declRefExpr(to(varDecl(hasName("hs10")))))),
4298 hasEitherOperand(ignoringImplicit(
4299 declRefExpr(to(varDecl(hasName("hs9")))))),
4300 hasOperands(ignoringImplicit(
4301 declRefExpr(to(varDecl(hasName("hs9"))))),
4302 ignoringImplicit(declRefExpr(
4303 to(varDecl(hasName("hs10")))))))),
4304 true, {"-std=c++20"}));
4305 EXPECT_TRUE(matchesConditionally(
4306 Code,
4307 traverse(TK_IgnoreUnlessSpelledInSource,
4308 cxxRewrittenBinaryOperator(
4309 hasOperatorName("<="), hasAnyOperatorName("<", "<="),
4310 isComparisonOperator(),
4311 hasLHS(declRefExpr(to(varDecl(hasName("hs9"))))),
4312 hasRHS(declRefExpr(to(varDecl(hasName("hs10"))))),
4313 hasEitherOperand(declRefExpr(to(varDecl(hasName("hs9"))))),
4314 hasOperands(declRefExpr(to(varDecl(hasName("hs9")))),
4315 declRefExpr(to(varDecl(hasName("hs10"))))))),
4316 true, {"-std=c++20"}));
4319 EXPECT_TRUE(matchesConditionally(
4320 Code,
4321 traverse(TK_AsIs,
4322 cxxRewrittenBinaryOperator(
4323 hasOperatorName(">="), hasAnyOperatorName("<", ">="),
4324 isComparisonOperator(),
4325 hasLHS(ignoringImplicit(
4326 declRefExpr(to(varDecl(hasName("hs11")))))),
4327 hasRHS(ignoringImplicit(
4328 declRefExpr(to(varDecl(hasName("hs12")))))),
4329 hasEitherOperand(ignoringImplicit(
4330 declRefExpr(to(varDecl(hasName("hs11")))))),
4331 hasOperands(ignoringImplicit(
4332 declRefExpr(to(varDecl(hasName("hs11"))))),
4333 ignoringImplicit(declRefExpr(
4334 to(varDecl(hasName("hs12")))))))),
4335 true, {"-std=c++20"}));
4336 EXPECT_TRUE(matchesConditionally(
4337 Code,
4338 traverse(
4339 TK_IgnoreUnlessSpelledInSource,
4340 cxxRewrittenBinaryOperator(
4341 hasOperatorName(">="), hasAnyOperatorName("<", ">="),
4342 isComparisonOperator(),
4343 hasLHS(declRefExpr(to(varDecl(hasName("hs11"))))),
4344 hasRHS(declRefExpr(to(varDecl(hasName("hs12"))))),
4345 hasEitherOperand(declRefExpr(to(varDecl(hasName("hs11"))))),
4346 hasOperands(declRefExpr(to(varDecl(hasName("hs11")))),
4347 declRefExpr(to(varDecl(hasName("hs12"))))))),
4348 true, {"-std=c++20"}));
4351 Code = R"cpp(
4352 struct S {};
4354 struct HasOpEq
4356 bool operator==(const S& other) const
4358 return true;
4362 struct HasOpEqMem {
4363 bool operator==(const HasOpEqMem&) const { return true; }
4366 struct HasOpEqFree {
4368 bool operator==(const HasOpEqFree&, const HasOpEqFree&) { return true; }
4370 void binop()
4373 HasOpEq s1;
4374 S s2;
4375 if (s1 != s2)
4376 return;
4380 int i1;
4381 int i2;
4382 if (i1 != i2)
4383 return;
4387 HasOpEqMem M1;
4388 HasOpEqMem M2;
4389 if (M1 == M2)
4390 return;
4394 HasOpEqFree F1;
4395 HasOpEqFree F2;
4396 if (F1 == F2)
4397 return;
4400 )cpp";
4402 EXPECT_TRUE(matchesConditionally(
4403 Code,
4404 traverse(TK_AsIs,
4405 binaryOperation(
4406 hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4407 isComparisonOperator(),
4408 hasLHS(ignoringImplicit(
4409 declRefExpr(to(varDecl(hasName("s1")))))),
4410 hasRHS(ignoringImplicit(
4411 declRefExpr(to(varDecl(hasName("s2")))))),
4412 hasEitherOperand(ignoringImplicit(
4413 declRefExpr(to(varDecl(hasName("s2")))))),
4414 hasOperands(ignoringImplicit(
4415 declRefExpr(to(varDecl(hasName("s1"))))),
4416 ignoringImplicit(declRefExpr(
4417 to(varDecl(hasName("s2")))))))),
4418 true, {"-std=c++20"}));
4419 EXPECT_TRUE(matchesConditionally(
4420 Code,
4421 traverse(TK_AsIs, binaryOperation(hasOperatorName("!="),
4422 hasLHS(ignoringImplicit(declRefExpr(
4423 to(varDecl(hasName("i1")))))),
4424 hasRHS(ignoringImplicit(declRefExpr(
4425 to(varDecl(hasName("i2")))))))),
4426 true, {"-std=c++20"}));
4427 EXPECT_TRUE(matchesConditionally(
4428 Code,
4429 traverse(TK_AsIs, binaryOperation(hasOperatorName("=="),
4430 hasLHS(ignoringImplicit(declRefExpr(
4431 to(varDecl(hasName("M1")))))),
4432 hasRHS(ignoringImplicit(declRefExpr(
4433 to(varDecl(hasName("M2")))))))),
4434 true, {"-std=c++20"}));
4435 EXPECT_TRUE(matchesConditionally(
4436 Code,
4437 traverse(TK_AsIs, binaryOperation(hasOperatorName("=="),
4438 hasLHS(ignoringImplicit(declRefExpr(
4439 to(varDecl(hasName("F1")))))),
4440 hasRHS(ignoringImplicit(declRefExpr(
4441 to(varDecl(hasName("F2")))))))),
4442 true, {"-std=c++20"}));
4443 EXPECT_TRUE(matchesConditionally(
4444 Code,
4445 traverse(TK_IgnoreUnlessSpelledInSource,
4446 binaryOperation(
4447 hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4448 isComparisonOperator(),
4449 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
4450 hasRHS(declRefExpr(to(varDecl(hasName("s2"))))),
4451 hasEitherOperand(declRefExpr(to(varDecl(hasName("s2"))))),
4452 hasOperands(declRefExpr(to(varDecl(hasName("s1")))),
4453 declRefExpr(to(varDecl(hasName("s2"))))))),
4454 true, {"-std=c++20"}));
4455 EXPECT_TRUE(matchesConditionally(
4456 Code,
4457 traverse(
4458 TK_IgnoreUnlessSpelledInSource,
4459 binaryOperation(hasOperatorName("!="),
4460 hasLHS(declRefExpr(to(varDecl(hasName("i1"))))),
4461 hasRHS(declRefExpr(to(varDecl(hasName("i2"))))))),
4462 true, {"-std=c++20"}));
4463 EXPECT_TRUE(matchesConditionally(
4464 Code,
4465 traverse(
4466 TK_IgnoreUnlessSpelledInSource,
4467 binaryOperation(hasOperatorName("=="),
4468 hasLHS(declRefExpr(to(varDecl(hasName("M1"))))),
4469 hasRHS(declRefExpr(to(varDecl(hasName("M2"))))))),
4470 true, {"-std=c++20"}));
4471 EXPECT_TRUE(matchesConditionally(
4472 Code,
4473 traverse(
4474 TK_IgnoreUnlessSpelledInSource,
4475 binaryOperation(hasOperatorName("=="),
4476 hasLHS(declRefExpr(to(varDecl(hasName("F1"))))),
4477 hasRHS(declRefExpr(to(varDecl(hasName("F2"))))))),
4478 true, {"-std=c++20"}));
4482 TEST(IgnoringImpCasts, PathologicalLambda) {
4484 // Test that deeply nested lambdas are not a performance penalty
4485 StringRef Code = R"cpp(
4486 void f() {
4487 [] {
4488 [] {
4489 [] {
4490 [] {
4491 [] {
4492 [] {
4493 [] {
4494 [] {
4495 [] {
4496 [] {
4497 [] {
4498 [] {
4499 [] {
4500 [] {
4501 [] {
4502 [] {
4503 [] {
4504 [] {
4505 [] {
4506 [] {
4507 [] {
4508 [] {
4509 [] {
4510 [] {
4511 [] {
4512 [] {
4513 [] {
4514 [] {
4515 [] {
4516 int i = 42;
4517 (void)i;
4518 }();
4519 }();
4520 }();
4521 }();
4522 }();
4523 }();
4524 }();
4525 }();
4526 }();
4527 }();
4528 }();
4529 }();
4530 }();
4531 }();
4532 }();
4533 }();
4534 }();
4535 }();
4536 }();
4537 }();
4538 }();
4539 }();
4540 }();
4541 }();
4542 }();
4543 }();
4544 }();
4545 }();
4546 }();
4548 )cpp";
4550 EXPECT_TRUE(matches(Code, integerLiteral(equals(42))));
4551 EXPECT_TRUE(matches(Code, functionDecl(hasDescendant(integerLiteral(equals(42))))));
4554 TEST(IgnoringImpCasts, MatchesImpCasts) {
4555 // This test checks that ignoringImpCasts matches when implicit casts are
4556 // present and its inner matcher alone does not match.
4557 // Note that this test creates an implicit const cast.
4558 EXPECT_TRUE(matches("int x = 0; const int y = x;",
4559 varDecl(hasInitializer(ignoringImpCasts(
4560 declRefExpr(to(varDecl(hasName("x")))))))));
4561 // This test creates an implict cast from int to char.
4562 EXPECT_TRUE(matches("char x = 0;",
4563 varDecl(hasInitializer(ignoringImpCasts(
4564 integerLiteral(equals(0)))))));
4567 TEST(IgnoringImpCasts, DoesNotMatchIncorrectly) {
4568 // These tests verify that ignoringImpCasts does not match if the inner
4569 // matcher does not match.
4570 // Note that the first test creates an implicit const cast.
4571 EXPECT_TRUE(notMatches("int x; const int y = x;",
4572 varDecl(hasInitializer(ignoringImpCasts(
4573 unless(anything()))))));
4574 EXPECT_TRUE(notMatches("int x; int y = x;",
4575 varDecl(hasInitializer(ignoringImpCasts(
4576 unless(anything()))))));
4578 // These tests verify that ignoringImplictCasts does not look through explicit
4579 // casts or parentheses.
4580 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
4581 varDecl(hasInitializer(ignoringImpCasts(
4582 integerLiteral())))));
4583 EXPECT_TRUE(notMatches(
4584 "int i = (0);",
4585 traverse(TK_AsIs,
4586 varDecl(hasInitializer(ignoringImpCasts(integerLiteral()))))));
4587 EXPECT_TRUE(notMatches("float i = (float)0;",
4588 varDecl(hasInitializer(ignoringImpCasts(
4589 integerLiteral())))));
4590 EXPECT_TRUE(notMatches("float i = float(0);",
4591 varDecl(hasInitializer(ignoringImpCasts(
4592 integerLiteral())))));
4595 TEST(IgnoringImpCasts, MatchesWithoutImpCasts) {
4596 // This test verifies that expressions that do not have implicit casts
4597 // still match the inner matcher.
4598 EXPECT_TRUE(matches("int x = 0; int &y = x;",
4599 varDecl(hasInitializer(ignoringImpCasts(
4600 declRefExpr(to(varDecl(hasName("x")))))))));
4603 TEST(IgnoringParenCasts, MatchesParenCasts) {
4604 // This test checks that ignoringParenCasts matches when parentheses and/or
4605 // casts are present and its inner matcher alone does not match.
4606 EXPECT_TRUE(matches("int x = (0);",
4607 varDecl(hasInitializer(ignoringParenCasts(
4608 integerLiteral(equals(0)))))));
4609 EXPECT_TRUE(matches("int x = (((((0)))));",
4610 varDecl(hasInitializer(ignoringParenCasts(
4611 integerLiteral(equals(0)))))));
4613 // This test creates an implict cast from int to char in addition to the
4614 // parentheses.
4615 EXPECT_TRUE(matches("char x = (0);",
4616 varDecl(hasInitializer(ignoringParenCasts(
4617 integerLiteral(equals(0)))))));
4619 EXPECT_TRUE(matches("char x = (char)0;",
4620 varDecl(hasInitializer(ignoringParenCasts(
4621 integerLiteral(equals(0)))))));
4622 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
4623 varDecl(hasInitializer(ignoringParenCasts(
4624 integerLiteral(equals(0)))))));
4627 TEST(IgnoringParenCasts, MatchesWithoutParenCasts) {
4628 // This test verifies that expressions that do not have any casts still match.
4629 EXPECT_TRUE(matches("int x = 0;",
4630 varDecl(hasInitializer(ignoringParenCasts(
4631 integerLiteral(equals(0)))))));
4634 TEST(IgnoringParenCasts, DoesNotMatchIncorrectly) {
4635 // These tests verify that ignoringImpCasts does not match if the inner
4636 // matcher does not match.
4637 EXPECT_TRUE(notMatches("int x = ((0));",
4638 varDecl(hasInitializer(ignoringParenCasts(
4639 unless(anything()))))));
4641 // This test creates an implicit cast from int to char in addition to the
4642 // parentheses.
4643 EXPECT_TRUE(notMatches("char x = ((0));",
4644 varDecl(hasInitializer(ignoringParenCasts(
4645 unless(anything()))))));
4647 EXPECT_TRUE(notMatches("char *x = static_cast<char *>((0));",
4648 varDecl(hasInitializer(ignoringParenCasts(
4649 unless(anything()))))));
4652 TEST(IgnoringParenAndImpCasts, MatchesParenImpCasts) {
4653 // This test checks that ignoringParenAndImpCasts matches when
4654 // parentheses and/or implicit casts are present and its inner matcher alone
4655 // does not match.
4656 // Note that this test creates an implicit const cast.
4657 EXPECT_TRUE(matches("int x = 0; const int y = x;",
4658 varDecl(hasInitializer(ignoringParenImpCasts(
4659 declRefExpr(to(varDecl(hasName("x")))))))));
4660 // This test creates an implicit cast from int to char.
4661 EXPECT_TRUE(matches("const char x = (0);",
4662 varDecl(hasInitializer(ignoringParenImpCasts(
4663 integerLiteral(equals(0)))))));
4666 TEST(IgnoringParenAndImpCasts, MatchesWithoutParenImpCasts) {
4667 // This test verifies that expressions that do not have parentheses or
4668 // implicit casts still match.
4669 EXPECT_TRUE(matches("int x = 0; int &y = x;",
4670 varDecl(hasInitializer(ignoringParenImpCasts(
4671 declRefExpr(to(varDecl(hasName("x")))))))));
4672 EXPECT_TRUE(matches("int x = 0;",
4673 varDecl(hasInitializer(ignoringParenImpCasts(
4674 integerLiteral(equals(0)))))));
4677 TEST(IgnoringParenAndImpCasts, DoesNotMatchIncorrectly) {
4678 // These tests verify that ignoringParenImpCasts does not match if
4679 // the inner matcher does not match.
4680 // This test creates an implicit cast.
4681 EXPECT_TRUE(notMatches("char c = ((3));",
4682 varDecl(hasInitializer(ignoringParenImpCasts(
4683 unless(anything()))))));
4684 // These tests verify that ignoringParenAndImplictCasts does not look
4685 // through explicit casts.
4686 EXPECT_TRUE(notMatches("float y = (float(0));",
4687 varDecl(hasInitializer(ignoringParenImpCasts(
4688 integerLiteral())))));
4689 EXPECT_TRUE(notMatches("float y = (float)0;",
4690 varDecl(hasInitializer(ignoringParenImpCasts(
4691 integerLiteral())))));
4692 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
4693 varDecl(hasInitializer(ignoringParenImpCasts(
4694 integerLiteral())))));
4697 TEST(HasSourceExpression, MatchesImplicitCasts) {
4698 EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
4699 "void r() {string a_string; URL url = a_string; }",
4700 traverse(TK_AsIs, implicitCastExpr(hasSourceExpression(
4701 cxxConstructExpr())))));
4704 TEST(HasSourceExpression, MatchesExplicitCasts) {
4705 EXPECT_TRUE(
4706 matches("float x = static_cast<float>(42);",
4707 traverse(TK_AsIs, explicitCastExpr(hasSourceExpression(
4708 hasDescendant(expr(integerLiteral())))))));
4711 TEST(UsingDeclaration, MatchesSpecificTarget) {
4712 EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
4713 usingDecl(hasAnyUsingShadowDecl(
4714 hasTargetDecl(functionDecl())))));
4715 EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
4716 usingDecl(hasAnyUsingShadowDecl(
4717 hasTargetDecl(functionDecl())))));
4720 TEST(UsingDeclaration, ThroughUsingDeclaration) {
4721 EXPECT_TRUE(matches(
4722 "namespace a { void f(); } using a::f; void g() { f(); }",
4723 declRefExpr(throughUsingDecl(anything()))));
4724 EXPECT_TRUE(notMatches(
4725 "namespace a { void f(); } using a::f; void g() { a::f(); }",
4726 declRefExpr(throughUsingDecl(anything()))));
4729 TEST(SingleDecl, IsSingleDecl) {
4730 StatementMatcher SingleDeclStmt =
4731 declStmt(hasSingleDecl(varDecl(hasInitializer(anything()))));
4732 EXPECT_TRUE(matches("void f() {int a = 4;}", SingleDeclStmt));
4733 EXPECT_TRUE(notMatches("void f() {int a;}", SingleDeclStmt));
4734 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
4735 SingleDeclStmt));
4738 TEST(DeclStmt, ContainsDeclaration) {
4739 DeclarationMatcher MatchesInit = varDecl(hasInitializer(anything()));
4741 EXPECT_TRUE(matches("void f() {int a = 4;}",
4742 declStmt(containsDeclaration(0, MatchesInit))));
4743 EXPECT_TRUE(matches("void f() {int a = 4, b = 3;}",
4744 declStmt(containsDeclaration(0, MatchesInit),
4745 containsDeclaration(1, MatchesInit))));
4746 unsigned WrongIndex = 42;
4747 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
4748 declStmt(containsDeclaration(WrongIndex,
4749 MatchesInit))));
4752 TEST(SwitchCase, MatchesEachCase) {
4753 EXPECT_TRUE(notMatches("void x() { switch(42); }",
4754 switchStmt(forEachSwitchCase(caseStmt()))));
4755 EXPECT_TRUE(matches("void x() { switch(42) case 42:; }",
4756 switchStmt(forEachSwitchCase(caseStmt()))));
4757 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }",
4758 switchStmt(forEachSwitchCase(caseStmt()))));
4759 EXPECT_TRUE(notMatches(
4760 "void x() { if (1) switch(42) { case 42: switch (42) { default:; } } }",
4761 ifStmt(has(switchStmt(forEachSwitchCase(defaultStmt()))))));
4762 EXPECT_TRUE(matches(
4763 "void x() { switch(42) { case 1+1: case 4:; } }",
4764 traverse(TK_AsIs, switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant(
4765 constantExpr(has(integerLiteral())))))))));
4766 EXPECT_TRUE(notMatches(
4767 "void x() { switch(42) { case 1+1: case 2+2:; } }",
4768 traverse(TK_AsIs, switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant(
4769 constantExpr(has(integerLiteral())))))))));
4770 EXPECT_TRUE(notMatches(
4771 "void x() { switch(42) { case 1 ... 2:; } }",
4772 traverse(TK_AsIs, switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant(
4773 constantExpr(has(integerLiteral())))))))));
4774 EXPECT_TRUE(matchAndVerifyResultTrue(
4775 "void x() { switch (42) { case 1: case 2: case 3: default:; } }",
4776 switchStmt(forEachSwitchCase(caseStmt().bind("x"))),
4777 std::make_unique<VerifyIdIsBoundTo<CaseStmt>>("x", 3)));
4780 TEST(Declaration, HasExplicitSpecifier) {
4782 EXPECT_TRUE(notMatches("void f();",
4783 functionDecl(hasExplicitSpecifier(constantExpr())),
4784 langCxx20OrLater()));
4785 EXPECT_TRUE(
4786 notMatches("template<bool b> struct S { explicit operator int(); };",
4787 cxxConversionDecl(
4788 hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
4789 langCxx20OrLater()));
4790 EXPECT_TRUE(
4791 notMatches("template<bool b> struct S { explicit(b) operator int(); };",
4792 cxxConversionDecl(
4793 hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
4794 langCxx20OrLater()));
4795 EXPECT_TRUE(
4796 matches("struct S { explicit(true) operator int(); };",
4797 traverse(TK_AsIs, cxxConversionDecl(hasExplicitSpecifier(
4798 constantExpr(has(cxxBoolLiteral()))))),
4799 langCxx20OrLater()));
4800 EXPECT_TRUE(
4801 matches("struct S { explicit(false) operator int(); };",
4802 traverse(TK_AsIs, cxxConversionDecl(hasExplicitSpecifier(
4803 constantExpr(has(cxxBoolLiteral()))))),
4804 langCxx20OrLater()));
4805 EXPECT_TRUE(
4806 notMatches("template<bool b> struct S { explicit(b) S(int); };",
4807 traverse(TK_AsIs, cxxConstructorDecl(hasExplicitSpecifier(
4808 constantExpr(has(cxxBoolLiteral()))))),
4809 langCxx20OrLater()));
4810 EXPECT_TRUE(
4811 matches("struct S { explicit(true) S(int); };",
4812 traverse(TK_AsIs, cxxConstructorDecl(hasExplicitSpecifier(
4813 constantExpr(has(cxxBoolLiteral()))))),
4814 langCxx20OrLater()));
4815 EXPECT_TRUE(
4816 matches("struct S { explicit(false) S(int); };",
4817 traverse(TK_AsIs, cxxConstructorDecl(hasExplicitSpecifier(
4818 constantExpr(has(cxxBoolLiteral()))))),
4819 langCxx20OrLater()));
4820 EXPECT_TRUE(
4821 notMatches("template<typename T> struct S { S(int); };"
4822 "template<bool b = true> explicit(b) S(int) -> S<int>;",
4823 traverse(TK_AsIs, cxxDeductionGuideDecl(hasExplicitSpecifier(
4824 constantExpr(has(cxxBoolLiteral()))))),
4825 langCxx20OrLater()));
4826 EXPECT_TRUE(
4827 matches("template<typename T> struct S { S(int); };"
4828 "explicit(true) S(int) -> S<int>;",
4829 traverse(TK_AsIs, cxxDeductionGuideDecl(hasExplicitSpecifier(
4830 constantExpr(has(cxxBoolLiteral()))))),
4831 langCxx20OrLater()));
4832 EXPECT_TRUE(
4833 matches("template<typename T> struct S { S(int); };"
4834 "explicit(false) S(int) -> S<int>;",
4835 traverse(TK_AsIs, cxxDeductionGuideDecl(hasExplicitSpecifier(
4836 constantExpr(has(cxxBoolLiteral()))))),
4837 langCxx20OrLater()));
4840 TEST(ForEachConstructorInitializer, MatchesInitializers) {
4841 EXPECT_TRUE(matches(
4842 "struct X { X() : i(42), j(42) {} int i, j; };",
4843 cxxConstructorDecl(forEachConstructorInitializer(cxxCtorInitializer()))));
4846 TEST(ForEachLambdaCapture, MatchesCaptures) {
4847 EXPECT_TRUE(matches(
4848 "int main() { int x, y; auto f = [x, y]() { return x + y; }; }",
4849 lambdaExpr(forEachLambdaCapture(lambdaCapture())), langCxx11OrLater()));
4850 auto matcher = lambdaExpr(forEachLambdaCapture(
4851 lambdaCapture(capturesVar(varDecl(hasType(isInteger())))).bind("LC")));
4852 EXPECT_TRUE(matchAndVerifyResultTrue(
4853 "int main() { int x, y; float z; auto f = [=]() { return x + y + z; }; }",
4854 matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 2)));
4855 EXPECT_TRUE(matchAndVerifyResultTrue(
4856 "int main() { int x, y; float z; auto f = [x, y, z]() { return x + y + "
4857 "z; }; }",
4858 matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 2)));
4861 TEST(ForEachLambdaCapture, IgnoreUnlessSpelledInSource) {
4862 auto matcher =
4863 traverse(TK_IgnoreUnlessSpelledInSource,
4864 lambdaExpr(forEachLambdaCapture(
4865 lambdaCapture(capturesVar(varDecl(hasType(isInteger()))))
4866 .bind("LC"))));
4867 EXPECT_TRUE(
4868 notMatches("int main() { int x, y; auto f = [=]() { return x + y; }; }",
4869 matcher, langCxx11OrLater()));
4870 EXPECT_TRUE(
4871 notMatches("int main() { int x, y; auto f = [&]() { return x + y; }; }",
4872 matcher, langCxx11OrLater()));
4873 EXPECT_TRUE(matchAndVerifyResultTrue(
4874 R"cc(
4875 int main() {
4876 int x, y;
4877 float z;
4878 auto f = [=, &y]() { return x + y + z; };
4880 )cc",
4881 matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 1)));
4884 TEST(ForEachLambdaCapture, MatchImplicitCapturesOnly) {
4885 auto matcher =
4886 lambdaExpr(forEachLambdaCapture(lambdaCapture(isImplicit()).bind("LC")));
4887 EXPECT_TRUE(matchAndVerifyResultTrue(
4888 "int main() { int x, y, z; auto f = [=, &z]() { return x + y + z; }; }",
4889 matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 2)));
4890 EXPECT_TRUE(matchAndVerifyResultTrue(
4891 "int main() { int x, y, z; auto f = [&, z]() { return x + y + z; }; }",
4892 matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 2)));
4895 TEST(ForEachLambdaCapture, MatchExplicitCapturesOnly) {
4896 auto matcher = lambdaExpr(
4897 forEachLambdaCapture(lambdaCapture(unless(isImplicit())).bind("LC")));
4898 EXPECT_TRUE(matchAndVerifyResultTrue(
4899 "int main() { int x, y, z; auto f = [=, &z]() { return x + y + z; }; }",
4900 matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 1)));
4901 EXPECT_TRUE(matchAndVerifyResultTrue(
4902 "int main() { int x, y, z; auto f = [&, z]() { return x + y + z; }; }",
4903 matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 1)));
4906 TEST(HasConditionVariableStatement, DoesNotMatchCondition) {
4907 EXPECT_TRUE(notMatches(
4908 "void x() { if(true) {} }",
4909 ifStmt(hasConditionVariableStatement(declStmt()))));
4910 EXPECT_TRUE(notMatches(
4911 "void x() { int x; if((x = 42)) {} }",
4912 ifStmt(hasConditionVariableStatement(declStmt()))));
4915 TEST(HasConditionVariableStatement, MatchesConditionVariables) {
4916 EXPECT_TRUE(matches(
4917 "void x() { if(int* a = 0) {} }",
4918 ifStmt(hasConditionVariableStatement(declStmt()))));
4921 TEST(ForEach, BindsOneNode) {
4922 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
4923 recordDecl(hasName("C"), forEach(fieldDecl(hasName("x")).bind("x"))),
4924 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("x", 1)));
4927 TEST(ForEach, BindsMultipleNodes) {
4928 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
4929 recordDecl(hasName("C"), forEach(fieldDecl().bind("f"))),
4930 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 3)));
4933 TEST(ForEach, BindsRecursiveCombinations) {
4934 EXPECT_TRUE(matchAndVerifyResultTrue(
4935 "class C { class D { int x; int y; }; class E { int y; int z; }; };",
4936 recordDecl(hasName("C"),
4937 forEach(recordDecl(forEach(fieldDecl().bind("f"))))),
4938 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 4)));
4941 TEST(ForEach, DoesNotIgnoreImplicit) {
4942 StringRef Code = R"cpp(
4943 void foo()
4945 int i = 0;
4946 int b = 4;
4947 i < b;
4949 )cpp";
4950 EXPECT_TRUE(matchAndVerifyResultFalse(
4951 Code, binaryOperator(forEach(declRefExpr().bind("dre"))),
4952 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 0)));
4954 EXPECT_TRUE(matchAndVerifyResultTrue(
4955 Code,
4956 binaryOperator(forEach(
4957 implicitCastExpr(hasSourceExpression(declRefExpr().bind("dre"))))),
4958 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 2)));
4960 EXPECT_TRUE(matchAndVerifyResultTrue(
4961 Code,
4962 binaryOperator(
4963 forEach(expr(ignoringImplicit(declRefExpr().bind("dre"))))),
4964 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 2)));
4966 EXPECT_TRUE(matchAndVerifyResultTrue(
4967 Code,
4968 traverse(TK_IgnoreUnlessSpelledInSource,
4969 binaryOperator(forEach(declRefExpr().bind("dre")))),
4970 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 2)));
4973 TEST(ForEachDescendant, BindsOneNode) {
4974 EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
4975 recordDecl(hasName("C"),
4976 forEachDescendant(fieldDecl(hasName("x")).bind("x"))),
4977 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("x", 1)));
4980 TEST(ForEachDescendant, NestedForEachDescendant) {
4981 DeclarationMatcher m = recordDecl(
4982 isDefinition(), decl().bind("x"), hasName("C"));
4983 EXPECT_TRUE(matchAndVerifyResultTrue(
4984 "class A { class B { class C {}; }; };",
4985 recordDecl(hasName("A"), anyOf(m, forEachDescendant(m))),
4986 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", "C")));
4988 // Check that a partial match of 'm' that binds 'x' in the
4989 // first part of anyOf(m, anything()) will not overwrite the
4990 // binding created by the earlier binding in the hasDescendant.
4991 EXPECT_TRUE(matchAndVerifyResultTrue(
4992 "class A { class B { class C {}; }; };",
4993 recordDecl(hasName("A"), allOf(hasDescendant(m), anyOf(m, anything()))),
4994 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", "C")));
4997 TEST(ForEachDescendant, BindsMultipleNodes) {
4998 EXPECT_TRUE(matchAndVerifyResultTrue(
4999 "class C { class D { int x; int y; }; "
5000 " class E { class F { int y; int z; }; }; };",
5001 recordDecl(hasName("C"), forEachDescendant(fieldDecl().bind("f"))),
5002 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 4)));
5005 TEST(ForEachDescendant, BindsRecursiveCombinations) {
5006 EXPECT_TRUE(matchAndVerifyResultTrue(
5007 "class C { class D { "
5008 " class E { class F { class G { int y; int z; }; }; }; }; };",
5009 recordDecl(hasName("C"), forEachDescendant(recordDecl(
5010 forEachDescendant(fieldDecl().bind("f"))))),
5011 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 8)));
5014 TEST(ForEachDescendant, BindsCombinations) {
5015 EXPECT_TRUE(matchAndVerifyResultTrue(
5016 "void f() { if(true) {} if (true) {} while (true) {} if (true) {} while "
5017 "(true) {} }",
5018 compoundStmt(forEachDescendant(ifStmt().bind("if")),
5019 forEachDescendant(whileStmt().bind("while"))),
5020 std::make_unique<VerifyIdIsBoundTo<IfStmt>>("if", 6)));
5023 TEST(ForEachTemplateArgument, OnFunctionDecl) {
5024 const std::string Code = R"(
5025 template <typename T, typename U> void f(T, U) {}
5026 void test() {
5027 int I = 1;
5028 bool B = false;
5029 f(I, B);
5030 })";
5031 EXPECT_TRUE(matches(
5032 Code, functionDecl(forEachTemplateArgument(refersToType(builtinType()))),
5033 langCxx11OrLater()));
5034 auto matcher =
5035 functionDecl(forEachTemplateArgument(
5036 templateArgument(refersToType(builtinType().bind("BT")))
5037 .bind("TA")))
5038 .bind("FN");
5040 EXPECT_TRUE(matchAndVerifyResultTrue(
5041 Code, matcher,
5042 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("FN", 2)));
5043 EXPECT_TRUE(matchAndVerifyResultTrue(
5044 Code, matcher,
5045 std::make_unique<VerifyIdIsBoundTo<TemplateArgument>>("TA", 2)));
5046 EXPECT_TRUE(matchAndVerifyResultTrue(
5047 Code, matcher,
5048 std::make_unique<VerifyIdIsBoundTo<BuiltinType>>("BT", 2)));
5051 TEST(ForEachTemplateArgument, OnClassTemplateSpecialization) {
5052 const std::string Code = R"(
5053 template <typename T, unsigned N, unsigned M>
5054 struct Matrix {};
5056 static constexpr unsigned R = 2;
5058 Matrix<int, R * 2, R * 4> M;
5060 EXPECT_TRUE(matches(
5061 Code, templateSpecializationType(forEachTemplateArgument(isExpr(expr()))),
5062 langCxx11OrLater()));
5063 auto matcher = templateSpecializationType(
5064 forEachTemplateArgument(
5065 templateArgument(isExpr(expr().bind("E"))).bind("TA")))
5066 .bind("TST");
5068 EXPECT_TRUE(matchAndVerifyResultTrue(
5069 Code, matcher,
5070 std::make_unique<VerifyIdIsBoundTo<TemplateSpecializationType>>("TST",
5071 2)));
5072 EXPECT_TRUE(matchAndVerifyResultTrue(
5073 Code, matcher,
5074 std::make_unique<VerifyIdIsBoundTo<TemplateArgument>>("TA", 2)));
5075 EXPECT_TRUE(matchAndVerifyResultTrue(
5076 Code, matcher, std::make_unique<VerifyIdIsBoundTo<Expr>>("E", 2)));
5079 TEST(Has, DoesNotDeleteBindings) {
5080 EXPECT_TRUE(matchAndVerifyResultTrue(
5081 "class X { int a; };", recordDecl(decl().bind("x"), has(fieldDecl())),
5082 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5085 TEST(TemplateArgumentLoc, Matches) {
5086 EXPECT_TRUE(matchAndVerifyResultTrue(
5087 R"cpp(
5088 template <typename A, int B, template <typename> class C> class X {};
5089 class A {};
5090 const int B = 42;
5091 template <typename> class C {};
5092 X<A, B, C> x;
5093 )cpp",
5094 templateArgumentLoc().bind("x"),
5095 std::make_unique<VerifyIdIsBoundTo<TemplateArgumentLoc>>("x", 3)));
5098 TEST(LoopingMatchers, DoNotOverwritePreviousMatchResultOnFailure) {
5099 // Those matchers cover all the cases where an inner matcher is called
5100 // and there is not a 1:1 relationship between the match of the outer
5101 // matcher and the match of the inner matcher.
5102 // The pattern to look for is:
5103 // ... return InnerMatcher.matches(...); ...
5104 // In which case no special handling is needed.
5106 // On the other hand, if there are multiple alternative matches
5107 // (for example forEach*) or matches might be discarded (for example has*)
5108 // the implementation must make sure that the discarded matches do not
5109 // affect the bindings.
5110 // When new such matchers are added, add a test here that:
5111 // - matches a simple node, and binds it as the first thing in the matcher:
5112 // recordDecl(decl().bind("x"), hasName("X")))
5113 // - uses the matcher under test afterwards in a way that not the first
5114 // alternative is matched; for anyOf, that means the first branch
5115 // would need to return false; for hasAncestor, it means that not
5116 // the direct parent matches the inner matcher.
5118 EXPECT_TRUE(matchAndVerifyResultTrue(
5119 "class X { int y; };",
5120 recordDecl(
5121 recordDecl().bind("x"), hasName("::X"),
5122 anyOf(forEachDescendant(recordDecl(hasName("Y"))), anything())),
5123 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("x", 1)));
5124 EXPECT_TRUE(matchAndVerifyResultTrue(
5125 "class X {};", recordDecl(recordDecl().bind("x"), hasName("::X"),
5126 anyOf(unless(anything()), anything())),
5127 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("x", 1)));
5128 EXPECT_TRUE(matchAndVerifyResultTrue(
5129 "template<typename T1, typename T2> class X {}; X<float, int> x;",
5130 classTemplateSpecializationDecl(
5131 decl().bind("x"),
5132 hasAnyTemplateArgument(refersToType(asString("int")))),
5133 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5134 EXPECT_TRUE(matchAndVerifyResultTrue(
5135 "class X { void f(); void g(); };",
5136 cxxRecordDecl(decl().bind("x"), hasMethod(hasName("g"))),
5137 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5138 EXPECT_TRUE(matchAndVerifyResultTrue(
5139 "class X { X() : a(1), b(2) {} double a; int b; };",
5140 recordDecl(decl().bind("x"),
5141 has(cxxConstructorDecl(
5142 hasAnyConstructorInitializer(forField(hasName("b")))))),
5143 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5144 EXPECT_TRUE(matchAndVerifyResultTrue(
5145 "void x(int, int) { x(0, 42); }",
5146 callExpr(expr().bind("x"), hasAnyArgument(integerLiteral(equals(42)))),
5147 std::make_unique<VerifyIdIsBoundTo<Expr>>("x", 1)));
5148 EXPECT_TRUE(matchAndVerifyResultTrue(
5149 "void x(int, int y) {}",
5150 functionDecl(decl().bind("x"), hasAnyParameter(hasName("y"))),
5151 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5152 EXPECT_TRUE(matchAndVerifyResultTrue(
5153 "void x() { return; if (true) {} }",
5154 functionDecl(decl().bind("x"),
5155 has(compoundStmt(hasAnySubstatement(ifStmt())))),
5156 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5157 EXPECT_TRUE(matchAndVerifyResultTrue(
5158 "namespace X { void b(int); void b(); }"
5159 "using X::b;",
5160 usingDecl(decl().bind("x"), hasAnyUsingShadowDecl(hasTargetDecl(
5161 functionDecl(parameterCountIs(1))))),
5162 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5163 EXPECT_TRUE(matchAndVerifyResultTrue(
5164 "class A{}; class B{}; class C : B, A {};",
5165 cxxRecordDecl(decl().bind("x"), isDerivedFrom("::A")),
5166 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5167 EXPECT_TRUE(matchAndVerifyResultTrue(
5168 "class A{}; typedef A B; typedef A C; typedef A D;"
5169 "class E : A {};",
5170 cxxRecordDecl(decl().bind("x"), isDerivedFrom("C")),
5171 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5172 EXPECT_TRUE(matchAndVerifyResultTrue(
5173 "class A { class B { void f() {} }; };",
5174 functionDecl(decl().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
5175 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5176 EXPECT_TRUE(matchAndVerifyResultTrue(
5177 "template <typename T> struct A { struct B {"
5178 " void f() { if(true) {} }"
5179 "}; };"
5180 "void t() { A<int>::B b; b.f(); }",
5181 ifStmt(stmt().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
5182 std::make_unique<VerifyIdIsBoundTo<Stmt>>("x", 2)));
5183 EXPECT_TRUE(matchAndVerifyResultTrue(
5184 "class A {};",
5185 recordDecl(hasName("::A"), decl().bind("x"), unless(hasName("fooble"))),
5186 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5187 EXPECT_TRUE(matchAndVerifyResultTrue(
5188 "class A { A() : s(), i(42) {} const char *s; int i; };",
5189 cxxConstructorDecl(hasName("::A::A"), decl().bind("x"),
5190 forEachConstructorInitializer(forField(hasName("i")))),
5191 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5194 TEST(ForEachDescendant, BindsCorrectNodes) {
5195 EXPECT_TRUE(matchAndVerifyResultTrue(
5196 "class C { void f(); int i; };",
5197 recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
5198 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("decl", 1)));
5199 EXPECT_TRUE(matchAndVerifyResultTrue(
5200 "class C { void f() {} int i; };",
5201 recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
5202 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("decl", 1)));
5205 TEST(FindAll, BindsNodeOnMatch) {
5206 EXPECT_TRUE(matchAndVerifyResultTrue(
5207 "class A {};",
5208 recordDecl(hasName("::A"), findAll(recordDecl(hasName("::A")).bind("v"))),
5209 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("v", 1)));
5212 TEST(FindAll, BindsDescendantNodeOnMatch) {
5213 EXPECT_TRUE(matchAndVerifyResultTrue(
5214 "class A { int a; int b; };",
5215 recordDecl(hasName("::A"), findAll(fieldDecl().bind("v"))),
5216 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 2)));
5219 TEST(FindAll, BindsNodeAndDescendantNodesOnOneMatch) {
5220 EXPECT_TRUE(matchAndVerifyResultTrue(
5221 "class A { int a; int b; };",
5222 recordDecl(hasName("::A"),
5223 findAll(decl(anyOf(recordDecl(hasName("::A")).bind("v"),
5224 fieldDecl().bind("v"))))),
5225 std::make_unique<VerifyIdIsBoundTo<Decl>>("v", 3)));
5227 EXPECT_TRUE(matchAndVerifyResultTrue(
5228 "class A { class B {}; class C {}; };",
5229 recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("v"))),
5230 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("v", 3)));
5233 TEST(HasAncenstor, MatchesDeclarationAncestors) {
5234 EXPECT_TRUE(matches(
5235 "class A { class B { class C {}; }; };",
5236 recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("A"))))));
5239 TEST(HasAncenstor, FailsIfNoAncestorMatches) {
5240 EXPECT_TRUE(notMatches(
5241 "class A { class B { class C {}; }; };",
5242 recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("X"))))));
5245 TEST(HasAncestor, MatchesDeclarationsThatGetVisitedLater) {
5246 EXPECT_TRUE(matches(
5247 "class A { class B { void f() { C c; } class C {}; }; };",
5248 varDecl(hasName("c"), hasType(recordDecl(hasName("C"),
5249 hasAncestor(recordDecl(hasName("A"))))))));
5252 TEST(HasAncenstor, MatchesStatementAncestors) {
5253 EXPECT_TRUE(matches(
5254 "void f() { if (true) { while (false) { 42; } } }",
5255 integerLiteral(equals(42), hasAncestor(ifStmt()))));
5258 TEST(HasAncestor, DrillsThroughDifferentHierarchies) {
5259 EXPECT_TRUE(matches(
5260 "void f() { if (true) { int x = 42; } }",
5261 integerLiteral(equals(42), hasAncestor(functionDecl(hasName("f"))))));
5264 TEST(HasAncestor, BindsRecursiveCombinations) {
5265 EXPECT_TRUE(matchAndVerifyResultTrue(
5266 "class C { class D { class E { class F { int y; }; }; }; };",
5267 fieldDecl(hasAncestor(recordDecl(hasAncestor(recordDecl().bind("r"))))),
5268 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("r", 1)));
5271 TEST(HasAncestor, BindsCombinationsWithHasDescendant) {
5272 EXPECT_TRUE(matchAndVerifyResultTrue(
5273 "class C { class D { class E { class F { int y; }; }; }; };",
5274 fieldDecl(hasAncestor(
5275 decl(
5276 hasDescendant(recordDecl(isDefinition(),
5277 hasAncestor(recordDecl())))
5278 ).bind("d")
5280 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("d", "E")));
5283 TEST(HasAncestor, MatchesClosestAncestor) {
5284 EXPECT_TRUE(matchAndVerifyResultTrue(
5285 "template <typename T> struct C {"
5286 " void f(int) {"
5287 " struct I { void g(T) { int x; } } i; i.g(42);"
5288 " }"
5289 "};"
5290 "template struct C<int>;",
5291 varDecl(hasName("x"),
5292 hasAncestor(functionDecl(hasParameter(
5293 0, varDecl(hasType(asString("int"))))).bind("f"))).bind("v"),
5294 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("f", "g", 2)));
5297 TEST(HasAncestor, MatchesInTemplateInstantiations) {
5298 EXPECT_TRUE(matches(
5299 "template <typename T> struct A { struct B { struct C { T t; }; }; }; "
5300 "A<int>::B::C a;",
5301 fieldDecl(hasType(asString("int")),
5302 hasAncestor(recordDecl(hasName("A"))))));
5305 TEST(HasAncestor, MatchesInImplicitCode) {
5306 EXPECT_TRUE(matches(
5307 "struct X {}; struct A { A() {} X x; };",
5308 cxxConstructorDecl(
5309 hasAnyConstructorInitializer(withInitializer(expr(
5310 hasAncestor(recordDecl(hasName("A")))))))));
5313 TEST(HasParent, MatchesOnlyParent) {
5314 EXPECT_TRUE(matches(
5315 "void f() { if (true) { int x = 42; } }",
5316 compoundStmt(hasParent(ifStmt()))));
5317 EXPECT_TRUE(notMatches(
5318 "void f() { for (;;) { int x = 42; } }",
5319 compoundStmt(hasParent(ifStmt()))));
5320 EXPECT_TRUE(notMatches(
5321 "void f() { if (true) for (;;) { int x = 42; } }",
5322 compoundStmt(hasParent(ifStmt()))));
5325 TEST(MatcherMemoize, HasParentDiffersFromHas) {
5326 // Test introduced after detecting a bug in memoization
5327 constexpr auto code = "void f() { throw 1; }";
5328 EXPECT_TRUE(notMatches(
5329 code,
5330 cxxThrowExpr(hasParent(expr()))));
5331 EXPECT_TRUE(matches(
5332 code,
5333 cxxThrowExpr(has(expr()))));
5334 EXPECT_TRUE(matches(
5335 code,
5336 cxxThrowExpr(anyOf(hasParent(expr()), has(expr())))));
5339 TEST(MatcherMemoize, HasDiffersFromHasDescendant) {
5340 // Test introduced after detecting a bug in memoization
5341 constexpr auto code = "void f() { throw 1+1; }";
5342 EXPECT_TRUE(notMatches(
5343 code,
5344 cxxThrowExpr(has(integerLiteral()))));
5345 EXPECT_TRUE(matches(
5346 code,
5347 cxxThrowExpr(hasDescendant(integerLiteral()))));
5348 EXPECT_TRUE(
5349 notMatches(code, cxxThrowExpr(allOf(hasDescendant(integerLiteral()),
5350 has(integerLiteral())))));
5352 TEST(HasAncestor, MatchesAllAncestors) {
5353 EXPECT_TRUE(matches(
5354 "template <typename T> struct C { static void f() { 42; } };"
5355 "void t() { C<int>::f(); }",
5356 integerLiteral(
5357 equals(42),
5358 allOf(
5359 hasAncestor(cxxRecordDecl(isTemplateInstantiation())),
5360 hasAncestor(cxxRecordDecl(unless(isTemplateInstantiation())))))));
5363 TEST(HasAncestor, ImplicitArrayCopyCtorDeclRefExpr) {
5364 EXPECT_TRUE(matches("struct MyClass {\n"
5365 " int c[1];\n"
5366 " static MyClass Create() { return MyClass(); }\n"
5367 "};",
5368 declRefExpr(to(decl(hasAncestor(decl()))))));
5371 TEST(HasAncestor, AnonymousUnionMemberExpr) {
5372 EXPECT_TRUE(matches("int F() {\n"
5373 " union { int i; };\n"
5374 " return i;\n"
5375 "}\n",
5376 memberExpr(member(hasAncestor(decl())))));
5377 EXPECT_TRUE(matches("void f() {\n"
5378 " struct {\n"
5379 " struct { int a; int b; };\n"
5380 " } s;\n"
5381 " s.a = 4;\n"
5382 "}\n",
5383 memberExpr(member(hasAncestor(decl())))));
5384 EXPECT_TRUE(matches("void f() {\n"
5385 " struct {\n"
5386 " struct { int a; int b; };\n"
5387 " } s;\n"
5388 " s.a = 4;\n"
5389 "}\n",
5390 declRefExpr(to(decl(hasAncestor(decl()))))));
5392 TEST(HasAncestor, NonParmDependentTemplateParmVarDeclRefExpr) {
5393 EXPECT_TRUE(matches("struct PartitionAllocator {\n"
5394 " template<typename T>\n"
5395 " static int quantizedSize(int count) {\n"
5396 " return count;\n"
5397 " }\n"
5398 " void f() { quantizedSize<int>(10); }\n"
5399 "};",
5400 declRefExpr(to(decl(hasAncestor(decl()))))));
5403 TEST(HasAncestor, AddressOfExplicitSpecializationFunction) {
5404 EXPECT_TRUE(matches("template <class T> void f();\n"
5405 "template <> void f<int>();\n"
5406 "void (*get_f())() { return f<int>; }\n",
5407 declRefExpr(to(decl(hasAncestor(decl()))))));
5410 TEST(HasParent, MatchesAllParents) {
5411 EXPECT_TRUE(matches(
5412 "template <typename T> struct C { static void f() { 42; } };"
5413 "void t() { C<int>::f(); }",
5414 integerLiteral(
5415 equals(42),
5416 hasParent(compoundStmt(hasParent(functionDecl(
5417 hasParent(cxxRecordDecl(isTemplateInstantiation())))))))));
5418 EXPECT_TRUE(
5419 matches("template <typename T> struct C { static void f() { 42; } };"
5420 "void t() { C<int>::f(); }",
5421 integerLiteral(
5422 equals(42),
5423 hasParent(compoundStmt(hasParent(functionDecl(hasParent(
5424 cxxRecordDecl(unless(isTemplateInstantiation()))))))))));
5425 EXPECT_TRUE(matches(
5426 "template <typename T> struct C { static void f() { 42; } };"
5427 "void t() { C<int>::f(); }",
5428 integerLiteral(equals(42),
5429 hasParent(compoundStmt(
5430 allOf(hasParent(functionDecl(hasParent(
5431 cxxRecordDecl(isTemplateInstantiation())))),
5432 hasParent(functionDecl(hasParent(cxxRecordDecl(
5433 unless(isTemplateInstantiation())))))))))));
5434 EXPECT_TRUE(
5435 notMatches("template <typename T> struct C { static void f() {} };"
5436 "void t() { C<int>::f(); }",
5437 compoundStmt(hasParent(recordDecl()))));
5440 TEST(HasParent, NoDuplicateParents) {
5441 class HasDuplicateParents : public BoundNodesCallback {
5442 public:
5443 bool run(const BoundNodes *Nodes) override { return false; }
5444 bool run(const BoundNodes *Nodes, ASTContext *Context) override {
5445 const Stmt *Node = Nodes->getNodeAs<Stmt>("node");
5446 std::set<const void *> Parents;
5447 for (const auto &Parent : Context->getParents(*Node)) {
5448 if (!Parents.insert(Parent.getMemoizationData()).second) {
5449 return true;
5452 return false;
5455 EXPECT_FALSE(matchAndVerifyResultTrue(
5456 "template <typename T> int Foo() { return 1 + 2; }\n"
5457 "int x = Foo<int>() + Foo<unsigned>();",
5458 stmt().bind("node"), std::make_unique<HasDuplicateParents>()));
5461 TEST(HasAnyBase, BindsInnerBoundNodes) {
5462 EXPECT_TRUE(matchAndVerifyResultTrue(
5463 "struct Inner {}; struct Proxy : Inner {}; struct Main : public "
5464 "Proxy {};",
5465 cxxRecordDecl(hasName("Main"),
5466 hasAnyBase(cxxBaseSpecifier(hasType(
5467 cxxRecordDecl(hasName("Inner")).bind("base-class")))))
5468 .bind("class"),
5469 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("base-class",
5470 "Inner")));
5473 TEST(TypeMatching, PointeeTypes) {
5474 EXPECT_TRUE(matches("int b; int &a = b;",
5475 referenceType(pointee(builtinType()))));
5476 EXPECT_TRUE(matches("int *a;", pointerType(pointee(builtinType()))));
5478 EXPECT_TRUE(matches("int *a;",
5479 loc(pointerType(pointee(builtinType())))));
5481 EXPECT_TRUE(matches(
5482 "int const *A;",
5483 pointerType(pointee(isConstQualified(), builtinType()))));
5484 EXPECT_TRUE(notMatches(
5485 "int *A;",
5486 pointerType(pointee(isConstQualified(), builtinType()))));
5489 TEST(ElaboratedTypeNarrowing, hasQualifier) {
5490 EXPECT_TRUE(matches(
5491 "namespace N {"
5492 " namespace M {"
5493 " class D {};"
5494 " }"
5496 "N::M::D d;",
5497 elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
5498 EXPECT_TRUE(notMatches(
5499 "namespace M {"
5500 " class D {};"
5502 "M::D d;",
5503 elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
5504 EXPECT_TRUE(notMatches(
5505 "struct D {"
5506 "} d;",
5507 elaboratedType(hasQualifier(nestedNameSpecifier()))));
5510 TEST(ElaboratedTypeNarrowing, namesType) {
5511 EXPECT_TRUE(matches(
5512 "namespace N {"
5513 " namespace M {"
5514 " class D {};"
5515 " }"
5517 "N::M::D d;",
5518 elaboratedType(elaboratedType(namesType(recordType(
5519 hasDeclaration(namedDecl(hasName("D")))))))));
5520 EXPECT_TRUE(notMatches(
5521 "namespace M {"
5522 " class D {};"
5524 "M::D d;",
5525 elaboratedType(elaboratedType(namesType(typedefType())))));
5528 TEST(NNS, BindsNestedNameSpecifiers) {
5529 EXPECT_TRUE(matchAndVerifyResultTrue(
5530 "namespace ns { struct E { struct B {}; }; } ns::E::B b;",
5531 nestedNameSpecifier(specifiesType(asString("struct ns::E"))).bind("nns"),
5532 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>(
5533 "nns", "ns::struct E::")));
5536 TEST(NNS, BindsNestedNameSpecifierLocs) {
5537 EXPECT_TRUE(matchAndVerifyResultTrue(
5538 "namespace ns { struct B {}; } ns::B b;",
5539 loc(nestedNameSpecifier()).bind("loc"),
5540 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifierLoc>>("loc", 1)));
5543 TEST(NNS, DescendantsOfNestedNameSpecifiers) {
5544 StringRef Fragment =
5545 "namespace a { struct A { struct B { struct C {}; }; }; };"
5546 "void f() { a::A::B::C c; }";
5547 EXPECT_TRUE(matches(
5548 Fragment,
5549 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
5550 hasDescendant(nestedNameSpecifier(
5551 specifiesNamespace(hasName("a")))))));
5552 EXPECT_TRUE(notMatches(
5553 Fragment,
5554 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
5555 has(nestedNameSpecifier(
5556 specifiesNamespace(hasName("a")))))));
5557 EXPECT_TRUE(matches(
5558 Fragment,
5559 nestedNameSpecifier(specifiesType(asString("struct a::A")),
5560 has(nestedNameSpecifier(
5561 specifiesNamespace(hasName("a")))))));
5563 // Not really useful because a NestedNameSpecifier can af at most one child,
5564 // but to complete the interface.
5565 EXPECT_TRUE(matchAndVerifyResultTrue(
5566 Fragment,
5567 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
5568 forEach(nestedNameSpecifier().bind("x"))),
5569 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>("x", 1)));
5572 TEST(NNS, NestedNameSpecifiersAsDescendants) {
5573 StringRef Fragment =
5574 "namespace a { struct A { struct B { struct C {}; }; }; };"
5575 "void f() { a::A::B::C c; }";
5576 EXPECT_TRUE(matches(
5577 Fragment,
5578 decl(hasDescendant(nestedNameSpecifier(specifiesType(
5579 asString("struct a::A")))))));
5580 EXPECT_TRUE(matchAndVerifyResultTrue(
5581 Fragment,
5582 functionDecl(hasName("f"),
5583 forEachDescendant(nestedNameSpecifier().bind("x"))),
5584 // Nested names: a, a::A and a::A::B.
5585 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>("x", 3)));
5588 TEST(NNSLoc, DescendantsOfNestedNameSpecifierLocs) {
5589 StringRef Fragment =
5590 "namespace a { struct A { struct B { struct C {}; }; }; };"
5591 "void f() { a::A::B::C c; }";
5592 EXPECT_TRUE(matches(
5593 Fragment,
5594 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5595 hasDescendant(loc(nestedNameSpecifier(
5596 specifiesNamespace(hasName("a"))))))));
5597 EXPECT_TRUE(notMatches(
5598 Fragment,
5599 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5600 has(loc(nestedNameSpecifier(
5601 specifiesNamespace(hasName("a"))))))));
5602 EXPECT_TRUE(matches(
5603 Fragment,
5604 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A"))),
5605 has(loc(nestedNameSpecifier(
5606 specifiesNamespace(hasName("a"))))))));
5608 EXPECT_TRUE(matchAndVerifyResultTrue(
5609 Fragment,
5610 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5611 forEach(nestedNameSpecifierLoc().bind("x"))),
5612 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifierLoc>>("x", 1)));
5615 TEST(NNSLoc, NestedNameSpecifierLocsAsDescendants) {
5616 StringRef Fragment =
5617 "namespace a { struct A { struct B { struct C {}; }; }; };"
5618 "void f() { a::A::B::C c; }";
5619 EXPECT_TRUE(matches(
5620 Fragment,
5621 decl(hasDescendant(loc(nestedNameSpecifier(specifiesType(
5622 asString("struct a::A"))))))));
5623 EXPECT_TRUE(matchAndVerifyResultTrue(
5624 Fragment,
5625 functionDecl(hasName("f"),
5626 forEachDescendant(nestedNameSpecifierLoc().bind("x"))),
5627 // Nested names: a, a::A and a::A::B.
5628 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifierLoc>>("x", 3)));
5631 TEST(Attr, AttrsAsDescendants) {
5632 StringRef Fragment = "namespace a { struct [[clang::warn_unused_result]] "
5633 "F{}; [[noreturn]] void foo(); }";
5634 EXPECT_TRUE(matches(Fragment, namespaceDecl(hasDescendant(attr()))));
5635 EXPECT_TRUE(matchAndVerifyResultTrue(
5636 Fragment,
5637 namespaceDecl(hasName("a"),
5638 forEachDescendant(attr(unless(isImplicit())).bind("x"))),
5639 std::make_unique<VerifyIdIsBoundTo<Attr>>("x", 2)));
5642 TEST(Attr, ParentsOfAttrs) {
5643 StringRef Fragment =
5644 "namespace a { struct [[clang::warn_unused_result]] F{}; }";
5645 EXPECT_TRUE(matches(Fragment, attr(hasAncestor(namespaceDecl()))));
5648 template <typename T> class VerifyMatchOnNode : public BoundNodesCallback {
5649 public:
5650 VerifyMatchOnNode(StringRef Id, const internal::Matcher<T> &InnerMatcher,
5651 StringRef InnerId)
5652 : Id(Id), InnerMatcher(InnerMatcher), InnerId(InnerId) {
5655 bool run(const BoundNodes *Nodes) override { return false; }
5657 bool run(const BoundNodes *Nodes, ASTContext *Context) override {
5658 const T *Node = Nodes->getNodeAs<T>(Id);
5659 return selectFirst<T>(InnerId, match(InnerMatcher, *Node, *Context)) !=
5660 nullptr;
5662 private:
5663 std::string Id;
5664 internal::Matcher<T> InnerMatcher;
5665 std::string InnerId;
5668 TEST(MatchFinder, CanMatchDeclarationsRecursively) {
5669 EXPECT_TRUE(matchAndVerifyResultTrue(
5670 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5671 std::make_unique<VerifyMatchOnNode<Decl>>(
5672 "X", decl(hasDescendant(recordDecl(hasName("X::Y")).bind("Y"))),
5673 "Y")));
5674 EXPECT_TRUE(matchAndVerifyResultFalse(
5675 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5676 std::make_unique<VerifyMatchOnNode<Decl>>(
5677 "X", decl(hasDescendant(recordDecl(hasName("X::Z")).bind("Z"))),
5678 "Z")));
5681 TEST(MatchFinder, CanMatchStatementsRecursively) {
5682 EXPECT_TRUE(matchAndVerifyResultTrue(
5683 "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
5684 std::make_unique<VerifyMatchOnNode<Stmt>>(
5685 "if", stmt(hasDescendant(forStmt().bind("for"))), "for")));
5686 EXPECT_TRUE(matchAndVerifyResultFalse(
5687 "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
5688 std::make_unique<VerifyMatchOnNode<Stmt>>(
5689 "if", stmt(hasDescendant(declStmt().bind("decl"))), "decl")));
5692 TEST(MatchFinder, CanMatchSingleNodesRecursively) {
5693 EXPECT_TRUE(matchAndVerifyResultTrue(
5694 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5695 std::make_unique<VerifyMatchOnNode<Decl>>(
5696 "X", recordDecl(has(recordDecl(hasName("X::Y")).bind("Y"))), "Y")));
5697 EXPECT_TRUE(matchAndVerifyResultFalse(
5698 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5699 std::make_unique<VerifyMatchOnNode<Decl>>(
5700 "X", recordDecl(has(recordDecl(hasName("X::Z")).bind("Z"))), "Z")));
5703 TEST(StatementMatcher, HasReturnValue) {
5704 StatementMatcher RetVal = returnStmt(hasReturnValue(binaryOperator()));
5705 EXPECT_TRUE(matches("int F() { int a, b; return a + b; }", RetVal));
5706 EXPECT_FALSE(matches("int F() { int a; return a; }", RetVal));
5707 EXPECT_FALSE(matches("void F() { return; }", RetVal));
5710 TEST(StatementMatcher, ForFunction) {
5711 StringRef CppString1 = "struct PosVec {"
5712 " PosVec& operator=(const PosVec&) {"
5713 " auto x = [] { return 1; };"
5714 " return *this;"
5715 " }"
5716 "};";
5717 StringRef CppString2 = "void F() {"
5718 " struct S {"
5719 " void F2() {"
5720 " return;"
5721 " }"
5722 " };"
5723 "}";
5724 EXPECT_TRUE(
5725 matches(
5726 CppString1,
5727 returnStmt(forFunction(hasName("operator=")),
5728 has(unaryOperator(hasOperatorName("*"))))));
5729 EXPECT_TRUE(
5730 notMatches(
5731 CppString1,
5732 returnStmt(forFunction(hasName("operator=")),
5733 has(integerLiteral()))));
5734 EXPECT_TRUE(
5735 matches(
5736 CppString1,
5737 returnStmt(forFunction(hasName("operator()")),
5738 has(integerLiteral()))));
5739 EXPECT_TRUE(matches(CppString2, returnStmt(forFunction(hasName("F2")))));
5740 EXPECT_TRUE(notMatches(CppString2, returnStmt(forFunction(hasName("F")))));
5743 TEST(StatementMatcher, ForCallable) {
5744 // These tests are copied over from the forFunction() test above.
5745 StringRef CppString1 = "struct PosVec {"
5746 " PosVec& operator=(const PosVec&) {"
5747 " auto x = [] { return 1; };"
5748 " return *this;"
5749 " }"
5750 "};";
5751 StringRef CppString2 = "void F() {"
5752 " struct S {"
5753 " void F2() {"
5754 " return;"
5755 " }"
5756 " };"
5757 "}";
5759 EXPECT_TRUE(
5760 matches(
5761 CppString1,
5762 returnStmt(forCallable(functionDecl(hasName("operator="))),
5763 has(unaryOperator(hasOperatorName("*"))))));
5764 EXPECT_TRUE(
5765 notMatches(
5766 CppString1,
5767 returnStmt(forCallable(functionDecl(hasName("operator="))),
5768 has(integerLiteral()))));
5769 EXPECT_TRUE(
5770 matches(
5771 CppString1,
5772 returnStmt(forCallable(functionDecl(hasName("operator()"))),
5773 has(integerLiteral()))));
5774 EXPECT_TRUE(matches(CppString2,
5775 returnStmt(forCallable(functionDecl(hasName("F2"))))));
5776 EXPECT_TRUE(notMatches(CppString2,
5777 returnStmt(forCallable(functionDecl(hasName("F"))))));
5779 // These tests are specific to forCallable().
5780 StringRef ObjCString1 = "@interface I"
5781 "-(void) foo;"
5782 "@end"
5783 "@implementation I"
5784 "-(void) foo {"
5785 " void (^block)() = ^{ 0x2b | ~0x2b; };"
5787 "@end";
5789 EXPECT_TRUE(
5790 matchesObjC(
5791 ObjCString1,
5792 binaryOperator(forCallable(blockDecl()))));
5794 EXPECT_TRUE(
5795 notMatchesObjC(
5796 ObjCString1,
5797 binaryOperator(forCallable(objcMethodDecl()))));
5799 StringRef ObjCString2 = "@interface I"
5800 "-(void) foo;"
5801 "@end"
5802 "@implementation I"
5803 "-(void) foo {"
5804 " 0x2b | ~0x2b;"
5805 " void (^block)() = ^{};"
5807 "@end";
5809 EXPECT_TRUE(
5810 matchesObjC(
5811 ObjCString2,
5812 binaryOperator(forCallable(objcMethodDecl()))));
5814 EXPECT_TRUE(
5815 notMatchesObjC(
5816 ObjCString2,
5817 binaryOperator(forCallable(blockDecl()))));
5820 TEST(Matcher, ForEachOverriden) {
5821 const auto ForEachOverriddenInClass = [](const char *ClassName) {
5822 return cxxMethodDecl(ofClass(hasName(ClassName)), isVirtual(),
5823 forEachOverridden(cxxMethodDecl().bind("overridden")))
5824 .bind("override");
5826 static const char Code1[] = "class A { virtual void f(); };"
5827 "class B : public A { void f(); };"
5828 "class C : public B { void f(); };";
5829 // C::f overrides A::f.
5830 EXPECT_TRUE(matchAndVerifyResultTrue(
5831 Code1, ForEachOverriddenInClass("C"),
5832 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("override", "f", 1)));
5833 EXPECT_TRUE(matchAndVerifyResultTrue(
5834 Code1, ForEachOverriddenInClass("C"),
5835 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("overridden", "f",
5836 1)));
5837 // B::f overrides A::f.
5838 EXPECT_TRUE(matchAndVerifyResultTrue(
5839 Code1, ForEachOverriddenInClass("B"),
5840 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("override", "f", 1)));
5841 EXPECT_TRUE(matchAndVerifyResultTrue(
5842 Code1, ForEachOverriddenInClass("B"),
5843 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("overridden", "f",
5844 1)));
5845 // A::f overrides nothing.
5846 EXPECT_TRUE(notMatches(Code1, ForEachOverriddenInClass("A")));
5848 static const char Code2[] =
5849 "class A1 { virtual void f(); };"
5850 "class A2 { virtual void f(); };"
5851 "class B : public A1, public A2 { void f(); };";
5852 // B::f overrides A1::f and A2::f. This produces two matches.
5853 EXPECT_TRUE(matchAndVerifyResultTrue(
5854 Code2, ForEachOverriddenInClass("B"),
5855 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("override", "f", 2)));
5856 EXPECT_TRUE(matchAndVerifyResultTrue(
5857 Code2, ForEachOverriddenInClass("B"),
5858 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("overridden", "f",
5859 2)));
5860 // A1::f overrides nothing.
5861 EXPECT_TRUE(notMatches(Code2, ForEachOverriddenInClass("A1")));
5864 TEST(Matcher, HasAnyDeclaration) {
5865 StringRef Fragment = "void foo(int p1);"
5866 "void foo(int *p2);"
5867 "void bar(int p3);"
5868 "template <typename T> void baz(T t) { foo(t); }";
5870 EXPECT_TRUE(
5871 matches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(functionDecl(
5872 hasParameter(0, parmVarDecl(hasName("p1"))))))));
5873 EXPECT_TRUE(
5874 matches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(functionDecl(
5875 hasParameter(0, parmVarDecl(hasName("p2"))))))));
5876 EXPECT_TRUE(
5877 notMatches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(functionDecl(
5878 hasParameter(0, parmVarDecl(hasName("p3"))))))));
5879 EXPECT_TRUE(notMatches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(
5880 functionDecl(hasName("bar"))))));
5883 TEST(SubstTemplateTypeParmType, HasReplacementType) {
5884 StringRef Fragment = "template<typename T>"
5885 "double F(T t);"
5886 "int i;"
5887 "double j = F(i);";
5888 EXPECT_TRUE(matches(Fragment, substTemplateTypeParmType(hasReplacementType(
5889 qualType(asString("int"))))));
5890 EXPECT_TRUE(notMatches(Fragment, substTemplateTypeParmType(hasReplacementType(
5891 qualType(asString("double"))))));
5892 EXPECT_TRUE(
5893 notMatches("template<int N>"
5894 "double F();"
5895 "double j = F<5>();",
5896 substTemplateTypeParmType(hasReplacementType(qualType()))));
5899 TEST(ClassTemplateSpecializationDecl, HasSpecializedTemplate) {
5900 auto Matcher = classTemplateSpecializationDecl(
5901 hasSpecializedTemplate(classTemplateDecl()));
5902 EXPECT_TRUE(
5903 matches("template<typename T> class A {}; typedef A<int> B;", Matcher));
5904 EXPECT_TRUE(notMatches("template<typename T> class A {};", Matcher));
5907 TEST(CXXNewExpr, Array) {
5908 StatementMatcher NewArray = cxxNewExpr(isArray());
5910 EXPECT_TRUE(matches("void foo() { int *Ptr = new int[10]; }", NewArray));
5911 EXPECT_TRUE(notMatches("void foo() { int *Ptr = new int; }", NewArray));
5913 StatementMatcher NewArraySize10 =
5914 cxxNewExpr(hasArraySize(integerLiteral(equals(10))));
5915 EXPECT_TRUE(
5916 matches("void foo() { int *Ptr = new int[10]; }", NewArraySize10));
5917 EXPECT_TRUE(
5918 notMatches("void foo() { int *Ptr = new int[20]; }", NewArraySize10));
5921 TEST(CXXNewExpr, PlacementArgs) {
5922 StatementMatcher IsPlacementNew = cxxNewExpr(hasAnyPlacementArg(anything()));
5924 EXPECT_TRUE(matches(R"(
5925 void* operator new(decltype(sizeof(void*)), void*);
5926 int *foo(void* Storage) {
5927 return new (Storage) int;
5928 })",
5929 IsPlacementNew));
5931 EXPECT_TRUE(matches(R"(
5932 void* operator new(decltype(sizeof(void*)), void*, unsigned);
5933 int *foo(void* Storage) {
5934 return new (Storage, 16) int;
5935 })",
5936 cxxNewExpr(hasPlacementArg(
5937 1, ignoringImpCasts(integerLiteral(equals(16)))))));
5939 EXPECT_TRUE(notMatches(R"(
5940 void* operator new(decltype(sizeof(void*)), void*);
5941 int *foo(void* Storage) {
5942 return new int;
5943 })",
5944 IsPlacementNew));
5947 TEST(HasUnqualifiedLoc, BindsToConstIntVarDecl) {
5948 EXPECT_TRUE(matches(
5949 "const int x = 0;",
5950 varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
5951 hasUnqualifiedLoc(loc(asString("int"))))))));
5954 TEST(HasUnqualifiedLoc, BindsToVolatileIntVarDecl) {
5955 EXPECT_TRUE(matches(
5956 "volatile int x = 0;",
5957 varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
5958 hasUnqualifiedLoc(loc(asString("int"))))))));
5961 TEST(HasUnqualifiedLoc, BindsToConstVolatileIntVarDecl) {
5962 EXPECT_TRUE(matches(
5963 "const volatile int x = 0;",
5964 varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
5965 hasUnqualifiedLoc(loc(asString("int"))))))));
5968 TEST(HasUnqualifiedLoc, BindsToConstPointerVarDecl) {
5969 auto matcher = varDecl(
5970 hasName("x"),
5971 hasTypeLoc(qualifiedTypeLoc(hasUnqualifiedLoc(pointerTypeLoc()))));
5972 EXPECT_TRUE(matches("int* const x = 0;", matcher));
5973 EXPECT_TRUE(notMatches("int const x = 0;", matcher));
5976 TEST(HasUnqualifiedLoc, BindsToPointerToConstVolatileIntVarDecl) {
5977 EXPECT_TRUE(
5978 matches("const volatile int* x = 0;",
5979 varDecl(hasName("x"),
5980 hasTypeLoc(pointerTypeLoc(hasPointeeLoc(qualifiedTypeLoc(
5981 hasUnqualifiedLoc(loc(asString("int"))))))))));
5984 TEST(HasUnqualifiedLoc, BindsToConstIntFunctionDecl) {
5985 EXPECT_TRUE(
5986 matches("const int f() { return 5; }",
5987 functionDecl(hasName("f"),
5988 hasReturnTypeLoc(qualifiedTypeLoc(
5989 hasUnqualifiedLoc(loc(asString("int"))))))));
5992 TEST(HasUnqualifiedLoc, FloatBindsToConstFloatVarDecl) {
5993 EXPECT_TRUE(matches(
5994 "const float x = 0;",
5995 varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
5996 hasUnqualifiedLoc(loc(asString("float"))))))));
5999 TEST(HasUnqualifiedLoc, FloatDoesNotBindToIntVarDecl) {
6000 EXPECT_TRUE(notMatches(
6001 "int x = 0;",
6002 varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
6003 hasUnqualifiedLoc(loc(asString("float"))))))));
6006 TEST(HasUnqualifiedLoc, FloatDoesNotBindToConstIntVarDecl) {
6007 EXPECT_TRUE(notMatches(
6008 "const int x = 0;",
6009 varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
6010 hasUnqualifiedLoc(loc(asString("float"))))))));
6013 TEST(HasReturnTypeLoc, BindsToIntReturnTypeLoc) {
6014 EXPECT_TRUE(matches(
6015 "int f() { return 5; }",
6016 functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("int"))))));
6019 TEST(HasReturnTypeLoc, BindsToFloatReturnTypeLoc) {
6020 EXPECT_TRUE(matches(
6021 "float f() { return 5.0; }",
6022 functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("float"))))));
6025 TEST(HasReturnTypeLoc, BindsToVoidReturnTypeLoc) {
6026 EXPECT_TRUE(matches(
6027 "void f() {}",
6028 functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("void"))))));
6031 TEST(HasReturnTypeLoc, FloatDoesNotBindToIntReturnTypeLoc) {
6032 EXPECT_TRUE(notMatches(
6033 "int f() { return 5; }",
6034 functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("float"))))));
6037 TEST(HasReturnTypeLoc, IntDoesNotBindToFloatReturnTypeLoc) {
6038 EXPECT_TRUE(notMatches(
6039 "float f() { return 5.0; }",
6040 functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("int"))))));
6043 TEST(HasPointeeLoc, BindsToAnyPointeeTypeLoc) {
6044 auto matcher = varDecl(hasName("x"),
6045 hasTypeLoc(pointerTypeLoc(hasPointeeLoc(typeLoc()))));
6046 EXPECT_TRUE(matches("int* x;", matcher));
6047 EXPECT_TRUE(matches("float* x;", matcher));
6048 EXPECT_TRUE(matches("char* x;", matcher));
6049 EXPECT_TRUE(matches("void* x;", matcher));
6052 TEST(HasPointeeLoc, DoesNotBindToTypeLocWithoutPointee) {
6053 auto matcher = varDecl(hasName("x"),
6054 hasTypeLoc(pointerTypeLoc(hasPointeeLoc(typeLoc()))));
6055 EXPECT_TRUE(notMatches("int x;", matcher));
6056 EXPECT_TRUE(notMatches("float x;", matcher));
6057 EXPECT_TRUE(notMatches("char x;", matcher));
6060 TEST(HasPointeeLoc, BindsToTypeLocPointingToInt) {
6061 EXPECT_TRUE(
6062 matches("int* x;", pointerTypeLoc(hasPointeeLoc(loc(asString("int"))))));
6065 TEST(HasPointeeLoc, BindsToTypeLocPointingToIntPointer) {
6066 EXPECT_TRUE(matches("int** x;",
6067 pointerTypeLoc(hasPointeeLoc(loc(asString("int *"))))));
6070 TEST(HasPointeeLoc, BindsToTypeLocPointingToTypeLocPointingToInt) {
6071 EXPECT_TRUE(matches("int** x;", pointerTypeLoc(hasPointeeLoc(pointerTypeLoc(
6072 hasPointeeLoc(loc(asString("int"))))))));
6075 TEST(HasPointeeLoc, BindsToTypeLocPointingToFloat) {
6076 EXPECT_TRUE(matches("float* x;",
6077 pointerTypeLoc(hasPointeeLoc(loc(asString("float"))))));
6080 TEST(HasPointeeLoc, IntPointeeDoesNotBindToTypeLocPointingToFloat) {
6081 EXPECT_TRUE(notMatches("float* x;",
6082 pointerTypeLoc(hasPointeeLoc(loc(asString("int"))))));
6085 TEST(HasPointeeLoc, FloatPointeeDoesNotBindToTypeLocPointingToInt) {
6086 EXPECT_TRUE(notMatches(
6087 "int* x;", pointerTypeLoc(hasPointeeLoc(loc(asString("float"))))));
6090 TEST(HasReferentLoc, BindsToAnyReferentTypeLoc) {
6091 auto matcher = varDecl(
6092 hasName("r"), hasTypeLoc(referenceTypeLoc(hasReferentLoc(typeLoc()))));
6093 EXPECT_TRUE(matches("int rr = 3; int& r = rr;", matcher));
6094 EXPECT_TRUE(matches("int rr = 3; auto& r = rr;", matcher));
6095 EXPECT_TRUE(matches("int rr = 3; const int& r = rr;", matcher));
6096 EXPECT_TRUE(matches("float rr = 3.0; float& r = rr;", matcher));
6097 EXPECT_TRUE(matches("char rr = 'a'; char& r = rr;", matcher));
6100 TEST(HasReferentLoc, DoesNotBindToTypeLocWithoutReferent) {
6101 auto matcher = varDecl(
6102 hasName("r"), hasTypeLoc(referenceTypeLoc(hasReferentLoc(typeLoc()))));
6103 EXPECT_TRUE(notMatches("int r;", matcher));
6104 EXPECT_TRUE(notMatches("int r = 3;", matcher));
6105 EXPECT_TRUE(notMatches("const int r = 3;", matcher));
6106 EXPECT_TRUE(notMatches("int* r;", matcher));
6107 EXPECT_TRUE(notMatches("float r;", matcher));
6108 EXPECT_TRUE(notMatches("char r;", matcher));
6111 TEST(HasReferentLoc, BindsToAnyRvalueReference) {
6112 auto matcher = varDecl(
6113 hasName("r"), hasTypeLoc(referenceTypeLoc(hasReferentLoc(typeLoc()))));
6114 EXPECT_TRUE(matches("int&& r = 3;", matcher));
6115 EXPECT_TRUE(matches("auto&& r = 3;", matcher));
6116 EXPECT_TRUE(matches("float&& r = 3.0;", matcher));
6119 TEST(HasReferentLoc, BindsToIntReferenceTypeLoc) {
6120 EXPECT_TRUE(matches("int rr = 3; int& r = rr;",
6121 referenceTypeLoc(hasReferentLoc(loc(asString("int"))))));
6124 TEST(HasReferentLoc, BindsToIntRvalueReferenceTypeLoc) {
6125 EXPECT_TRUE(matches("int&& r = 3;",
6126 referenceTypeLoc(hasReferentLoc(loc(asString("int"))))));
6129 TEST(HasReferentLoc, BindsToFloatReferenceTypeLoc) {
6130 EXPECT_TRUE(
6131 matches("float rr = 3.0; float& r = rr;",
6132 referenceTypeLoc(hasReferentLoc(loc(asString("float"))))));
6135 TEST(HasReferentLoc, BindsToParameterWithIntReferenceTypeLoc) {
6136 EXPECT_TRUE(matches(
6137 "int f(int& r) { return r; }",
6138 parmVarDecl(hasName("r"), hasTypeLoc(referenceTypeLoc(
6139 hasReferentLoc(loc(asString("int"))))))));
6142 TEST(HasReferentLoc, IntReferenceDoesNotBindToFloatReferenceTypeLoc) {
6143 EXPECT_TRUE(
6144 notMatches("float rr = 3.0; float& r = rr;",
6145 referenceTypeLoc(hasReferentLoc(loc(asString("int"))))));
6148 TEST(HasReferentLoc, FloatReferenceDoesNotBindToIntReferenceTypeLoc) {
6149 EXPECT_TRUE(
6150 notMatches("int rr = 3; int& r = rr;",
6151 referenceTypeLoc(hasReferentLoc(loc(asString("float"))))));
6154 TEST(HasReferentLoc, DoesNotBindToParameterWithoutIntReferenceTypeLoc) {
6155 EXPECT_TRUE(notMatches(
6156 "int f(int r) { return r; }",
6157 parmVarDecl(hasName("r"), hasTypeLoc(referenceTypeLoc(
6158 hasReferentLoc(loc(asString("int"))))))));
6161 TEST(HasAnyTemplateArgumentLoc, BindsToSpecializationWithIntArgument) {
6162 EXPECT_TRUE(matches(
6163 "template<typename T> class A {}; A<int> a;",
6164 varDecl(hasName("a"),
6165 hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc(
6166 templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
6167 hasTypeLoc(loc(asString("int")))))))))));
6170 TEST(HasAnyTemplateArgumentLoc, BindsToSpecializationWithDoubleArgument) {
6171 EXPECT_TRUE(matches(
6172 "template<typename T> class A {}; A<double> a;",
6173 varDecl(hasName("a"),
6174 hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc(
6175 templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
6176 hasTypeLoc(loc(asString("double")))))))))));
6179 TEST(HasAnyTemplateArgumentLoc, BindsToExplicitSpecializationWithIntArgument) {
6180 EXPECT_TRUE(matches(
6181 "template<typename T> class A {}; template<> class A<int> {};",
6182 classTemplateSpecializationDecl(
6183 hasName("A"),
6184 hasTypeLoc(templateSpecializationTypeLoc(
6185 hasAnyTemplateArgumentLoc(hasTypeLoc(loc(asString("int")))))))));
6188 TEST(HasAnyTemplateArgumentLoc,
6189 BindsToExplicitSpecializationWithDoubleArgument) {
6190 EXPECT_TRUE(matches(
6191 "template<typename T> class A {}; template<> class A<double> {};",
6192 classTemplateSpecializationDecl(
6193 hasName("A"),
6194 hasTypeLoc(templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
6195 hasTypeLoc(loc(asString("double")))))))));
6198 TEST(HasAnyTemplateArgumentLoc, BindsToSpecializationWithMultipleArguments) {
6199 auto code = R"(
6200 template<typename T, typename U> class A {};
6201 template<> class A<double, int> {};
6203 EXPECT_TRUE(
6204 matches(code, classTemplateSpecializationDecl(
6205 hasName("A"), hasTypeLoc(templateSpecializationTypeLoc(
6206 hasAnyTemplateArgumentLoc(hasTypeLoc(
6207 loc(asString("double")))))))));
6208 EXPECT_TRUE(matches(
6209 code,
6210 classTemplateSpecializationDecl(
6211 hasName("A"),
6212 hasTypeLoc(templateSpecializationTypeLoc(
6213 hasAnyTemplateArgumentLoc(hasTypeLoc(loc(asString("int")))))))));
6216 TEST(HasAnyTemplateArgumentLoc, DoesNotBindToSpecializationWithIntArgument) {
6217 EXPECT_TRUE(notMatches(
6218 "template<typename T> class A {}; A<int> a;",
6219 classTemplateSpecializationDecl(
6220 hasName("A"),
6221 hasTypeLoc(templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
6222 hasTypeLoc(loc(asString("double")))))))));
6225 TEST(HasAnyTemplateArgumentLoc,
6226 DoesNotBindToExplicitSpecializationWithIntArgument) {
6227 EXPECT_TRUE(notMatches(
6228 "template<typename T> class A {}; template<> class A<int> {};",
6229 classTemplateSpecializationDecl(
6230 hasName("A"),
6231 hasTypeLoc(templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
6232 hasTypeLoc(loc(asString("double")))))))));
6235 TEST(HasTemplateArgumentLoc, BindsToSpecializationWithIntArgument) {
6236 EXPECT_TRUE(
6237 matches("template<typename T> class A {}; A<int> a;",
6238 varDecl(hasName("a"),
6239 hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc(
6240 templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6241 0, hasTypeLoc(loc(asString("int")))))))))));
6244 TEST(HasTemplateArgumentLoc, BindsToSpecializationWithDoubleArgument) {
6245 EXPECT_TRUE(
6246 matches("template<typename T> class A {}; A<double> a;",
6247 varDecl(hasName("a"),
6248 hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc(
6249 templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6250 0, hasTypeLoc(loc(asString("double")))))))))));
6253 TEST(HasTemplateArgumentLoc, BindsToExplicitSpecializationWithIntArgument) {
6254 EXPECT_TRUE(matches(
6255 "template<typename T> class A {}; template<> class A<int> {};",
6256 classTemplateSpecializationDecl(
6257 hasName("A"),
6258 hasTypeLoc(templateSpecializationTypeLoc(
6259 hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("int")))))))));
6262 TEST(HasTemplateArgumentLoc, BindsToExplicitSpecializationWithDoubleArgument) {
6263 EXPECT_TRUE(matches(
6264 "template<typename T> class A {}; template<> class A<double> {};",
6265 classTemplateSpecializationDecl(
6266 hasName("A"),
6267 hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6268 0, hasTypeLoc(loc(asString("double")))))))));
6271 TEST(HasTemplateArgumentLoc, BindsToSpecializationWithMultipleArguments) {
6272 auto code = R"(
6273 template<typename T, typename U> class A {};
6274 template<> class A<double, int> {};
6276 EXPECT_TRUE(matches(
6277 code, classTemplateSpecializationDecl(
6278 hasName("A"),
6279 hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6280 0, hasTypeLoc(loc(asString("double")))))))));
6281 EXPECT_TRUE(matches(
6282 code, classTemplateSpecializationDecl(
6283 hasName("A"),
6284 hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6285 1, hasTypeLoc(loc(asString("int")))))))));
6288 TEST(HasTemplateArgumentLoc, DoesNotBindToSpecializationWithIntArgument) {
6289 EXPECT_TRUE(notMatches(
6290 "template<typename T> class A {}; A<int> a;",
6291 classTemplateSpecializationDecl(
6292 hasName("A"),
6293 hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6294 0, hasTypeLoc(loc(asString("double")))))))));
6297 TEST(HasTemplateArgumentLoc,
6298 DoesNotBindToExplicitSpecializationWithIntArgument) {
6299 EXPECT_TRUE(notMatches(
6300 "template<typename T> class A {}; template<> class A<int> {};",
6301 classTemplateSpecializationDecl(
6302 hasName("A"),
6303 hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6304 0, hasTypeLoc(loc(asString("double")))))))));
6307 TEST(HasTemplateArgumentLoc,
6308 DoesNotBindToSpecializationWithMisplacedArguments) {
6309 auto code = R"(
6310 template<typename T, typename U> class A {};
6311 template<> class A<double, int> {};
6313 EXPECT_TRUE(notMatches(
6314 code, classTemplateSpecializationDecl(
6315 hasName("A"),
6316 hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6317 1, hasTypeLoc(loc(asString("double")))))))));
6318 EXPECT_TRUE(notMatches(
6319 code, classTemplateSpecializationDecl(
6320 hasName("A"),
6321 hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6322 0, hasTypeLoc(loc(asString("int")))))))));
6325 TEST(HasTemplateArgumentLoc, DoesNotBindWithBadIndex) {
6326 auto code = R"(
6327 template<typename T, typename U> class A {};
6328 template<> class A<double, int> {};
6330 EXPECT_TRUE(notMatches(
6331 code, classTemplateSpecializationDecl(
6332 hasName("A"),
6333 hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6334 -1, hasTypeLoc(loc(asString("double")))))))));
6335 EXPECT_TRUE(notMatches(
6336 code, classTemplateSpecializationDecl(
6337 hasName("A"),
6338 hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6339 100, hasTypeLoc(loc(asString("int")))))))));
6342 TEST(HasTemplateArgumentLoc, BindsToDeclRefExprWithIntArgument) {
6343 EXPECT_TRUE(matches(R"(
6344 template<typename T> T f(T t) { return t; }
6345 int g() { int i = f<int>(3); return i; }
6347 declRefExpr(to(functionDecl(hasName("f"))),
6348 hasTemplateArgumentLoc(
6349 0, hasTypeLoc(loc(asString("int")))))));
6352 TEST(HasTemplateArgumentLoc, BindsToDeclRefExprWithDoubleArgument) {
6353 EXPECT_TRUE(matches(
6355 template<typename T> T f(T t) { return t; }
6356 double g() { double i = f<double>(3.0); return i; }
6358 declRefExpr(
6359 to(functionDecl(hasName("f"))),
6360 hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("double")))))));
6363 TEST(HasTemplateArgumentLoc, DoesNotBindToDeclRefExprWithDoubleArgument) {
6364 EXPECT_TRUE(notMatches(
6366 template<typename T> T f(T t) { return t; }
6367 double g() { double i = f<double>(3.0); return i; }
6369 declRefExpr(
6370 to(functionDecl(hasName("f"))),
6371 hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("int")))))));
6374 TEST(HasNamedTypeLoc, BindsToElaboratedObjectDeclaration) {
6375 EXPECT_TRUE(matches(
6377 template <typename T>
6378 class C {};
6379 class C<int> c;
6381 varDecl(hasName("c"),
6382 hasTypeLoc(elaboratedTypeLoc(
6383 hasNamedTypeLoc(templateSpecializationTypeLoc(
6384 hasAnyTemplateArgumentLoc(templateArgumentLoc()))))))));
6387 TEST(HasNamedTypeLoc, DoesNotBindToNonElaboratedObjectDeclaration) {
6388 EXPECT_TRUE(matches(
6390 template <typename T>
6391 class C {};
6392 C<int> c;
6394 varDecl(hasName("c"),
6395 hasTypeLoc(elaboratedTypeLoc(
6396 hasNamedTypeLoc(templateSpecializationTypeLoc(
6397 hasAnyTemplateArgumentLoc(templateArgumentLoc()))))))));
6400 } // namespace ast_matchers
6401 } // namespace clang