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