[libc] Switch to using the generic `<gpuintrin.h>` implementations (#121810)
[llvm-project.git] / clang / unittests / ASTMatchers / ASTMatchersTraversalTest.cpp
blob75d6ca5ba17f8bd65b98ec81cc022021a0946e15
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(HasDeclaration, HasDeclarationOfObjCInterface) {
287 EXPECT_TRUE(matchesObjC("@interface BaseClass @end void f() {BaseClass* b;}",
288 varDecl(hasType(objcObjectPointerType(
289 pointee(hasDeclaration(objcInterfaceDecl())))))));
292 TEST(HasUnqualifiedDesugaredType, DesugarsUsing) {
293 EXPECT_TRUE(
294 matches("struct A {}; using B = A; B b;",
295 varDecl(hasType(hasUnqualifiedDesugaredType(recordType())))));
296 EXPECT_TRUE(
297 matches("struct A {}; using B = A; using C = B; C b;",
298 varDecl(hasType(hasUnqualifiedDesugaredType(recordType())))));
301 TEST(HasUnderlyingDecl, Matches) {
302 EXPECT_TRUE(matches("namespace N { template <class T> void f(T t); }"
303 "template <class T> void g() { using N::f; f(T()); }",
304 unresolvedLookupExpr(hasAnyDeclaration(
305 namedDecl(hasUnderlyingDecl(hasName("::N::f")))))));
306 EXPECT_TRUE(matches(
307 "namespace N { template <class T> void f(T t); }"
308 "template <class T> void g() { N::f(T()); }",
309 unresolvedLookupExpr(hasAnyDeclaration(namedDecl(hasName("::N::f"))))));
310 EXPECT_TRUE(notMatches(
311 "namespace N { template <class T> void f(T t); }"
312 "template <class T> void g() { using N::f; f(T()); }",
313 unresolvedLookupExpr(hasAnyDeclaration(namedDecl(hasName("::N::f"))))));
316 TEST(HasType, TakesQualTypeMatcherAndMatchesExpr) {
317 TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
318 EXPECT_TRUE(
319 matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX))));
320 EXPECT_TRUE(
321 notMatches("class X {}; void y(X *x) { x; }",
322 expr(hasType(ClassX))));
323 EXPECT_TRUE(
324 matches("class X {}; void y(X *x) { x; }",
325 expr(hasType(pointsTo(ClassX)))));
328 TEST(HasType, TakesQualTypeMatcherAndMatchesValueDecl) {
329 TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
330 EXPECT_TRUE(
331 matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX))));
332 EXPECT_TRUE(
333 notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX))));
334 EXPECT_TRUE(
335 matches("class X {}; void y() { X *x; }",
336 varDecl(hasType(pointsTo(ClassX)))));
339 TEST(HasType, TakesQualTypeMatcherAndMatchesCXXBaseSpecifier) {
340 TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
341 CXXBaseSpecifierMatcher BaseClassX = cxxBaseSpecifier(hasType(ClassX));
342 DeclarationMatcher ClassHasBaseClassX =
343 cxxRecordDecl(hasDirectBase(BaseClassX));
344 EXPECT_TRUE(matches("class X {}; class Y : X {};", ClassHasBaseClassX));
345 EXPECT_TRUE(notMatches("class Z {}; class Y : Z {};", ClassHasBaseClassX));
348 TEST(HasType, TakesDeclMatcherAndMatchesExpr) {
349 DeclarationMatcher ClassX = recordDecl(hasName("X"));
350 EXPECT_TRUE(
351 matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX))));
352 EXPECT_TRUE(
353 notMatches("class X {}; void y(X *x) { x; }",
354 expr(hasType(ClassX))));
357 TEST(HasType, TakesDeclMatcherAndMatchesValueDecl) {
358 DeclarationMatcher ClassX = recordDecl(hasName("X"));
359 EXPECT_TRUE(
360 matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX))));
361 EXPECT_TRUE(
362 notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX))));
365 TEST(HasType, TakesDeclMatcherAndMatchesCXXBaseSpecifier) {
366 DeclarationMatcher ClassX = recordDecl(hasName("X"));
367 CXXBaseSpecifierMatcher BaseClassX = cxxBaseSpecifier(hasType(ClassX));
368 DeclarationMatcher ClassHasBaseClassX =
369 cxxRecordDecl(hasDirectBase(BaseClassX));
370 EXPECT_TRUE(matches("class X {}; class Y : X {};", ClassHasBaseClassX));
371 EXPECT_TRUE(notMatches("class Z {}; class Y : Z {};", ClassHasBaseClassX));
374 TEST(HasType, MatchesTypedefDecl) {
375 EXPECT_TRUE(matches("typedef int X;", typedefDecl(hasType(asString("int")))));
376 EXPECT_TRUE(matches("typedef const int T;",
377 typedefDecl(hasType(asString("const int")))));
378 EXPECT_TRUE(notMatches("typedef const int T;",
379 typedefDecl(hasType(asString("int")))));
380 EXPECT_TRUE(matches("typedef int foo; typedef foo bar;",
381 typedefDecl(hasType(asString("foo")), hasName("bar"))));
384 TEST(HasType, MatchesTypedefNameDecl) {
385 EXPECT_TRUE(matches("using X = int;", typedefNameDecl(hasType(asString("int")))));
386 EXPECT_TRUE(matches("using T = const int;",
387 typedefNameDecl(hasType(asString("const int")))));
388 EXPECT_TRUE(notMatches("using T = const int;",
389 typedefNameDecl(hasType(asString("int")))));
390 EXPECT_TRUE(matches("using foo = int; using bar = foo;",
391 typedefNameDecl(hasType(asString("foo")), hasName("bar"))));
394 TEST(HasTypeLoc, MatchesBlockDecl) {
395 EXPECT_TRUE(matchesConditionally(
396 "auto x = ^int (int a, int b) { return a + b; };",
397 blockDecl(hasTypeLoc(loc(asString("int (int, int)")))), true,
398 {"-fblocks"}));
401 TEST(HasTypeLoc, MatchesCXXBaseSpecifierAndCtorInitializer) {
402 llvm::StringRef code = R"cpp(
403 class Foo {};
404 class Bar : public Foo {
405 Bar() : Foo() {}
407 )cpp";
409 EXPECT_TRUE(matches(
410 code, cxxRecordDecl(hasAnyBase(hasTypeLoc(loc(asString("Foo")))))));
411 EXPECT_TRUE(
412 matches(code, cxxCtorInitializer(hasTypeLoc(loc(asString("Foo"))))));
415 TEST(HasTypeLoc, MatchesCXXFunctionalCastExpr) {
416 EXPECT_TRUE(matches("auto x = int(3);",
417 cxxFunctionalCastExpr(hasTypeLoc(loc(asString("int"))))));
420 TEST(HasTypeLoc, MatchesCXXNewExpr) {
421 EXPECT_TRUE(matches("auto* x = new int(3);",
422 cxxNewExpr(hasTypeLoc(loc(asString("int"))))));
423 EXPECT_TRUE(matches("class Foo{}; auto* x = new Foo();",
424 cxxNewExpr(hasTypeLoc(loc(asString("Foo"))))));
427 TEST(HasTypeLoc, MatchesCXXTemporaryObjectExpr) {
428 EXPECT_TRUE(
429 matches("struct Foo { Foo(int, int); }; auto x = Foo(1, 2);",
430 cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("Foo"))))));
433 TEST(HasTypeLoc, MatchesCXXUnresolvedConstructExpr) {
434 EXPECT_TRUE(
435 matches("template <typename T> T make() { return T(); }",
436 cxxUnresolvedConstructExpr(hasTypeLoc(loc(asString("T"))))));
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()), true,
663 {"-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()), true,
672 {"-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()), true,
681 {"-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_P(ASTMatchersTest,
989 ForEachArgumentWithParamMatchesExplicitObjectParamOnOperatorCalls) {
990 if (!GetParam().isCXX23OrLater()) {
991 return;
994 auto DeclRef = declRefExpr(to(varDecl().bind("declOfArg"))).bind("arg");
995 auto SelfParam = parmVarDecl().bind("param");
996 StatementMatcher CallExpr =
997 callExpr(forEachArgumentWithParam(DeclRef, SelfParam));
999 StringRef S = R"cpp(
1000 struct A {
1001 int operator()(this const A &self);
1003 A obj;
1004 int global = obj();
1005 )cpp";
1007 auto Args = GetParam().getCommandLineArgs();
1008 auto Filename = getFilenameForTesting(GetParam().Language);
1010 EXPECT_TRUE(matchAndVerifyResultTrue(
1011 S, CallExpr,
1012 std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param", "self"), Args,
1013 Filename));
1014 EXPECT_TRUE(matchAndVerifyResultTrue(
1015 S, CallExpr,
1016 std::make_unique<VerifyIdIsBoundTo<VarDecl>>("declOfArg", "obj"), Args,
1017 Filename));
1020 TEST(ForEachArgumentWithParamType, ReportsNoFalsePositives) {
1021 StatementMatcher ArgumentY =
1022 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1023 TypeMatcher IntType = qualType(isInteger()).bind("type");
1024 StatementMatcher CallExpr =
1025 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1027 // IntParam does not match.
1028 EXPECT_TRUE(notMatches("void f(int* i) { int* y; f(y); }", CallExpr));
1029 // ArgumentY does not match.
1030 EXPECT_TRUE(notMatches("void f(int i) { int x; f(x); }", CallExpr));
1033 TEST(ForEachArgumentWithParamType, MatchesCXXMemberCallExpr) {
1034 StatementMatcher ArgumentY =
1035 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1036 TypeMatcher IntType = qualType(isInteger()).bind("type");
1037 StatementMatcher CallExpr =
1038 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1039 EXPECT_TRUE(matchAndVerifyResultTrue(
1040 "struct S {"
1041 " const S& operator[](int i) { return *this; }"
1042 "};"
1043 "void f(S S1) {"
1044 " int y = 1;"
1045 " S1[y];"
1046 "}",
1047 CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type", 1)));
1049 StatementMatcher CallExpr2 =
1050 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1051 EXPECT_TRUE(matchAndVerifyResultTrue(
1052 "struct S {"
1053 " static void g(int i);"
1054 "};"
1055 "void f() {"
1056 " int y = 1;"
1057 " S::g(y);"
1058 "}",
1059 CallExpr2, std::make_unique<VerifyIdIsBoundTo<QualType>>("type", 1)));
1062 TEST(ForEachArgumentWithParamType, MatchesCallExpr) {
1063 StatementMatcher ArgumentY =
1064 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1065 TypeMatcher IntType = qualType(isInteger()).bind("type");
1066 StatementMatcher CallExpr =
1067 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1069 EXPECT_TRUE(matchAndVerifyResultTrue(
1070 "void f(int i) { int y; f(y); }", CallExpr,
1071 std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
1072 EXPECT_TRUE(matchAndVerifyResultTrue(
1073 "void f(int i) { int y; f(y); }", CallExpr,
1074 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
1076 EXPECT_TRUE(matchAndVerifyResultTrue(
1077 "void f(int i, int j) { int y; f(y, y); }", CallExpr,
1078 std::make_unique<VerifyIdIsBoundTo<QualType>>("type", 2)));
1079 EXPECT_TRUE(matchAndVerifyResultTrue(
1080 "void f(int i, int j) { int y; f(y, y); }", CallExpr,
1081 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg", 2)));
1084 TEST(ForEachArgumentWithParamType, MatchesConstructExpr) {
1085 StatementMatcher ArgumentY =
1086 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1087 TypeMatcher IntType = qualType(isInteger()).bind("type");
1088 StatementMatcher ConstructExpr =
1089 cxxConstructExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1091 EXPECT_TRUE(matchAndVerifyResultTrue(
1092 "struct C {"
1093 " C(int i) {}"
1094 "};"
1095 "int y = 0;"
1096 "C Obj(y);",
1097 ConstructExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
1098 EXPECT_TRUE(matchAndVerifyResultTrue(
1099 "struct C {"
1100 " C(int i) {}"
1101 "};"
1102 "int y = 0;"
1103 "C Obj(y);",
1104 ConstructExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
1107 TEST(ForEachArgumentWithParamType, HandlesKandRFunctions) {
1108 StatementMatcher ArgumentY =
1109 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1110 TypeMatcher IntType = qualType(isInteger()).bind("type");
1111 StatementMatcher CallExpr =
1112 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1114 EXPECT_TRUE(matchesC("void f();\n"
1115 "void call_it(void) { int x, y; f(x, y); }\n"
1116 "void f(a, b) int a, b; {}\n"
1117 "void call_it2(void) { int x, y; f(x, y); }",
1118 CallExpr));
1121 TEST(ForEachArgumentWithParamType, HandlesBoundNodesForNonMatches) {
1122 EXPECT_TRUE(matchAndVerifyResultTrue(
1123 "void g(int i, int j) {"
1124 " int a;"
1125 " int b;"
1126 " int c;"
1127 " g(a, 0);"
1128 " g(a, b);"
1129 " g(0, b);"
1130 "}",
1131 functionDecl(
1132 forEachDescendant(varDecl().bind("v")),
1133 forEachDescendant(callExpr(forEachArgumentWithParamType(
1134 declRefExpr(to(decl(equalsBoundNode("v")))), qualType())))),
1135 std::make_unique<VerifyIdIsBoundTo<VarDecl>>("v", 4)));
1138 TEST(ForEachArgumentWithParamType, MatchesFunctionPtrCalls) {
1139 StatementMatcher ArgumentY =
1140 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1141 TypeMatcher IntType = qualType(builtinType()).bind("type");
1142 StatementMatcher CallExpr =
1143 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1145 EXPECT_TRUE(matchAndVerifyResultTrue(
1146 "void f(int i) {"
1147 "void (*f_ptr)(int) = f; int y; f_ptr(y); }",
1148 CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
1149 EXPECT_TRUE(matchAndVerifyResultTrue(
1150 "void f(int i) {"
1151 "void (*f_ptr)(int) = f; int y; f_ptr(y); }",
1152 CallExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
1155 TEST(ForEachArgumentWithParamType, MatchesMemberFunctionPtrCalls) {
1156 StatementMatcher ArgumentY =
1157 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1158 TypeMatcher IntType = qualType(builtinType()).bind("type");
1159 StatementMatcher CallExpr =
1160 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1162 StringRef S = "struct A {\n"
1163 " int f(int i) { return i + 1; }\n"
1164 " int (A::*x)(int);\n"
1165 "};\n"
1166 "void f() {\n"
1167 " int y = 42;\n"
1168 " A a;\n"
1169 " a.x = &A::f;\n"
1170 " (a.*(a.x))(y);\n"
1171 "}";
1172 EXPECT_TRUE(matchAndVerifyResultTrue(
1173 S, CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
1174 EXPECT_TRUE(matchAndVerifyResultTrue(
1175 S, CallExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
1178 TEST(ForEachArgumentWithParamType, MatchesVariadicFunctionPtrCalls) {
1179 StatementMatcher ArgumentY =
1180 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1181 TypeMatcher IntType = qualType(builtinType()).bind("type");
1182 StatementMatcher CallExpr =
1183 callExpr(forEachArgumentWithParamType(ArgumentY, IntType));
1185 StringRef S = R"cpp(
1186 void fcntl(int fd, int cmd, ...) {}
1188 template <typename Func>
1189 void f(Func F) {
1190 int y = 42;
1191 F(y, 1, 3);
1194 void g() { f(fcntl); }
1195 )cpp";
1197 EXPECT_TRUE(matchAndVerifyResultTrue(
1198 S, CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type")));
1199 EXPECT_TRUE(matchAndVerifyResultTrue(
1200 S, CallExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
1203 TEST_P(ASTMatchersTest,
1204 ForEachArgumentWithParamTypeMatchesExplicitObjectParamOnOperatorCalls) {
1205 if (!GetParam().isCXX23OrLater()) {
1206 return;
1209 auto DeclRef = declRefExpr(to(varDecl().bind("declOfArg"))).bind("arg");
1210 auto SelfTy = qualType(asString("const A &")).bind("selfType");
1211 StatementMatcher CallExpr =
1212 callExpr(forEachArgumentWithParamType(DeclRef, SelfTy));
1214 StringRef S = R"cpp(
1215 struct A {
1216 int operator()(this const A &self);
1218 A obj;
1219 int global = obj();
1220 )cpp";
1222 auto Args = GetParam().getCommandLineArgs();
1223 auto Filename = getFilenameForTesting(GetParam().Language);
1225 EXPECT_TRUE(matchAndVerifyResultTrue(
1226 S, CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("selfType"),
1227 Args, Filename));
1228 EXPECT_TRUE(matchAndVerifyResultTrue(
1229 S, CallExpr,
1230 std::make_unique<VerifyIdIsBoundTo<VarDecl>>("declOfArg", "obj"), Args,
1231 Filename));
1234 TEST(QualType, hasCanonicalType) {
1235 EXPECT_TRUE(notMatches("typedef int &int_ref;"
1236 "int a;"
1237 "int_ref b = a;",
1238 varDecl(hasType(qualType(referenceType())))));
1239 EXPECT_TRUE(
1240 matches("typedef int &int_ref;"
1241 "int a;"
1242 "int_ref b = a;",
1243 varDecl(hasType(qualType(hasCanonicalType(referenceType()))))));
1246 TEST(HasParameter, CallsInnerMatcher) {
1247 EXPECT_TRUE(matches("class X { void x(int) {} };",
1248 cxxMethodDecl(hasParameter(0, varDecl()))));
1249 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
1250 cxxMethodDecl(hasParameter(0, hasName("x")))));
1251 EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) x; @end",
1252 objcMethodDecl(hasParameter(0, hasName("x")))));
1253 EXPECT_TRUE(matchesObjC("int main() { void (^b)(int) = ^(int p) {}; }",
1254 blockDecl(hasParameter(0, hasName("p")))));
1257 TEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) {
1258 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
1259 cxxMethodDecl(hasParameter(42, varDecl()))));
1262 TEST(HasType, MatchesParameterVariableTypesStrictly) {
1263 EXPECT_TRUE(matches(
1264 "class X { void x(X x) {} };",
1265 cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
1266 EXPECT_TRUE(notMatches(
1267 "class X { void x(const X &x) {} };",
1268 cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
1269 EXPECT_TRUE(matches("class X { void x(const X *x) {} };",
1270 cxxMethodDecl(hasParameter(
1271 0, hasType(pointsTo(recordDecl(hasName("X"))))))));
1272 EXPECT_TRUE(matches("class X { void x(const X &x) {} };",
1273 cxxMethodDecl(hasParameter(
1274 0, hasType(references(recordDecl(hasName("X"))))))));
1277 TEST(HasAnyParameter, MatchesIndependentlyOfPosition) {
1278 EXPECT_TRUE(matches(
1279 "class Y {}; class X { void x(X x, Y y) {} };",
1280 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
1281 EXPECT_TRUE(matches(
1282 "class Y {}; class X { void x(Y y, X x) {} };",
1283 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
1284 EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) x; @end",
1285 objcMethodDecl(hasAnyParameter(hasName("x")))));
1286 EXPECT_TRUE(matchesObjC("int main() { void (^b)(int) = ^(int p) {}; }",
1287 blockDecl(hasAnyParameter(hasName("p")))));
1290 TEST(Returns, MatchesReturnTypes) {
1291 EXPECT_TRUE(matches("class Y { int f() { return 1; } };",
1292 functionDecl(returns(asString("int")))));
1293 EXPECT_TRUE(notMatches("class Y { int f() { return 1; } };",
1294 functionDecl(returns(asString("float")))));
1295 EXPECT_TRUE(matches("class Y { Y getMe() { return *this; } };",
1296 functionDecl(returns(hasDeclaration(
1297 recordDecl(hasName("Y")))))));
1300 TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
1301 EXPECT_TRUE(notMatches(
1302 "class Y {}; class X { void x(int) {} };",
1303 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
1306 TEST(HasAnyParameter, DoesNotMatchThisPointer) {
1307 EXPECT_TRUE(notMatches("class Y {}; class X { void x() {} };",
1308 cxxMethodDecl(hasAnyParameter(
1309 hasType(pointsTo(recordDecl(hasName("X"))))))));
1312 TEST(HasName, MatchesParameterVariableDeclarations) {
1313 EXPECT_TRUE(matches("class Y {}; class X { void x(int x) {} };",
1314 cxxMethodDecl(hasAnyParameter(hasName("x")))));
1315 EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
1316 cxxMethodDecl(hasAnyParameter(hasName("x")))));
1319 TEST(Matcher, MatchesTypeTemplateArgument) {
1320 EXPECT_TRUE(matches(
1321 "template<typename T> struct B {};"
1322 "B<int> b;",
1323 classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToType(
1324 asString("int"))))));
1327 TEST(Matcher, MatchesTemplateTemplateArgument) {
1328 EXPECT_TRUE(matches("template<template <typename> class S> class X {};"
1329 "template<typename T> class Y {};"
1330 "X<Y> xi;",
1331 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1332 refersToTemplate(templateName())))));
1335 TEST(Matcher, MatchesDeclarationReferenceTemplateArgument) {
1336 EXPECT_TRUE(matches(
1337 "struct B { int next; };"
1338 "template<int(B::*next_ptr)> struct A {};"
1339 "A<&B::next> a;",
1340 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1341 refersToDeclaration(fieldDecl(hasName("next")))))));
1343 EXPECT_TRUE(notMatches(
1344 "template <typename T> struct A {};"
1345 "A<int> a;",
1346 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1347 refersToDeclaration(decl())))));
1349 EXPECT_TRUE(matches(
1350 "struct B { int next; };"
1351 "template<int(B::*next_ptr)> struct A {};"
1352 "A<&B::next> a;",
1353 templateSpecializationType(hasAnyTemplateArgument(isExpr(
1354 hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))));
1356 EXPECT_TRUE(notMatches(
1357 "template <typename T> struct A {};"
1358 "A<int> a;",
1359 templateSpecializationType(hasAnyTemplateArgument(
1360 refersToDeclaration(decl())))));
1364 TEST(Matcher, MatchesSpecificArgument) {
1365 EXPECT_TRUE(matches(
1366 "template<typename T, typename U> class A {};"
1367 "A<bool, int> a;",
1368 classTemplateSpecializationDecl(hasTemplateArgument(
1369 1, refersToType(asString("int"))))));
1370 EXPECT_TRUE(notMatches(
1371 "template<typename T, typename U> class A {};"
1372 "A<int, bool> a;",
1373 classTemplateSpecializationDecl(hasTemplateArgument(
1374 1, refersToType(asString("int"))))));
1376 EXPECT_TRUE(matches(
1377 "template<typename T, typename U> class A {};"
1378 "A<bool, int> a;",
1379 templateSpecializationType(hasTemplateArgument(
1380 1, refersToType(asString("int"))))));
1381 EXPECT_TRUE(notMatches(
1382 "template<typename T, typename U> class A {};"
1383 "A<int, bool> a;",
1384 templateSpecializationType(hasTemplateArgument(
1385 1, refersToType(asString("int"))))));
1387 EXPECT_TRUE(matches(
1388 "template<typename T> void f() {};"
1389 "void func() { f<int>(); }",
1390 functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))));
1391 EXPECT_TRUE(notMatches(
1392 "template<typename T> void f() {};",
1393 functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))));
1396 TEST(TemplateArgument, Matches) {
1397 EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
1398 classTemplateSpecializationDecl(
1399 hasAnyTemplateArgument(templateArgument()))));
1400 EXPECT_TRUE(matches(
1401 "template<typename T> struct C {}; C<int> c;",
1402 templateSpecializationType(hasAnyTemplateArgument(templateArgument()))));
1404 EXPECT_TRUE(matches(
1405 "template<typename T> void f() {};"
1406 "void func() { f<int>(); }",
1407 functionDecl(hasAnyTemplateArgument(templateArgument()))));
1410 TEST(TemplateTypeParmDecl, CXXMethodDecl) {
1411 const char input[] =
1412 "template<typename T>\n"
1413 "class Class {\n"
1414 " void method();\n"
1415 "};\n"
1416 "template<typename U>\n"
1417 "void Class<U>::method() {}\n";
1418 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1419 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1422 TEST(TemplateTypeParmDecl, VarDecl) {
1423 const char input[] =
1424 "template<typename T>\n"
1425 "class Class {\n"
1426 " static T pi;\n"
1427 "};\n"
1428 "template<typename U>\n"
1429 "U Class<U>::pi = U(3.1415926535897932385);\n";
1430 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1431 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1434 TEST(TemplateTypeParmDecl, VarTemplatePartialSpecializationDecl) {
1435 const char input[] =
1436 "template<typename T>\n"
1437 "struct Struct {\n"
1438 " template<typename T2> static int field;\n"
1439 "};\n"
1440 "template<typename U>\n"
1441 "template<typename U2>\n"
1442 "int Struct<U>::field<U2*> = 123;\n";
1443 EXPECT_TRUE(
1444 matches(input, templateTypeParmDecl(hasName("T")), langCxx14OrLater()));
1445 EXPECT_TRUE(
1446 matches(input, templateTypeParmDecl(hasName("T2")), langCxx14OrLater()));
1447 EXPECT_TRUE(
1448 matches(input, templateTypeParmDecl(hasName("U")), langCxx14OrLater()));
1449 EXPECT_TRUE(
1450 matches(input, templateTypeParmDecl(hasName("U2")), langCxx14OrLater()));
1453 TEST(TemplateTypeParmDecl, ClassTemplatePartialSpecializationDecl) {
1454 const char input[] =
1455 "template<typename T>\n"
1456 "class Class {\n"
1457 " template<typename T2> struct Struct;\n"
1458 "};\n"
1459 "template<typename U>\n"
1460 "template<typename U2>\n"
1461 "struct Class<U>::Struct<U2*> {};\n";
1462 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1463 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T2"))));
1464 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1465 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U2"))));
1468 TEST(TemplateTypeParmDecl, EnumDecl) {
1469 const char input[] =
1470 "template<typename T>\n"
1471 "struct Struct {\n"
1472 " enum class Enum : T;\n"
1473 "};\n"
1474 "template<typename U>\n"
1475 "enum class Struct<U>::Enum : U {\n"
1476 " e1,\n"
1477 " e2\n"
1478 "};\n";
1479 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1480 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1483 TEST(TemplateTypeParmDecl, RecordDecl) {
1484 const char input[] =
1485 "template<typename T>\n"
1486 "class Class {\n"
1487 " struct Struct;\n"
1488 "};\n"
1489 "template<typename U>\n"
1490 "struct Class<U>::Struct {\n"
1491 " U field;\n"
1492 "};\n";
1493 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T"))));
1494 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U"))));
1497 TEST(RefersToIntegralType, Matches) {
1498 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
1499 classTemplateSpecializationDecl(
1500 hasAnyTemplateArgument(refersToIntegralType(
1501 asString("int"))))));
1502 EXPECT_TRUE(notMatches("template<unsigned T> struct C {}; C<42> c;",
1503 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1504 refersToIntegralType(asString("int"))))));
1507 TEST(ConstructorDeclaration, SimpleCase) {
1508 EXPECT_TRUE(matches("class Foo { Foo(int i); };",
1509 cxxConstructorDecl(ofClass(hasName("Foo")))));
1510 EXPECT_TRUE(notMatches("class Foo { Foo(int i); };",
1511 cxxConstructorDecl(ofClass(hasName("Bar")))));
1514 TEST(DestructorDeclaration, MatchesVirtualDestructor) {
1515 EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };",
1516 cxxDestructorDecl(ofClass(hasName("Foo")))));
1519 TEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) {
1520 EXPECT_TRUE(notMatches("class Foo {};",
1521 cxxDestructorDecl(ofClass(hasName("Foo")))));
1524 TEST(HasAnyConstructorInitializer, SimpleCase) {
1525 EXPECT_TRUE(
1526 notMatches("class Foo { Foo() { } };",
1527 cxxConstructorDecl(hasAnyConstructorInitializer(anything()))));
1528 EXPECT_TRUE(
1529 matches("class Foo {"
1530 " Foo() : foo_() { }"
1531 " int foo_;"
1532 "};",
1533 cxxConstructorDecl(hasAnyConstructorInitializer(anything()))));
1536 TEST(HasAnyConstructorInitializer, ForField) {
1537 static const char Code[] =
1538 "class Baz { };"
1539 "class Foo {"
1540 " Foo() : foo_(), bar_() { }"
1541 " Baz foo_;"
1542 " struct {"
1543 " Baz bar_;"
1544 " };"
1545 "};";
1546 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1547 forField(hasType(recordDecl(hasName("Baz"))))))));
1548 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1549 forField(hasName("foo_"))))));
1550 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1551 forField(hasName("bar_"))))));
1552 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1553 forField(hasType(recordDecl(hasName("Bar"))))))));
1556 TEST(HasAnyConstructorInitializer, WithInitializer) {
1557 static const char Code[] =
1558 "class Foo {"
1559 " Foo() : foo_(0) { }"
1560 " int foo_;"
1561 "};";
1562 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1563 withInitializer(integerLiteral(equals(0)))))));
1564 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1565 withInitializer(integerLiteral(equals(1)))))));
1568 TEST(HasAnyConstructorInitializer, IsWritten) {
1569 static const char Code[] =
1570 "struct Bar { Bar(){} };"
1571 "class Foo {"
1572 " Foo() : foo_() { }"
1573 " Bar foo_;"
1574 " Bar bar_;"
1575 "};";
1576 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1577 allOf(forField(hasName("foo_")), isWritten())))));
1578 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1579 allOf(forField(hasName("bar_")), isWritten())))));
1580 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
1581 allOf(forField(hasName("bar_")), unless(isWritten()))))));
1584 TEST(HasAnyConstructorInitializer, IsBaseInitializer) {
1585 static const char Code[] =
1586 "struct B {};"
1587 "struct D : B {"
1588 " int I;"
1589 " D(int i) : I(i) {}"
1590 "};"
1591 "struct E : B {"
1592 " E() : B() {}"
1593 "};";
1594 EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf(
1595 hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())),
1596 hasName("E")))));
1597 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf(
1598 hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())),
1599 hasName("D")))));
1600 EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf(
1601 hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())),
1602 hasName("D")))));
1603 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf(
1604 hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())),
1605 hasName("E")))));
1608 TEST(IfStmt, ChildTraversalMatchers) {
1609 EXPECT_TRUE(matches("void f() { if (false) true; else false; }",
1610 ifStmt(hasThen(cxxBoolLiteral(equals(true))))));
1611 EXPECT_TRUE(notMatches("void f() { if (false) false; else true; }",
1612 ifStmt(hasThen(cxxBoolLiteral(equals(true))))));
1613 EXPECT_TRUE(matches("void f() { if (false) false; else true; }",
1614 ifStmt(hasElse(cxxBoolLiteral(equals(true))))));
1615 EXPECT_TRUE(notMatches("void f() { if (false) true; else false; }",
1616 ifStmt(hasElse(cxxBoolLiteral(equals(true))))));
1619 TEST(MatchBinaryOperator, HasOperatorName) {
1620 StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
1622 EXPECT_TRUE(matches("void x() { true || false; }", OperatorOr));
1623 EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
1626 TEST(MatchBinaryOperator, HasAnyOperatorName) {
1627 StatementMatcher Matcher =
1628 binaryOperator(hasAnyOperatorName("+", "-", "*", "/"));
1630 EXPECT_TRUE(matches("int x(int I) { return I + 2; }", Matcher));
1631 EXPECT_TRUE(matches("int x(int I) { return I - 2; }", Matcher));
1632 EXPECT_TRUE(matches("int x(int I) { return I * 2; }", Matcher));
1633 EXPECT_TRUE(matches("int x(int I) { return I / 2; }", Matcher));
1634 EXPECT_TRUE(notMatches("int x(int I) { return I % 2; }", Matcher));
1635 // Ensure '+= isn't mistaken.
1636 EXPECT_TRUE(notMatches("void x(int &I) { I += 1; }", Matcher));
1639 TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
1640 StatementMatcher OperatorTrueFalse =
1641 binaryOperator(hasLHS(cxxBoolLiteral(equals(true))),
1642 hasRHS(cxxBoolLiteral(equals(false))));
1644 EXPECT_TRUE(matches("void x() { true || false; }", OperatorTrueFalse));
1645 EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse));
1646 EXPECT_TRUE(notMatches("void x() { false || true; }", OperatorTrueFalse));
1648 StatementMatcher OperatorIntPointer = arraySubscriptExpr(
1649 hasLHS(hasType(isInteger())),
1650 traverse(TK_AsIs, hasRHS(hasType(pointsTo(qualType())))));
1651 EXPECT_TRUE(matches("void x() { 1[\"abc\"]; }", OperatorIntPointer));
1652 EXPECT_TRUE(notMatches("void x() { \"abc\"[1]; }", OperatorIntPointer));
1654 StringRef Code = R"cpp(
1655 struct HasOpEqMem
1657 bool operator==(const HasOpEqMem& other) const
1659 return true;
1663 struct HasOpFree
1666 bool operator==(const HasOpFree& lhs, const HasOpFree& rhs)
1668 return true;
1671 void opMem()
1673 HasOpEqMem s1;
1674 HasOpEqMem s2;
1675 if (s1 == s2)
1676 return;
1679 void opFree()
1681 HasOpFree s1;
1682 HasOpFree s2;
1683 if (s1 == s2)
1684 return;
1686 )cpp";
1687 auto s1Expr = declRefExpr(to(varDecl(hasName("s1"))));
1688 auto s2Expr = declRefExpr(to(varDecl(hasName("s2"))));
1689 EXPECT_TRUE(matches(
1690 Code,
1691 traverse(TK_IgnoreUnlessSpelledInSource,
1692 cxxOperatorCallExpr(forFunction(functionDecl(hasName("opMem"))),
1693 hasOperatorName("=="), hasLHS(s1Expr),
1694 hasRHS(s2Expr)))));
1695 EXPECT_TRUE(matches(
1696 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1697 cxxOperatorCallExpr(
1698 forFunction(functionDecl(hasName("opMem"))),
1699 hasAnyOperatorName("!=", "=="), hasLHS(s1Expr)))));
1700 EXPECT_TRUE(matches(
1701 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1702 cxxOperatorCallExpr(
1703 forFunction(functionDecl(hasName("opMem"))),
1704 hasOperatorName("=="), hasOperands(s1Expr, s2Expr)))));
1705 EXPECT_TRUE(matches(
1706 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1707 cxxOperatorCallExpr(
1708 forFunction(functionDecl(hasName("opMem"))),
1709 hasOperatorName("=="), hasEitherOperand(s2Expr)))));
1711 EXPECT_TRUE(matches(
1712 Code,
1713 traverse(TK_IgnoreUnlessSpelledInSource,
1714 cxxOperatorCallExpr(forFunction(functionDecl(hasName("opFree"))),
1715 hasOperatorName("=="), hasLHS(s1Expr),
1716 hasRHS(s2Expr)))));
1717 EXPECT_TRUE(matches(
1718 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1719 cxxOperatorCallExpr(
1720 forFunction(functionDecl(hasName("opFree"))),
1721 hasAnyOperatorName("!=", "=="), hasLHS(s1Expr)))));
1722 EXPECT_TRUE(matches(
1723 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1724 cxxOperatorCallExpr(
1725 forFunction(functionDecl(hasName("opFree"))),
1726 hasOperatorName("=="), hasOperands(s1Expr, s2Expr)))));
1727 EXPECT_TRUE(matches(
1728 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1729 cxxOperatorCallExpr(
1730 forFunction(functionDecl(hasName("opFree"))),
1731 hasOperatorName("=="), hasEitherOperand(s2Expr)))));
1734 TEST(MatchBinaryOperator, HasEitherOperand) {
1735 StatementMatcher HasOperand =
1736 binaryOperator(hasEitherOperand(cxxBoolLiteral(equals(false))));
1738 EXPECT_TRUE(matches("void x() { true || false; }", HasOperand));
1739 EXPECT_TRUE(matches("void x() { false && true; }", HasOperand));
1740 EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand));
1743 TEST(MatchBinaryOperator, HasOperands) {
1744 StatementMatcher HasOperands = binaryOperator(
1745 hasOperands(integerLiteral(equals(1)), integerLiteral(equals(2))));
1746 EXPECT_TRUE(matches("void x() { 1 + 2; }", HasOperands));
1747 EXPECT_TRUE(matches("void x() { 2 + 1; }", HasOperands));
1748 EXPECT_TRUE(notMatches("void x() { 1 + 1; }", HasOperands));
1749 EXPECT_TRUE(notMatches("void x() { 2 + 2; }", HasOperands));
1750 EXPECT_TRUE(notMatches("void x() { 0 + 0; }", HasOperands));
1751 EXPECT_TRUE(notMatches("void x() { 0 + 1; }", HasOperands));
1754 TEST(MatchBinaryOperator, HasOperandsEnsureOrdering) {
1755 StatementMatcher HasOperandsWithBindings = binaryOperator(hasOperands(
1756 cStyleCastExpr(has(declRefExpr(hasDeclaration(valueDecl().bind("d"))))),
1757 declRefExpr(hasDeclaration(valueDecl(equalsBoundNode("d"))))));
1758 EXPECT_TRUE(matches(
1759 "int a; int b = ((int) a) + a;",
1760 traverse(TK_IgnoreUnlessSpelledInSource, HasOperandsWithBindings)));
1761 EXPECT_TRUE(matches(
1762 "int a; int b = a + ((int) a);",
1763 traverse(TK_IgnoreUnlessSpelledInSource, HasOperandsWithBindings)));
1766 TEST(Matcher, BinaryOperatorTypes) {
1767 // Integration test that verifies the AST provides all binary operators in
1768 // a way we expect.
1769 // FIXME: Operator ','
1770 EXPECT_TRUE(
1771 matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(","))));
1772 EXPECT_TRUE(
1773 matches("bool b; bool c = (b = true);",
1774 binaryOperator(hasOperatorName("="))));
1775 EXPECT_TRUE(
1776 matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!="))));
1777 EXPECT_TRUE(
1778 matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("=="))));
1779 EXPECT_TRUE(matches("bool b = 1 < 2;", binaryOperator(hasOperatorName("<"))));
1780 EXPECT_TRUE(
1781 matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<="))));
1782 EXPECT_TRUE(
1783 matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<"))));
1784 EXPECT_TRUE(
1785 matches("int i = 1; int j = (i <<= 2);",
1786 binaryOperator(hasOperatorName("<<="))));
1787 EXPECT_TRUE(matches("bool b = 1 > 2;", binaryOperator(hasOperatorName(">"))));
1788 EXPECT_TRUE(
1789 matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">="))));
1790 EXPECT_TRUE(
1791 matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>"))));
1792 EXPECT_TRUE(
1793 matches("int i = 1; int j = (i >>= 2);",
1794 binaryOperator(hasOperatorName(">>="))));
1795 EXPECT_TRUE(
1796 matches("int i = 42 ^ 23;", binaryOperator(hasOperatorName("^"))));
1797 EXPECT_TRUE(
1798 matches("int i = 42; int j = (i ^= 42);",
1799 binaryOperator(hasOperatorName("^="))));
1800 EXPECT_TRUE(
1801 matches("int i = 42 % 23;", binaryOperator(hasOperatorName("%"))));
1802 EXPECT_TRUE(
1803 matches("int i = 42; int j = (i %= 42);",
1804 binaryOperator(hasOperatorName("%="))));
1805 EXPECT_TRUE(
1806 matches("bool b = 42 &23;", binaryOperator(hasOperatorName("&"))));
1807 EXPECT_TRUE(
1808 matches("bool b = true && false;",
1809 binaryOperator(hasOperatorName("&&"))));
1810 EXPECT_TRUE(
1811 matches("bool b = true; bool c = (b &= false);",
1812 binaryOperator(hasOperatorName("&="))));
1813 EXPECT_TRUE(
1814 matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|"))));
1815 EXPECT_TRUE(
1816 matches("bool b = true || false;",
1817 binaryOperator(hasOperatorName("||"))));
1818 EXPECT_TRUE(
1819 matches("bool b = true; bool c = (b |= false);",
1820 binaryOperator(hasOperatorName("|="))));
1821 EXPECT_TRUE(
1822 matches("int i = 42 *23;", binaryOperator(hasOperatorName("*"))));
1823 EXPECT_TRUE(
1824 matches("int i = 42; int j = (i *= 23);",
1825 binaryOperator(hasOperatorName("*="))));
1826 EXPECT_TRUE(
1827 matches("int i = 42 / 23;", binaryOperator(hasOperatorName("/"))));
1828 EXPECT_TRUE(
1829 matches("int i = 42; int j = (i /= 23);",
1830 binaryOperator(hasOperatorName("/="))));
1831 EXPECT_TRUE(
1832 matches("int i = 42 + 23;", binaryOperator(hasOperatorName("+"))));
1833 EXPECT_TRUE(
1834 matches("int i = 42; int j = (i += 23);",
1835 binaryOperator(hasOperatorName("+="))));
1836 EXPECT_TRUE(
1837 matches("int i = 42 - 23;", binaryOperator(hasOperatorName("-"))));
1838 EXPECT_TRUE(
1839 matches("int i = 42; int j = (i -= 23);",
1840 binaryOperator(hasOperatorName("-="))));
1841 EXPECT_TRUE(
1842 matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };",
1843 binaryOperator(hasOperatorName("->*"))));
1844 EXPECT_TRUE(
1845 matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };",
1846 binaryOperator(hasOperatorName(".*"))));
1848 // Member expressions as operators are not supported in matches.
1849 EXPECT_TRUE(
1850 notMatches("struct A { void x(A *a) { a->x(this); } };",
1851 binaryOperator(hasOperatorName("->"))));
1853 // Initializer assignments are not represented as operator equals.
1854 EXPECT_TRUE(
1855 notMatches("bool b = true;", binaryOperator(hasOperatorName("="))));
1857 // Array indexing is not represented as operator.
1858 EXPECT_TRUE(notMatches("int a[42]; void x() { a[23]; }", unaryOperator()));
1860 // Overloaded operators do not match at all.
1861 EXPECT_TRUE(notMatches(
1862 "struct A { bool operator&&(const A &a) const { return false; } };"
1863 "void x() { A a, b; a && b; }",
1864 binaryOperator()));
1867 TEST(MatchUnaryOperator, HasOperatorName) {
1868 StatementMatcher OperatorNot = unaryOperator(hasOperatorName("!"));
1870 EXPECT_TRUE(matches("void x() { !true; } ", OperatorNot));
1871 EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
1874 TEST(MatchUnaryOperator, HasAnyOperatorName) {
1875 StatementMatcher Matcher = unaryOperator(hasAnyOperatorName("-", "*", "++"));
1877 EXPECT_TRUE(matches("int x(int *I) { return *I; }", Matcher));
1878 EXPECT_TRUE(matches("int x(int I) { return -I; }", Matcher));
1879 EXPECT_TRUE(matches("void x(int &I) { I++; }", Matcher));
1880 EXPECT_TRUE(matches("void x(int &I) { ++I; }", Matcher));
1881 EXPECT_TRUE(notMatches("void x(int &I) { I--; }", Matcher));
1882 EXPECT_TRUE(notMatches("void x(int &I) { --I; }", Matcher));
1883 EXPECT_TRUE(notMatches("int *x(int &I) { return &I; }", Matcher));
1886 TEST(MatchUnaryOperator, HasUnaryOperand) {
1887 StatementMatcher OperatorOnFalse =
1888 unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false))));
1890 EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse));
1891 EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse));
1893 StringRef Code = R"cpp(
1894 struct HasOpBangMem
1896 bool operator!() const
1898 return false;
1901 struct HasOpBangFree
1904 bool operator!(HasOpBangFree const&)
1906 return false;
1909 void opMem()
1911 HasOpBangMem s1;
1912 if (!s1)
1913 return;
1915 void opFree()
1917 HasOpBangFree s1;
1918 if (!s1)
1919 return;
1921 )cpp";
1922 auto s1Expr = declRefExpr(to(varDecl(hasName("s1"))));
1923 EXPECT_TRUE(matches(
1924 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1925 cxxOperatorCallExpr(
1926 forFunction(functionDecl(hasName("opMem"))),
1927 hasOperatorName("!"), hasUnaryOperand(s1Expr)))));
1928 EXPECT_TRUE(matches(
1929 Code,
1930 traverse(TK_IgnoreUnlessSpelledInSource,
1931 cxxOperatorCallExpr(forFunction(functionDecl(hasName("opMem"))),
1932 hasAnyOperatorName("+", "!"),
1933 hasUnaryOperand(s1Expr)))));
1935 EXPECT_TRUE(matches(
1936 Code, traverse(TK_IgnoreUnlessSpelledInSource,
1937 cxxOperatorCallExpr(
1938 forFunction(functionDecl(hasName("opFree"))),
1939 hasOperatorName("!"), hasUnaryOperand(s1Expr)))));
1940 EXPECT_TRUE(matches(
1941 Code,
1942 traverse(TK_IgnoreUnlessSpelledInSource,
1943 cxxOperatorCallExpr(forFunction(functionDecl(hasName("opFree"))),
1944 hasAnyOperatorName("+", "!"),
1945 hasUnaryOperand(s1Expr)))));
1947 Code = R"cpp(
1948 struct HasIncOperatorsMem
1950 HasIncOperatorsMem& operator++();
1951 HasIncOperatorsMem operator++(int);
1953 struct HasIncOperatorsFree
1956 HasIncOperatorsFree& operator++(HasIncOperatorsFree&);
1957 HasIncOperatorsFree operator++(HasIncOperatorsFree&, int);
1959 void prefixIncOperatorMem()
1961 HasIncOperatorsMem s1;
1962 ++s1;
1964 void prefixIncOperatorFree()
1966 HasIncOperatorsFree s1;
1967 ++s1;
1969 void postfixIncOperatorMem()
1971 HasIncOperatorsMem s1;
1972 s1++;
1974 void postfixIncOperatorFree()
1976 HasIncOperatorsFree s1;
1977 s1++;
1980 struct HasOpPlusInt
1982 HasOpPlusInt& operator+(int);
1984 void plusIntOperator()
1986 HasOpPlusInt s1;
1987 s1+1;
1989 )cpp";
1991 EXPECT_TRUE(matches(
1992 Code,
1993 traverse(TK_IgnoreUnlessSpelledInSource,
1994 cxxOperatorCallExpr(
1995 forFunction(functionDecl(hasName("prefixIncOperatorMem"))),
1996 hasOperatorName("++"), hasUnaryOperand(declRefExpr())))));
1998 EXPECT_TRUE(matches(
1999 Code,
2000 traverse(TK_IgnoreUnlessSpelledInSource,
2001 cxxOperatorCallExpr(
2002 forFunction(functionDecl(hasName("prefixIncOperatorFree"))),
2003 hasOperatorName("++"), hasUnaryOperand(declRefExpr())))));
2005 EXPECT_TRUE(matches(
2006 Code,
2007 traverse(TK_IgnoreUnlessSpelledInSource,
2008 cxxOperatorCallExpr(
2009 forFunction(functionDecl(hasName("postfixIncOperatorMem"))),
2010 hasOperatorName("++"), hasUnaryOperand(declRefExpr())))));
2012 EXPECT_TRUE(matches(
2013 Code,
2014 traverse(TK_IgnoreUnlessSpelledInSource,
2015 cxxOperatorCallExpr(
2016 forFunction(functionDecl(hasName("postfixIncOperatorFree"))),
2017 hasOperatorName("++"), hasUnaryOperand(declRefExpr())))));
2019 EXPECT_FALSE(matches(
2020 Code, traverse(TK_IgnoreUnlessSpelledInSource,
2021 cxxOperatorCallExpr(
2022 forFunction(functionDecl(hasName("plusIntOperator"))),
2023 hasOperatorName("+"), hasUnaryOperand(expr())))));
2025 Code = R"cpp(
2026 struct HasOpArrow
2028 int& operator*();
2030 void foo()
2032 HasOpArrow s1;
2033 *s1;
2035 )cpp";
2037 EXPECT_TRUE(
2038 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
2039 cxxOperatorCallExpr(hasOperatorName("*"),
2040 hasUnaryOperand(expr())))));
2043 TEST(Matcher, UnaryOperatorTypes) {
2044 // Integration test that verifies the AST provides all unary operators in
2045 // a way we expect.
2046 EXPECT_TRUE(matches("bool b = !true;", unaryOperator(hasOperatorName("!"))));
2047 EXPECT_TRUE(
2048 matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&"))));
2049 EXPECT_TRUE(matches("int i = ~ 1;", unaryOperator(hasOperatorName("~"))));
2050 EXPECT_TRUE(
2051 matches("bool *p; bool b = *p;", unaryOperator(hasOperatorName("*"))));
2052 EXPECT_TRUE(
2053 matches("int i; int j = +i;", unaryOperator(hasOperatorName("+"))));
2054 EXPECT_TRUE(
2055 matches("int i; int j = -i;", unaryOperator(hasOperatorName("-"))));
2056 EXPECT_TRUE(
2057 matches("int i; int j = ++i;", unaryOperator(hasOperatorName("++"))));
2058 EXPECT_TRUE(
2059 matches("int i; int j = i++;", unaryOperator(hasOperatorName("++"))));
2060 EXPECT_TRUE(
2061 matches("int i; int j = --i;", unaryOperator(hasOperatorName("--"))));
2062 EXPECT_TRUE(
2063 matches("int i; int j = i--;", unaryOperator(hasOperatorName("--"))));
2065 // We don't match conversion operators.
2066 EXPECT_TRUE(notMatches("int i; double d = (double)i;", unaryOperator()));
2068 // Function calls are not represented as operator.
2069 EXPECT_TRUE(notMatches("void f(); void x() { f(); }", unaryOperator()));
2071 // Overloaded operators do not match at all.
2072 // FIXME: We probably want to add that.
2073 EXPECT_TRUE(notMatches(
2074 "struct A { bool operator!() const { return false; } };"
2075 "void x() { A a; !a; }", unaryOperator(hasOperatorName("!"))));
2078 TEST_P(ASTMatchersTest, HasInit) {
2079 if (!GetParam().isCXX11OrLater()) {
2080 // FIXME: Add a test for `hasInit()` that does not depend on C++.
2081 return;
2084 EXPECT_TRUE(matches("int x{0};", initListExpr(hasInit(0, expr()))));
2085 EXPECT_FALSE(matches("int x{0};", initListExpr(hasInit(1, expr()))));
2086 EXPECT_FALSE(matches("int x;", initListExpr(hasInit(0, expr()))));
2089 TEST_P(ASTMatchersTest, HasFoldInit) {
2090 if (!GetParam().isCXX17OrLater()) {
2091 return;
2094 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2095 "return (0 + ... + args); }",
2096 cxxFoldExpr(hasFoldInit(expr()))));
2097 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2098 "return (args + ... + 0); }",
2099 cxxFoldExpr(hasFoldInit(expr()))));
2100 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
2101 "return (... + args); };",
2102 cxxFoldExpr(hasFoldInit(expr()))));
2105 TEST_P(ASTMatchersTest, HasPattern) {
2106 if (!GetParam().isCXX17OrLater()) {
2107 return;
2110 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2111 "return (0 + ... + args); }",
2112 cxxFoldExpr(hasPattern(expr()))));
2113 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2114 "return (args + ... + 0); }",
2115 cxxFoldExpr(hasPattern(expr()))));
2116 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2117 "return (... + args); };",
2118 cxxFoldExpr(hasPattern(expr()))));
2121 TEST_P(ASTMatchersTest, HasLHSAndHasRHS) {
2122 if (!GetParam().isCXX17OrLater()) {
2123 return;
2126 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2127 "return (0 + ... + args); }",
2128 cxxFoldExpr(hasLHS(expr()))));
2129 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2130 "return (args + ... + 0); }",
2131 cxxFoldExpr(hasLHS(expr()))));
2132 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
2133 "return (... + args); };",
2134 cxxFoldExpr(hasLHS(expr()))));
2135 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2136 "return (args + ...); };",
2137 cxxFoldExpr(hasLHS(expr()))));
2139 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2140 "return (0 + ... + args); }",
2141 cxxFoldExpr(hasRHS(expr()))));
2142 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2143 "return (args + ... + 0); }",
2144 cxxFoldExpr(hasRHS(expr()))));
2145 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2146 "return (... + args); };",
2147 cxxFoldExpr(hasRHS(expr()))));
2148 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
2149 "return (args + ...); };",
2150 cxxFoldExpr(hasRHS(expr()))));
2153 TEST_P(ASTMatchersTest, HasEitherOperandAndHasOperands) {
2154 if (!GetParam().isCXX17OrLater()) {
2155 return;
2158 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2159 "return (0 + ... + args); }",
2160 cxxFoldExpr(hasEitherOperand(integerLiteral()))));
2161 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2162 "return (args + ... + 0); }",
2163 cxxFoldExpr(hasEitherOperand(integerLiteral()))));
2165 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2166 "return (0 + ... + args); }",
2167 cxxFoldExpr(hasEitherOperand(
2168 declRefExpr(to(namedDecl(hasName("args"))))))));
2169 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2170 "return (args + ... + 0); }",
2171 cxxFoldExpr(hasEitherOperand(
2172 declRefExpr(to(namedDecl(hasName("args"))))))));
2173 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2174 "return (... + args); };",
2175 cxxFoldExpr(hasEitherOperand(
2176 declRefExpr(to(namedDecl(hasName("args"))))))));
2177 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2178 "return (args + ...); };",
2179 cxxFoldExpr(hasEitherOperand(
2180 declRefExpr(to(namedDecl(hasName("args"))))))));
2182 EXPECT_TRUE(matches(
2183 "template <typename... Args> auto sum(Args... args) { "
2184 "return (0 + ... + args); }",
2185 cxxFoldExpr(hasOperands(declRefExpr(to(namedDecl(hasName("args")))),
2186 integerLiteral()))));
2187 EXPECT_TRUE(matches(
2188 "template <typename... Args> auto sum(Args... args) { "
2189 "return (args + ... + 0); }",
2190 cxxFoldExpr(hasOperands(declRefExpr(to(namedDecl(hasName("args")))),
2191 integerLiteral()))));
2192 EXPECT_FALSE(matches(
2193 "template <typename... Args> auto sum(Args... args) { "
2194 "return (... + args); };",
2195 cxxFoldExpr(hasOperands(declRefExpr(to(namedDecl(hasName("args")))),
2196 integerLiteral()))));
2197 EXPECT_FALSE(matches(
2198 "template <typename... Args> auto sum(Args... args) { "
2199 "return (args + ...); };",
2200 cxxFoldExpr(hasOperands(declRefExpr(to(namedDecl(hasName("args")))),
2201 integerLiteral()))));
2204 TEST_P(ASTMatchersTest, Callee) {
2205 if (!GetParam().isCXX17OrLater()) {
2206 return;
2209 EXPECT_TRUE(matches(
2210 "struct Dummy {}; Dummy operator+(Dummy, Dummy); template "
2211 "<typename... Args> auto sum(Args... args) { return (0 + ... + args); }",
2212 cxxFoldExpr(callee(expr()))));
2213 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
2214 "return (0 + ... + args); }",
2215 cxxFoldExpr(callee(expr()))));
2218 TEST(ArraySubscriptMatchers, ArrayIndex) {
2219 EXPECT_TRUE(matches(
2220 "int i[2]; void f() { i[1] = 1; }",
2221 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
2222 EXPECT_TRUE(matches(
2223 "int i[2]; void f() { 1[i] = 1; }",
2224 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
2225 EXPECT_TRUE(notMatches(
2226 "int i[2]; void f() { i[1] = 1; }",
2227 arraySubscriptExpr(hasIndex(integerLiteral(equals(0))))));
2230 TEST(ArraySubscriptMatchers, MatchesArrayBase) {
2231 EXPECT_TRUE(
2232 matches("int i[2]; void f() { i[1] = 2; }",
2233 traverse(TK_AsIs, arraySubscriptExpr(hasBase(implicitCastExpr(
2234 hasSourceExpression(declRefExpr())))))));
2237 TEST(Matcher, OfClass) {
2238 StatementMatcher Constructor = cxxConstructExpr(hasDeclaration(cxxMethodDecl(
2239 ofClass(hasName("X")))));
2241 EXPECT_TRUE(
2242 matches("class X { public: X(); }; void x(int) { X x; }", Constructor));
2243 EXPECT_TRUE(
2244 matches("class X { public: X(); }; void x(int) { X x = X(); }",
2245 Constructor));
2246 EXPECT_TRUE(
2247 notMatches("class Y { public: Y(); }; void x(int) { Y y; }",
2248 Constructor));
2251 TEST(Matcher, VisitsTemplateInstantiations) {
2252 EXPECT_TRUE(matches(
2253 "class A { public: void x(); };"
2254 "template <typename T> class B { public: void y() { T t; t.x(); } };"
2255 "void f() { B<A> b; b.y(); }",
2256 callExpr(callee(cxxMethodDecl(hasName("x"))))));
2258 EXPECT_TRUE(matches(
2259 "class A { public: void x(); };"
2260 "class C {"
2261 " public:"
2262 " template <typename T> class B { public: void y() { T t; t.x(); } };"
2263 "};"
2264 "void f() {"
2265 " C::B<A> b; b.y();"
2266 "}",
2267 recordDecl(hasName("C"), hasDescendant(callExpr(
2268 callee(cxxMethodDecl(hasName("x"))))))));
2271 TEST(Matcher, HasCondition) {
2272 StatementMatcher IfStmt =
2273 ifStmt(hasCondition(cxxBoolLiteral(equals(true))));
2274 EXPECT_TRUE(matches("void x() { if (true) {} }", IfStmt));
2275 EXPECT_TRUE(notMatches("void x() { if (false) {} }", IfStmt));
2277 StatementMatcher ForStmt =
2278 forStmt(hasCondition(cxxBoolLiteral(equals(true))));
2279 EXPECT_TRUE(matches("void x() { for (;true;) {} }", ForStmt));
2280 EXPECT_TRUE(notMatches("void x() { for (;false;) {} }", ForStmt));
2282 StatementMatcher WhileStmt =
2283 whileStmt(hasCondition(cxxBoolLiteral(equals(true))));
2284 EXPECT_TRUE(matches("void x() { while (true) {} }", WhileStmt));
2285 EXPECT_TRUE(notMatches("void x() { while (false) {} }", WhileStmt));
2287 StatementMatcher SwitchStmt =
2288 switchStmt(hasCondition(integerLiteral(equals(42))));
2289 EXPECT_TRUE(matches("void x() { switch (42) {case 42:;} }", SwitchStmt));
2290 EXPECT_TRUE(notMatches("void x() { switch (43) {case 43:;} }", SwitchStmt));
2293 TEST(For, ForLoopInternals) {
2294 EXPECT_TRUE(matches("void f(){ int i; for (; i < 3 ; ); }",
2295 forStmt(hasCondition(anything()))));
2296 EXPECT_TRUE(matches("void f() { for (int i = 0; ;); }",
2297 forStmt(hasLoopInit(anything()))));
2300 TEST(For, ForRangeLoopInternals) {
2301 EXPECT_TRUE(matches("void f(){ int a[] {1, 2}; for (int i : a); }",
2302 cxxForRangeStmt(hasLoopVariable(anything()))));
2303 EXPECT_TRUE(matches(
2304 "void f(){ int a[] {1, 2}; for (int i : a); }",
2305 cxxForRangeStmt(hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))))));
2308 TEST(For, NegativeForLoopInternals) {
2309 EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }",
2310 forStmt(hasCondition(expr()))));
2311 EXPECT_TRUE(notMatches("void f() {int i; for (; i < 4; ++i) {} }",
2312 forStmt(hasLoopInit(anything()))));
2315 TEST(HasBody, FindsBodyOfForWhileDoLoops) {
2316 EXPECT_TRUE(matches("void f() { for(;;) {} }",
2317 forStmt(hasBody(compoundStmt()))));
2318 EXPECT_TRUE(notMatches("void f() { for(;;); }",
2319 forStmt(hasBody(compoundStmt()))));
2320 EXPECT_TRUE(matches("void f() { while(true) {} }",
2321 whileStmt(hasBody(compoundStmt()))));
2322 EXPECT_TRUE(matches("void f() { do {} while(true); }",
2323 doStmt(hasBody(compoundStmt()))));
2324 EXPECT_TRUE(matches("void f() { int p[2]; for (auto x : p) {} }",
2325 cxxForRangeStmt(hasBody(compoundStmt()))));
2328 TEST(HasBody, FindsBodyOfFunctions) {
2329 EXPECT_TRUE(matches("void f() {}", functionDecl(hasBody(compoundStmt()))));
2330 EXPECT_TRUE(notMatches("void f();", functionDecl(hasBody(compoundStmt()))));
2331 EXPECT_TRUE(matchAndVerifyResultTrue(
2332 "void f(); void f() {}",
2333 functionDecl(hasBody(compoundStmt())).bind("func"),
2334 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("func", 1)));
2335 EXPECT_TRUE(matchAndVerifyResultTrue(
2336 "class C { void f(); }; void C::f() {}",
2337 cxxMethodDecl(hasBody(compoundStmt())).bind("met"),
2338 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("met", 1)));
2339 EXPECT_TRUE(matchAndVerifyResultTrue(
2340 "class C { C(); }; C::C() {}",
2341 cxxConstructorDecl(hasBody(compoundStmt())).bind("ctr"),
2342 std::make_unique<VerifyIdIsBoundTo<CXXConstructorDecl>>("ctr", 1)));
2343 EXPECT_TRUE(matchAndVerifyResultTrue(
2344 "class C { ~C(); }; C::~C() {}",
2345 cxxDestructorDecl(hasBody(compoundStmt())).bind("dtr"),
2346 std::make_unique<VerifyIdIsBoundTo<CXXDestructorDecl>>("dtr", 1)));
2349 TEST(HasAnyBody, FindsAnyBodyOfFunctions) {
2350 EXPECT_TRUE(matches("void f() {}", functionDecl(hasAnyBody(compoundStmt()))));
2351 EXPECT_TRUE(notMatches("void f();",
2352 functionDecl(hasAnyBody(compoundStmt()))));
2353 EXPECT_TRUE(matchAndVerifyResultTrue(
2354 "void f(); void f() {}",
2355 functionDecl(hasAnyBody(compoundStmt())).bind("func"),
2356 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("func", 2)));
2357 EXPECT_TRUE(matchAndVerifyResultTrue(
2358 "class C { void f(); }; void C::f() {}",
2359 cxxMethodDecl(hasAnyBody(compoundStmt())).bind("met"),
2360 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("met", 2)));
2361 EXPECT_TRUE(matchAndVerifyResultTrue(
2362 "class C { C(); }; C::C() {}",
2363 cxxConstructorDecl(hasAnyBody(compoundStmt())).bind("ctr"),
2364 std::make_unique<VerifyIdIsBoundTo<CXXConstructorDecl>>("ctr", 2)));
2365 EXPECT_TRUE(matchAndVerifyResultTrue(
2366 "class C { ~C(); }; C::~C() {}",
2367 cxxDestructorDecl(hasAnyBody(compoundStmt())).bind("dtr"),
2368 std::make_unique<VerifyIdIsBoundTo<CXXDestructorDecl>>("dtr", 2)));
2371 TEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
2372 // The simplest case: every compound statement is in a function
2373 // definition, and the function body itself must be a compound
2374 // statement.
2375 EXPECT_TRUE(matches("void f() { for (;;); }",
2376 compoundStmt(hasAnySubstatement(forStmt()))));
2379 TEST(HasAnySubstatement, IsNotRecursive) {
2380 // It's really "has any immediate substatement".
2381 EXPECT_TRUE(notMatches("void f() { if (true) for (;;); }",
2382 compoundStmt(hasAnySubstatement(forStmt()))));
2385 TEST(HasAnySubstatement, MatchesInNestedCompoundStatements) {
2386 EXPECT_TRUE(matches("void f() { if (true) { for (;;); } }",
2387 compoundStmt(hasAnySubstatement(forStmt()))));
2390 TEST(HasAnySubstatement, FindsSubstatementBetweenOthers) {
2391 EXPECT_TRUE(matches("void f() { 1; 2; 3; for (;;); 4; 5; 6; }",
2392 compoundStmt(hasAnySubstatement(forStmt()))));
2395 TEST(Member, MatchesMemberAllocationFunction) {
2396 // Fails in C++11 mode
2397 EXPECT_TRUE(matchesConditionally(
2398 "namespace std { typedef typeof(sizeof(int)) size_t; }"
2399 "class X { void *operator new(std::size_t); };",
2400 cxxMethodDecl(ofClass(hasName("X"))), true, {"-std=gnu++03"}));
2402 EXPECT_TRUE(matches("class X { void operator delete(void*); };",
2403 cxxMethodDecl(ofClass(hasName("X")))));
2405 // Fails in C++11 mode
2406 EXPECT_TRUE(matchesConditionally(
2407 "namespace std { typedef typeof(sizeof(int)) size_t; }"
2408 "class X { void operator delete[](void*, std::size_t); };",
2409 cxxMethodDecl(ofClass(hasName("X"))), true, {"-std=gnu++03"}));
2412 TEST(HasDestinationType, MatchesSimpleCase) {
2413 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
2414 cxxStaticCastExpr(hasDestinationType(
2415 pointsTo(TypeMatcher(anything()))))));
2418 TEST(HasImplicitDestinationType, MatchesSimpleCase) {
2419 // This test creates an implicit const cast.
2420 EXPECT_TRUE(matches(
2421 "int x; const int i = x;",
2422 traverse(TK_AsIs,
2423 implicitCastExpr(hasImplicitDestinationType(isInteger())))));
2424 // This test creates an implicit array-to-pointer cast.
2425 EXPECT_TRUE(
2426 matches("int arr[3]; int *p = arr;",
2427 traverse(TK_AsIs, implicitCastExpr(hasImplicitDestinationType(
2428 pointsTo(TypeMatcher(anything())))))));
2431 TEST(HasImplicitDestinationType, DoesNotMatchIncorrectly) {
2432 // This test creates an implicit cast from int to char.
2433 EXPECT_TRUE(notMatches("char c = 0;",
2434 implicitCastExpr(hasImplicitDestinationType(
2435 unless(anything())))));
2436 // This test creates an implicit array-to-pointer cast.
2437 EXPECT_TRUE(notMatches("int arr[3]; int *p = arr;",
2438 implicitCastExpr(hasImplicitDestinationType(
2439 unless(anything())))));
2442 TEST(Matcher, IgnoresElidableConstructors) {
2443 EXPECT_TRUE(
2444 matches("struct H {};"
2445 "template<typename T> H B(T A);"
2446 "void f() {"
2447 " H D1;"
2448 " D1 = B(B(1));"
2449 "}",
2450 cxxOperatorCallExpr(hasArgument(
2451 1, callExpr(hasArgument(
2452 0, ignoringElidableConstructorCall(callExpr()))))),
2453 langCxx11OrLater()));
2454 EXPECT_TRUE(
2455 matches("struct H {};"
2456 "template<typename T> H B(T A);"
2457 "void f() {"
2458 " H D1;"
2459 " D1 = B(1);"
2460 "}",
2461 cxxOperatorCallExpr(hasArgument(
2462 1, callExpr(hasArgument(0, ignoringElidableConstructorCall(
2463 integerLiteral()))))),
2464 langCxx11OrLater()));
2465 EXPECT_TRUE(matches(
2466 "struct H {};"
2467 "H G();"
2468 "void f() {"
2469 " H D = G();"
2470 "}",
2471 varDecl(hasInitializer(anyOf(
2472 ignoringElidableConstructorCall(callExpr()),
2473 exprWithCleanups(has(ignoringElidableConstructorCall(callExpr())))))),
2474 langCxx11OrLater()));
2477 TEST(Matcher, IgnoresElidableInReturn) {
2478 auto matcher = expr(ignoringElidableConstructorCall(declRefExpr()));
2479 EXPECT_TRUE(matches("struct H {};"
2480 "H f() {"
2481 " H g;"
2482 " return g;"
2483 "}",
2484 matcher, langCxx11OrLater()));
2485 EXPECT_TRUE(notMatches("struct H {};"
2486 "H f() {"
2487 " return H();"
2488 "}",
2489 matcher, langCxx11OrLater()));
2492 TEST(Matcher, IgnoreElidableConstructorDoesNotMatchConstructors) {
2493 EXPECT_TRUE(matches("struct H {};"
2494 "void f() {"
2495 " H D;"
2496 "}",
2497 varDecl(hasInitializer(
2498 ignoringElidableConstructorCall(cxxConstructExpr()))),
2499 langCxx11OrLater()));
2502 TEST(Matcher, IgnoresElidableDoesNotPreventMatches) {
2503 EXPECT_TRUE(matches("void f() {"
2504 " int D = 10;"
2505 "}",
2506 expr(ignoringElidableConstructorCall(integerLiteral())),
2507 langCxx11OrLater()));
2510 TEST(Matcher, IgnoresElidableInVarInit) {
2511 auto matcher =
2512 varDecl(hasInitializer(ignoringElidableConstructorCall(callExpr())));
2513 EXPECT_TRUE(matches("struct H {};"
2514 "H G();"
2515 "void f(H D = G()) {"
2516 " return;"
2517 "}",
2518 matcher, langCxx11OrLater()));
2519 EXPECT_TRUE(matches("struct H {};"
2520 "H G();"
2521 "void f() {"
2522 " H D = G();"
2523 "}",
2524 matcher, langCxx11OrLater()));
2527 TEST(IgnoringImplicit, MatchesImplicit) {
2528 EXPECT_TRUE(matches("class C {}; C a = C();",
2529 varDecl(has(ignoringImplicit(cxxConstructExpr())))));
2532 TEST(IgnoringImplicit, MatchesNestedImplicit) {
2533 StringRef Code = R"(
2535 struct OtherType;
2537 struct SomeType
2539 SomeType() {}
2540 SomeType(const OtherType&) {}
2541 SomeType& operator=(OtherType const&) { return *this; }
2544 struct OtherType
2546 OtherType() {}
2547 ~OtherType() {}
2550 OtherType something()
2552 return {};
2555 int main()
2557 SomeType i = something();
2560 EXPECT_TRUE(matches(
2561 Code,
2562 traverse(TK_AsIs,
2563 varDecl(hasName("i"),
2564 hasInitializer(exprWithCleanups(has(cxxConstructExpr(
2565 has(expr(ignoringImplicit(cxxConstructExpr(has(
2566 expr(ignoringImplicit(callExpr())))))))))))))));
2569 TEST(IgnoringImplicit, DoesNotMatchIncorrectly) {
2570 EXPECT_TRUE(notMatches("class C {}; C a = C();",
2571 traverse(TK_AsIs, varDecl(has(cxxConstructExpr())))));
2574 TEST(Traversal, traverseMatcher) {
2576 StringRef VarDeclCode = R"cpp(
2577 void foo()
2579 int i = 3.0;
2581 )cpp";
2583 auto Matcher = varDecl(hasInitializer(floatLiteral()));
2585 EXPECT_TRUE(notMatches(VarDeclCode, traverse(TK_AsIs, Matcher)));
2586 EXPECT_TRUE(
2587 matches(VarDeclCode, traverse(TK_IgnoreUnlessSpelledInSource, Matcher)));
2589 auto ParentMatcher = floatLiteral(hasParent(varDecl(hasName("i"))));
2591 EXPECT_TRUE(notMatches(VarDeclCode, traverse(TK_AsIs, ParentMatcher)));
2592 EXPECT_TRUE(matches(VarDeclCode,
2593 traverse(TK_IgnoreUnlessSpelledInSource, ParentMatcher)));
2595 EXPECT_TRUE(matches(
2596 VarDeclCode, decl(traverse(TK_AsIs, anyOf(cxxRecordDecl(), varDecl())))));
2598 EXPECT_TRUE(
2599 matches(VarDeclCode,
2600 floatLiteral(traverse(TK_AsIs, hasParent(implicitCastExpr())))));
2602 EXPECT_TRUE(
2603 matches(VarDeclCode, floatLiteral(traverse(TK_IgnoreUnlessSpelledInSource,
2604 hasParent(varDecl())))));
2606 EXPECT_TRUE(
2607 matches(VarDeclCode, varDecl(traverse(TK_IgnoreUnlessSpelledInSource,
2608 unless(parmVarDecl())))));
2610 EXPECT_TRUE(
2611 notMatches(VarDeclCode, varDecl(traverse(TK_IgnoreUnlessSpelledInSource,
2612 has(implicitCastExpr())))));
2614 EXPECT_TRUE(matches(VarDeclCode,
2615 varDecl(traverse(TK_AsIs, has(implicitCastExpr())))));
2617 EXPECT_TRUE(matches(
2618 VarDeclCode, traverse(TK_IgnoreUnlessSpelledInSource,
2619 // The has() below strips away the ImplicitCastExpr
2620 // before the traverse(AsIs) gets to process it.
2621 varDecl(has(traverse(TK_AsIs, floatLiteral()))))));
2623 EXPECT_TRUE(
2624 matches(VarDeclCode, functionDecl(traverse(TK_AsIs, hasName("foo")))));
2626 EXPECT_TRUE(matches(
2627 VarDeclCode,
2628 functionDecl(traverse(TK_IgnoreUnlessSpelledInSource, hasName("foo")))));
2630 EXPECT_TRUE(matches(
2631 VarDeclCode, functionDecl(traverse(TK_AsIs, hasAnyName("foo", "bar")))));
2633 EXPECT_TRUE(
2634 matches(VarDeclCode, functionDecl(traverse(TK_IgnoreUnlessSpelledInSource,
2635 hasAnyName("foo", "bar")))));
2637 StringRef Code = R"cpp(
2638 void foo(int a)
2640 int i = 3.0 + a;
2642 void bar()
2644 foo(7.0);
2646 )cpp";
2647 EXPECT_TRUE(
2648 matches(Code, callExpr(traverse(TK_IgnoreUnlessSpelledInSource,
2649 hasArgument(0, floatLiteral())))));
2651 EXPECT_TRUE(
2652 matches(Code, callExpr(traverse(TK_IgnoreUnlessSpelledInSource,
2653 hasAnyArgument(floatLiteral())))));
2655 EXPECT_TRUE(matches(
2656 R"cpp(
2657 void takesBool(bool){}
2659 template <typename T>
2660 void neverInstantiatedTemplate() {
2661 takesBool(T{});
2663 )cpp",
2664 traverse(TK_IgnoreUnlessSpelledInSource,
2665 callExpr(unless(callExpr(hasDeclaration(functionDecl())))))));
2667 EXPECT_TRUE(
2668 matches(VarDeclCode, varDecl(traverse(TK_IgnoreUnlessSpelledInSource,
2669 hasType(builtinType())))));
2671 EXPECT_TRUE(
2672 matches(VarDeclCode,
2673 functionDecl(hasName("foo"),
2674 traverse(TK_AsIs, hasDescendant(floatLiteral())))));
2676 EXPECT_TRUE(notMatches(
2677 Code, traverse(TK_AsIs, floatLiteral(hasParent(callExpr(
2678 callee(functionDecl(hasName("foo")))))))));
2679 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
2680 floatLiteral(hasParent(callExpr(callee(
2681 functionDecl(hasName("foo")))))))));
2683 Code = R"cpp(
2684 void foo()
2686 int i = (3);
2688 )cpp";
2689 EXPECT_TRUE(matches(
2690 Code, traverse(TK_IgnoreUnlessSpelledInSource,
2691 varDecl(hasInitializer(integerLiteral(equals(3)))))));
2692 EXPECT_TRUE(matches(
2693 Code,
2694 traverse(TK_IgnoreUnlessSpelledInSource,
2695 integerLiteral(equals(3), hasParent(varDecl(hasName("i")))))));
2697 Code = R"cpp(
2698 const char *SomeString{"str"};
2699 )cpp";
2700 EXPECT_TRUE(
2701 matches(Code, traverse(TK_AsIs, stringLiteral(hasParent(implicitCastExpr(
2702 hasParent(initListExpr())))))));
2703 EXPECT_TRUE(
2704 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
2705 stringLiteral(hasParent(initListExpr())))));
2707 Code = R"cpp(
2708 struct String
2710 String(const char*, int = -1) {}
2713 void stringConstruct()
2715 String s = "foo";
2716 s = "bar";
2718 )cpp";
2719 EXPECT_TRUE(matches(
2720 Code,
2721 traverse(
2722 TK_AsIs,
2723 functionDecl(
2724 hasName("stringConstruct"),
2725 hasDescendant(varDecl(
2726 hasName("s"),
2727 hasInitializer(ignoringImplicit(cxxConstructExpr(hasArgument(
2728 0, ignoringImplicit(cxxConstructExpr(hasArgument(
2729 0, ignoringImplicit(stringLiteral()))))))))))))));
2731 EXPECT_TRUE(matches(
2732 Code,
2733 traverse(
2734 TK_AsIs,
2735 functionDecl(hasName("stringConstruct"),
2736 hasDescendant(cxxOperatorCallExpr(
2737 isAssignmentOperator(),
2738 hasArgument(1, ignoringImplicit(
2739 cxxConstructExpr(hasArgument(
2740 0, ignoringImplicit(stringLiteral())))))
2741 ))))));
2743 EXPECT_TRUE(matches(
2744 Code, traverse(TK_IgnoreUnlessSpelledInSource,
2745 functionDecl(hasName("stringConstruct"),
2746 hasDescendant(varDecl(
2747 hasName("s"),
2748 hasInitializer(stringLiteral())))))));
2750 EXPECT_TRUE(
2751 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
2752 functionDecl(hasName("stringConstruct"),
2753 hasDescendant(cxxOperatorCallExpr(
2754 isAssignmentOperator(),
2755 hasArgument(1, stringLiteral())))))));
2757 Code = R"cpp(
2759 struct C1 {};
2760 struct C2 { operator C1(); };
2762 void conversionOperator()
2764 C2* c2;
2765 C1 c1 = (*c2);
2768 )cpp";
2769 EXPECT_TRUE(matches(
2770 Code,
2771 traverse(
2772 TK_AsIs,
2773 functionDecl(
2774 hasName("conversionOperator"),
2775 hasDescendant(
2776 varDecl(
2777 hasName("c1"),
2778 hasInitializer(
2779 ignoringImplicit(cxxConstructExpr(hasArgument(
2780 0, ignoringImplicit(
2781 cxxMemberCallExpr(onImplicitObjectArgument(
2782 ignoringParenImpCasts(unaryOperator(
2783 hasOperatorName("*")))))))))))
2784 .bind("c1"))))));
2786 EXPECT_TRUE(matches(
2787 Code,
2788 traverse(TK_IgnoreUnlessSpelledInSource,
2789 functionDecl(hasName("conversionOperator"),
2790 hasDescendant(varDecl(
2791 hasName("c1"), hasInitializer(unaryOperator(
2792 hasOperatorName("*")))))))));
2794 Code = R"cpp(
2796 template <unsigned alignment>
2797 void template_test() {
2798 static_assert(alignment, "");
2800 void actual_template_test() {
2801 template_test<4>();
2804 )cpp";
2805 EXPECT_TRUE(matches(
2806 Code,
2807 traverse(TK_AsIs,
2808 staticAssertDecl(has(implicitCastExpr(has(
2809 substNonTypeTemplateParmExpr(has(integerLiteral())))))))));
2810 EXPECT_TRUE(matches(
2811 Code, traverse(TK_IgnoreUnlessSpelledInSource,
2812 staticAssertDecl(has(declRefExpr(
2813 to(nonTypeTemplateParmDecl(hasName("alignment"))),
2814 hasType(asString("unsigned int"))))))));
2816 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, staticAssertDecl(hasDescendant(
2817 integerLiteral())))));
2818 EXPECT_FALSE(matches(
2819 Code, traverse(TK_IgnoreUnlessSpelledInSource,
2820 staticAssertDecl(hasDescendant(integerLiteral())))));
2822 Code = R"cpp(
2824 struct OneParamCtor {
2825 explicit OneParamCtor(int);
2827 struct TwoParamCtor {
2828 explicit TwoParamCtor(int, int);
2831 void varDeclCtors() {
2833 auto var1 = OneParamCtor(5);
2834 auto var2 = TwoParamCtor(6, 7);
2837 OneParamCtor var3(5);
2838 TwoParamCtor var4(6, 7);
2840 int i = 0;
2842 auto var5 = OneParamCtor(i);
2843 auto var6 = TwoParamCtor(i, 7);
2846 OneParamCtor var7(i);
2847 TwoParamCtor var8(i, 7);
2851 )cpp";
2852 EXPECT_TRUE(matches(
2853 Code,
2854 traverse(TK_AsIs, varDecl(hasName("var1"), hasInitializer(hasDescendant(
2855 cxxConstructExpr()))))));
2856 EXPECT_TRUE(matches(
2857 Code,
2858 traverse(TK_AsIs, varDecl(hasName("var2"), hasInitializer(hasDescendant(
2859 cxxConstructExpr()))))));
2860 EXPECT_TRUE(matches(
2861 Code, traverse(TK_AsIs, varDecl(hasName("var3"),
2862 hasInitializer(cxxConstructExpr())))));
2863 EXPECT_TRUE(matches(
2864 Code, traverse(TK_AsIs, varDecl(hasName("var4"),
2865 hasInitializer(cxxConstructExpr())))));
2866 EXPECT_TRUE(matches(
2867 Code,
2868 traverse(TK_AsIs, varDecl(hasName("var5"), hasInitializer(hasDescendant(
2869 cxxConstructExpr()))))));
2870 EXPECT_TRUE(matches(
2871 Code,
2872 traverse(TK_AsIs, varDecl(hasName("var6"), hasInitializer(hasDescendant(
2873 cxxConstructExpr()))))));
2874 EXPECT_TRUE(matches(
2875 Code, traverse(TK_AsIs, varDecl(hasName("var7"),
2876 hasInitializer(cxxConstructExpr())))));
2877 EXPECT_TRUE(matches(
2878 Code, traverse(TK_AsIs, varDecl(hasName("var8"),
2879 hasInitializer(cxxConstructExpr())))));
2881 EXPECT_TRUE(matches(
2882 Code,
2883 traverse(TK_IgnoreUnlessSpelledInSource,
2884 varDecl(hasName("var1"), hasInitializer(cxxConstructExpr())))));
2885 EXPECT_TRUE(matches(
2886 Code,
2887 traverse(TK_IgnoreUnlessSpelledInSource,
2888 varDecl(hasName("var2"), hasInitializer(cxxConstructExpr())))));
2889 EXPECT_TRUE(matches(
2890 Code,
2891 traverse(TK_IgnoreUnlessSpelledInSource,
2892 varDecl(hasName("var3"), hasInitializer(cxxConstructExpr())))));
2893 EXPECT_TRUE(matches(
2894 Code,
2895 traverse(TK_IgnoreUnlessSpelledInSource,
2896 varDecl(hasName("var4"), hasInitializer(cxxConstructExpr())))));
2897 EXPECT_TRUE(matches(
2898 Code,
2899 traverse(TK_IgnoreUnlessSpelledInSource,
2900 varDecl(hasName("var5"), hasInitializer(cxxConstructExpr())))));
2901 EXPECT_TRUE(matches(
2902 Code,
2903 traverse(TK_IgnoreUnlessSpelledInSource,
2904 varDecl(hasName("var6"), hasInitializer(cxxConstructExpr())))));
2905 EXPECT_TRUE(matches(
2906 Code,
2907 traverse(TK_IgnoreUnlessSpelledInSource,
2908 varDecl(hasName("var7"), hasInitializer(cxxConstructExpr())))));
2909 EXPECT_TRUE(matches(
2910 Code,
2911 traverse(TK_IgnoreUnlessSpelledInSource,
2912 varDecl(hasName("var8"), hasInitializer(cxxConstructExpr())))));
2914 Code = R"cpp(
2916 template<typename T>
2917 struct TemplStruct {
2918 TemplStruct() {}
2919 ~TemplStruct() {}
2921 void outOfLine(T);
2923 private:
2924 T m_t;
2927 template<typename T>
2928 void TemplStruct<T>::outOfLine(T)
2933 template<typename T>
2934 T timesTwo(T input)
2936 return input * 2;
2939 void instantiate()
2941 TemplStruct<int> ti;
2942 TemplStruct<double> td;
2943 (void)timesTwo<int>(2);
2944 (void)timesTwo<double>(2);
2947 template class TemplStruct<float>;
2949 extern template class TemplStruct<long>;
2951 template<> class TemplStruct<bool> {
2952 TemplStruct() {}
2953 ~TemplStruct() {}
2955 void boolSpecializationMethodOnly() {}
2956 private:
2957 bool m_t;
2960 template float timesTwo(float);
2961 template<> bool timesTwo<bool>(bool){
2962 return true;
2964 )cpp";
2966 auto M = cxxRecordDecl(hasName("TemplStruct"),
2967 has(fieldDecl(hasType(asString("int")))));
2968 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2969 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2972 auto M = cxxRecordDecl(hasName("TemplStruct"),
2973 has(fieldDecl(hasType(asString("double")))));
2974 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2975 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2978 auto M =
2979 functionDecl(hasName("timesTwo"),
2980 hasParameter(0, parmVarDecl(hasType(asString("int")))));
2981 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2982 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2985 auto M =
2986 functionDecl(hasName("timesTwo"),
2987 hasParameter(0, parmVarDecl(hasType(asString("double")))));
2988 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
2989 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
2992 // Match on the integer literal in the explicit instantiation:
2993 auto MDef =
2994 functionDecl(hasName("timesTwo"),
2995 hasParameter(0, parmVarDecl(hasType(asString("float")))),
2996 hasDescendant(integerLiteral(equals(2))));
2997 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MDef)));
2998 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MDef)));
3000 auto MTempl =
3001 functionDecl(hasName("timesTwo"),
3002 hasTemplateArgument(0, refersToType(asString("float"))));
3003 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MTempl)));
3004 // TODO: If we could match on explicit instantiations of function templates,
3005 // this would be EXPECT_TRUE. See Sema::ActOnExplicitInstantiation.
3006 EXPECT_FALSE(
3007 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MTempl)));
3010 auto M = functionDecl(hasName("timesTwo"),
3011 hasParameter(0, parmVarDecl(hasType(booleanType()))));
3012 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3013 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3016 // Match on the field within the explicit instantiation:
3017 auto MRecord = cxxRecordDecl(hasName("TemplStruct"),
3018 has(fieldDecl(hasType(asString("float")))));
3019 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MRecord)));
3020 EXPECT_FALSE(
3021 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MRecord)));
3023 // Match on the explicit template instantiation itself:
3024 auto MTempl = classTemplateSpecializationDecl(
3025 hasName("TemplStruct"),
3026 hasTemplateArgument(0,
3027 templateArgument(refersToType(asString("float")))));
3028 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MTempl)));
3029 EXPECT_TRUE(
3030 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MTempl)));
3033 // The template argument is matchable, but the instantiation is not:
3034 auto M = classTemplateSpecializationDecl(
3035 hasName("TemplStruct"),
3036 hasTemplateArgument(0,
3037 templateArgument(refersToType(asString("float")))),
3038 has(cxxConstructorDecl(hasName("TemplStruct"))));
3039 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3040 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3043 // The template argument is matchable, but the instantiation is not:
3044 auto M = classTemplateSpecializationDecl(
3045 hasName("TemplStruct"),
3046 hasTemplateArgument(0,
3047 templateArgument(refersToType(asString("long")))),
3048 has(cxxConstructorDecl(hasName("TemplStruct"))));
3049 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3050 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3053 // Instantiated, out-of-line methods are not matchable.
3054 auto M =
3055 cxxMethodDecl(hasName("outOfLine"), isDefinition(),
3056 hasParameter(0, parmVarDecl(hasType(asString("float")))));
3057 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3058 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3061 // Explicit specialization is written in source and it matches:
3062 auto M = classTemplateSpecializationDecl(
3063 hasName("TemplStruct"),
3064 hasTemplateArgument(0, templateArgument(refersToType(booleanType()))),
3065 has(cxxConstructorDecl(hasName("TemplStruct"))),
3066 has(cxxMethodDecl(hasName("boolSpecializationMethodOnly"))));
3067 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3068 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3071 Code = R"cpp(
3072 struct B {
3073 B(int);
3076 B func1() { return 42; }
3077 )cpp";
3079 auto M = expr(ignoringImplicit(integerLiteral(equals(42)).bind("intLit")));
3080 EXPECT_TRUE(matchAndVerifyResultTrue(
3081 Code, traverse(TK_AsIs, M),
3082 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
3083 EXPECT_TRUE(matchAndVerifyResultTrue(
3084 Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3085 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
3088 auto M = expr(unless(integerLiteral(equals(24)))).bind("intLit");
3089 EXPECT_TRUE(matchAndVerifyResultTrue(
3090 Code, traverse(TK_AsIs, M),
3091 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 6),
3092 {"-std=c++11"}));
3094 EXPECT_TRUE(matchAndVerifyResultTrue(
3095 Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3096 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1),
3097 {"-std=c++11"}));
3100 auto M =
3101 expr(anyOf(integerLiteral(equals(42)).bind("intLit"), unless(expr())));
3102 EXPECT_TRUE(matchAndVerifyResultTrue(
3103 Code, traverse(TK_AsIs, M),
3104 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
3105 EXPECT_TRUE(matchAndVerifyResultTrue(
3106 Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3107 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
3110 auto M = expr(allOf(integerLiteral(equals(42)).bind("intLit"), expr()));
3111 EXPECT_TRUE(matchAndVerifyResultTrue(
3112 Code, traverse(TK_AsIs, M),
3113 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
3114 EXPECT_TRUE(matchAndVerifyResultTrue(
3115 Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3116 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
3119 auto M = expr(integerLiteral(equals(42)).bind("intLit"), expr());
3120 EXPECT_TRUE(matchAndVerifyResultTrue(
3121 Code, traverse(TK_AsIs, M),
3122 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
3123 EXPECT_TRUE(matchAndVerifyResultTrue(
3124 Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3125 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
3128 auto M = expr(optionally(integerLiteral(equals(42)).bind("intLit")));
3129 EXPECT_TRUE(matchAndVerifyResultTrue(
3130 Code, traverse(TK_AsIs, M),
3131 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
3132 EXPECT_TRUE(matchAndVerifyResultTrue(
3133 Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3134 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1)));
3137 auto M = expr().bind("allExprs");
3138 EXPECT_TRUE(matchAndVerifyResultTrue(
3139 Code, traverse(TK_AsIs, M),
3140 std::make_unique<VerifyIdIsBoundTo<Expr>>("allExprs", 6),
3141 {"-std=c++11"}));
3142 EXPECT_TRUE(matchAndVerifyResultTrue(
3143 Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3144 std::make_unique<VerifyIdIsBoundTo<Expr>>("allExprs", 1)));
3147 Code = R"cpp(
3148 void foo()
3150 int arr[3];
3151 auto &[f, s, t] = arr;
3153 f = 42;
3155 )cpp";
3157 auto M = bindingDecl(hasName("f"));
3158 EXPECT_TRUE(
3159 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++17"}));
3160 EXPECT_TRUE(
3161 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3162 true, {"-std=c++17"}));
3165 auto M = bindingDecl(hasName("f"), has(expr()));
3166 EXPECT_TRUE(
3167 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++17"}));
3168 EXPECT_FALSE(
3169 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3170 true, {"-std=c++17"}));
3173 auto M = integerLiteral(hasAncestor(bindingDecl(hasName("f"))));
3174 EXPECT_TRUE(
3175 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++17"}));
3176 EXPECT_FALSE(
3177 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3178 true, {"-std=c++17"}));
3181 auto M = declRefExpr(hasAncestor(bindingDecl(hasName("f"))));
3182 EXPECT_TRUE(
3183 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++17"}));
3184 EXPECT_FALSE(
3185 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3186 true, {"-std=c++17"}));
3190 TEST(Traversal, traverseNoImplicit) {
3191 StringRef Code = R"cpp(
3192 struct NonTrivial {
3193 NonTrivial() {}
3194 NonTrivial(const NonTrivial&) {}
3195 NonTrivial& operator=(const NonTrivial&) { return *this; }
3197 ~NonTrivial() {}
3200 struct NoSpecialMethods {
3201 NonTrivial nt;
3204 struct ContainsArray {
3205 NonTrivial arr[2];
3206 ContainsArray& operator=(const ContainsArray &other) = default;
3209 void copyIt()
3211 NoSpecialMethods nc1;
3212 NoSpecialMethods nc2(nc1);
3213 nc2 = nc1;
3215 ContainsArray ca;
3216 ContainsArray ca2;
3217 ca2 = ca;
3220 struct HasCtorInits : NoSpecialMethods, NonTrivial
3222 int m_i;
3223 NonTrivial m_nt;
3224 HasCtorInits() : NoSpecialMethods(), m_i(42) {}
3227 struct CtorInitsNonTrivial : NonTrivial
3229 int m_i;
3230 NonTrivial m_nt;
3231 CtorInitsNonTrivial() : NonTrivial(), m_i(42) {}
3234 )cpp";
3236 auto M = cxxRecordDecl(hasName("NoSpecialMethods"),
3237 has(cxxRecordDecl(hasName("NoSpecialMethods"))));
3238 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3239 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3241 M = cxxRecordDecl(hasName("NoSpecialMethods"),
3242 has(cxxConstructorDecl(isCopyConstructor())));
3243 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3244 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3246 M = cxxRecordDecl(hasName("NoSpecialMethods"),
3247 has(cxxMethodDecl(isCopyAssignmentOperator())));
3248 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3249 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3251 M = cxxRecordDecl(hasName("NoSpecialMethods"),
3252 has(cxxConstructorDecl(isDefaultConstructor())));
3253 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3254 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3256 M = cxxRecordDecl(hasName("NoSpecialMethods"), has(cxxDestructorDecl()));
3257 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3258 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3260 M = cxxRecordDecl(hasName("NoSpecialMethods"),
3261 hasMethod(cxxConstructorDecl(isCopyConstructor())));
3262 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3263 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3265 M = cxxRecordDecl(hasName("NoSpecialMethods"),
3266 hasMethod(cxxMethodDecl(isCopyAssignmentOperator())));
3267 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3268 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3270 M = cxxRecordDecl(hasName("NoSpecialMethods"),
3271 hasMethod(cxxConstructorDecl(isDefaultConstructor())));
3272 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3273 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3275 M = cxxRecordDecl(hasName("NoSpecialMethods"),
3276 hasMethod(cxxDestructorDecl()));
3277 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3278 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3281 // Because the copy-assignment operator is not spelled in the
3282 // source (ie, isImplicit()), we don't match it
3283 auto M =
3284 cxxOperatorCallExpr(hasType(cxxRecordDecl(hasName("NoSpecialMethods"))),
3285 callee(cxxMethodDecl(isCopyAssignmentOperator())));
3286 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3287 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3290 // Compiler generates a forStmt to copy the array
3291 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, forStmt())));
3292 EXPECT_FALSE(
3293 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, forStmt())));
3296 // The defaulted method declaration can be matched, but not its
3297 // definition, in IgnoreUnlessSpelledInSource mode
3298 auto MDecl = cxxMethodDecl(ofClass(cxxRecordDecl(hasName("ContainsArray"))),
3299 isCopyAssignmentOperator(), isDefaulted());
3301 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MDecl)));
3302 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MDecl)));
3304 auto MDef = cxxMethodDecl(MDecl, has(compoundStmt()));
3306 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MDef)));
3307 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MDef)));
3309 auto MBody = cxxMethodDecl(MDecl, hasBody(compoundStmt()));
3311 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MBody)));
3312 EXPECT_FALSE(
3313 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MBody)));
3315 auto MIsDefn = cxxMethodDecl(MDecl, isDefinition());
3317 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MIsDefn)));
3318 EXPECT_TRUE(
3319 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MIsDefn)));
3321 auto MIsInline = cxxMethodDecl(MDecl, isInline());
3323 EXPECT_FALSE(matches(Code, traverse(TK_AsIs, MIsInline)));
3324 EXPECT_FALSE(
3325 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MIsInline)));
3327 // The parameter of the defaulted method can still be matched.
3328 auto MParm =
3329 cxxMethodDecl(MDecl, hasParameter(0, parmVarDecl(hasName("other"))));
3331 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MParm)));
3332 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MParm)));
3335 auto M =
3336 cxxConstructorDecl(hasName("HasCtorInits"),
3337 has(cxxCtorInitializer(forField(hasName("m_i")))));
3338 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3339 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3342 auto M =
3343 cxxConstructorDecl(hasName("HasCtorInits"),
3344 has(cxxCtorInitializer(forField(hasName("m_nt")))));
3345 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3346 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3349 auto M = cxxConstructorDecl(hasName("HasCtorInits"),
3350 hasAnyConstructorInitializer(cxxCtorInitializer(
3351 forField(hasName("m_nt")))));
3352 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3353 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3356 auto M =
3357 cxxConstructorDecl(hasName("HasCtorInits"),
3358 forEachConstructorInitializer(
3359 cxxCtorInitializer(forField(hasName("m_nt")))));
3360 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3361 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3364 auto M = cxxConstructorDecl(
3365 hasName("CtorInitsNonTrivial"),
3366 has(cxxCtorInitializer(withInitializer(cxxConstructExpr(
3367 hasDeclaration(cxxConstructorDecl(hasName("NonTrivial"))))))));
3368 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3369 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3372 auto M = cxxConstructorDecl(
3373 hasName("HasCtorInits"),
3374 has(cxxCtorInitializer(withInitializer(cxxConstructExpr(hasDeclaration(
3375 cxxConstructorDecl(hasName("NoSpecialMethods"))))))));
3376 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3377 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3380 auto M = cxxCtorInitializer(forField(hasName("m_nt")));
3381 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3382 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3385 Code = R"cpp(
3386 void rangeFor()
3388 int arr[2];
3389 for (auto i : arr)
3391 if (true)
3396 )cpp";
3398 auto M = cxxForRangeStmt(has(binaryOperator(hasOperatorName("!="))));
3399 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3400 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3403 auto M =
3404 cxxForRangeStmt(hasDescendant(binaryOperator(hasOperatorName("+"))));
3405 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3406 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3409 auto M =
3410 cxxForRangeStmt(hasDescendant(unaryOperator(hasOperatorName("++"))));
3411 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3412 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3415 auto M = cxxForRangeStmt(has(declStmt()));
3416 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3417 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3420 auto M =
3421 cxxForRangeStmt(hasLoopVariable(varDecl(hasName("i"))),
3422 hasRangeInit(declRefExpr(to(varDecl(hasName("arr"))))));
3423 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3424 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3427 auto M = cxxForRangeStmt(unless(hasInitStatement(stmt())));
3428 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3429 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3432 auto M = cxxForRangeStmt(hasBody(stmt()));
3433 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3434 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3437 auto M = cxxForRangeStmt(hasDescendant(ifStmt()));
3438 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3439 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3442 EXPECT_TRUE(matches(
3443 Code, traverse(TK_AsIs, cxxForRangeStmt(has(declStmt(
3444 hasSingleDecl(varDecl(hasName("i")))))))));
3445 EXPECT_TRUE(
3446 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
3447 cxxForRangeStmt(has(varDecl(hasName("i")))))));
3450 EXPECT_TRUE(matches(
3451 Code, traverse(TK_AsIs, cxxForRangeStmt(has(declStmt(hasSingleDecl(
3452 varDecl(hasInitializer(declRefExpr(
3453 to(varDecl(hasName("arr")))))))))))));
3454 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
3455 cxxForRangeStmt(has(declRefExpr(
3456 to(varDecl(hasName("arr")))))))));
3459 auto M = cxxForRangeStmt(has(compoundStmt()));
3460 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3461 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3464 auto M = binaryOperator(hasOperatorName("!="));
3465 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3466 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3469 auto M = unaryOperator(hasOperatorName("++"));
3470 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3471 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3474 auto M = declStmt(hasSingleDecl(varDecl(matchesName("__range"))));
3475 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3476 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3479 auto M = declStmt(hasSingleDecl(varDecl(matchesName("__begin"))));
3480 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3481 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3484 auto M = declStmt(hasSingleDecl(varDecl(matchesName("__end"))));
3485 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3486 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3489 auto M = ifStmt(hasParent(compoundStmt(hasParent(cxxForRangeStmt()))));
3490 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3491 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3494 auto M = cxxForRangeStmt(
3495 has(varDecl(hasName("i"), hasParent(cxxForRangeStmt()))));
3496 EXPECT_FALSE(matches(Code, traverse(TK_AsIs, M)));
3497 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3500 auto M = cxxForRangeStmt(hasDescendant(varDecl(
3501 hasName("i"), hasParent(declStmt(hasParent(cxxForRangeStmt()))))));
3502 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3503 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3506 auto M = cxxForRangeStmt(hasRangeInit(declRefExpr(
3507 to(varDecl(hasName("arr"))), hasParent(cxxForRangeStmt()))));
3508 EXPECT_FALSE(matches(Code, traverse(TK_AsIs, M)));
3509 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3513 auto M = cxxForRangeStmt(hasRangeInit(declRefExpr(
3514 to(varDecl(hasName("arr"))), hasParent(varDecl(hasParent(declStmt(
3515 hasParent(cxxForRangeStmt()))))))));
3516 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3517 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3520 Code = R"cpp(
3521 struct Range {
3522 int* begin() const;
3523 int* end() const;
3525 Range getRange(int);
3527 void rangeFor()
3529 for (auto i : getRange(42))
3533 )cpp";
3535 auto M = integerLiteral(equals(42));
3536 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3537 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3540 auto M = callExpr(hasDescendant(integerLiteral(equals(42))));
3541 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3542 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3545 auto M = compoundStmt(hasDescendant(integerLiteral(equals(42))));
3546 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3547 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3550 Code = R"cpp(
3551 void rangeFor()
3553 int arr[2];
3554 for (auto& a = arr; auto i : a)
3559 )cpp";
3561 auto M = cxxForRangeStmt(has(binaryOperator(hasOperatorName("!="))));
3562 EXPECT_TRUE(
3563 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3564 EXPECT_FALSE(
3565 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3566 true, {"-std=c++20"}));
3569 auto M =
3570 cxxForRangeStmt(hasDescendant(binaryOperator(hasOperatorName("+"))));
3571 EXPECT_TRUE(
3572 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3573 EXPECT_FALSE(
3574 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3575 true, {"-std=c++20"}));
3578 auto M =
3579 cxxForRangeStmt(hasDescendant(unaryOperator(hasOperatorName("++"))));
3580 EXPECT_TRUE(
3581 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3582 EXPECT_FALSE(
3583 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3584 true, {"-std=c++20"}));
3587 auto M =
3588 cxxForRangeStmt(has(declStmt(hasSingleDecl(varDecl(hasName("i"))))));
3589 EXPECT_TRUE(
3590 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3591 EXPECT_FALSE(
3592 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3593 true, {"-std=c++20"}));
3596 auto M = cxxForRangeStmt(
3597 hasInitStatement(declStmt(hasSingleDecl(varDecl(
3598 hasName("a"),
3599 hasInitializer(declRefExpr(to(varDecl(hasName("arr"))))))))),
3600 hasLoopVariable(varDecl(hasName("i"))),
3601 hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))));
3602 EXPECT_TRUE(
3603 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3604 EXPECT_TRUE(
3605 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3606 true, {"-std=c++20"}));
3609 auto M = cxxForRangeStmt(
3610 has(declStmt(hasSingleDecl(varDecl(
3611 hasName("a"),
3612 hasInitializer(declRefExpr(to(varDecl(hasName("arr"))))))))),
3613 hasLoopVariable(varDecl(hasName("i"))),
3614 hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))));
3615 EXPECT_TRUE(
3616 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3617 EXPECT_TRUE(
3618 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3619 true, {"-std=c++20"}));
3622 auto M = cxxForRangeStmt(hasInitStatement(declStmt(
3623 hasSingleDecl(varDecl(hasName("a"))), hasParent(cxxForRangeStmt()))));
3624 EXPECT_TRUE(
3625 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3626 EXPECT_TRUE(
3627 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3628 true, {"-std=c++20"}));
3631 Code = R"cpp(
3632 struct Range {
3633 int* begin() const;
3634 int* end() const;
3636 Range getRange(int);
3638 int getNum(int);
3640 void rangeFor()
3642 for (auto j = getNum(42); auto i : getRange(j))
3646 )cpp";
3648 auto M = integerLiteral(equals(42));
3649 EXPECT_TRUE(
3650 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3651 EXPECT_TRUE(
3652 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3653 true, {"-std=c++20"}));
3656 auto M = compoundStmt(hasDescendant(integerLiteral(equals(42))));
3657 EXPECT_TRUE(
3658 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
3659 EXPECT_TRUE(
3660 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
3661 true, {"-std=c++20"}));
3664 Code = R"cpp(
3665 void hasDefaultArg(int i, int j = 0)
3668 void callDefaultArg()
3670 hasDefaultArg(42);
3672 )cpp";
3673 auto hasDefaultArgCall = [](auto InnerMatcher) {
3674 return callExpr(callee(functionDecl(hasName("hasDefaultArg"))),
3675 InnerMatcher);
3678 auto M = hasDefaultArgCall(has(integerLiteral(equals(42))));
3679 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3680 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3683 auto M = hasDefaultArgCall(has(cxxDefaultArgExpr()));
3684 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3685 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3688 auto M = hasDefaultArgCall(argumentCountIs(2));
3689 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3690 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3693 auto M = hasDefaultArgCall(argumentCountIs(1));
3694 EXPECT_FALSE(matches(Code, traverse(TK_AsIs, M)));
3695 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3698 auto M = hasDefaultArgCall(hasArgument(1, cxxDefaultArgExpr()));
3699 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3700 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3703 auto M = hasDefaultArgCall(hasAnyArgument(cxxDefaultArgExpr()));
3704 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3705 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3707 Code = R"cpp(
3708 struct A
3710 ~A();
3711 private:
3712 int i;
3715 A::~A() = default;
3716 )cpp";
3718 auto M = cxxDestructorDecl(isDefaulted(),
3719 ofClass(cxxRecordDecl(has(fieldDecl()))));
3720 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
3721 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
3723 Code = R"cpp(
3724 struct S
3726 static constexpr bool getTrue() { return true; }
3729 struct A
3731 explicit(S::getTrue()) A();
3734 A::A() = default;
3735 )cpp";
3737 EXPECT_TRUE(matchesConditionally(
3738 Code,
3739 traverse(TK_AsIs,
3740 cxxConstructorDecl(
3741 isDefaulted(),
3742 hasExplicitSpecifier(expr(ignoringImplicit(
3743 callExpr(has(ignoringImplicit(declRefExpr())))))))),
3744 true, {"-std=c++20"}));
3745 EXPECT_TRUE(matchesConditionally(
3746 Code,
3747 traverse(TK_IgnoreUnlessSpelledInSource,
3748 cxxConstructorDecl(
3749 isDefaulted(),
3750 hasExplicitSpecifier(callExpr(has(declRefExpr()))))),
3751 true, {"-std=c++20"}));
3755 template <typename MatcherT>
3756 bool matcherTemplateWithBinding(StringRef Code, const MatcherT &M) {
3757 return matchAndVerifyResultTrue(
3758 Code, M.bind("matchedStmt"),
3759 std::make_unique<VerifyIdIsBoundTo<ReturnStmt>>("matchedStmt", 1));
3762 TEST(Traversal, traverseWithBinding) {
3763 // Some existing matcher code expects to take a matcher as a
3764 // template arg and bind to it. Verify that that works.
3766 llvm::StringRef Code = R"cpp(
3767 int foo()
3769 return 42.0;
3771 )cpp";
3772 EXPECT_TRUE(matcherTemplateWithBinding(
3773 Code, traverse(TK_AsIs,
3774 returnStmt(has(implicitCastExpr(has(floatLiteral())))))));
3777 TEST(Traversal, traverseMatcherNesting) {
3779 StringRef Code = R"cpp(
3780 float bar(int i)
3782 return i;
3785 void foo()
3787 bar(bar(3.0));
3789 )cpp";
3791 EXPECT_TRUE(
3792 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
3793 callExpr(has(callExpr(traverse(
3794 TK_AsIs, callExpr(has(implicitCastExpr(
3795 has(floatLiteral())))))))))));
3797 EXPECT_TRUE(matches(
3798 Code,
3799 traverse(TK_IgnoreUnlessSpelledInSource,
3800 traverse(TK_AsIs, implicitCastExpr(has(floatLiteral()))))));
3803 TEST(Traversal, traverseMatcherThroughImplicit) {
3804 StringRef Code = R"cpp(
3805 struct S {
3806 S(int x);
3809 void constructImplicit() {
3810 int a = 8;
3811 S s(a);
3813 )cpp";
3815 auto Matcher = traverse(TK_IgnoreUnlessSpelledInSource, implicitCastExpr());
3817 // Verfiy that it does not segfault
3818 EXPECT_FALSE(matches(Code, Matcher));
3821 TEST(Traversal, traverseMatcherThroughMemoization) {
3823 StringRef Code = R"cpp(
3824 void foo()
3826 int i = 3.0;
3828 )cpp";
3830 auto Matcher = varDecl(hasInitializer(floatLiteral()));
3832 // Matchers such as hasDescendant memoize their result regarding AST
3833 // nodes. In the matcher below, the first use of hasDescendant(Matcher)
3834 // fails, and the use of it inside the traverse() matcher should pass
3835 // causing the overall matcher to be a true match.
3836 // This test verifies that the first false result is not re-used, which
3837 // would cause the overall matcher to be incorrectly false.
3839 EXPECT_TRUE(matches(
3840 Code,
3841 functionDecl(anyOf(hasDescendant(Matcher),
3842 traverse(TK_IgnoreUnlessSpelledInSource,
3843 functionDecl(hasDescendant(Matcher)))))));
3846 TEST(Traversal, traverseUnlessSpelledInSource) {
3848 StringRef Code = R"cpp(
3850 struct A
3854 struct B
3856 B(int);
3857 B(A const& a);
3858 B();
3861 struct C
3863 operator B();
3866 B func1() {
3867 return 42;
3870 B func2() {
3871 return B{42};
3874 B func3() {
3875 return B(42);
3878 B func4() {
3879 return B();
3882 B func5() {
3883 return B{};
3886 B func6() {
3887 return C();
3890 B func7() {
3891 return A();
3894 B func8() {
3895 return C{};
3898 B func9() {
3899 return A{};
3902 B func10() {
3903 A a;
3904 return a;
3907 B func11() {
3908 B b;
3909 return b;
3912 B func12() {
3913 C c;
3914 return c;
3917 void func13() {
3918 int a = 0;
3919 int c = 0;
3921 [a, b = c](int d) { int e = d; };
3924 void func14() {
3925 [] <typename TemplateType> (TemplateType t, TemplateType u) { int e = t + u; };
3926 float i = 42.0;
3929 void func15() {
3930 int count = 0;
3931 auto l = [&] { ++count; };
3932 (void)l;
3935 )cpp";
3937 EXPECT_TRUE(
3938 matches(Code,
3939 traverse(TK_IgnoreUnlessSpelledInSource,
3940 returnStmt(forFunction(functionDecl(hasName("func1"))),
3941 hasReturnValue(integerLiteral(equals(42))))),
3942 langCxx20OrLater()));
3944 EXPECT_TRUE(
3945 matches(Code,
3946 traverse(TK_IgnoreUnlessSpelledInSource,
3947 integerLiteral(equals(42),
3948 hasParent(returnStmt(forFunction(
3949 functionDecl(hasName("func1"))))))),
3950 langCxx20OrLater()));
3952 EXPECT_TRUE(matches(
3953 Code,
3954 traverse(TK_IgnoreUnlessSpelledInSource,
3955 returnStmt(forFunction(functionDecl(hasName("func2"))),
3956 hasReturnValue(cxxTemporaryObjectExpr(
3957 hasArgument(0, integerLiteral(equals(42))))))),
3958 langCxx20OrLater()));
3959 EXPECT_TRUE(matches(
3960 Code,
3961 traverse(
3962 TK_IgnoreUnlessSpelledInSource,
3963 integerLiteral(equals(42),
3964 hasParent(cxxTemporaryObjectExpr(hasParent(returnStmt(
3965 forFunction(functionDecl(hasName("func2"))))))))),
3966 langCxx20OrLater()));
3968 EXPECT_TRUE(
3969 matches(Code,
3970 traverse(TK_IgnoreUnlessSpelledInSource,
3971 returnStmt(forFunction(functionDecl(hasName("func3"))),
3972 hasReturnValue(cxxConstructExpr(hasArgument(
3973 0, integerLiteral(equals(42))))))),
3974 langCxx20OrLater()));
3976 EXPECT_TRUE(matches(
3977 Code,
3978 traverse(
3979 TK_IgnoreUnlessSpelledInSource,
3980 integerLiteral(equals(42),
3981 hasParent(cxxConstructExpr(hasParent(returnStmt(
3982 forFunction(functionDecl(hasName("func3"))))))))),
3983 langCxx20OrLater()));
3985 EXPECT_TRUE(
3986 matches(Code,
3987 traverse(TK_IgnoreUnlessSpelledInSource,
3988 returnStmt(forFunction(functionDecl(hasName("func4"))),
3989 hasReturnValue(cxxTemporaryObjectExpr()))),
3990 langCxx20OrLater()));
3992 EXPECT_TRUE(
3993 matches(Code,
3994 traverse(TK_IgnoreUnlessSpelledInSource,
3995 returnStmt(forFunction(functionDecl(hasName("func5"))),
3996 hasReturnValue(cxxTemporaryObjectExpr()))),
3997 langCxx20OrLater()));
3999 EXPECT_TRUE(
4000 matches(Code,
4001 traverse(TK_IgnoreUnlessSpelledInSource,
4002 returnStmt(forFunction(functionDecl(hasName("func6"))),
4003 hasReturnValue(cxxTemporaryObjectExpr()))),
4004 langCxx20OrLater()));
4006 EXPECT_TRUE(
4007 matches(Code,
4008 traverse(TK_IgnoreUnlessSpelledInSource,
4009 returnStmt(forFunction(functionDecl(hasName("func7"))),
4010 hasReturnValue(cxxTemporaryObjectExpr()))),
4011 langCxx20OrLater()));
4013 EXPECT_TRUE(
4014 matches(Code,
4015 traverse(TK_IgnoreUnlessSpelledInSource,
4016 returnStmt(forFunction(functionDecl(hasName("func8"))),
4017 hasReturnValue(cxxFunctionalCastExpr(
4018 hasSourceExpression(initListExpr()))))),
4019 langCxx20OrLater()));
4021 EXPECT_TRUE(
4022 matches(Code,
4023 traverse(TK_IgnoreUnlessSpelledInSource,
4024 returnStmt(forFunction(functionDecl(hasName("func9"))),
4025 hasReturnValue(cxxFunctionalCastExpr(
4026 hasSourceExpression(initListExpr()))))),
4027 langCxx20OrLater()));
4029 EXPECT_TRUE(matches(
4030 Code,
4031 traverse(
4032 TK_IgnoreUnlessSpelledInSource,
4033 returnStmt(forFunction(functionDecl(hasName("func10"))),
4034 hasReturnValue(declRefExpr(to(varDecl(hasName("a"))))))),
4035 langCxx20OrLater()));
4037 EXPECT_TRUE(
4038 matches(Code,
4039 traverse(TK_IgnoreUnlessSpelledInSource,
4040 declRefExpr(to(varDecl(hasName("a"))),
4041 hasParent(returnStmt(forFunction(
4042 functionDecl(hasName("func10"))))))),
4043 langCxx20OrLater()));
4045 EXPECT_TRUE(matches(
4046 Code,
4047 traverse(
4048 TK_IgnoreUnlessSpelledInSource,
4049 returnStmt(forFunction(functionDecl(hasName("func11"))),
4050 hasReturnValue(declRefExpr(to(varDecl(hasName("b"))))))),
4051 langCxx20OrLater()));
4053 EXPECT_TRUE(
4054 matches(Code,
4055 traverse(TK_IgnoreUnlessSpelledInSource,
4056 declRefExpr(to(varDecl(hasName("b"))),
4057 hasParent(returnStmt(forFunction(
4058 functionDecl(hasName("func11"))))))),
4059 langCxx20OrLater()));
4061 EXPECT_TRUE(matches(
4062 Code,
4063 traverse(
4064 TK_IgnoreUnlessSpelledInSource,
4065 returnStmt(forFunction(functionDecl(hasName("func12"))),
4066 hasReturnValue(declRefExpr(to(varDecl(hasName("c"))))))),
4067 langCxx20OrLater()));
4069 EXPECT_TRUE(
4070 matches(Code,
4071 traverse(TK_IgnoreUnlessSpelledInSource,
4072 declRefExpr(to(varDecl(hasName("c"))),
4073 hasParent(returnStmt(forFunction(
4074 functionDecl(hasName("func12"))))))),
4075 langCxx20OrLater()));
4077 EXPECT_TRUE(matches(
4078 Code,
4079 traverse(
4080 TK_IgnoreUnlessSpelledInSource,
4081 lambdaExpr(forFunction(functionDecl(hasName("func13"))),
4082 has(compoundStmt(hasDescendant(varDecl(hasName("e"))))),
4083 has(declRefExpr(to(varDecl(hasName("a"))))),
4084 has(varDecl(hasName("b"), hasInitializer(declRefExpr(to(
4085 varDecl(hasName("c"))))))),
4086 has(parmVarDecl(hasName("d"))))),
4087 langCxx20OrLater()));
4089 EXPECT_TRUE(
4090 matches(Code,
4091 traverse(TK_IgnoreUnlessSpelledInSource,
4092 declRefExpr(to(varDecl(hasName("a"))),
4093 hasParent(lambdaExpr(forFunction(
4094 functionDecl(hasName("func13"))))))),
4095 langCxx20OrLater()));
4097 EXPECT_TRUE(matches(
4098 Code,
4099 traverse(TK_IgnoreUnlessSpelledInSource,
4100 varDecl(hasName("b"),
4101 hasInitializer(declRefExpr(to(varDecl(hasName("c"))))),
4102 hasParent(lambdaExpr(
4103 forFunction(functionDecl(hasName("func13"))))))),
4104 langCxx20OrLater()));
4106 EXPECT_TRUE(matches(Code,
4107 traverse(TK_IgnoreUnlessSpelledInSource,
4108 compoundStmt(hasParent(lambdaExpr(forFunction(
4109 functionDecl(hasName("func13"))))))),
4110 langCxx20OrLater()));
4112 EXPECT_TRUE(matches(
4113 Code,
4114 traverse(TK_IgnoreUnlessSpelledInSource,
4115 templateTypeParmDecl(hasName("TemplateType"),
4116 hasParent(lambdaExpr(forFunction(
4117 functionDecl(hasName("func14"))))))),
4118 langCxx20OrLater()));
4120 EXPECT_TRUE(matches(
4121 Code,
4122 traverse(TK_IgnoreUnlessSpelledInSource,
4123 lambdaExpr(forFunction(functionDecl(hasName("func14"))),
4124 has(templateTypeParmDecl(hasName("TemplateType"))))),
4125 langCxx20OrLater()));
4127 EXPECT_TRUE(matches(
4128 Code,
4129 traverse(TK_IgnoreUnlessSpelledInSource,
4130 functionDecl(hasName("func14"), hasDescendant(floatLiteral()))),
4131 langCxx20OrLater()));
4133 EXPECT_TRUE(matches(
4134 Code,
4135 traverse(TK_IgnoreUnlessSpelledInSource,
4136 compoundStmt(
4137 hasDescendant(varDecl(hasName("count")).bind("countVar")),
4138 hasDescendant(
4139 declRefExpr(to(varDecl(equalsBoundNode("countVar"))))))),
4140 langCxx20OrLater()));
4142 Code = R"cpp(
4143 void foo() {
4144 int explicit_captured = 0;
4145 int implicit_captured = 0;
4146 auto l = [&, explicit_captured](int i) {
4147 if (i || explicit_captured || implicit_captured) return;
4150 )cpp";
4152 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, ifStmt())));
4153 EXPECT_TRUE(
4154 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, ifStmt())));
4156 auto lambdaExplicitCapture = declRefExpr(
4157 to(varDecl(hasName("explicit_captured"))), unless(hasAncestor(ifStmt())));
4158 auto lambdaImplicitCapture = declRefExpr(
4159 to(varDecl(hasName("implicit_captured"))), unless(hasAncestor(ifStmt())));
4161 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, lambdaExplicitCapture)));
4162 EXPECT_TRUE(matches(
4163 Code, traverse(TK_IgnoreUnlessSpelledInSource, lambdaExplicitCapture)));
4165 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, lambdaImplicitCapture)));
4166 EXPECT_FALSE(matches(
4167 Code, traverse(TK_IgnoreUnlessSpelledInSource, lambdaImplicitCapture)));
4169 Code = R"cpp(
4170 struct S {};
4172 struct HasOpEq
4174 bool operator==(const S& other)
4176 return true;
4180 void binop()
4182 HasOpEq s1;
4183 S s2;
4184 if (s1 != s2)
4185 return;
4187 )cpp";
4189 auto M = unaryOperator(
4190 hasOperatorName("!"),
4191 has(cxxOperatorCallExpr(hasOverloadedOperatorName("=="))));
4192 EXPECT_TRUE(
4193 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4194 EXPECT_FALSE(
4195 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4196 true, {"-std=c++20"}));
4199 auto M = declRefExpr(to(varDecl(hasName("s1"))));
4200 EXPECT_TRUE(
4201 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4202 EXPECT_TRUE(
4203 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4204 true, {"-std=c++20"}));
4207 auto M = cxxOperatorCallExpr(hasOverloadedOperatorName("=="));
4208 EXPECT_TRUE(
4209 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4210 EXPECT_FALSE(
4211 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4212 true, {"-std=c++20"}));
4215 auto M = cxxOperatorCallExpr(hasOverloadedOperatorName("!="));
4216 EXPECT_FALSE(
4217 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4218 EXPECT_FALSE(
4219 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4220 true, {"-std=c++20"}));
4222 auto withDescendants = [](StringRef lName, StringRef rName) {
4223 return stmt(hasDescendant(declRefExpr(to(varDecl(hasName(lName))))),
4224 hasDescendant(declRefExpr(to(varDecl(hasName(rName))))));
4227 auto M = cxxRewrittenBinaryOperator(withDescendants("s1", "s2"));
4228 EXPECT_TRUE(
4229 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4230 EXPECT_TRUE(
4231 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4232 true, {"-std=c++20"}));
4235 auto M = cxxRewrittenBinaryOperator(
4236 has(declRefExpr(to(varDecl(hasName("s1"))))),
4237 has(declRefExpr(to(varDecl(hasName("s2"))))));
4238 EXPECT_FALSE(
4239 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4240 EXPECT_TRUE(
4241 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4242 true, {"-std=c++20"}));
4245 auto M = cxxRewrittenBinaryOperator(
4246 hasLHS(expr(hasParent(cxxRewrittenBinaryOperator()))),
4247 hasRHS(expr(hasParent(cxxRewrittenBinaryOperator()))));
4248 EXPECT_FALSE(
4249 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4250 EXPECT_TRUE(
4251 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4252 true, {"-std=c++20"}));
4255 EXPECT_TRUE(matchesConditionally(
4256 Code,
4257 traverse(TK_AsIs,
4258 cxxRewrittenBinaryOperator(
4259 hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4260 isComparisonOperator(),
4261 hasLHS(ignoringImplicit(
4262 declRefExpr(to(varDecl(hasName("s1")))))),
4263 hasRHS(ignoringImplicit(
4264 declRefExpr(to(varDecl(hasName("s2")))))),
4265 hasEitherOperand(ignoringImplicit(
4266 declRefExpr(to(varDecl(hasName("s2")))))),
4267 hasOperands(ignoringImplicit(
4268 declRefExpr(to(varDecl(hasName("s1"))))),
4269 ignoringImplicit(declRefExpr(
4270 to(varDecl(hasName("s2")))))))),
4271 true, {"-std=c++20"}));
4272 EXPECT_TRUE(matchesConditionally(
4273 Code,
4274 traverse(TK_IgnoreUnlessSpelledInSource,
4275 cxxRewrittenBinaryOperator(
4276 hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4277 isComparisonOperator(),
4278 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
4279 hasRHS(declRefExpr(to(varDecl(hasName("s2"))))),
4280 hasEitherOperand(declRefExpr(to(varDecl(hasName("s2"))))),
4281 hasOperands(declRefExpr(to(varDecl(hasName("s1")))),
4282 declRefExpr(to(varDecl(hasName("s2"))))))),
4283 true, {"-std=c++20"}));
4286 Code = R"cpp(
4287 namespace std {
4288 struct strong_ordering {
4289 int n;
4290 constexpr operator int() const { return n; }
4291 static const strong_ordering equal, greater, less;
4293 constexpr strong_ordering strong_ordering::equal = {0};
4294 constexpr strong_ordering strong_ordering::greater = {1};
4295 constexpr strong_ordering strong_ordering::less = {-1};
4298 struct HasSpaceshipMem {
4299 int a;
4300 constexpr auto operator<=>(const HasSpaceshipMem&) const = default;
4303 void binop()
4305 HasSpaceshipMem hs1, hs2;
4306 if (hs1 == hs2)
4307 return;
4309 HasSpaceshipMem hs3, hs4;
4310 if (hs3 != hs4)
4311 return;
4313 HasSpaceshipMem hs5, hs6;
4314 if (hs5 < hs6)
4315 return;
4317 HasSpaceshipMem hs7, hs8;
4318 if (hs7 > hs8)
4319 return;
4321 HasSpaceshipMem hs9, hs10;
4322 if (hs9 <= hs10)
4323 return;
4325 HasSpaceshipMem hs11, hs12;
4326 if (hs11 >= hs12)
4327 return;
4329 )cpp";
4330 auto withArgs = [](StringRef lName, StringRef rName) {
4331 return cxxOperatorCallExpr(
4332 hasArgument(0, declRefExpr(to(varDecl(hasName(lName))))),
4333 hasArgument(1, declRefExpr(to(varDecl(hasName(rName))))));
4336 auto M = ifStmt(hasCondition(cxxOperatorCallExpr(
4337 hasOverloadedOperatorName("=="), withArgs("hs1", "hs2"))));
4338 EXPECT_TRUE(
4339 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4340 EXPECT_TRUE(
4341 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4342 true, {"-std=c++20"}));
4345 auto M =
4346 unaryOperator(hasOperatorName("!"),
4347 has(cxxOperatorCallExpr(hasOverloadedOperatorName("=="),
4348 withArgs("hs3", "hs4"))));
4349 EXPECT_TRUE(
4350 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4351 EXPECT_FALSE(
4352 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4353 true, {"-std=c++20"}));
4356 auto M =
4357 unaryOperator(hasOperatorName("!"),
4358 has(cxxOperatorCallExpr(hasOverloadedOperatorName("=="),
4359 withArgs("hs3", "hs4"))));
4360 EXPECT_TRUE(
4361 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4362 EXPECT_FALSE(
4363 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4364 true, {"-std=c++20"}));
4367 auto M = binaryOperator(
4368 hasOperatorName("<"),
4369 hasLHS(hasDescendant(cxxOperatorCallExpr(
4370 hasOverloadedOperatorName("<=>"), withArgs("hs5", "hs6")))),
4371 hasRHS(integerLiteral(equals(0))));
4372 EXPECT_TRUE(
4373 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4374 EXPECT_FALSE(
4375 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4376 true, {"-std=c++20"}));
4379 auto M = cxxRewrittenBinaryOperator(withDescendants("hs3", "hs4"));
4380 EXPECT_TRUE(
4381 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4382 EXPECT_TRUE(
4383 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4384 true, {"-std=c++20"}));
4387 auto M = declRefExpr(to(varDecl(hasName("hs3"))));
4388 EXPECT_TRUE(
4389 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4390 EXPECT_TRUE(
4391 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4392 true, {"-std=c++20"}));
4395 auto M = cxxRewrittenBinaryOperator(has(
4396 unaryOperator(hasOperatorName("!"), withDescendants("hs3", "hs4"))));
4397 EXPECT_TRUE(
4398 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4399 EXPECT_FALSE(
4400 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4401 true, {"-std=c++20"}));
4404 auto M = cxxRewrittenBinaryOperator(
4405 has(declRefExpr(to(varDecl(hasName("hs3"))))),
4406 has(declRefExpr(to(varDecl(hasName("hs4"))))));
4407 EXPECT_FALSE(
4408 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
4409 EXPECT_TRUE(
4410 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
4411 true, {"-std=c++20"}));
4414 EXPECT_TRUE(matchesConditionally(
4415 Code,
4416 traverse(TK_AsIs,
4417 cxxRewrittenBinaryOperator(
4418 hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4419 isComparisonOperator(),
4420 hasLHS(ignoringImplicit(
4421 declRefExpr(to(varDecl(hasName("hs3")))))),
4422 hasRHS(ignoringImplicit(
4423 declRefExpr(to(varDecl(hasName("hs4")))))),
4424 hasEitherOperand(ignoringImplicit(
4425 declRefExpr(to(varDecl(hasName("hs3")))))),
4426 hasOperands(ignoringImplicit(
4427 declRefExpr(to(varDecl(hasName("hs3"))))),
4428 ignoringImplicit(declRefExpr(
4429 to(varDecl(hasName("hs4")))))))),
4430 true, {"-std=c++20"}));
4431 EXPECT_TRUE(matchesConditionally(
4432 Code,
4433 traverse(TK_IgnoreUnlessSpelledInSource,
4434 cxxRewrittenBinaryOperator(
4435 hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4436 isComparisonOperator(),
4437 hasLHS(declRefExpr(to(varDecl(hasName("hs3"))))),
4438 hasRHS(declRefExpr(to(varDecl(hasName("hs4"))))),
4439 hasEitherOperand(declRefExpr(to(varDecl(hasName("hs3"))))),
4440 hasOperands(declRefExpr(to(varDecl(hasName("hs3")))),
4441 declRefExpr(to(varDecl(hasName("hs4"))))))),
4442 true, {"-std=c++20"}));
4445 EXPECT_TRUE(matchesConditionally(
4446 Code,
4447 traverse(TK_AsIs,
4448 cxxRewrittenBinaryOperator(
4449 hasOperatorName("<"), hasAnyOperatorName("<", "!="),
4450 isComparisonOperator(),
4451 hasLHS(ignoringImplicit(
4452 declRefExpr(to(varDecl(hasName("hs5")))))),
4453 hasRHS(ignoringImplicit(
4454 declRefExpr(to(varDecl(hasName("hs6")))))),
4455 hasEitherOperand(ignoringImplicit(
4456 declRefExpr(to(varDecl(hasName("hs5")))))),
4457 hasOperands(ignoringImplicit(
4458 declRefExpr(to(varDecl(hasName("hs5"))))),
4459 ignoringImplicit(declRefExpr(
4460 to(varDecl(hasName("hs6")))))))),
4461 true, {"-std=c++20"}));
4462 EXPECT_TRUE(matchesConditionally(
4463 Code,
4464 traverse(TK_IgnoreUnlessSpelledInSource,
4465 cxxRewrittenBinaryOperator(
4466 hasOperatorName("<"), hasAnyOperatorName("<", "!="),
4467 isComparisonOperator(),
4468 hasLHS(declRefExpr(to(varDecl(hasName("hs5"))))),
4469 hasRHS(declRefExpr(to(varDecl(hasName("hs6"))))),
4470 hasEitherOperand(declRefExpr(to(varDecl(hasName("hs5"))))),
4471 hasOperands(declRefExpr(to(varDecl(hasName("hs5")))),
4472 declRefExpr(to(varDecl(hasName("hs6"))))))),
4473 true, {"-std=c++20"}));
4476 EXPECT_TRUE(matchesConditionally(
4477 Code,
4478 traverse(TK_AsIs,
4479 cxxRewrittenBinaryOperator(
4480 hasOperatorName(">"), hasAnyOperatorName("<", ">"),
4481 isComparisonOperator(),
4482 hasLHS(ignoringImplicit(
4483 declRefExpr(to(varDecl(hasName("hs7")))))),
4484 hasRHS(ignoringImplicit(
4485 declRefExpr(to(varDecl(hasName("hs8")))))),
4486 hasEitherOperand(ignoringImplicit(
4487 declRefExpr(to(varDecl(hasName("hs7")))))),
4488 hasOperands(ignoringImplicit(
4489 declRefExpr(to(varDecl(hasName("hs7"))))),
4490 ignoringImplicit(declRefExpr(
4491 to(varDecl(hasName("hs8")))))))),
4492 true, {"-std=c++20"}));
4493 EXPECT_TRUE(matchesConditionally(
4494 Code,
4495 traverse(TK_IgnoreUnlessSpelledInSource,
4496 cxxRewrittenBinaryOperator(
4497 hasOperatorName(">"), hasAnyOperatorName("<", ">"),
4498 isComparisonOperator(),
4499 hasLHS(declRefExpr(to(varDecl(hasName("hs7"))))),
4500 hasRHS(declRefExpr(to(varDecl(hasName("hs8"))))),
4501 hasEitherOperand(declRefExpr(to(varDecl(hasName("hs7"))))),
4502 hasOperands(declRefExpr(to(varDecl(hasName("hs7")))),
4503 declRefExpr(to(varDecl(hasName("hs8"))))))),
4504 true, {"-std=c++20"}));
4507 EXPECT_TRUE(matchesConditionally(
4508 Code,
4509 traverse(TK_AsIs,
4510 cxxRewrittenBinaryOperator(
4511 hasOperatorName("<="), hasAnyOperatorName("<", "<="),
4512 isComparisonOperator(),
4513 hasLHS(ignoringImplicit(
4514 declRefExpr(to(varDecl(hasName("hs9")))))),
4515 hasRHS(ignoringImplicit(
4516 declRefExpr(to(varDecl(hasName("hs10")))))),
4517 hasEitherOperand(ignoringImplicit(
4518 declRefExpr(to(varDecl(hasName("hs9")))))),
4519 hasOperands(ignoringImplicit(
4520 declRefExpr(to(varDecl(hasName("hs9"))))),
4521 ignoringImplicit(declRefExpr(
4522 to(varDecl(hasName("hs10")))))))),
4523 true, {"-std=c++20"}));
4524 EXPECT_TRUE(matchesConditionally(
4525 Code,
4526 traverse(TK_IgnoreUnlessSpelledInSource,
4527 cxxRewrittenBinaryOperator(
4528 hasOperatorName("<="), hasAnyOperatorName("<", "<="),
4529 isComparisonOperator(),
4530 hasLHS(declRefExpr(to(varDecl(hasName("hs9"))))),
4531 hasRHS(declRefExpr(to(varDecl(hasName("hs10"))))),
4532 hasEitherOperand(declRefExpr(to(varDecl(hasName("hs9"))))),
4533 hasOperands(declRefExpr(to(varDecl(hasName("hs9")))),
4534 declRefExpr(to(varDecl(hasName("hs10"))))))),
4535 true, {"-std=c++20"}));
4538 EXPECT_TRUE(matchesConditionally(
4539 Code,
4540 traverse(TK_AsIs,
4541 cxxRewrittenBinaryOperator(
4542 hasOperatorName(">="), hasAnyOperatorName("<", ">="),
4543 isComparisonOperator(),
4544 hasLHS(ignoringImplicit(
4545 declRefExpr(to(varDecl(hasName("hs11")))))),
4546 hasRHS(ignoringImplicit(
4547 declRefExpr(to(varDecl(hasName("hs12")))))),
4548 hasEitherOperand(ignoringImplicit(
4549 declRefExpr(to(varDecl(hasName("hs11")))))),
4550 hasOperands(ignoringImplicit(
4551 declRefExpr(to(varDecl(hasName("hs11"))))),
4552 ignoringImplicit(declRefExpr(
4553 to(varDecl(hasName("hs12")))))))),
4554 true, {"-std=c++20"}));
4555 EXPECT_TRUE(matchesConditionally(
4556 Code,
4557 traverse(
4558 TK_IgnoreUnlessSpelledInSource,
4559 cxxRewrittenBinaryOperator(
4560 hasOperatorName(">="), hasAnyOperatorName("<", ">="),
4561 isComparisonOperator(),
4562 hasLHS(declRefExpr(to(varDecl(hasName("hs11"))))),
4563 hasRHS(declRefExpr(to(varDecl(hasName("hs12"))))),
4564 hasEitherOperand(declRefExpr(to(varDecl(hasName("hs11"))))),
4565 hasOperands(declRefExpr(to(varDecl(hasName("hs11")))),
4566 declRefExpr(to(varDecl(hasName("hs12"))))))),
4567 true, {"-std=c++20"}));
4570 Code = R"cpp(
4571 struct S {};
4573 struct HasOpEq
4575 bool operator==(const S& other) const
4577 return true;
4581 struct HasOpEqMem {
4582 bool operator==(const HasOpEqMem&) const { return true; }
4585 struct HasOpEqFree {
4587 bool operator==(const HasOpEqFree&, const HasOpEqFree&) { return true; }
4589 void binop()
4592 HasOpEq s1;
4593 S s2;
4594 if (s1 != s2)
4595 return;
4599 int i1;
4600 int i2;
4601 if (i1 != i2)
4602 return;
4606 HasOpEqMem M1;
4607 HasOpEqMem M2;
4608 if (M1 == M2)
4609 return;
4613 HasOpEqFree F1;
4614 HasOpEqFree F2;
4615 if (F1 == F2)
4616 return;
4619 )cpp";
4621 EXPECT_TRUE(matchesConditionally(
4622 Code,
4623 traverse(TK_AsIs,
4624 binaryOperation(
4625 hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4626 isComparisonOperator(),
4627 hasLHS(ignoringImplicit(
4628 declRefExpr(to(varDecl(hasName("s1")))))),
4629 hasRHS(ignoringImplicit(
4630 declRefExpr(to(varDecl(hasName("s2")))))),
4631 hasEitherOperand(ignoringImplicit(
4632 declRefExpr(to(varDecl(hasName("s2")))))),
4633 hasOperands(ignoringImplicit(
4634 declRefExpr(to(varDecl(hasName("s1"))))),
4635 ignoringImplicit(declRefExpr(
4636 to(varDecl(hasName("s2")))))))),
4637 true, {"-std=c++20"}));
4638 EXPECT_TRUE(matchesConditionally(
4639 Code,
4640 traverse(TK_AsIs, binaryOperation(hasOperatorName("!="),
4641 hasLHS(ignoringImplicit(declRefExpr(
4642 to(varDecl(hasName("i1")))))),
4643 hasRHS(ignoringImplicit(declRefExpr(
4644 to(varDecl(hasName("i2")))))))),
4645 true, {"-std=c++20"}));
4646 EXPECT_TRUE(matchesConditionally(
4647 Code,
4648 traverse(TK_AsIs, binaryOperation(hasOperatorName("=="),
4649 hasLHS(ignoringImplicit(declRefExpr(
4650 to(varDecl(hasName("M1")))))),
4651 hasRHS(ignoringImplicit(declRefExpr(
4652 to(varDecl(hasName("M2")))))))),
4653 true, {"-std=c++20"}));
4654 EXPECT_TRUE(matchesConditionally(
4655 Code,
4656 traverse(TK_AsIs, binaryOperation(hasOperatorName("=="),
4657 hasLHS(ignoringImplicit(declRefExpr(
4658 to(varDecl(hasName("F1")))))),
4659 hasRHS(ignoringImplicit(declRefExpr(
4660 to(varDecl(hasName("F2")))))))),
4661 true, {"-std=c++20"}));
4662 EXPECT_TRUE(matchesConditionally(
4663 Code,
4664 traverse(TK_IgnoreUnlessSpelledInSource,
4665 binaryOperation(
4666 hasOperatorName("!="), hasAnyOperatorName("<", "!="),
4667 isComparisonOperator(),
4668 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
4669 hasRHS(declRefExpr(to(varDecl(hasName("s2"))))),
4670 hasEitherOperand(declRefExpr(to(varDecl(hasName("s2"))))),
4671 hasOperands(declRefExpr(to(varDecl(hasName("s1")))),
4672 declRefExpr(to(varDecl(hasName("s2"))))))),
4673 true, {"-std=c++20"}));
4674 EXPECT_TRUE(matchesConditionally(
4675 Code,
4676 traverse(
4677 TK_IgnoreUnlessSpelledInSource,
4678 binaryOperation(hasOperatorName("!="),
4679 hasLHS(declRefExpr(to(varDecl(hasName("i1"))))),
4680 hasRHS(declRefExpr(to(varDecl(hasName("i2"))))))),
4681 true, {"-std=c++20"}));
4682 EXPECT_TRUE(matchesConditionally(
4683 Code,
4684 traverse(
4685 TK_IgnoreUnlessSpelledInSource,
4686 binaryOperation(hasOperatorName("=="),
4687 hasLHS(declRefExpr(to(varDecl(hasName("M1"))))),
4688 hasRHS(declRefExpr(to(varDecl(hasName("M2"))))))),
4689 true, {"-std=c++20"}));
4690 EXPECT_TRUE(matchesConditionally(
4691 Code,
4692 traverse(
4693 TK_IgnoreUnlessSpelledInSource,
4694 binaryOperation(hasOperatorName("=="),
4695 hasLHS(declRefExpr(to(varDecl(hasName("F1"))))),
4696 hasRHS(declRefExpr(to(varDecl(hasName("F2"))))))),
4697 true, {"-std=c++20"}));
4701 TEST(IgnoringImpCasts, PathologicalLambda) {
4703 // Test that deeply nested lambdas are not a performance penalty
4704 StringRef Code = R"cpp(
4705 void f() {
4706 [] {
4707 [] {
4708 [] {
4709 [] {
4710 [] {
4711 [] {
4712 [] {
4713 [] {
4714 [] {
4715 [] {
4716 [] {
4717 [] {
4718 [] {
4719 [] {
4720 [] {
4721 [] {
4722 [] {
4723 [] {
4724 [] {
4725 [] {
4726 [] {
4727 [] {
4728 [] {
4729 [] {
4730 [] {
4731 [] {
4732 [] {
4733 [] {
4734 [] {
4735 int i = 42;
4736 (void)i;
4737 }();
4738 }();
4739 }();
4740 }();
4741 }();
4742 }();
4743 }();
4744 }();
4745 }();
4746 }();
4747 }();
4748 }();
4749 }();
4750 }();
4751 }();
4752 }();
4753 }();
4754 }();
4755 }();
4756 }();
4757 }();
4758 }();
4759 }();
4760 }();
4761 }();
4762 }();
4763 }();
4764 }();
4765 }();
4767 )cpp";
4769 EXPECT_TRUE(matches(Code, integerLiteral(equals(42))));
4770 EXPECT_TRUE(matches(Code, functionDecl(hasDescendant(integerLiteral(equals(42))))));
4773 TEST(IgnoringImpCasts, MatchesImpCasts) {
4774 // This test checks that ignoringImpCasts matches when implicit casts are
4775 // present and its inner matcher alone does not match.
4776 // Note that this test creates an implicit const cast.
4777 EXPECT_TRUE(matches("int x = 0; const int y = x;",
4778 varDecl(hasInitializer(ignoringImpCasts(
4779 declRefExpr(to(varDecl(hasName("x")))))))));
4780 // This test creates an implict cast from int to char.
4781 EXPECT_TRUE(matches("char x = 0;",
4782 varDecl(hasInitializer(ignoringImpCasts(
4783 integerLiteral(equals(0)))))));
4786 TEST(IgnoringImpCasts, DoesNotMatchIncorrectly) {
4787 // These tests verify that ignoringImpCasts does not match if the inner
4788 // matcher does not match.
4789 // Note that the first test creates an implicit const cast.
4790 EXPECT_TRUE(notMatches("int x; const int y = x;",
4791 varDecl(hasInitializer(ignoringImpCasts(
4792 unless(anything()))))));
4793 EXPECT_TRUE(notMatches("int x; int y = x;",
4794 varDecl(hasInitializer(ignoringImpCasts(
4795 unless(anything()))))));
4797 // These tests verify that ignoringImplictCasts does not look through explicit
4798 // casts or parentheses.
4799 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
4800 varDecl(hasInitializer(ignoringImpCasts(
4801 integerLiteral())))));
4802 EXPECT_TRUE(notMatches(
4803 "int i = (0);",
4804 traverse(TK_AsIs,
4805 varDecl(hasInitializer(ignoringImpCasts(integerLiteral()))))));
4806 EXPECT_TRUE(notMatches("float i = (float)0;",
4807 varDecl(hasInitializer(ignoringImpCasts(
4808 integerLiteral())))));
4809 EXPECT_TRUE(notMatches("float i = float(0);",
4810 varDecl(hasInitializer(ignoringImpCasts(
4811 integerLiteral())))));
4814 TEST(IgnoringImpCasts, MatchesWithoutImpCasts) {
4815 // This test verifies that expressions that do not have implicit casts
4816 // still match the inner matcher.
4817 EXPECT_TRUE(matches("int x = 0; int &y = x;",
4818 varDecl(hasInitializer(ignoringImpCasts(
4819 declRefExpr(to(varDecl(hasName("x")))))))));
4822 TEST(IgnoringParenCasts, MatchesParenCasts) {
4823 // This test checks that ignoringParenCasts matches when parentheses and/or
4824 // casts are present and its inner matcher alone does not match.
4825 EXPECT_TRUE(matches("int x = (0);",
4826 varDecl(hasInitializer(ignoringParenCasts(
4827 integerLiteral(equals(0)))))));
4828 EXPECT_TRUE(matches("int x = (((((0)))));",
4829 varDecl(hasInitializer(ignoringParenCasts(
4830 integerLiteral(equals(0)))))));
4832 // This test creates an implict cast from int to char in addition to the
4833 // parentheses.
4834 EXPECT_TRUE(matches("char x = (0);",
4835 varDecl(hasInitializer(ignoringParenCasts(
4836 integerLiteral(equals(0)))))));
4838 EXPECT_TRUE(matches("char x = (char)0;",
4839 varDecl(hasInitializer(ignoringParenCasts(
4840 integerLiteral(equals(0)))))));
4841 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
4842 varDecl(hasInitializer(ignoringParenCasts(
4843 integerLiteral(equals(0)))))));
4846 TEST(IgnoringParenCasts, MatchesWithoutParenCasts) {
4847 // This test verifies that expressions that do not have any casts still match.
4848 EXPECT_TRUE(matches("int x = 0;",
4849 varDecl(hasInitializer(ignoringParenCasts(
4850 integerLiteral(equals(0)))))));
4853 TEST(IgnoringParenCasts, DoesNotMatchIncorrectly) {
4854 // These tests verify that ignoringImpCasts does not match if the inner
4855 // matcher does not match.
4856 EXPECT_TRUE(notMatches("int x = ((0));",
4857 varDecl(hasInitializer(ignoringParenCasts(
4858 unless(anything()))))));
4860 // This test creates an implicit cast from int to char in addition to the
4861 // parentheses.
4862 EXPECT_TRUE(notMatches("char x = ((0));",
4863 varDecl(hasInitializer(ignoringParenCasts(
4864 unless(anything()))))));
4866 EXPECT_TRUE(notMatches("char *x = static_cast<char *>((0));",
4867 varDecl(hasInitializer(ignoringParenCasts(
4868 unless(anything()))))));
4871 TEST(IgnoringParenAndImpCasts, MatchesParenImpCasts) {
4872 // This test checks that ignoringParenAndImpCasts matches when
4873 // parentheses and/or implicit casts are present and its inner matcher alone
4874 // does not match.
4875 // Note that this test creates an implicit const cast.
4876 EXPECT_TRUE(matches("int x = 0; const int y = x;",
4877 varDecl(hasInitializer(ignoringParenImpCasts(
4878 declRefExpr(to(varDecl(hasName("x")))))))));
4879 // This test creates an implicit cast from int to char.
4880 EXPECT_TRUE(matches("const char x = (0);",
4881 varDecl(hasInitializer(ignoringParenImpCasts(
4882 integerLiteral(equals(0)))))));
4885 TEST(IgnoringParenAndImpCasts, MatchesWithoutParenImpCasts) {
4886 // This test verifies that expressions that do not have parentheses or
4887 // implicit casts still match.
4888 EXPECT_TRUE(matches("int x = 0; int &y = x;",
4889 varDecl(hasInitializer(ignoringParenImpCasts(
4890 declRefExpr(to(varDecl(hasName("x")))))))));
4891 EXPECT_TRUE(matches("int x = 0;",
4892 varDecl(hasInitializer(ignoringParenImpCasts(
4893 integerLiteral(equals(0)))))));
4896 TEST(IgnoringParenAndImpCasts, DoesNotMatchIncorrectly) {
4897 // These tests verify that ignoringParenImpCasts does not match if
4898 // the inner matcher does not match.
4899 // This test creates an implicit cast.
4900 EXPECT_TRUE(notMatches("char c = ((3));",
4901 varDecl(hasInitializer(ignoringParenImpCasts(
4902 unless(anything()))))));
4903 // These tests verify that ignoringParenAndImplictCasts does not look
4904 // through explicit casts.
4905 EXPECT_TRUE(notMatches("float y = (float(0));",
4906 varDecl(hasInitializer(ignoringParenImpCasts(
4907 integerLiteral())))));
4908 EXPECT_TRUE(notMatches("float y = (float)0;",
4909 varDecl(hasInitializer(ignoringParenImpCasts(
4910 integerLiteral())))));
4911 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
4912 varDecl(hasInitializer(ignoringParenImpCasts(
4913 integerLiteral())))));
4916 TEST(HasSourceExpression, MatchesImplicitCasts) {
4917 EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
4918 "void r() {string a_string; URL url = a_string; }",
4919 traverse(TK_AsIs, implicitCastExpr(hasSourceExpression(
4920 cxxConstructExpr())))));
4923 TEST(HasSourceExpression, MatchesExplicitCasts) {
4924 EXPECT_TRUE(
4925 matches("float x = static_cast<float>(42);",
4926 traverse(TK_AsIs, explicitCastExpr(hasSourceExpression(
4927 hasDescendant(expr(integerLiteral())))))));
4930 TEST(UsingDeclaration, MatchesSpecificTarget) {
4931 EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
4932 usingDecl(hasAnyUsingShadowDecl(
4933 hasTargetDecl(functionDecl())))));
4934 EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
4935 usingDecl(hasAnyUsingShadowDecl(
4936 hasTargetDecl(functionDecl())))));
4939 TEST(UsingDeclaration, ThroughUsingDeclaration) {
4940 EXPECT_TRUE(matches(
4941 "namespace a { void f(); } using a::f; void g() { f(); }",
4942 declRefExpr(throughUsingDecl(anything()))));
4943 EXPECT_TRUE(notMatches(
4944 "namespace a { void f(); } using a::f; void g() { a::f(); }",
4945 declRefExpr(throughUsingDecl(anything()))));
4948 TEST(SingleDecl, IsSingleDecl) {
4949 StatementMatcher SingleDeclStmt =
4950 declStmt(hasSingleDecl(varDecl(hasInitializer(anything()))));
4951 EXPECT_TRUE(matches("void f() {int a = 4;}", SingleDeclStmt));
4952 EXPECT_TRUE(notMatches("void f() {int a;}", SingleDeclStmt));
4953 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
4954 SingleDeclStmt));
4957 TEST(DeclStmt, ContainsDeclaration) {
4958 DeclarationMatcher MatchesInit = varDecl(hasInitializer(anything()));
4960 EXPECT_TRUE(matches("void f() {int a = 4;}",
4961 declStmt(containsDeclaration(0, MatchesInit))));
4962 EXPECT_TRUE(matches("void f() {int a = 4, b = 3;}",
4963 declStmt(containsDeclaration(0, MatchesInit),
4964 containsDeclaration(1, MatchesInit))));
4965 unsigned WrongIndex = 42;
4966 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
4967 declStmt(containsDeclaration(WrongIndex,
4968 MatchesInit))));
4971 TEST(SwitchCase, MatchesEachCase) {
4972 EXPECT_TRUE(notMatches("void x() { switch(42); }",
4973 switchStmt(forEachSwitchCase(caseStmt()))));
4974 EXPECT_TRUE(matches("void x() { switch(42) case 42:; }",
4975 switchStmt(forEachSwitchCase(caseStmt()))));
4976 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }",
4977 switchStmt(forEachSwitchCase(caseStmt()))));
4978 EXPECT_TRUE(notMatches(
4979 "void x() { if (1) switch(42) { case 42: switch (42) { default:; } } }",
4980 ifStmt(has(switchStmt(forEachSwitchCase(defaultStmt()))))));
4981 EXPECT_TRUE(matches(
4982 "void x() { switch(42) { case 1+1: case 4:; } }",
4983 traverse(TK_AsIs, switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant(
4984 constantExpr(has(integerLiteral())))))))));
4985 EXPECT_TRUE(notMatches(
4986 "void x() { switch(42) { case 1+1: case 2+2:; } }",
4987 traverse(TK_AsIs, switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant(
4988 constantExpr(has(integerLiteral())))))))));
4989 EXPECT_TRUE(notMatches(
4990 "void x() { switch(42) { case 1 ... 2:; } }",
4991 traverse(TK_AsIs, switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant(
4992 constantExpr(has(integerLiteral())))))))));
4993 EXPECT_TRUE(matchAndVerifyResultTrue(
4994 "void x() { switch (42) { case 1: case 2: case 3: default:; } }",
4995 switchStmt(forEachSwitchCase(caseStmt().bind("x"))),
4996 std::make_unique<VerifyIdIsBoundTo<CaseStmt>>("x", 3)));
4999 TEST(Declaration, HasExplicitSpecifier) {
5001 EXPECT_TRUE(notMatches("void f();",
5002 functionDecl(hasExplicitSpecifier(constantExpr())),
5003 langCxx20OrLater()));
5004 EXPECT_TRUE(
5005 notMatches("template<bool b> struct S { explicit operator int(); };",
5006 cxxConversionDecl(
5007 hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
5008 langCxx20OrLater()));
5009 EXPECT_TRUE(
5010 notMatches("template<bool b> struct S { explicit(b) operator int(); };",
5011 cxxConversionDecl(
5012 hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
5013 langCxx20OrLater()));
5014 EXPECT_TRUE(
5015 matches("struct S { explicit(true) operator int(); };",
5016 traverse(TK_AsIs, cxxConversionDecl(hasExplicitSpecifier(
5017 constantExpr(has(cxxBoolLiteral()))))),
5018 langCxx20OrLater()));
5019 EXPECT_TRUE(
5020 matches("struct S { explicit(false) operator int(); };",
5021 traverse(TK_AsIs, cxxConversionDecl(hasExplicitSpecifier(
5022 constantExpr(has(cxxBoolLiteral()))))),
5023 langCxx20OrLater()));
5024 EXPECT_TRUE(
5025 notMatches("template<bool b> struct S { explicit(b) S(int); };",
5026 traverse(TK_AsIs, cxxConstructorDecl(hasExplicitSpecifier(
5027 constantExpr(has(cxxBoolLiteral()))))),
5028 langCxx20OrLater()));
5029 EXPECT_TRUE(
5030 matches("struct S { explicit(true) S(int); };",
5031 traverse(TK_AsIs, cxxConstructorDecl(hasExplicitSpecifier(
5032 constantExpr(has(cxxBoolLiteral()))))),
5033 langCxx20OrLater()));
5034 EXPECT_TRUE(
5035 matches("struct S { explicit(false) S(int); };",
5036 traverse(TK_AsIs, cxxConstructorDecl(hasExplicitSpecifier(
5037 constantExpr(has(cxxBoolLiteral()))))),
5038 langCxx20OrLater()));
5039 EXPECT_TRUE(
5040 notMatches("template<typename T> struct S { S(int); };"
5041 "template<bool b = true> explicit(b) S(int) -> S<int>;",
5042 traverse(TK_AsIs, cxxDeductionGuideDecl(hasExplicitSpecifier(
5043 constantExpr(has(cxxBoolLiteral()))))),
5044 langCxx20OrLater()));
5045 EXPECT_TRUE(
5046 matches("template<typename T> struct S { S(int); };"
5047 "explicit(true) S(int) -> S<int>;",
5048 traverse(TK_AsIs, cxxDeductionGuideDecl(hasExplicitSpecifier(
5049 constantExpr(has(cxxBoolLiteral()))))),
5050 langCxx20OrLater()));
5051 EXPECT_TRUE(
5052 matches("template<typename T> struct S { S(int); };"
5053 "explicit(false) S(int) -> S<int>;",
5054 traverse(TK_AsIs, cxxDeductionGuideDecl(hasExplicitSpecifier(
5055 constantExpr(has(cxxBoolLiteral()))))),
5056 langCxx20OrLater()));
5059 TEST(ForEachConstructorInitializer, MatchesInitializers) {
5060 EXPECT_TRUE(matches(
5061 "struct X { X() : i(42), j(42) {} int i, j; };",
5062 cxxConstructorDecl(forEachConstructorInitializer(cxxCtorInitializer()))));
5065 TEST(LambdaCapture, InvalidLambdaCapture) {
5066 // not crash
5067 EXPECT_FALSE(matches(
5068 R"(int main() {
5069 struct A { A()=default; A(A const&)=delete; };
5070 A a; [a]() -> void {}();
5071 return 0;
5072 })",
5073 traverse(TK_IgnoreUnlessSpelledInSource,
5074 lambdaExpr(has(lambdaCapture()))),
5075 langCxx11OrLater()));
5078 TEST(ForEachLambdaCapture, MatchesCaptures) {
5079 EXPECT_TRUE(matches(
5080 "int main() { int x, y; auto f = [x, y]() { return x + y; }; }",
5081 lambdaExpr(forEachLambdaCapture(lambdaCapture())), langCxx11OrLater()));
5082 auto matcher = lambdaExpr(forEachLambdaCapture(
5083 lambdaCapture(capturesVar(varDecl(hasType(isInteger())))).bind("LC")));
5084 EXPECT_TRUE(matchAndVerifyResultTrue(
5085 "int main() { int x, y; float z; auto f = [=]() { return x + y + z; }; }",
5086 matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 2)));
5087 EXPECT_TRUE(matchAndVerifyResultTrue(
5088 "int main() { int x, y; float z; auto f = [x, y, z]() { return x + y + "
5089 "z; }; }",
5090 matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 2)));
5093 TEST(ForEachLambdaCapture, IgnoreUnlessSpelledInSource) {
5094 auto matcher =
5095 traverse(TK_IgnoreUnlessSpelledInSource,
5096 lambdaExpr(forEachLambdaCapture(
5097 lambdaCapture(capturesVar(varDecl(hasType(isInteger()))))
5098 .bind("LC"))));
5099 EXPECT_TRUE(
5100 notMatches("int main() { int x, y; auto f = [=]() { return x + y; }; }",
5101 matcher, langCxx11OrLater()));
5102 EXPECT_TRUE(
5103 notMatches("int main() { int x, y; auto f = [&]() { return x + y; }; }",
5104 matcher, langCxx11OrLater()));
5105 EXPECT_TRUE(matchAndVerifyResultTrue(
5106 R"cc(
5107 int main() {
5108 int x, y;
5109 float z;
5110 auto f = [=, &y]() { return x + y + z; };
5112 )cc",
5113 matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 1)));
5116 TEST(ForEachLambdaCapture, MatchImplicitCapturesOnly) {
5117 auto matcher =
5118 lambdaExpr(forEachLambdaCapture(lambdaCapture(isImplicit()).bind("LC")));
5119 EXPECT_TRUE(matchAndVerifyResultTrue(
5120 "int main() { int x, y, z; auto f = [=, &z]() { return x + y + z; }; }",
5121 matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 2)));
5122 EXPECT_TRUE(matchAndVerifyResultTrue(
5123 "int main() { int x, y, z; auto f = [&, z]() { return x + y + z; }; }",
5124 matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 2)));
5127 TEST(ForEachLambdaCapture, MatchExplicitCapturesOnly) {
5128 auto matcher = lambdaExpr(
5129 forEachLambdaCapture(lambdaCapture(unless(isImplicit())).bind("LC")));
5130 EXPECT_TRUE(matchAndVerifyResultTrue(
5131 "int main() { int x, y, z; auto f = [=, &z]() { return x + y + z; }; }",
5132 matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 1)));
5133 EXPECT_TRUE(matchAndVerifyResultTrue(
5134 "int main() { int x, y, z; auto f = [&, z]() { return x + y + z; }; }",
5135 matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 1)));
5138 TEST(HasConditionVariableStatement, DoesNotMatchCondition) {
5139 EXPECT_TRUE(notMatches(
5140 "void x() { if(true) {} }",
5141 ifStmt(hasConditionVariableStatement(declStmt()))));
5142 EXPECT_TRUE(notMatches(
5143 "void x() { int x; if((x = 42)) {} }",
5144 ifStmt(hasConditionVariableStatement(declStmt()))));
5147 TEST(HasConditionVariableStatement, MatchesConditionVariables) {
5148 EXPECT_TRUE(matches(
5149 "void x() { if(int* a = 0) {} }",
5150 ifStmt(hasConditionVariableStatement(declStmt()))));
5153 TEST(ForEach, BindsOneNode) {
5154 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
5155 recordDecl(hasName("C"), forEach(fieldDecl(hasName("x")).bind("x"))),
5156 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("x", 1)));
5159 TEST(ForEach, BindsMultipleNodes) {
5160 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
5161 recordDecl(hasName("C"), forEach(fieldDecl().bind("f"))),
5162 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 3)));
5165 TEST(ForEach, BindsRecursiveCombinations) {
5166 EXPECT_TRUE(matchAndVerifyResultTrue(
5167 "class C { class D { int x; int y; }; class E { int y; int z; }; };",
5168 recordDecl(hasName("C"),
5169 forEach(recordDecl(forEach(fieldDecl().bind("f"))))),
5170 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 4)));
5173 TEST(ForEach, DoesNotIgnoreImplicit) {
5174 StringRef Code = R"cpp(
5175 void foo()
5177 int i = 0;
5178 int b = 4;
5179 i < b;
5181 )cpp";
5182 EXPECT_TRUE(matchAndVerifyResultFalse(
5183 Code, binaryOperator(forEach(declRefExpr().bind("dre"))),
5184 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 0)));
5186 EXPECT_TRUE(matchAndVerifyResultTrue(
5187 Code,
5188 binaryOperator(forEach(
5189 implicitCastExpr(hasSourceExpression(declRefExpr().bind("dre"))))),
5190 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 2)));
5192 EXPECT_TRUE(matchAndVerifyResultTrue(
5193 Code,
5194 binaryOperator(
5195 forEach(expr(ignoringImplicit(declRefExpr().bind("dre"))))),
5196 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 2)));
5198 EXPECT_TRUE(matchAndVerifyResultTrue(
5199 Code,
5200 traverse(TK_IgnoreUnlessSpelledInSource,
5201 binaryOperator(forEach(declRefExpr().bind("dre")))),
5202 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 2)));
5205 TEST(ForEachDescendant, BindsOneNode) {
5206 EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
5207 recordDecl(hasName("C"),
5208 forEachDescendant(fieldDecl(hasName("x")).bind("x"))),
5209 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("x", 1)));
5212 TEST(ForEachDescendant, NestedForEachDescendant) {
5213 DeclarationMatcher m = recordDecl(
5214 isDefinition(), decl().bind("x"), hasName("C"));
5215 EXPECT_TRUE(matchAndVerifyResultTrue(
5216 "class A { class B { class C {}; }; };",
5217 recordDecl(hasName("A"), anyOf(m, forEachDescendant(m))),
5218 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", "C")));
5220 // Check that a partial match of 'm' that binds 'x' in the
5221 // first part of anyOf(m, anything()) will not overwrite the
5222 // binding created by the earlier binding in the hasDescendant.
5223 EXPECT_TRUE(matchAndVerifyResultTrue(
5224 "class A { class B { class C {}; }; };",
5225 recordDecl(hasName("A"), allOf(hasDescendant(m), anyOf(m, anything()))),
5226 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", "C")));
5229 TEST(ForEachDescendant, BindsMultipleNodes) {
5230 EXPECT_TRUE(matchAndVerifyResultTrue(
5231 "class C { class D { int x; int y; }; "
5232 " class E { class F { int y; int z; }; }; };",
5233 recordDecl(hasName("C"), forEachDescendant(fieldDecl().bind("f"))),
5234 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 4)));
5237 TEST(ForEachDescendant, BindsRecursiveCombinations) {
5238 EXPECT_TRUE(matchAndVerifyResultTrue(
5239 "class C { class D { "
5240 " class E { class F { class G { int y; int z; }; }; }; }; };",
5241 recordDecl(hasName("C"), forEachDescendant(recordDecl(
5242 forEachDescendant(fieldDecl().bind("f"))))),
5243 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 8)));
5246 TEST(ForEachDescendant, BindsCombinations) {
5247 EXPECT_TRUE(matchAndVerifyResultTrue(
5248 "void f() { if(true) {} if (true) {} while (true) {} if (true) {} while "
5249 "(true) {} }",
5250 compoundStmt(forEachDescendant(ifStmt().bind("if")),
5251 forEachDescendant(whileStmt().bind("while"))),
5252 std::make_unique<VerifyIdIsBoundTo<IfStmt>>("if", 6)));
5255 TEST(ForEachTemplateArgument, OnFunctionDecl) {
5256 const std::string Code = R"(
5257 template <typename T, typename U> void f(T, U) {}
5258 void test() {
5259 int I = 1;
5260 bool B = false;
5261 f(I, B);
5262 })";
5263 EXPECT_TRUE(matches(
5264 Code, functionDecl(forEachTemplateArgument(refersToType(builtinType()))),
5265 langCxx11OrLater()));
5266 auto matcher =
5267 functionDecl(forEachTemplateArgument(
5268 templateArgument(refersToType(builtinType().bind("BT")))
5269 .bind("TA")))
5270 .bind("FN");
5272 EXPECT_TRUE(matchAndVerifyResultTrue(
5273 Code, matcher,
5274 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("FN", 2)));
5275 EXPECT_TRUE(matchAndVerifyResultTrue(
5276 Code, matcher,
5277 std::make_unique<VerifyIdIsBoundTo<TemplateArgument>>("TA", 2)));
5278 EXPECT_TRUE(matchAndVerifyResultTrue(
5279 Code, matcher,
5280 std::make_unique<VerifyIdIsBoundTo<BuiltinType>>("BT", 2)));
5283 TEST(ForEachTemplateArgument, OnClassTemplateSpecialization) {
5284 const std::string Code = R"(
5285 template <typename T, unsigned N, unsigned M>
5286 struct Matrix {};
5288 static constexpr unsigned R = 2;
5290 Matrix<int, R * 2, R * 4> M;
5292 EXPECT_TRUE(matches(
5293 Code, templateSpecializationType(forEachTemplateArgument(isExpr(expr()))),
5294 langCxx11OrLater()));
5295 auto matcher = templateSpecializationType(
5296 forEachTemplateArgument(
5297 templateArgument(isExpr(expr().bind("E"))).bind("TA")))
5298 .bind("TST");
5300 EXPECT_TRUE(matchAndVerifyResultTrue(
5301 Code, matcher,
5302 std::make_unique<VerifyIdIsBoundTo<TemplateSpecializationType>>("TST",
5303 2)));
5304 EXPECT_TRUE(matchAndVerifyResultTrue(
5305 Code, matcher,
5306 std::make_unique<VerifyIdIsBoundTo<TemplateArgument>>("TA", 2)));
5307 EXPECT_TRUE(matchAndVerifyResultTrue(
5308 Code, matcher, std::make_unique<VerifyIdIsBoundTo<Expr>>("E", 2)));
5311 TEST(Has, DoesNotDeleteBindings) {
5312 EXPECT_TRUE(matchAndVerifyResultTrue(
5313 "class X { int a; };", recordDecl(decl().bind("x"), has(fieldDecl())),
5314 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5317 TEST(TemplateArgumentLoc, Matches) {
5318 EXPECT_TRUE(matchAndVerifyResultTrue(
5319 R"cpp(
5320 template <typename A, int B, template <typename> class C> class X {};
5321 class A {};
5322 const int B = 42;
5323 template <typename> class C {};
5324 X<A, B, C> x;
5325 )cpp",
5326 templateArgumentLoc().bind("x"),
5327 std::make_unique<VerifyIdIsBoundTo<TemplateArgumentLoc>>("x", 3)));
5330 TEST(LoopingMatchers, DoNotOverwritePreviousMatchResultOnFailure) {
5331 // Those matchers cover all the cases where an inner matcher is called
5332 // and there is not a 1:1 relationship between the match of the outer
5333 // matcher and the match of the inner matcher.
5334 // The pattern to look for is:
5335 // ... return InnerMatcher.matches(...); ...
5336 // In which case no special handling is needed.
5338 // On the other hand, if there are multiple alternative matches
5339 // (for example forEach*) or matches might be discarded (for example has*)
5340 // the implementation must make sure that the discarded matches do not
5341 // affect the bindings.
5342 // When new such matchers are added, add a test here that:
5343 // - matches a simple node, and binds it as the first thing in the matcher:
5344 // recordDecl(decl().bind("x"), hasName("X")))
5345 // - uses the matcher under test afterwards in a way that not the first
5346 // alternative is matched; for anyOf, that means the first branch
5347 // would need to return false; for hasAncestor, it means that not
5348 // the direct parent matches the inner matcher.
5350 EXPECT_TRUE(matchAndVerifyResultTrue(
5351 "class X { int y; };",
5352 recordDecl(
5353 recordDecl().bind("x"), hasName("::X"),
5354 anyOf(forEachDescendant(recordDecl(hasName("Y"))), anything())),
5355 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("x", 1)));
5356 EXPECT_TRUE(matchAndVerifyResultTrue(
5357 "class X {};", recordDecl(recordDecl().bind("x"), hasName("::X"),
5358 anyOf(unless(anything()), anything())),
5359 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("x", 1)));
5360 EXPECT_TRUE(matchAndVerifyResultTrue(
5361 "template<typename T1, typename T2> class X {}; X<float, int> x;",
5362 classTemplateSpecializationDecl(
5363 decl().bind("x"),
5364 hasAnyTemplateArgument(refersToType(asString("int")))),
5365 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5366 EXPECT_TRUE(matchAndVerifyResultTrue(
5367 "class X { void f(); void g(); };",
5368 cxxRecordDecl(decl().bind("x"), hasMethod(hasName("g"))),
5369 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5370 EXPECT_TRUE(matchAndVerifyResultTrue(
5371 "class X { X() : a(1), b(2) {} double a; int b; };",
5372 recordDecl(decl().bind("x"),
5373 has(cxxConstructorDecl(
5374 hasAnyConstructorInitializer(forField(hasName("b")))))),
5375 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5376 EXPECT_TRUE(matchAndVerifyResultTrue(
5377 "void x(int, int) { x(0, 42); }",
5378 callExpr(expr().bind("x"), hasAnyArgument(integerLiteral(equals(42)))),
5379 std::make_unique<VerifyIdIsBoundTo<Expr>>("x", 1)));
5380 EXPECT_TRUE(matchAndVerifyResultTrue(
5381 "void x(int, int y) {}",
5382 functionDecl(decl().bind("x"), hasAnyParameter(hasName("y"))),
5383 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5384 EXPECT_TRUE(matchAndVerifyResultTrue(
5385 "void x() { return; if (true) {} }",
5386 functionDecl(decl().bind("x"),
5387 has(compoundStmt(hasAnySubstatement(ifStmt())))),
5388 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5389 EXPECT_TRUE(matchAndVerifyResultTrue(
5390 "namespace X { void b(int); void b(); }"
5391 "using X::b;",
5392 usingDecl(decl().bind("x"), hasAnyUsingShadowDecl(hasTargetDecl(
5393 functionDecl(parameterCountIs(1))))),
5394 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5395 EXPECT_TRUE(matchAndVerifyResultTrue(
5396 "class A{}; class B{}; class C : B, A {};",
5397 cxxRecordDecl(decl().bind("x"), isDerivedFrom("::A")),
5398 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5399 EXPECT_TRUE(matchAndVerifyResultTrue(
5400 "class A{}; typedef A B; typedef A C; typedef A D;"
5401 "class E : A {};",
5402 cxxRecordDecl(decl().bind("x"), isDerivedFrom("C")),
5403 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5404 EXPECT_TRUE(matchAndVerifyResultTrue(
5405 "class A { class B { void f() {} }; };",
5406 functionDecl(decl().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
5407 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5408 EXPECT_TRUE(matchAndVerifyResultTrue(
5409 "template <typename T> struct A { struct B {"
5410 " void f() { if(true) {} }"
5411 "}; };"
5412 "void t() { A<int>::B b; b.f(); }",
5413 ifStmt(stmt().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
5414 std::make_unique<VerifyIdIsBoundTo<Stmt>>("x", 2)));
5415 EXPECT_TRUE(matchAndVerifyResultTrue(
5416 "class A {};",
5417 recordDecl(hasName("::A"), decl().bind("x"), unless(hasName("fooble"))),
5418 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5419 EXPECT_TRUE(matchAndVerifyResultTrue(
5420 "class A { A() : s(), i(42) {} const char *s; int i; };",
5421 cxxConstructorDecl(hasName("::A::A"), decl().bind("x"),
5422 forEachConstructorInitializer(forField(hasName("i")))),
5423 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
5426 TEST(ForEachDescendant, BindsCorrectNodes) {
5427 EXPECT_TRUE(matchAndVerifyResultTrue(
5428 "class C { void f(); int i; };",
5429 recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
5430 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("decl", 1)));
5431 EXPECT_TRUE(matchAndVerifyResultTrue(
5432 "class C { void f() {} int i; };",
5433 recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
5434 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("decl", 1)));
5437 TEST(FindAll, BindsNodeOnMatch) {
5438 EXPECT_TRUE(matchAndVerifyResultTrue(
5439 "class A {};",
5440 recordDecl(hasName("::A"), findAll(recordDecl(hasName("::A")).bind("v"))),
5441 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("v", 1)));
5444 TEST(FindAll, BindsDescendantNodeOnMatch) {
5445 EXPECT_TRUE(matchAndVerifyResultTrue(
5446 "class A { int a; int b; };",
5447 recordDecl(hasName("::A"), findAll(fieldDecl().bind("v"))),
5448 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 2)));
5451 TEST(FindAll, BindsNodeAndDescendantNodesOnOneMatch) {
5452 EXPECT_TRUE(matchAndVerifyResultTrue(
5453 "class A { int a; int b; };",
5454 recordDecl(hasName("::A"),
5455 findAll(decl(anyOf(recordDecl(hasName("::A")).bind("v"),
5456 fieldDecl().bind("v"))))),
5457 std::make_unique<VerifyIdIsBoundTo<Decl>>("v", 3)));
5459 EXPECT_TRUE(matchAndVerifyResultTrue(
5460 "class A { class B {}; class C {}; };",
5461 recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("v"))),
5462 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("v", 3)));
5465 TEST(HasAncenstor, MatchesDeclarationAncestors) {
5466 EXPECT_TRUE(matches(
5467 "class A { class B { class C {}; }; };",
5468 recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("A"))))));
5471 TEST(HasAncenstor, FailsIfNoAncestorMatches) {
5472 EXPECT_TRUE(notMatches(
5473 "class A { class B { class C {}; }; };",
5474 recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("X"))))));
5477 TEST(HasAncestor, MatchesDeclarationsThatGetVisitedLater) {
5478 EXPECT_TRUE(matches(
5479 "class A { class B { void f() { C c; } class C {}; }; };",
5480 varDecl(hasName("c"), hasType(recordDecl(hasName("C"),
5481 hasAncestor(recordDecl(hasName("A"))))))));
5484 TEST(HasAncenstor, MatchesStatementAncestors) {
5485 EXPECT_TRUE(matches(
5486 "void f() { if (true) { while (false) { 42; } } }",
5487 integerLiteral(equals(42), hasAncestor(ifStmt()))));
5490 TEST(HasAncestor, DrillsThroughDifferentHierarchies) {
5491 EXPECT_TRUE(matches(
5492 "void f() { if (true) { int x = 42; } }",
5493 integerLiteral(equals(42), hasAncestor(functionDecl(hasName("f"))))));
5496 TEST(HasAncestor, BindsRecursiveCombinations) {
5497 EXPECT_TRUE(matchAndVerifyResultTrue(
5498 "class C { class D { class E { class F { int y; }; }; }; };",
5499 fieldDecl(hasAncestor(recordDecl(hasAncestor(recordDecl().bind("r"))))),
5500 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("r", 1)));
5503 TEST(HasAncestor, BindsCombinationsWithHasDescendant) {
5504 EXPECT_TRUE(matchAndVerifyResultTrue(
5505 "class C { class D { class E { class F { int y; }; }; }; };",
5506 fieldDecl(hasAncestor(
5507 decl(
5508 hasDescendant(recordDecl(isDefinition(),
5509 hasAncestor(recordDecl())))
5510 ).bind("d")
5512 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("d", "E")));
5515 TEST(HasAncestor, MatchesClosestAncestor) {
5516 EXPECT_TRUE(matchAndVerifyResultTrue(
5517 "template <typename T> struct C {"
5518 " void f(int) {"
5519 " struct I { void g(T) { int x; } } i; i.g(42);"
5520 " }"
5521 "};"
5522 "template struct C<int>;",
5523 varDecl(hasName("x"),
5524 hasAncestor(functionDecl(hasParameter(
5525 0, varDecl(hasType(asString("int"))))).bind("f"))).bind("v"),
5526 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("f", "g", 2)));
5529 TEST(HasAncestor, MatchesInTemplateInstantiations) {
5530 EXPECT_TRUE(matches(
5531 "template <typename T> struct A { struct B { struct C { T t; }; }; }; "
5532 "A<int>::B::C a;",
5533 fieldDecl(hasType(asString("int")),
5534 hasAncestor(recordDecl(hasName("A"))))));
5537 TEST(HasAncestor, MatchesInImplicitCode) {
5538 EXPECT_TRUE(matches(
5539 "struct X {}; struct A { A() {} X x; };",
5540 cxxConstructorDecl(
5541 hasAnyConstructorInitializer(withInitializer(expr(
5542 hasAncestor(recordDecl(hasName("A")))))))));
5545 TEST(HasParent, MatchesOnlyParent) {
5546 EXPECT_TRUE(matches(
5547 "void f() { if (true) { int x = 42; } }",
5548 compoundStmt(hasParent(ifStmt()))));
5549 EXPECT_TRUE(notMatches(
5550 "void f() { for (;;) { int x = 42; } }",
5551 compoundStmt(hasParent(ifStmt()))));
5552 EXPECT_TRUE(notMatches(
5553 "void f() { if (true) for (;;) { int x = 42; } }",
5554 compoundStmt(hasParent(ifStmt()))));
5557 TEST(MatcherMemoize, HasParentDiffersFromHas) {
5558 // Test introduced after detecting a bug in memoization
5559 constexpr auto code = "void f() { throw 1; }";
5560 EXPECT_TRUE(notMatches(
5561 code,
5562 cxxThrowExpr(hasParent(expr()))));
5563 EXPECT_TRUE(matches(
5564 code,
5565 cxxThrowExpr(has(expr()))));
5566 EXPECT_TRUE(matches(
5567 code,
5568 cxxThrowExpr(anyOf(hasParent(expr()), has(expr())))));
5571 TEST(MatcherMemoize, HasDiffersFromHasDescendant) {
5572 // Test introduced after detecting a bug in memoization
5573 constexpr auto code = "void f() { throw 1+1; }";
5574 EXPECT_TRUE(notMatches(
5575 code,
5576 cxxThrowExpr(has(integerLiteral()))));
5577 EXPECT_TRUE(matches(
5578 code,
5579 cxxThrowExpr(hasDescendant(integerLiteral()))));
5580 EXPECT_TRUE(
5581 notMatches(code, cxxThrowExpr(allOf(hasDescendant(integerLiteral()),
5582 has(integerLiteral())))));
5584 TEST(HasAncestor, MatchesAllAncestors) {
5585 EXPECT_TRUE(matches(
5586 "template <typename T> struct C { static void f() { 42; } };"
5587 "void t() { C<int>::f(); }",
5588 integerLiteral(
5589 equals(42),
5590 allOf(
5591 hasAncestor(cxxRecordDecl(isTemplateInstantiation())),
5592 hasAncestor(cxxRecordDecl(unless(isTemplateInstantiation())))))));
5595 TEST(HasAncestor, ImplicitArrayCopyCtorDeclRefExpr) {
5596 EXPECT_TRUE(matches("struct MyClass {\n"
5597 " int c[1];\n"
5598 " static MyClass Create() { return MyClass(); }\n"
5599 "};",
5600 declRefExpr(to(decl(hasAncestor(decl()))))));
5603 TEST(HasAncestor, AnonymousUnionMemberExpr) {
5604 EXPECT_TRUE(matches("int F() {\n"
5605 " union { int i; };\n"
5606 " return i;\n"
5607 "}\n",
5608 memberExpr(member(hasAncestor(decl())))));
5609 EXPECT_TRUE(matches("void f() {\n"
5610 " struct {\n"
5611 " struct { int a; int b; };\n"
5612 " } s;\n"
5613 " s.a = 4;\n"
5614 "}\n",
5615 memberExpr(member(hasAncestor(decl())))));
5616 EXPECT_TRUE(matches("void f() {\n"
5617 " struct {\n"
5618 " struct { int a; int b; };\n"
5619 " } s;\n"
5620 " s.a = 4;\n"
5621 "}\n",
5622 declRefExpr(to(decl(hasAncestor(decl()))))));
5624 TEST(HasAncestor, NonParmDependentTemplateParmVarDeclRefExpr) {
5625 EXPECT_TRUE(matches("struct PartitionAllocator {\n"
5626 " template<typename T>\n"
5627 " static int quantizedSize(int count) {\n"
5628 " return count;\n"
5629 " }\n"
5630 " void f() { quantizedSize<int>(10); }\n"
5631 "};",
5632 declRefExpr(to(decl(hasAncestor(decl()))))));
5635 TEST(HasAncestor, AddressOfExplicitSpecializationFunction) {
5636 EXPECT_TRUE(matches("template <class T> void f();\n"
5637 "template <> void f<int>();\n"
5638 "void (*get_f())() { return f<int>; }\n",
5639 declRefExpr(to(decl(hasAncestor(decl()))))));
5642 TEST(HasParent, MatchesAllParents) {
5643 EXPECT_TRUE(matches(
5644 "template <typename T> struct C { static void f() { 42; } };"
5645 "void t() { C<int>::f(); }",
5646 integerLiteral(
5647 equals(42),
5648 hasParent(compoundStmt(hasParent(functionDecl(
5649 hasParent(cxxRecordDecl(isTemplateInstantiation())))))))));
5650 EXPECT_TRUE(
5651 matches("template <typename T> struct C { static void f() { 42; } };"
5652 "void t() { C<int>::f(); }",
5653 integerLiteral(
5654 equals(42),
5655 hasParent(compoundStmt(hasParent(functionDecl(hasParent(
5656 cxxRecordDecl(unless(isTemplateInstantiation()))))))))));
5657 EXPECT_TRUE(matches(
5658 "template <typename T> struct C { static void f() { 42; } };"
5659 "void t() { C<int>::f(); }",
5660 integerLiteral(equals(42),
5661 hasParent(compoundStmt(
5662 allOf(hasParent(functionDecl(hasParent(
5663 cxxRecordDecl(isTemplateInstantiation())))),
5664 hasParent(functionDecl(hasParent(cxxRecordDecl(
5665 unless(isTemplateInstantiation())))))))))));
5666 EXPECT_TRUE(
5667 notMatches("template <typename T> struct C { static void f() {} };"
5668 "void t() { C<int>::f(); }",
5669 compoundStmt(hasParent(recordDecl()))));
5672 TEST(HasParent, NoDuplicateParents) {
5673 class HasDuplicateParents : public BoundNodesCallback {
5674 public:
5675 bool run(const BoundNodes *Nodes, ASTContext *Context) override {
5676 const Stmt *Node = Nodes->getNodeAs<Stmt>("node");
5677 std::set<const void *> Parents;
5678 for (const auto &Parent : Context->getParents(*Node)) {
5679 if (!Parents.insert(Parent.getMemoizationData()).second) {
5680 return true;
5683 return false;
5686 EXPECT_FALSE(matchAndVerifyResultTrue(
5687 "template <typename T> int Foo() { return 1 + 2; }\n"
5688 "int x = Foo<int>() + Foo<unsigned>();",
5689 stmt().bind("node"), std::make_unique<HasDuplicateParents>()));
5692 TEST(HasAnyBase, BindsInnerBoundNodes) {
5693 EXPECT_TRUE(matchAndVerifyResultTrue(
5694 "struct Inner {}; struct Proxy : Inner {}; struct Main : public "
5695 "Proxy {};",
5696 cxxRecordDecl(hasName("Main"),
5697 hasAnyBase(cxxBaseSpecifier(hasType(
5698 cxxRecordDecl(hasName("Inner")).bind("base-class")))))
5699 .bind("class"),
5700 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("base-class",
5701 "Inner")));
5704 TEST(TypeMatching, PointeeTypes) {
5705 EXPECT_TRUE(matches("int b; int &a = b;",
5706 referenceType(pointee(builtinType()))));
5707 EXPECT_TRUE(matches("int *a;", pointerType(pointee(builtinType()))));
5709 EXPECT_TRUE(matches("int *a;",
5710 loc(pointerType(pointee(builtinType())))));
5712 EXPECT_TRUE(matches(
5713 "int const *A;",
5714 pointerType(pointee(isConstQualified(), builtinType()))));
5715 EXPECT_TRUE(notMatches(
5716 "int *A;",
5717 pointerType(pointee(isConstQualified(), builtinType()))));
5720 TEST(ElaboratedTypeNarrowing, hasQualifier) {
5721 EXPECT_TRUE(matches(
5722 "namespace N {"
5723 " namespace M {"
5724 " class D {};"
5725 " }"
5727 "N::M::D d;",
5728 elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
5729 EXPECT_TRUE(notMatches(
5730 "namespace M {"
5731 " class D {};"
5733 "M::D d;",
5734 elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
5735 EXPECT_TRUE(notMatches(
5736 "struct D {"
5737 "} d;",
5738 elaboratedType(hasQualifier(nestedNameSpecifier()))));
5741 TEST(ElaboratedTypeNarrowing, namesType) {
5742 EXPECT_TRUE(matches(
5743 "namespace N {"
5744 " namespace M {"
5745 " class D {};"
5746 " }"
5748 "N::M::D d;",
5749 elaboratedType(elaboratedType(namesType(recordType(
5750 hasDeclaration(namedDecl(hasName("D")))))))));
5751 EXPECT_TRUE(notMatches(
5752 "namespace M {"
5753 " class D {};"
5755 "M::D d;",
5756 elaboratedType(elaboratedType(namesType(typedefType())))));
5759 TEST(NNS, BindsNestedNameSpecifiers) {
5760 EXPECT_TRUE(matchAndVerifyResultTrue(
5761 "namespace ns { struct E { struct B {}; }; } ns::E::B b;",
5762 nestedNameSpecifier(specifiesType(asString("struct ns::E"))).bind("nns"),
5763 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>(
5764 "nns", "ns::struct E::")));
5767 TEST(NNS, BindsNestedNameSpecifierLocs) {
5768 EXPECT_TRUE(matchAndVerifyResultTrue(
5769 "namespace ns { struct B {}; } ns::B b;",
5770 loc(nestedNameSpecifier()).bind("loc"),
5771 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifierLoc>>("loc", 1)));
5774 TEST(NNS, DescendantsOfNestedNameSpecifiers) {
5775 StringRef Fragment =
5776 "namespace a { struct A { struct B { struct C {}; }; }; };"
5777 "void f() { a::A::B::C c; }";
5778 EXPECT_TRUE(matches(
5779 Fragment,
5780 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
5781 hasDescendant(nestedNameSpecifier(
5782 specifiesNamespace(hasName("a")))))));
5783 EXPECT_TRUE(notMatches(
5784 Fragment,
5785 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
5786 has(nestedNameSpecifier(
5787 specifiesNamespace(hasName("a")))))));
5788 EXPECT_TRUE(matches(
5789 Fragment,
5790 nestedNameSpecifier(specifiesType(asString("struct a::A")),
5791 has(nestedNameSpecifier(
5792 specifiesNamespace(hasName("a")))))));
5794 // Not really useful because a NestedNameSpecifier can af at most one child,
5795 // but to complete the interface.
5796 EXPECT_TRUE(matchAndVerifyResultTrue(
5797 Fragment,
5798 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
5799 forEach(nestedNameSpecifier().bind("x"))),
5800 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>("x", 1)));
5803 TEST(NNS, NestedNameSpecifiersAsDescendants) {
5804 StringRef Fragment =
5805 "namespace a { struct A { struct B { struct C {}; }; }; };"
5806 "void f() { a::A::B::C c; }";
5807 EXPECT_TRUE(matches(
5808 Fragment,
5809 decl(hasDescendant(nestedNameSpecifier(specifiesType(
5810 asString("struct a::A")))))));
5811 EXPECT_TRUE(matchAndVerifyResultTrue(
5812 Fragment,
5813 functionDecl(hasName("f"),
5814 forEachDescendant(nestedNameSpecifier().bind("x"))),
5815 // Nested names: a, a::A and a::A::B.
5816 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>("x", 3)));
5819 TEST(NNSLoc, DescendantsOfNestedNameSpecifierLocs) {
5820 StringRef Fragment =
5821 "namespace a { struct A { struct B { struct C {}; }; }; };"
5822 "void f() { a::A::B::C c; }";
5823 EXPECT_TRUE(matches(
5824 Fragment,
5825 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5826 hasDescendant(loc(nestedNameSpecifier(
5827 specifiesNamespace(hasName("a"))))))));
5828 EXPECT_TRUE(notMatches(
5829 Fragment,
5830 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5831 has(loc(nestedNameSpecifier(
5832 specifiesNamespace(hasName("a"))))))));
5833 EXPECT_TRUE(matches(
5834 Fragment,
5835 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A"))),
5836 has(loc(nestedNameSpecifier(
5837 specifiesNamespace(hasName("a"))))))));
5839 EXPECT_TRUE(matchAndVerifyResultTrue(
5840 Fragment,
5841 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5842 forEach(nestedNameSpecifierLoc().bind("x"))),
5843 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifierLoc>>("x", 1)));
5846 TEST(NNSLoc, NestedNameSpecifierLocsAsDescendants) {
5847 StringRef Fragment =
5848 "namespace a { struct A { struct B { struct C {}; }; }; };"
5849 "void f() { a::A::B::C c; }";
5850 EXPECT_TRUE(matches(
5851 Fragment,
5852 decl(hasDescendant(loc(nestedNameSpecifier(specifiesType(
5853 asString("struct a::A"))))))));
5854 EXPECT_TRUE(matchAndVerifyResultTrue(
5855 Fragment,
5856 functionDecl(hasName("f"),
5857 forEachDescendant(nestedNameSpecifierLoc().bind("x"))),
5858 // Nested names: a, a::A and a::A::B.
5859 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifierLoc>>("x", 3)));
5862 TEST(Attr, AttrsAsDescendants) {
5863 StringRef Fragment = "namespace a { struct [[clang::warn_unused_result]] "
5864 "F{}; [[noreturn]] void foo(); }";
5865 EXPECT_TRUE(matches(Fragment, namespaceDecl(hasDescendant(attr()))));
5866 EXPECT_TRUE(matchAndVerifyResultTrue(
5867 Fragment,
5868 namespaceDecl(hasName("a"),
5869 forEachDescendant(attr(unless(isImplicit())).bind("x"))),
5870 std::make_unique<VerifyIdIsBoundTo<Attr>>("x", 2)));
5873 TEST(Attr, ParentsOfAttrs) {
5874 StringRef Fragment =
5875 "namespace a { struct [[clang::warn_unused_result]] F{}; }";
5876 EXPECT_TRUE(matches(Fragment, attr(hasAncestor(namespaceDecl()))));
5879 template <typename T> class VerifyMatchOnNode : public BoundNodesCallback {
5880 public:
5881 VerifyMatchOnNode(StringRef Id, const internal::Matcher<T> &InnerMatcher,
5882 StringRef InnerId)
5883 : Id(Id), InnerMatcher(InnerMatcher), InnerId(InnerId) {}
5885 bool run(const BoundNodes *Nodes, ASTContext *Context) override {
5886 const T *Node = Nodes->getNodeAs<T>(Id);
5887 return selectFirst<T>(InnerId, match(InnerMatcher, *Node, *Context)) !=
5888 nullptr;
5891 private:
5892 std::string Id;
5893 internal::Matcher<T> InnerMatcher;
5894 std::string InnerId;
5897 TEST(MatchFinder, CanMatchDeclarationsRecursively) {
5898 EXPECT_TRUE(matchAndVerifyResultTrue(
5899 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5900 std::make_unique<VerifyMatchOnNode<Decl>>(
5901 "X", decl(hasDescendant(recordDecl(hasName("X::Y")).bind("Y"))),
5902 "Y")));
5903 EXPECT_TRUE(matchAndVerifyResultFalse(
5904 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5905 std::make_unique<VerifyMatchOnNode<Decl>>(
5906 "X", decl(hasDescendant(recordDecl(hasName("X::Z")).bind("Z"))),
5907 "Z")));
5910 TEST(MatchFinder, CanMatchStatementsRecursively) {
5911 EXPECT_TRUE(matchAndVerifyResultTrue(
5912 "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
5913 std::make_unique<VerifyMatchOnNode<Stmt>>(
5914 "if", stmt(hasDescendant(forStmt().bind("for"))), "for")));
5915 EXPECT_TRUE(matchAndVerifyResultFalse(
5916 "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
5917 std::make_unique<VerifyMatchOnNode<Stmt>>(
5918 "if", stmt(hasDescendant(declStmt().bind("decl"))), "decl")));
5921 TEST(MatchFinder, CanMatchSingleNodesRecursively) {
5922 EXPECT_TRUE(matchAndVerifyResultTrue(
5923 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5924 std::make_unique<VerifyMatchOnNode<Decl>>(
5925 "X", recordDecl(has(recordDecl(hasName("X::Y")).bind("Y"))), "Y")));
5926 EXPECT_TRUE(matchAndVerifyResultFalse(
5927 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5928 std::make_unique<VerifyMatchOnNode<Decl>>(
5929 "X", recordDecl(has(recordDecl(hasName("X::Z")).bind("Z"))), "Z")));
5932 TEST(StatementMatcher, HasReturnValue) {
5933 StatementMatcher RetVal = returnStmt(hasReturnValue(binaryOperator()));
5934 EXPECT_TRUE(matches("int F() { int a, b; return a + b; }", RetVal));
5935 EXPECT_FALSE(matches("int F() { int a; return a; }", RetVal));
5936 EXPECT_FALSE(matches("void F() { return; }", RetVal));
5939 TEST(StatementMatcher, ForFunction) {
5940 StringRef CppString1 = "struct PosVec {"
5941 " PosVec& operator=(const PosVec&) {"
5942 " auto x = [] { return 1; };"
5943 " return *this;"
5944 " }"
5945 "};";
5946 StringRef CppString2 = "void F() {"
5947 " struct S {"
5948 " void F2() {"
5949 " return;"
5950 " }"
5951 " };"
5952 "}";
5953 EXPECT_TRUE(
5954 matches(
5955 CppString1,
5956 returnStmt(forFunction(hasName("operator=")),
5957 has(unaryOperator(hasOperatorName("*"))))));
5958 EXPECT_TRUE(
5959 notMatches(
5960 CppString1,
5961 returnStmt(forFunction(hasName("operator=")),
5962 has(integerLiteral()))));
5963 EXPECT_TRUE(
5964 matches(
5965 CppString1,
5966 returnStmt(forFunction(hasName("operator()")),
5967 has(integerLiteral()))));
5968 EXPECT_TRUE(matches(CppString2, returnStmt(forFunction(hasName("F2")))));
5969 EXPECT_TRUE(notMatches(CppString2, returnStmt(forFunction(hasName("F")))));
5972 TEST(StatementMatcher, ForCallable) {
5973 // These tests are copied over from the forFunction() test above.
5974 StringRef CppString1 = "struct PosVec {"
5975 " PosVec& operator=(const PosVec&) {"
5976 " auto x = [] { return 1; };"
5977 " return *this;"
5978 " }"
5979 "};";
5980 StringRef CppString2 = "void F() {"
5981 " struct S {"
5982 " void F2() {"
5983 " return;"
5984 " }"
5985 " };"
5986 "}";
5988 EXPECT_TRUE(
5989 matches(
5990 CppString1,
5991 returnStmt(forCallable(functionDecl(hasName("operator="))),
5992 has(unaryOperator(hasOperatorName("*"))))));
5993 EXPECT_TRUE(
5994 notMatches(
5995 CppString1,
5996 returnStmt(forCallable(functionDecl(hasName("operator="))),
5997 has(integerLiteral()))));
5998 EXPECT_TRUE(
5999 matches(
6000 CppString1,
6001 returnStmt(forCallable(functionDecl(hasName("operator()"))),
6002 has(integerLiteral()))));
6003 EXPECT_TRUE(matches(CppString2,
6004 returnStmt(forCallable(functionDecl(hasName("F2"))))));
6005 EXPECT_TRUE(notMatches(CppString2,
6006 returnStmt(forCallable(functionDecl(hasName("F"))))));
6008 StringRef CodeWithDeepCallExpr = R"cpp(
6009 void Other();
6010 void Function() {
6013 Other()
6017 )cpp";
6018 auto ForCallableFirst =
6019 callExpr(forCallable(functionDecl(hasName("Function"))),
6020 callee(functionDecl(hasName("Other")).bind("callee")))
6021 .bind("call");
6022 auto ForCallableSecond =
6023 callExpr(callee(functionDecl(hasName("Other")).bind("callee")),
6024 forCallable(functionDecl(hasName("Function"))))
6025 .bind("call");
6026 EXPECT_TRUE(matchAndVerifyResultTrue(
6027 CodeWithDeepCallExpr, ForCallableFirst,
6028 std::make_unique<VerifyIdIsBoundTo<CallExpr>>("call")));
6029 EXPECT_TRUE(matchAndVerifyResultTrue(
6030 CodeWithDeepCallExpr, ForCallableFirst,
6031 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("callee")));
6032 EXPECT_TRUE(matchAndVerifyResultTrue(
6033 CodeWithDeepCallExpr, ForCallableSecond,
6034 std::make_unique<VerifyIdIsBoundTo<CallExpr>>("call")));
6035 EXPECT_TRUE(matchAndVerifyResultTrue(
6036 CodeWithDeepCallExpr, ForCallableSecond,
6037 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("callee")));
6039 // These tests are specific to forCallable().
6040 StringRef ObjCString1 = "@interface I"
6041 "-(void) foo;"
6042 "@end"
6043 "@implementation I"
6044 "-(void) foo {"
6045 " void (^block)() = ^{ 0x2b | ~0x2b; };"
6047 "@end";
6049 EXPECT_TRUE(
6050 matchesObjC(
6051 ObjCString1,
6052 binaryOperator(forCallable(blockDecl()))));
6054 EXPECT_TRUE(
6055 notMatchesObjC(
6056 ObjCString1,
6057 binaryOperator(forCallable(objcMethodDecl()))));
6059 StringRef ObjCString2 = "@interface I"
6060 "-(void) foo;"
6061 "@end"
6062 "@implementation I"
6063 "-(void) foo {"
6064 " 0x2b | ~0x2b;"
6065 " void (^block)() = ^{};"
6067 "@end";
6069 EXPECT_TRUE(
6070 matchesObjC(
6071 ObjCString2,
6072 binaryOperator(forCallable(objcMethodDecl()))));
6074 EXPECT_TRUE(
6075 notMatchesObjC(
6076 ObjCString2,
6077 binaryOperator(forCallable(blockDecl()))));
6080 namespace {
6081 class ForCallablePreservesBindingWithMultipleParentsTestCallback
6082 : public BoundNodesCallback {
6083 public:
6084 bool run(const BoundNodes *BoundNodes, ASTContext *Context) override {
6085 FunctionDecl const *FunDecl =
6086 BoundNodes->getNodeAs<FunctionDecl>("funDecl");
6087 // Validate test assumptions. This would be expressed as ASSERT_* in
6088 // a TEST().
6089 if (!FunDecl) {
6090 EXPECT_TRUE(false && "Incorrect test setup");
6091 return false;
6093 auto const *FunDef = FunDecl->getDefinition();
6094 if (!FunDef || !FunDef->getBody() ||
6095 FunDef->getNameAsString() != "Function") {
6096 EXPECT_TRUE(false && "Incorrect test setup");
6097 return false;
6100 ExpectCorrectResult(
6101 "Baseline",
6102 callExpr(callee(cxxMethodDecl().bind("callee"))).bind("call"), //
6103 FunDecl);
6105 ExpectCorrectResult("ForCallable first",
6106 callExpr(forCallable(equalsNode(FunDecl)),
6107 callee(cxxMethodDecl().bind("callee")))
6108 .bind("call"),
6109 FunDecl);
6111 ExpectCorrectResult("ForCallable second",
6112 callExpr(callee(cxxMethodDecl().bind("callee")),
6113 forCallable(equalsNode(FunDecl)))
6114 .bind("call"),
6115 FunDecl);
6117 // This value does not really matter: the EXPECT_* will set the exit code.
6118 return true;
6121 private:
6122 void ExpectCorrectResult(StringRef LogInfo,
6123 ArrayRef<BoundNodes> Results) const {
6124 EXPECT_EQ(Results.size(), 1u) << LogInfo;
6125 if (Results.empty())
6126 return;
6127 auto const &R = Results.front();
6128 EXPECT_TRUE(R.getNodeAs<CallExpr>("call")) << LogInfo;
6129 EXPECT_TRUE(R.getNodeAs<CXXMethodDecl>("callee")) << LogInfo;
6132 template <typename MatcherT>
6133 void ExpectCorrectResult(StringRef LogInfo, MatcherT Matcher,
6134 FunctionDecl const *FunDef) const {
6135 auto &Context = FunDef->getASTContext();
6136 auto const &Results = match(findAll(Matcher), *FunDef->getBody(), Context);
6137 ExpectCorrectResult(LogInfo, Results);
6140 } // namespace
6142 TEST(StatementMatcher, ForCallablePreservesBindingWithMultipleParents) {
6143 // Tests in this file are fairly simple and therefore can rely on matches,
6144 // matchAndVerifyResultTrue, etc. This test, however, needs a FunctionDecl* in
6145 // order to call equalsNode in order to reproduce the observed issue (bindings
6146 // being removed despite forCallable matching the node).
6148 // Because of this and because the machinery to compile the code into an
6149 // ASTUnit is not exposed outside matchAndVerifyResultConditionally, it is
6150 // cheaper to have a custom BoundNodesCallback for the purpose of this test.
6151 StringRef codeWithTemplateFunction = R"cpp(
6152 struct Klass {
6153 void Method();
6154 template <typename T>
6155 void Function(T t); // Declaration
6158 void Instantiate(Klass k) {
6159 k.Function(0);
6162 template <typename T>
6163 void Klass::Function(T t) { // Definition
6164 // Compound statement has two parents: the declaration and the definition.
6165 Method();
6167 )cpp";
6168 EXPECT_TRUE(matchAndVerifyResultTrue(
6169 codeWithTemplateFunction,
6170 callExpr(callee(functionDecl(hasName("Function")).bind("funDecl"))),
6171 std::make_unique<
6172 ForCallablePreservesBindingWithMultipleParentsTestCallback>()));
6175 TEST(Matcher, ForEachOverriden) {
6176 const auto ForEachOverriddenInClass = [](const char *ClassName) {
6177 return cxxMethodDecl(ofClass(hasName(ClassName)), isVirtual(),
6178 forEachOverridden(cxxMethodDecl().bind("overridden")))
6179 .bind("override");
6181 static const char Code1[] = "class A { virtual void f(); };"
6182 "class B : public A { void f(); };"
6183 "class C : public B { void f(); };";
6184 // C::f overrides A::f.
6185 EXPECT_TRUE(matchAndVerifyResultTrue(
6186 Code1, ForEachOverriddenInClass("C"),
6187 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("override", "f", 1)));
6188 EXPECT_TRUE(matchAndVerifyResultTrue(
6189 Code1, ForEachOverriddenInClass("C"),
6190 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("overridden", "f",
6191 1)));
6192 // B::f overrides A::f.
6193 EXPECT_TRUE(matchAndVerifyResultTrue(
6194 Code1, ForEachOverriddenInClass("B"),
6195 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("override", "f", 1)));
6196 EXPECT_TRUE(matchAndVerifyResultTrue(
6197 Code1, ForEachOverriddenInClass("B"),
6198 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("overridden", "f",
6199 1)));
6200 // A::f overrides nothing.
6201 EXPECT_TRUE(notMatches(Code1, ForEachOverriddenInClass("A")));
6203 static const char Code2[] =
6204 "class A1 { virtual void f(); };"
6205 "class A2 { virtual void f(); };"
6206 "class B : public A1, public A2 { void f(); };";
6207 // B::f overrides A1::f and A2::f. This produces two matches.
6208 EXPECT_TRUE(matchAndVerifyResultTrue(
6209 Code2, ForEachOverriddenInClass("B"),
6210 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("override", "f", 2)));
6211 EXPECT_TRUE(matchAndVerifyResultTrue(
6212 Code2, ForEachOverriddenInClass("B"),
6213 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("overridden", "f",
6214 2)));
6215 // A1::f overrides nothing.
6216 EXPECT_TRUE(notMatches(Code2, ForEachOverriddenInClass("A1")));
6219 TEST(Matcher, HasAnyDeclaration) {
6220 StringRef Fragment = "void foo(int p1);"
6221 "void foo(int *p2);"
6222 "void bar(int p3);"
6223 "template <typename T> void baz(T t) { foo(t); }";
6225 EXPECT_TRUE(
6226 matches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(functionDecl(
6227 hasParameter(0, parmVarDecl(hasName("p1"))))))));
6228 EXPECT_TRUE(
6229 matches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(functionDecl(
6230 hasParameter(0, parmVarDecl(hasName("p2"))))))));
6231 EXPECT_TRUE(
6232 notMatches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(functionDecl(
6233 hasParameter(0, parmVarDecl(hasName("p3"))))))));
6234 EXPECT_TRUE(notMatches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(
6235 functionDecl(hasName("bar"))))));
6238 TEST(SubstTemplateTypeParmType, HasReplacementType) {
6239 StringRef Fragment = "template<typename T>"
6240 "double F(T t);"
6241 "int i;"
6242 "double j = F(i);";
6243 EXPECT_TRUE(matches(Fragment, substTemplateTypeParmType(hasReplacementType(
6244 qualType(asString("int"))))));
6245 EXPECT_TRUE(notMatches(Fragment, substTemplateTypeParmType(hasReplacementType(
6246 qualType(asString("double"))))));
6247 EXPECT_TRUE(
6248 notMatches("template<int N>"
6249 "double F();"
6250 "double j = F<5>();",
6251 substTemplateTypeParmType(hasReplacementType(qualType()))));
6254 TEST(ClassTemplateSpecializationDecl, HasSpecializedTemplate) {
6255 auto Matcher = classTemplateSpecializationDecl(
6256 hasSpecializedTemplate(classTemplateDecl()));
6257 EXPECT_TRUE(
6258 matches("template<typename T> class A {}; typedef A<int> B;", Matcher));
6259 EXPECT_TRUE(notMatches("template<typename T> class A {};", Matcher));
6262 TEST(CXXNewExpr, Array) {
6263 StatementMatcher NewArray = cxxNewExpr(isArray());
6265 EXPECT_TRUE(matches("void foo() { int *Ptr = new int[10]; }", NewArray));
6266 EXPECT_TRUE(notMatches("void foo() { int *Ptr = new int; }", NewArray));
6268 StatementMatcher NewArraySize10 =
6269 cxxNewExpr(hasArraySize(integerLiteral(equals(10))));
6270 EXPECT_TRUE(
6271 matches("void foo() { int *Ptr = new int[10]; }", NewArraySize10));
6272 EXPECT_TRUE(
6273 notMatches("void foo() { int *Ptr = new int[20]; }", NewArraySize10));
6276 TEST(CXXNewExpr, PlacementArgs) {
6277 StatementMatcher IsPlacementNew = cxxNewExpr(hasAnyPlacementArg(anything()));
6279 EXPECT_TRUE(matches(R"(
6280 void* operator new(decltype(sizeof(void*)), void*);
6281 int *foo(void* Storage) {
6282 return new (Storage) int;
6283 })",
6284 IsPlacementNew));
6286 EXPECT_TRUE(matches(R"(
6287 void* operator new(decltype(sizeof(void*)), void*, unsigned);
6288 int *foo(void* Storage) {
6289 return new (Storage, 16) int;
6290 })",
6291 cxxNewExpr(hasPlacementArg(
6292 1, ignoringImpCasts(integerLiteral(equals(16)))))));
6294 EXPECT_TRUE(notMatches(R"(
6295 void* operator new(decltype(sizeof(void*)), void*);
6296 int *foo(void* Storage) {
6297 return new int;
6298 })",
6299 IsPlacementNew));
6302 TEST(HasUnqualifiedLoc, BindsToConstIntVarDecl) {
6303 EXPECT_TRUE(matches(
6304 "const int x = 0;",
6305 varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
6306 hasUnqualifiedLoc(loc(asString("int"))))))));
6309 TEST(HasUnqualifiedLoc, BindsToVolatileIntVarDecl) {
6310 EXPECT_TRUE(matches(
6311 "volatile int x = 0;",
6312 varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
6313 hasUnqualifiedLoc(loc(asString("int"))))))));
6316 TEST(HasUnqualifiedLoc, BindsToConstVolatileIntVarDecl) {
6317 EXPECT_TRUE(matches(
6318 "const volatile int x = 0;",
6319 varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
6320 hasUnqualifiedLoc(loc(asString("int"))))))));
6323 TEST(HasUnqualifiedLoc, BindsToConstPointerVarDecl) {
6324 auto matcher = varDecl(
6325 hasName("x"),
6326 hasTypeLoc(qualifiedTypeLoc(hasUnqualifiedLoc(pointerTypeLoc()))));
6327 EXPECT_TRUE(matches("int* const x = 0;", matcher));
6328 EXPECT_TRUE(notMatches("int const x = 0;", matcher));
6331 TEST(HasUnqualifiedLoc, BindsToPointerToConstVolatileIntVarDecl) {
6332 EXPECT_TRUE(
6333 matches("const volatile int* x = 0;",
6334 varDecl(hasName("x"),
6335 hasTypeLoc(pointerTypeLoc(hasPointeeLoc(qualifiedTypeLoc(
6336 hasUnqualifiedLoc(loc(asString("int"))))))))));
6339 TEST(HasUnqualifiedLoc, BindsToConstIntFunctionDecl) {
6340 EXPECT_TRUE(
6341 matches("const int f() { return 5; }",
6342 functionDecl(hasName("f"),
6343 hasReturnTypeLoc(qualifiedTypeLoc(
6344 hasUnqualifiedLoc(loc(asString("int"))))))));
6347 TEST(HasUnqualifiedLoc, FloatBindsToConstFloatVarDecl) {
6348 EXPECT_TRUE(matches(
6349 "const float x = 0;",
6350 varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
6351 hasUnqualifiedLoc(loc(asString("float"))))))));
6354 TEST(HasUnqualifiedLoc, FloatDoesNotBindToIntVarDecl) {
6355 EXPECT_TRUE(notMatches(
6356 "int x = 0;",
6357 varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
6358 hasUnqualifiedLoc(loc(asString("float"))))))));
6361 TEST(HasUnqualifiedLoc, FloatDoesNotBindToConstIntVarDecl) {
6362 EXPECT_TRUE(notMatches(
6363 "const int x = 0;",
6364 varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc(
6365 hasUnqualifiedLoc(loc(asString("float"))))))));
6368 TEST(HasReturnTypeLoc, BindsToIntReturnTypeLoc) {
6369 EXPECT_TRUE(matches(
6370 "int f() { return 5; }",
6371 functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("int"))))));
6374 TEST(HasReturnTypeLoc, BindsToFloatReturnTypeLoc) {
6375 EXPECT_TRUE(matches(
6376 "float f() { return 5.0; }",
6377 functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("float"))))));
6380 TEST(HasReturnTypeLoc, BindsToVoidReturnTypeLoc) {
6381 EXPECT_TRUE(matches(
6382 "void f() {}",
6383 functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("void"))))));
6386 TEST(HasReturnTypeLoc, FloatDoesNotBindToIntReturnTypeLoc) {
6387 EXPECT_TRUE(notMatches(
6388 "int f() { return 5; }",
6389 functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("float"))))));
6392 TEST(HasReturnTypeLoc, IntDoesNotBindToFloatReturnTypeLoc) {
6393 EXPECT_TRUE(notMatches(
6394 "float f() { return 5.0; }",
6395 functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("int"))))));
6398 TEST(HasPointeeLoc, BindsToAnyPointeeTypeLoc) {
6399 auto matcher = varDecl(hasName("x"),
6400 hasTypeLoc(pointerTypeLoc(hasPointeeLoc(typeLoc()))));
6401 EXPECT_TRUE(matches("int* x;", matcher));
6402 EXPECT_TRUE(matches("float* x;", matcher));
6403 EXPECT_TRUE(matches("char* x;", matcher));
6404 EXPECT_TRUE(matches("void* x;", matcher));
6407 TEST(HasPointeeLoc, DoesNotBindToTypeLocWithoutPointee) {
6408 auto matcher = varDecl(hasName("x"),
6409 hasTypeLoc(pointerTypeLoc(hasPointeeLoc(typeLoc()))));
6410 EXPECT_TRUE(notMatches("int x;", matcher));
6411 EXPECT_TRUE(notMatches("float x;", matcher));
6412 EXPECT_TRUE(notMatches("char x;", matcher));
6415 TEST(HasPointeeLoc, BindsToTypeLocPointingToInt) {
6416 EXPECT_TRUE(
6417 matches("int* x;", pointerTypeLoc(hasPointeeLoc(loc(asString("int"))))));
6420 TEST(HasPointeeLoc, BindsToTypeLocPointingToIntPointer) {
6421 EXPECT_TRUE(matches("int** x;",
6422 pointerTypeLoc(hasPointeeLoc(loc(asString("int *"))))));
6425 TEST(HasPointeeLoc, BindsToTypeLocPointingToTypeLocPointingToInt) {
6426 EXPECT_TRUE(matches("int** x;", pointerTypeLoc(hasPointeeLoc(pointerTypeLoc(
6427 hasPointeeLoc(loc(asString("int"))))))));
6430 TEST(HasPointeeLoc, BindsToTypeLocPointingToFloat) {
6431 EXPECT_TRUE(matches("float* x;",
6432 pointerTypeLoc(hasPointeeLoc(loc(asString("float"))))));
6435 TEST(HasPointeeLoc, IntPointeeDoesNotBindToTypeLocPointingToFloat) {
6436 EXPECT_TRUE(notMatches("float* x;",
6437 pointerTypeLoc(hasPointeeLoc(loc(asString("int"))))));
6440 TEST(HasPointeeLoc, FloatPointeeDoesNotBindToTypeLocPointingToInt) {
6441 EXPECT_TRUE(notMatches(
6442 "int* x;", pointerTypeLoc(hasPointeeLoc(loc(asString("float"))))));
6445 TEST(HasReferentLoc, BindsToAnyReferentTypeLoc) {
6446 auto matcher = varDecl(
6447 hasName("r"), hasTypeLoc(referenceTypeLoc(hasReferentLoc(typeLoc()))));
6448 EXPECT_TRUE(matches("int rr = 3; int& r = rr;", matcher));
6449 EXPECT_TRUE(matches("int rr = 3; auto& r = rr;", matcher));
6450 EXPECT_TRUE(matches("int rr = 3; const int& r = rr;", matcher));
6451 EXPECT_TRUE(matches("float rr = 3.0; float& r = rr;", matcher));
6452 EXPECT_TRUE(matches("char rr = 'a'; char& r = rr;", matcher));
6455 TEST(HasReferentLoc, DoesNotBindToTypeLocWithoutReferent) {
6456 auto matcher = varDecl(
6457 hasName("r"), hasTypeLoc(referenceTypeLoc(hasReferentLoc(typeLoc()))));
6458 EXPECT_TRUE(notMatches("int r;", matcher));
6459 EXPECT_TRUE(notMatches("int r = 3;", matcher));
6460 EXPECT_TRUE(notMatches("const int r = 3;", matcher));
6461 EXPECT_TRUE(notMatches("int* r;", matcher));
6462 EXPECT_TRUE(notMatches("float r;", matcher));
6463 EXPECT_TRUE(notMatches("char r;", matcher));
6466 TEST(HasReferentLoc, BindsToAnyRvalueReference) {
6467 auto matcher = varDecl(
6468 hasName("r"), hasTypeLoc(referenceTypeLoc(hasReferentLoc(typeLoc()))));
6469 EXPECT_TRUE(matches("int&& r = 3;", matcher));
6470 EXPECT_TRUE(matches("auto&& r = 3;", matcher));
6471 EXPECT_TRUE(matches("float&& r = 3.0;", matcher));
6474 TEST(HasReferentLoc, BindsToIntReferenceTypeLoc) {
6475 EXPECT_TRUE(matches("int rr = 3; int& r = rr;",
6476 referenceTypeLoc(hasReferentLoc(loc(asString("int"))))));
6479 TEST(HasReferentLoc, BindsToIntRvalueReferenceTypeLoc) {
6480 EXPECT_TRUE(matches("int&& r = 3;",
6481 referenceTypeLoc(hasReferentLoc(loc(asString("int"))))));
6484 TEST(HasReferentLoc, BindsToFloatReferenceTypeLoc) {
6485 EXPECT_TRUE(
6486 matches("float rr = 3.0; float& r = rr;",
6487 referenceTypeLoc(hasReferentLoc(loc(asString("float"))))));
6490 TEST(HasReferentLoc, BindsToParameterWithIntReferenceTypeLoc) {
6491 EXPECT_TRUE(matches(
6492 "int f(int& r) { return r; }",
6493 parmVarDecl(hasName("r"), hasTypeLoc(referenceTypeLoc(
6494 hasReferentLoc(loc(asString("int"))))))));
6497 TEST(HasReferentLoc, IntReferenceDoesNotBindToFloatReferenceTypeLoc) {
6498 EXPECT_TRUE(
6499 notMatches("float rr = 3.0; float& r = rr;",
6500 referenceTypeLoc(hasReferentLoc(loc(asString("int"))))));
6503 TEST(HasReferentLoc, FloatReferenceDoesNotBindToIntReferenceTypeLoc) {
6504 EXPECT_TRUE(
6505 notMatches("int rr = 3; int& r = rr;",
6506 referenceTypeLoc(hasReferentLoc(loc(asString("float"))))));
6509 TEST(HasReferentLoc, DoesNotBindToParameterWithoutIntReferenceTypeLoc) {
6510 EXPECT_TRUE(notMatches(
6511 "int f(int r) { return r; }",
6512 parmVarDecl(hasName("r"), hasTypeLoc(referenceTypeLoc(
6513 hasReferentLoc(loc(asString("int"))))))));
6516 TEST(HasAnyTemplateArgumentLoc, BindsToSpecializationWithIntArgument) {
6517 EXPECT_TRUE(matches(
6518 "template<typename T> class A {}; A<int> a;",
6519 varDecl(hasName("a"),
6520 hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc(
6521 templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
6522 hasTypeLoc(loc(asString("int")))))))))));
6525 TEST(HasAnyTemplateArgumentLoc, BindsToSpecializationWithDoubleArgument) {
6526 EXPECT_TRUE(matches(
6527 "template<typename T> class A {}; A<double> a;",
6528 varDecl(hasName("a"),
6529 hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc(
6530 templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
6531 hasTypeLoc(loc(asString("double")))))))))));
6534 TEST(HasAnyTemplateArgumentLoc, BindsToExplicitSpecializationWithIntArgument) {
6535 EXPECT_TRUE(matches(
6536 "template<typename T> class A {}; template<> class A<int> {};",
6537 classTemplateSpecializationDecl(
6538 hasName("A"),
6539 hasAnyTemplateArgumentLoc(hasTypeLoc(loc(asString("int")))))));
6542 TEST(HasAnyTemplateArgumentLoc,
6543 BindsToExplicitSpecializationWithDoubleArgument) {
6544 EXPECT_TRUE(matches(
6545 "template<typename T> class A {}; template<> class A<double> {};",
6546 classTemplateSpecializationDecl(
6547 hasName("A"),
6548 hasAnyTemplateArgumentLoc(hasTypeLoc(loc(asString("double")))))));
6551 TEST(HasAnyTemplateArgumentLoc, BindsToSpecializationWithMultipleArguments) {
6552 auto code = R"(
6553 template<typename T, typename U> class A {};
6554 template<> class A<double, int> {};
6556 EXPECT_TRUE(
6557 matches(code, classTemplateSpecializationDecl(
6558 hasName("A"), hasAnyTemplateArgumentLoc(hasTypeLoc(
6559 loc(asString("double")))))));
6561 EXPECT_TRUE(matches(
6562 code, classTemplateSpecializationDecl(
6563 hasName("A"),
6564 hasAnyTemplateArgumentLoc(hasTypeLoc(loc(asString("int")))))));
6567 TEST(HasAnyTemplateArgumentLoc, DoesNotBindToSpecializationWithIntArgument) {
6568 EXPECT_TRUE(notMatches("template<typename T> class A {}; A<int> a;",
6569 classTemplateSpecializationDecl(
6570 hasName("A"), hasAnyTemplateArgumentLoc(hasTypeLoc(
6571 loc(asString("double")))))));
6574 TEST(HasAnyTemplateArgumentLoc,
6575 DoesNotBindToExplicitSpecializationWithIntArgument) {
6576 EXPECT_TRUE(notMatches(
6577 "template<typename T> class A {}; template<> class A<int> {};",
6578 classTemplateSpecializationDecl(
6579 hasName("A"),
6580 hasAnyTemplateArgumentLoc(hasTypeLoc(loc(asString("double")))))));
6583 TEST(HasTemplateArgumentLoc, BindsToSpecializationWithIntArgument) {
6584 EXPECT_TRUE(
6585 matches("template<typename T> class A {}; A<int> a;",
6586 varDecl(hasName("a"),
6587 hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc(
6588 templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6589 0, hasTypeLoc(loc(asString("int")))))))))));
6592 TEST(HasTemplateArgumentLoc, BindsToSpecializationWithDoubleArgument) {
6593 EXPECT_TRUE(
6594 matches("template<typename T> class A {}; A<double> a;",
6595 varDecl(hasName("a"),
6596 hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc(
6597 templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6598 0, hasTypeLoc(loc(asString("double")))))))))));
6601 TEST(HasTemplateArgumentLoc, DoesNotBindToSpecializationWithIntArgument) {
6602 EXPECT_TRUE(notMatches(
6603 "template<typename T> class A {}; A<int> a;",
6604 varDecl(hasName("a"),
6605 hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc(
6606 templateSpecializationTypeLoc(hasTemplateArgumentLoc(
6607 0, hasTypeLoc(loc(asString("double")))))))))));
6610 TEST(HasTemplateArgumentLoc, BindsToExplicitSpecializationWithIntArgument) {
6611 EXPECT_TRUE(matches(
6612 "template<typename T> class A {}; template<> class A<int> {};",
6613 classTemplateSpecializationDecl(
6614 hasName("A"),
6615 hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("int")))))));
6618 TEST(HasTemplateArgumentLoc, BindsToExplicitSpecializationWithDoubleArgument) {
6619 EXPECT_TRUE(matches(
6620 "template<typename T> class A {}; template<> class A<double> {};",
6621 classTemplateSpecializationDecl(
6622 hasName("A"),
6623 hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("double")))))));
6626 TEST(HasTemplateArgumentLoc, BindsToSpecializationWithMultipleArguments) {
6627 auto code = R"(
6628 template<typename T, typename U> class A {};
6629 template<> class A<double, int> {};
6631 EXPECT_TRUE(matches(
6632 code, classTemplateSpecializationDecl(
6633 hasName("A"), hasTemplateArgumentLoc(
6634 0, hasTypeLoc(loc(asString("double")))))));
6635 EXPECT_TRUE(matches(
6636 code, classTemplateSpecializationDecl(
6637 hasName("A"),
6638 hasTemplateArgumentLoc(1, hasTypeLoc(loc(asString("int")))))));
6641 TEST(HasTemplateArgumentLoc,
6642 DoesNotBindToExplicitSpecializationWithIntArgument) {
6643 EXPECT_TRUE(notMatches(
6644 "template<typename T> class A {}; template<> class A<int> {};",
6645 classTemplateSpecializationDecl(
6646 hasName("A"),
6647 hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("double")))))));
6650 TEST(HasTemplateArgumentLoc,
6651 DoesNotBindToSpecializationWithMisplacedArguments) {
6652 auto code = R"(
6653 template<typename T, typename U> class A {};
6654 template<> class A<double, int> {};
6656 EXPECT_TRUE(notMatches(
6657 code, classTemplateSpecializationDecl(
6658 hasName("A"), hasTemplateArgumentLoc(
6659 1, hasTypeLoc(loc(asString("double")))))));
6660 EXPECT_TRUE(notMatches(
6661 code, classTemplateSpecializationDecl(
6662 hasName("A"),
6663 hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("int")))))));
6666 TEST(HasTemplateArgumentLoc, DoesNotBindWithBadIndex) {
6667 auto code = R"(
6668 template<typename T, typename U> class A {};
6669 template<> class A<double, int> {};
6671 EXPECT_TRUE(notMatches(
6672 code, classTemplateSpecializationDecl(
6673 hasName("A"), hasTemplateArgumentLoc(
6674 -1, hasTypeLoc(loc(asString("double")))))));
6675 EXPECT_TRUE(notMatches(
6676 code, classTemplateSpecializationDecl(
6677 hasName("A"), hasTemplateArgumentLoc(
6678 100, hasTypeLoc(loc(asString("int")))))));
6681 TEST(HasTemplateArgumentLoc, BindsToDeclRefExprWithIntArgument) {
6682 EXPECT_TRUE(matches(R"(
6683 template<typename T> T f(T t) { return t; }
6684 int g() { int i = f<int>(3); return i; }
6686 declRefExpr(to(functionDecl(hasName("f"))),
6687 hasTemplateArgumentLoc(
6688 0, hasTypeLoc(loc(asString("int")))))));
6691 TEST(HasTemplateArgumentLoc, BindsToDeclRefExprWithDoubleArgument) {
6692 EXPECT_TRUE(matches(
6694 template<typename T> T f(T t) { return t; }
6695 double g() { double i = f<double>(3.0); return i; }
6697 declRefExpr(
6698 to(functionDecl(hasName("f"))),
6699 hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("double")))))));
6702 TEST(HasTemplateArgumentLoc, DoesNotBindToDeclRefExprWithDoubleArgument) {
6703 EXPECT_TRUE(notMatches(
6705 template<typename T> T f(T t) { return t; }
6706 double g() { double i = f<double>(3.0); return i; }
6708 declRefExpr(
6709 to(functionDecl(hasName("f"))),
6710 hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("int")))))));
6713 TEST(HasNamedTypeLoc, BindsToElaboratedObjectDeclaration) {
6714 EXPECT_TRUE(matches(
6716 template <typename T>
6717 class C {};
6718 class C<int> c;
6720 varDecl(hasName("c"),
6721 hasTypeLoc(elaboratedTypeLoc(
6722 hasNamedTypeLoc(templateSpecializationTypeLoc(
6723 hasAnyTemplateArgumentLoc(templateArgumentLoc()))))))));
6726 TEST(HasNamedTypeLoc, DoesNotBindToNonElaboratedObjectDeclaration) {
6727 EXPECT_TRUE(matches(
6729 template <typename T>
6730 class C {};
6731 C<int> c;
6733 varDecl(hasName("c"),
6734 hasTypeLoc(elaboratedTypeLoc(
6735 hasNamedTypeLoc(templateSpecializationTypeLoc(
6736 hasAnyTemplateArgumentLoc(templateArgumentLoc()))))))));
6739 } // namespace ast_matchers
6740 } // namespace clang