blob: dc266076d3cbab1be175529ca1de127b7dbd56b3 [file] [log] [blame]
Piotr Padlewskic6e05022016-05-17 19:22:57 +00001// unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp - AST matcher unit tests//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "ASTMatchersTest.h"
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/Triple.h"
16#include "llvm/Support/Host.h"
17#include "gtest/gtest.h"
18
19namespace clang {
20namespace ast_matchers {
21
22
23TEST(AllOf, AllOverloadsWork) {
24 const char Program[] =
25 "struct T { };"
26 "int f(int, T*, int, int);"
27 "void g(int x) { T t; f(x, &t, 3, 4); }";
28 EXPECT_TRUE(matches(Program,
29 callExpr(allOf(callee(functionDecl(hasName("f"))),
30 hasArgument(0, declRefExpr(to(varDecl())))))));
31 EXPECT_TRUE(matches(Program,
32 callExpr(allOf(callee(functionDecl(hasName("f"))),
33 hasArgument(0, declRefExpr(to(varDecl()))),
34 hasArgument(1, hasType(pointsTo(
35 recordDecl(hasName("T")))))))));
36 EXPECT_TRUE(matches(Program,
37 callExpr(allOf(callee(functionDecl(hasName("f"))),
38 hasArgument(0, declRefExpr(to(varDecl()))),
39 hasArgument(1, hasType(pointsTo(
40 recordDecl(hasName("T"))))),
41 hasArgument(2, integerLiteral(equals(3)))))));
42 EXPECT_TRUE(matches(Program,
43 callExpr(allOf(callee(functionDecl(hasName("f"))),
44 hasArgument(0, declRefExpr(to(varDecl()))),
45 hasArgument(1, hasType(pointsTo(
46 recordDecl(hasName("T"))))),
47 hasArgument(2, integerLiteral(equals(3))),
48 hasArgument(3, integerLiteral(equals(4)))))));
49}
50
51TEST(DeclarationMatcher, MatchHas) {
52 DeclarationMatcher HasClassX = recordDecl(has(recordDecl(hasName("X"))));
53 EXPECT_TRUE(matches("class Y { class X {}; };", HasClassX));
54 EXPECT_TRUE(matches("class X {};", HasClassX));
55
56 DeclarationMatcher YHasClassX =
57 recordDecl(hasName("Y"), has(recordDecl(hasName("X"))));
58 EXPECT_TRUE(matches("class Y { class X {}; };", YHasClassX));
59 EXPECT_TRUE(notMatches("class X {};", YHasClassX));
60 EXPECT_TRUE(
61 notMatches("class Y { class Z { class X {}; }; };", YHasClassX));
62}
63
64TEST(DeclarationMatcher, MatchHasRecursiveAllOf) {
65 DeclarationMatcher Recursive =
66 recordDecl(
67 has(recordDecl(
68 has(recordDecl(hasName("X"))),
69 has(recordDecl(hasName("Y"))),
70 hasName("Z"))),
71 has(recordDecl(
72 has(recordDecl(hasName("A"))),
73 has(recordDecl(hasName("B"))),
74 hasName("C"))),
75 hasName("F"));
76
77 EXPECT_TRUE(matches(
78 "class F {"
79 " class Z {"
80 " class X {};"
81 " class Y {};"
82 " };"
83 " class C {"
84 " class A {};"
85 " class B {};"
86 " };"
87 "};", Recursive));
88
89 EXPECT_TRUE(matches(
90 "class F {"
91 " class Z {"
92 " class A {};"
93 " class X {};"
94 " class Y {};"
95 " };"
96 " class C {"
97 " class X {};"
98 " class A {};"
99 " class B {};"
100 " };"
101 "};", Recursive));
102
103 EXPECT_TRUE(matches(
104 "class O1 {"
105 " class O2 {"
106 " class F {"
107 " class Z {"
108 " class A {};"
109 " class X {};"
110 " class Y {};"
111 " };"
112 " class C {"
113 " class X {};"
114 " class A {};"
115 " class B {};"
116 " };"
117 " };"
118 " };"
119 "};", Recursive));
120}
121
122TEST(DeclarationMatcher, MatchHasRecursiveAnyOf) {
123 DeclarationMatcher Recursive =
124 recordDecl(
125 anyOf(
126 has(recordDecl(
127 anyOf(
128 has(recordDecl(
129 hasName("X"))),
130 has(recordDecl(
131 hasName("Y"))),
132 hasName("Z")))),
133 has(recordDecl(
134 anyOf(
135 hasName("C"),
136 has(recordDecl(
137 hasName("A"))),
138 has(recordDecl(
139 hasName("B")))))),
140 hasName("F")));
141
142 EXPECT_TRUE(matches("class F {};", Recursive));
143 EXPECT_TRUE(matches("class Z {};", Recursive));
144 EXPECT_TRUE(matches("class C {};", Recursive));
145 EXPECT_TRUE(matches("class M { class N { class X {}; }; };", Recursive));
146 EXPECT_TRUE(matches("class M { class N { class B {}; }; };", Recursive));
147 EXPECT_TRUE(
148 matches("class O1 { class O2 {"
149 " class M { class N { class B {}; }; }; "
150 "}; };", Recursive));
151}
152
153TEST(DeclarationMatcher, MatchNot) {
154 DeclarationMatcher NotClassX =
155 cxxRecordDecl(
156 isDerivedFrom("Y"),
157 unless(hasName("X")));
158 EXPECT_TRUE(notMatches("", NotClassX));
159 EXPECT_TRUE(notMatches("class Y {};", NotClassX));
160 EXPECT_TRUE(matches("class Y {}; class Z : public Y {};", NotClassX));
161 EXPECT_TRUE(notMatches("class Y {}; class X : public Y {};", NotClassX));
162 EXPECT_TRUE(
163 notMatches("class Y {}; class Z {}; class X : public Y {};",
164 NotClassX));
165
166 DeclarationMatcher ClassXHasNotClassY =
167 recordDecl(
168 hasName("X"),
169 has(recordDecl(hasName("Z"))),
170 unless(
171 has(recordDecl(hasName("Y")))));
172 EXPECT_TRUE(matches("class X { class Z {}; };", ClassXHasNotClassY));
173 EXPECT_TRUE(notMatches("class X { class Y {}; class Z {}; };",
174 ClassXHasNotClassY));
175
176 DeclarationMatcher NamedNotRecord =
177 namedDecl(hasName("Foo"), unless(recordDecl()));
178 EXPECT_TRUE(matches("void Foo(){}", NamedNotRecord));
179 EXPECT_TRUE(notMatches("struct Foo {};", NamedNotRecord));
180}
181
182TEST(CastExpression, HasCastKind) {
183 EXPECT_TRUE(matches("char *p = 0;",
184 castExpr(hasCastKind(CK_NullToPointer))));
185 EXPECT_TRUE(notMatches("char *p = 0;",
186 castExpr(hasCastKind(CK_DerivedToBase))));
187 EXPECT_TRUE(matches("char *p = 0;",
188 implicitCastExpr(hasCastKind(CK_NullToPointer))));
189}
190
191TEST(DeclarationMatcher, HasDescendant) {
192 DeclarationMatcher ZDescendantClassX =
193 recordDecl(
194 hasDescendant(recordDecl(hasName("X"))),
195 hasName("Z"));
196 EXPECT_TRUE(matches("class Z { class X {}; };", ZDescendantClassX));
197 EXPECT_TRUE(
198 matches("class Z { class Y { class X {}; }; };", ZDescendantClassX));
199 EXPECT_TRUE(
200 matches("class Z { class A { class Y { class X {}; }; }; };",
201 ZDescendantClassX));
202 EXPECT_TRUE(
203 matches("class Z { class A { class B { class Y { class X {}; }; }; }; };",
204 ZDescendantClassX));
205 EXPECT_TRUE(notMatches("class Z {};", ZDescendantClassX));
206
207 DeclarationMatcher ZDescendantClassXHasClassY =
208 recordDecl(
209 hasDescendant(recordDecl(has(recordDecl(hasName("Y"))),
210 hasName("X"))),
211 hasName("Z"));
212 EXPECT_TRUE(matches("class Z { class X { class Y {}; }; };",
213 ZDescendantClassXHasClassY));
214 EXPECT_TRUE(
215 matches("class Z { class A { class B { class X { class Y {}; }; }; }; };",
216 ZDescendantClassXHasClassY));
217 EXPECT_TRUE(notMatches(
218 "class Z {"
219 " class A {"
220 " class B {"
221 " class X {"
222 " class C {"
223 " class Y {};"
224 " };"
225 " };"
226 " }; "
227 " };"
228 "};", ZDescendantClassXHasClassY));
229
230 DeclarationMatcher ZDescendantClassXDescendantClassY =
231 recordDecl(
232 hasDescendant(recordDecl(hasDescendant(recordDecl(hasName("Y"))),
233 hasName("X"))),
234 hasName("Z"));
235 EXPECT_TRUE(
236 matches("class Z { class A { class X { class B { class Y {}; }; }; }; };",
237 ZDescendantClassXDescendantClassY));
238 EXPECT_TRUE(matches(
239 "class Z {"
240 " class A {"
241 " class X {"
242 " class B {"
243 " class Y {};"
244 " };"
245 " class Y {};"
246 " };"
247 " };"
248 "};", ZDescendantClassXDescendantClassY));
249}
250
251TEST(DeclarationMatcher, HasDescendantMemoization) {
252 DeclarationMatcher CannotMemoize =
253 decl(hasDescendant(typeLoc().bind("x")), has(decl()));
254 EXPECT_TRUE(matches("void f() { int i; }", CannotMemoize));
255}
256
257TEST(DeclarationMatcher, HasDescendantMemoizationUsesRestrictKind) {
258 auto Name = hasName("i");
259 auto VD = internal::Matcher<VarDecl>(Name).dynCastTo<Decl>();
260 auto RD = internal::Matcher<RecordDecl>(Name).dynCastTo<Decl>();
261 // Matching VD first should not make a cache hit for RD.
262 EXPECT_TRUE(notMatches("void f() { int i; }",
263 decl(hasDescendant(VD), hasDescendant(RD))));
264 EXPECT_TRUE(notMatches("void f() { int i; }",
265 decl(hasDescendant(RD), hasDescendant(VD))));
266 // Not matching RD first should not make a cache hit for VD either.
267 EXPECT_TRUE(matches("void f() { int i; }",
268 decl(anyOf(hasDescendant(RD), hasDescendant(VD)))));
269}
270
271TEST(DeclarationMatcher, HasAncestorMemoization) {
272 // This triggers an hasAncestor with a TemplateArgument in the bound nodes.
273 // That node can't be memoized so we have to check for it before trying to put
274 // it on the cache.
275 DeclarationMatcher CannotMemoize = classTemplateSpecializationDecl(
276 hasAnyTemplateArgument(templateArgument().bind("targ")),
277 forEach(fieldDecl(hasAncestor(forStmt()))));
278
279 EXPECT_TRUE(notMatches("template <typename T> struct S;"
280 "template <> struct S<int>{ int i; int j; };",
281 CannotMemoize));
282}
283
284TEST(DeclarationMatcher, HasAttr) {
285 EXPECT_TRUE(matches("struct __attribute__((warn_unused)) X {};",
286 decl(hasAttr(clang::attr::WarnUnused))));
287 EXPECT_FALSE(matches("struct X {};",
288 decl(hasAttr(clang::attr::WarnUnused))));
289}
290
291
292TEST(DeclarationMatcher, MatchAnyOf) {
293 DeclarationMatcher YOrZDerivedFromX = cxxRecordDecl(
294 anyOf(hasName("Y"), allOf(isDerivedFrom("X"), hasName("Z"))));
295 EXPECT_TRUE(matches("class X {}; class Z : public X {};", YOrZDerivedFromX));
296 EXPECT_TRUE(matches("class Y {};", YOrZDerivedFromX));
297 EXPECT_TRUE(
298 notMatches("class X {}; class W : public X {};", YOrZDerivedFromX));
299 EXPECT_TRUE(notMatches("class Z {};", YOrZDerivedFromX));
300
301 DeclarationMatcher XOrYOrZOrU =
302 recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U")));
303 EXPECT_TRUE(matches("class X {};", XOrYOrZOrU));
304 EXPECT_TRUE(notMatches("class V {};", XOrYOrZOrU));
305
306 DeclarationMatcher XOrYOrZOrUOrV =
307 recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U"),
308 hasName("V")));
309 EXPECT_TRUE(matches("class X {};", XOrYOrZOrUOrV));
310 EXPECT_TRUE(matches("class Y {};", XOrYOrZOrUOrV));
311 EXPECT_TRUE(matches("class Z {};", XOrYOrZOrUOrV));
312 EXPECT_TRUE(matches("class U {};", XOrYOrZOrUOrV));
313 EXPECT_TRUE(matches("class V {};", XOrYOrZOrUOrV));
314 EXPECT_TRUE(notMatches("class A {};", XOrYOrZOrUOrV));
315
316 StatementMatcher MixedTypes = stmt(anyOf(ifStmt(), binaryOperator()));
317 EXPECT_TRUE(matches("int F() { return 1 + 2; }", MixedTypes));
318 EXPECT_TRUE(matches("int F() { if (true) return 1; }", MixedTypes));
319 EXPECT_TRUE(notMatches("int F() { return 1; }", MixedTypes));
320
321 EXPECT_TRUE(
322 matches("void f() try { } catch (int) { } catch (...) { }",
323 cxxCatchStmt(anyOf(hasDescendant(varDecl()), isCatchAll()))));
324}
325
326TEST(DeclarationMatcher, ClassIsDerived) {
327 DeclarationMatcher IsDerivedFromX = cxxRecordDecl(isDerivedFrom("X"));
328
329 EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsDerivedFromX));
330 EXPECT_TRUE(notMatches("class X {};", IsDerivedFromX));
331 EXPECT_TRUE(notMatches("class X;", IsDerivedFromX));
332 EXPECT_TRUE(notMatches("class Y;", IsDerivedFromX));
333 EXPECT_TRUE(notMatches("", IsDerivedFromX));
334
335 DeclarationMatcher IsAX = cxxRecordDecl(isSameOrDerivedFrom("X"));
336
337 EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsAX));
338 EXPECT_TRUE(matches("class X {};", IsAX));
339 EXPECT_TRUE(matches("class X;", IsAX));
340 EXPECT_TRUE(notMatches("class Y;", IsAX));
341 EXPECT_TRUE(notMatches("", IsAX));
342
343 DeclarationMatcher ZIsDerivedFromX =
344 cxxRecordDecl(hasName("Z"), isDerivedFrom("X"));
345 EXPECT_TRUE(
346 matches("class X {}; class Y : public X {}; class Z : public Y {};",
347 ZIsDerivedFromX));
348 EXPECT_TRUE(
349 matches("class X {};"
350 "template<class T> class Y : public X {};"
351 "class Z : public Y<int> {};", ZIsDerivedFromX));
352 EXPECT_TRUE(matches("class X {}; template<class T> class Z : public X {};",
353 ZIsDerivedFromX));
354 EXPECT_TRUE(
355 matches("template<class T> class X {}; "
356 "template<class T> class Z : public X<T> {};",
357 ZIsDerivedFromX));
358 EXPECT_TRUE(
359 matches("template<class T, class U=T> class X {}; "
360 "template<class T> class Z : public X<T> {};",
361 ZIsDerivedFromX));
362 EXPECT_TRUE(
363 notMatches("template<class X> class A { class Z : public X {}; };",
364 ZIsDerivedFromX));
365 EXPECT_TRUE(
366 matches("template<class X> class A { public: class Z : public X {}; }; "
367 "class X{}; void y() { A<X>::Z z; }", ZIsDerivedFromX));
368 EXPECT_TRUE(
369 matches("template <class T> class X {}; "
370 "template<class Y> class A { class Z : public X<Y> {}; };",
371 ZIsDerivedFromX));
372 EXPECT_TRUE(
373 notMatches("template<template<class T> class X> class A { "
374 " class Z : public X<int> {}; };", ZIsDerivedFromX));
375 EXPECT_TRUE(
376 matches("template<template<class T> class X> class A { "
377 " public: class Z : public X<int> {}; }; "
378 "template<class T> class X {}; void y() { A<X>::Z z; }",
379 ZIsDerivedFromX));
380 EXPECT_TRUE(
381 notMatches("template<class X> class A { class Z : public X::D {}; };",
382 ZIsDerivedFromX));
383 EXPECT_TRUE(
384 matches("template<class X> class A { public: "
385 " class Z : public X::D {}; }; "
386 "class Y { public: class X {}; typedef X D; }; "
387 "void y() { A<Y>::Z z; }", ZIsDerivedFromX));
388 EXPECT_TRUE(
389 matches("class X {}; typedef X Y; class Z : public Y {};",
390 ZIsDerivedFromX));
391 EXPECT_TRUE(
392 matches("template<class T> class Y { typedef typename T::U X; "
393 " class Z : public X {}; };", ZIsDerivedFromX));
394 EXPECT_TRUE(matches("class X {}; class Z : public ::X {};",
395 ZIsDerivedFromX));
396 EXPECT_TRUE(
397 notMatches("template<class T> class X {}; "
398 "template<class T> class A { class Z : public X<T>::D {}; };",
399 ZIsDerivedFromX));
400 EXPECT_TRUE(
401 matches("template<class T> class X { public: typedef X<T> D; }; "
402 "template<class T> class A { public: "
403 " class Z : public X<T>::D {}; }; void y() { A<int>::Z z; }",
404 ZIsDerivedFromX));
405 EXPECT_TRUE(
406 notMatches("template<class X> class A { class Z : public X::D::E {}; };",
407 ZIsDerivedFromX));
408 EXPECT_TRUE(
409 matches("class X {}; typedef X V; typedef V W; class Z : public W {};",
410 ZIsDerivedFromX));
411 EXPECT_TRUE(
412 matches("class X {}; class Y : public X {}; "
413 "typedef Y V; typedef V W; class Z : public W {};",
414 ZIsDerivedFromX));
415 EXPECT_TRUE(
416 matches("template<class T, class U> class X {}; "
417 "template<class T> class A { class Z : public X<T, int> {}; };",
418 ZIsDerivedFromX));
419 EXPECT_TRUE(
420 notMatches("template<class X> class D { typedef X A; typedef A B; "
421 " typedef B C; class Z : public C {}; };",
422 ZIsDerivedFromX));
423 EXPECT_TRUE(
424 matches("class X {}; typedef X A; typedef A B; "
425 "class Z : public B {};", ZIsDerivedFromX));
426 EXPECT_TRUE(
427 matches("class X {}; typedef X A; typedef A B; typedef B C; "
428 "class Z : public C {};", ZIsDerivedFromX));
429 EXPECT_TRUE(
430 matches("class U {}; typedef U X; typedef X V; "
431 "class Z : public V {};", ZIsDerivedFromX));
432 EXPECT_TRUE(
433 matches("class Base {}; typedef Base X; "
434 "class Z : public Base {};", ZIsDerivedFromX));
435 EXPECT_TRUE(
436 matches("class Base {}; typedef Base Base2; typedef Base2 X; "
437 "class Z : public Base {};", ZIsDerivedFromX));
438 EXPECT_TRUE(
439 notMatches("class Base {}; class Base2 {}; typedef Base2 X; "
440 "class Z : public Base {};", ZIsDerivedFromX));
441 EXPECT_TRUE(
442 matches("class A {}; typedef A X; typedef A Y; "
443 "class Z : public Y {};", ZIsDerivedFromX));
444 EXPECT_TRUE(
445 notMatches("template <typename T> class Z;"
446 "template <> class Z<void> {};"
447 "template <typename T> class Z : public Z<void> {};",
448 IsDerivedFromX));
449 EXPECT_TRUE(
450 matches("template <typename T> class X;"
451 "template <> class X<void> {};"
452 "template <typename T> class X : public X<void> {};",
453 IsDerivedFromX));
454 EXPECT_TRUE(matches(
455 "class X {};"
456 "template <typename T> class Z;"
457 "template <> class Z<void> {};"
458 "template <typename T> class Z : public Z<void>, public X {};",
459 ZIsDerivedFromX));
460 EXPECT_TRUE(
461 notMatches("template<int> struct X;"
462 "template<int i> struct X : public X<i-1> {};",
463 cxxRecordDecl(isDerivedFrom(recordDecl(hasName("Some"))))));
464 EXPECT_TRUE(matches(
465 "struct A {};"
466 "template<int> struct X;"
467 "template<int i> struct X : public X<i-1> {};"
468 "template<> struct X<0> : public A {};"
469 "struct B : public X<42> {};",
470 cxxRecordDecl(hasName("B"), isDerivedFrom(recordDecl(hasName("A"))))));
471
472 // FIXME: Once we have better matchers for template type matching,
473 // get rid of the Variable(...) matching and match the right template
474 // declarations directly.
475 const char *RecursiveTemplateOneParameter =
476 "class Base1 {}; class Base2 {};"
477 "template <typename T> class Z;"
478 "template <> class Z<void> : public Base1 {};"
479 "template <> class Z<int> : public Base2 {};"
480 "template <> class Z<float> : public Z<void> {};"
481 "template <> class Z<double> : public Z<int> {};"
482 "template <typename T> class Z : public Z<float>, public Z<double> {};"
483 "void f() { Z<float> z_float; Z<double> z_double; Z<char> z_char; }";
484 EXPECT_TRUE(matches(
485 RecursiveTemplateOneParameter,
486 varDecl(hasName("z_float"),
487 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1")))))));
488 EXPECT_TRUE(notMatches(
489 RecursiveTemplateOneParameter,
490 varDecl(hasName("z_float"),
491 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2")))))));
492 EXPECT_TRUE(matches(
493 RecursiveTemplateOneParameter,
494 varDecl(hasName("z_char"),
495 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1"),
496 isDerivedFrom("Base2")))))));
497
498 const char *RecursiveTemplateTwoParameters =
499 "class Base1 {}; class Base2 {};"
500 "template <typename T1, typename T2> class Z;"
501 "template <typename T> class Z<void, T> : public Base1 {};"
502 "template <typename T> class Z<int, T> : public Base2 {};"
503 "template <typename T> class Z<float, T> : public Z<void, T> {};"
504 "template <typename T> class Z<double, T> : public Z<int, T> {};"
505 "template <typename T1, typename T2> class Z : "
506 " public Z<float, T2>, public Z<double, T2> {};"
507 "void f() { Z<float, void> z_float; Z<double, void> z_double; "
508 " Z<char, void> z_char; }";
509 EXPECT_TRUE(matches(
510 RecursiveTemplateTwoParameters,
511 varDecl(hasName("z_float"),
512 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1")))))));
513 EXPECT_TRUE(notMatches(
514 RecursiveTemplateTwoParameters,
515 varDecl(hasName("z_float"),
516 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2")))))));
517 EXPECT_TRUE(matches(
518 RecursiveTemplateTwoParameters,
519 varDecl(hasName("z_char"),
520 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1"),
521 isDerivedFrom("Base2")))))));
522 EXPECT_TRUE(matches(
523 "namespace ns { class X {}; class Y : public X {}; }",
524 cxxRecordDecl(isDerivedFrom("::ns::X"))));
525 EXPECT_TRUE(notMatches(
526 "class X {}; class Y : public X {};",
527 cxxRecordDecl(isDerivedFrom("::ns::X"))));
528
529 EXPECT_TRUE(matches(
530 "class X {}; class Y : public X {};",
531 cxxRecordDecl(isDerivedFrom(recordDecl(hasName("X")).bind("test")))));
532
533 EXPECT_TRUE(matches(
534 "template<typename T> class X {};"
535 "template<typename T> using Z = X<T>;"
536 "template <typename T> class Y : Z<T> {};",
537 cxxRecordDecl(isDerivedFrom(namedDecl(hasName("X"))))));
538}
539
540TEST(Matcher, BindMatchedNodes) {
541 DeclarationMatcher ClassX = has(recordDecl(hasName("::X")).bind("x"));
542
543 EXPECT_TRUE(matchAndVerifyResultTrue("class X {};",
544 ClassX, llvm::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("x")));
545
546 EXPECT_TRUE(matchAndVerifyResultFalse("class X {};",
547 ClassX, llvm::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("other-id")));
548
549 TypeMatcher TypeAHasClassB = hasDeclaration(
550 recordDecl(hasName("A"), has(recordDecl(hasName("B")).bind("b"))));
551
552 EXPECT_TRUE(matchAndVerifyResultTrue("class A { public: A *a; class B {}; };",
553 TypeAHasClassB,
554 llvm::make_unique<VerifyIdIsBoundTo<Decl>>("b")));
555
556 StatementMatcher MethodX =
557 callExpr(callee(cxxMethodDecl(hasName("x")))).bind("x");
558
559 EXPECT_TRUE(matchAndVerifyResultTrue("class A { void x() { x(); } };",
560 MethodX,
561 llvm::make_unique<VerifyIdIsBoundTo<CXXMemberCallExpr>>("x")));
562}
563
564TEST(Matcher, BindTheSameNameInAlternatives) {
565 StatementMatcher matcher = anyOf(
566 binaryOperator(hasOperatorName("+"),
567 hasLHS(expr().bind("x")),
568 hasRHS(integerLiteral(equals(0)))),
569 binaryOperator(hasOperatorName("+"),
570 hasLHS(integerLiteral(equals(0))),
571 hasRHS(expr().bind("x"))));
572
573 EXPECT_TRUE(matchAndVerifyResultTrue(
574 // The first branch of the matcher binds x to 0 but then fails.
575 // The second branch binds x to f() and succeeds.
576 "int f() { return 0 + f(); }",
577 matcher,
578 llvm::make_unique<VerifyIdIsBoundTo<CallExpr>>("x")));
579}
580
581TEST(Matcher, BindsIDForMemoizedResults) {
582 // Using the same matcher in two match expressions will make memoization
583 // kick in.
584 DeclarationMatcher ClassX = recordDecl(hasName("X")).bind("x");
585 EXPECT_TRUE(matchAndVerifyResultTrue(
586 "class A { class B { class X {}; }; };",
587 DeclarationMatcher(anyOf(
588 recordDecl(hasName("A"), hasDescendant(ClassX)),
589 recordDecl(hasName("B"), hasDescendant(ClassX)))),
590 llvm::make_unique<VerifyIdIsBoundTo<Decl>>("x", 2)));
591}
592
593TEST(HasType, MatchesAsString) {
594 EXPECT_TRUE(
595 matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }",
596 cxxMemberCallExpr(on(hasType(asString("class Y *"))))));
597 EXPECT_TRUE(
598 matches("class X { void x(int x) {} };",
599 cxxMethodDecl(hasParameter(0, hasType(asString("int"))))));
600 EXPECT_TRUE(matches("namespace ns { struct A {}; } struct B { ns::A a; };",
601 fieldDecl(hasType(asString("ns::A")))));
602 EXPECT_TRUE(matches("namespace { struct A {}; } struct B { A a; };",
603 fieldDecl(hasType(asString("struct (anonymous namespace)::A")))));
604}
605
606TEST(Matcher, HasOperatorNameForOverloadedOperatorCall) {
607 StatementMatcher OpCallAndAnd =
608 cxxOperatorCallExpr(hasOverloadedOperatorName("&&"));
609 EXPECT_TRUE(matches("class Y { }; "
610 "bool operator&&(Y x, Y y) { return true; }; "
611 "Y a; Y b; bool c = a && b;", OpCallAndAnd));
612 StatementMatcher OpCallLessLess =
613 cxxOperatorCallExpr(hasOverloadedOperatorName("<<"));
614 EXPECT_TRUE(notMatches("class Y { }; "
615 "bool operator&&(Y x, Y y) { return true; }; "
616 "Y a; Y b; bool c = a && b;",
617 OpCallLessLess));
618 StatementMatcher OpStarCall =
619 cxxOperatorCallExpr(hasOverloadedOperatorName("*"));
620 EXPECT_TRUE(matches("class Y; int operator*(Y &); void f(Y &y) { *y; }",
621 OpStarCall));
622 DeclarationMatcher ClassWithOpStar =
623 cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*")));
624 EXPECT_TRUE(matches("class Y { int operator*(); };",
625 ClassWithOpStar));
626 EXPECT_TRUE(notMatches("class Y { void myOperator(); };",
627 ClassWithOpStar)) ;
628 DeclarationMatcher AnyOpStar = functionDecl(hasOverloadedOperatorName("*"));
629 EXPECT_TRUE(matches("class Y; int operator*(Y &);", AnyOpStar));
630 EXPECT_TRUE(matches("class Y { int operator*(); };", AnyOpStar));
631}
632
633
634TEST(Matcher, NestedOverloadedOperatorCalls) {
635 EXPECT_TRUE(matchAndVerifyResultTrue(
636 "class Y { }; "
637 "Y& operator&&(Y& x, Y& y) { return x; }; "
638 "Y a; Y b; Y c; Y d = a && b && c;",
639 cxxOperatorCallExpr(hasOverloadedOperatorName("&&")).bind("x"),
640 llvm::make_unique<VerifyIdIsBoundTo<CXXOperatorCallExpr>>("x", 2)));
641 EXPECT_TRUE(matches("class Y { }; "
642 "Y& operator&&(Y& x, Y& y) { return x; }; "
643 "Y a; Y b; Y c; Y d = a && b && c;",
644 cxxOperatorCallExpr(hasParent(cxxOperatorCallExpr()))));
645 EXPECT_TRUE(
646 matches("class Y { }; "
647 "Y& operator&&(Y& x, Y& y) { return x; }; "
648 "Y a; Y b; Y c; Y d = a && b && c;",
649 cxxOperatorCallExpr(hasDescendant(cxxOperatorCallExpr()))));
650}
651
652TEST(Matcher, VarDecl_Storage) {
653 auto M = varDecl(hasName("X"), hasLocalStorage());
654 EXPECT_TRUE(matches("void f() { int X; }", M));
655 EXPECT_TRUE(notMatches("int X;", M));
656 EXPECT_TRUE(notMatches("void f() { static int X; }", M));
657
658 M = varDecl(hasName("X"), hasGlobalStorage());
659 EXPECT_TRUE(notMatches("void f() { int X; }", M));
660 EXPECT_TRUE(matches("int X;", M));
661 EXPECT_TRUE(matches("void f() { static int X; }", M));
662}
663
664TEST(Matcher, VarDecl_StorageDuration) {
665 std::string T =
666 "void f() { int x; static int y; } int a;";
667
668 EXPECT_TRUE(matches(T, varDecl(hasName("x"), hasAutomaticStorageDuration())));
669 EXPECT_TRUE(
670 notMatches(T, varDecl(hasName("y"), hasAutomaticStorageDuration())));
671 EXPECT_TRUE(
672 notMatches(T, varDecl(hasName("a"), hasAutomaticStorageDuration())));
673
674 EXPECT_TRUE(matches(T, varDecl(hasName("y"), hasStaticStorageDuration())));
675 EXPECT_TRUE(matches(T, varDecl(hasName("a"), hasStaticStorageDuration())));
676 EXPECT_TRUE(notMatches(T, varDecl(hasName("x"), hasStaticStorageDuration())));
677
678 // FIXME: It is really hard to test with thread_local itself because not all
679 // targets support TLS, which causes this to be an error depending on what
680 // platform the test is being run on. We do not have access to the TargetInfo
681 // object to be able to test whether the platform supports TLS or not.
682 EXPECT_TRUE(notMatches(T, varDecl(hasName("x"), hasThreadStorageDuration())));
683 EXPECT_TRUE(notMatches(T, varDecl(hasName("y"), hasThreadStorageDuration())));
684 EXPECT_TRUE(notMatches(T, varDecl(hasName("a"), hasThreadStorageDuration())));
685}
686
687TEST(Matcher, FindsVarDeclInFunctionParameter) {
688 EXPECT_TRUE(matches(
689 "void f(int i) {}",
690 varDecl(hasName("i"))));
691}
692
693TEST(UnaryExpressionOrTypeTraitExpression, MatchesCorrectType) {
694 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }", sizeOfExpr(
695 hasArgumentOfType(asString("int")))));
696 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
697 hasArgumentOfType(asString("float")))));
698 EXPECT_TRUE(matches(
699 "struct A {}; void x() { A a; int b = sizeof(a); }",
700 sizeOfExpr(hasArgumentOfType(hasDeclaration(recordDecl(hasName("A")))))));
701 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
702 hasArgumentOfType(hasDeclaration(recordDecl(hasName("string")))))));
703}
704
705TEST(IsInteger, MatchesIntegers) {
706 EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isInteger()))));
707 EXPECT_TRUE(matches(
708 "long long i = 0; void f(long long) { }; void g() {f(i);}",
709 callExpr(hasArgument(0, declRefExpr(
710 to(varDecl(hasType(isInteger()))))))));
711}
712
713TEST(IsInteger, ReportsNoFalsePositives) {
714 EXPECT_TRUE(notMatches("int *i;", varDecl(hasType(isInteger()))));
715 EXPECT_TRUE(notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}",
716 callExpr(hasArgument(0, declRefExpr(
717 to(varDecl(hasType(isInteger()))))))));
718}
719
720TEST(IsAnyPointer, MatchesPointers) {
721 EXPECT_TRUE(matches("int* i = nullptr;", varDecl(hasType(isAnyPointer()))));
722}
723
724TEST(IsAnyPointer, MatchesObjcPointer) {
725 EXPECT_TRUE(matchesObjC("@interface Foo @end Foo *f;",
726 varDecl(hasType(isAnyPointer()))));
727}
728
729TEST(IsAnyPointer, ReportsNoFalsePositives) {
730 EXPECT_TRUE(notMatches("int i = 0;", varDecl(hasType(isAnyPointer()))));
731}
732
733TEST(IsAnyCharacter, MatchesCharacters) {
734 EXPECT_TRUE(matches("char i = 0;", varDecl(hasType(isAnyCharacter()))));
735}
736
737TEST(IsAnyCharacter, ReportsNoFalsePositives) {
738 EXPECT_TRUE(notMatches("int i;", varDecl(hasType(isAnyCharacter()))));
739}
740
741TEST(IsArrow, MatchesMemberVariablesViaArrow) {
742 EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };",
743 memberExpr(isArrow())));
744 EXPECT_TRUE(matches("class Y { void x() { y; } int y; };",
745 memberExpr(isArrow())));
746 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };",
747 memberExpr(isArrow())));
748}
749
750TEST(IsArrow, MatchesStaticMemberVariablesViaArrow) {
751 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
752 memberExpr(isArrow())));
753 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
754 memberExpr(isArrow())));
755 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } static int y; };",
756 memberExpr(isArrow())));
757}
758
759TEST(IsArrow, MatchesMemberCallsViaArrow) {
760 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
761 memberExpr(isArrow())));
762 EXPECT_TRUE(matches("class Y { void x() { x(); } };",
763 memberExpr(isArrow())));
764 EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",
765 memberExpr(isArrow())));
766}
767
768TEST(ConversionDeclaration, IsExplicit) {
769 EXPECT_TRUE(matches("struct S { explicit operator int(); };",
770 cxxConversionDecl(isExplicit())));
771 EXPECT_TRUE(notMatches("struct S { operator int(); };",
772 cxxConversionDecl(isExplicit())));
773}
774
775TEST(Matcher, ArgumentCount) {
776 StatementMatcher Call1Arg = callExpr(argumentCountIs(1));
777
778 EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg));
779 EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg));
780 EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg));
781}
782
783TEST(Matcher, ParameterCount) {
784 DeclarationMatcher Function1Arg = functionDecl(parameterCountIs(1));
785 EXPECT_TRUE(matches("void f(int i) {}", Function1Arg));
786 EXPECT_TRUE(matches("class X { void f(int i) {} };", Function1Arg));
787 EXPECT_TRUE(notMatches("void f() {}", Function1Arg));
788 EXPECT_TRUE(notMatches("void f(int i, int j, int k) {}", Function1Arg));
789 EXPECT_TRUE(matches("void f(int i, ...) {};", Function1Arg));
790}
791
792TEST(Matcher, References) {
793 DeclarationMatcher ReferenceClassX = varDecl(
794 hasType(references(recordDecl(hasName("X")))));
795 EXPECT_TRUE(matches("class X {}; void y(X y) { X &x = y; }",
796 ReferenceClassX));
797 EXPECT_TRUE(
798 matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
799 // The match here is on the implicit copy constructor code for
800 // class X, not on code 'X x = y'.
801 EXPECT_TRUE(
802 matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
803 EXPECT_TRUE(
804 notMatches("class X {}; extern X x;", ReferenceClassX));
805 EXPECT_TRUE(
806 notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
807}
808
809TEST(QualType, hasLocalQualifiers) {
810 EXPECT_TRUE(notMatches("typedef const int const_int; const_int i = 1;",
811 varDecl(hasType(hasLocalQualifiers()))));
812 EXPECT_TRUE(matches("int *const j = nullptr;",
813 varDecl(hasType(hasLocalQualifiers()))));
814 EXPECT_TRUE(matches("int *volatile k;",
815 varDecl(hasType(hasLocalQualifiers()))));
816 EXPECT_TRUE(notMatches("int m;",
817 varDecl(hasType(hasLocalQualifiers()))));
818}
819
820TEST(IsExternC, MatchesExternCFunctionDeclarations) {
821 EXPECT_TRUE(matches("extern \"C\" void f() {}", functionDecl(isExternC())));
822 EXPECT_TRUE(matches("extern \"C\" { void f() {} }",
823 functionDecl(isExternC())));
824 EXPECT_TRUE(notMatches("void f() {}", functionDecl(isExternC())));
825}
826
827TEST(IsDefaulted, MatchesDefaultedFunctionDeclarations) {
828 EXPECT_TRUE(notMatches("class A { ~A(); };",
829 functionDecl(hasName("~A"), isDefaulted())));
830 EXPECT_TRUE(matches("class B { ~B() = default; };",
831 functionDecl(hasName("~B"), isDefaulted())));
832}
833
834TEST(IsDeleted, MatchesDeletedFunctionDeclarations) {
835 EXPECT_TRUE(
836 notMatches("void Func();", functionDecl(hasName("Func"), isDeleted())));
837 EXPECT_TRUE(matches("void Func() = delete;",
838 functionDecl(hasName("Func"), isDeleted())));
839}
840
841TEST(IsNoThrow, MatchesNoThrowFunctionDeclarations) {
842 EXPECT_TRUE(notMatches("void f();", functionDecl(isNoThrow())));
843 EXPECT_TRUE(notMatches("void f() throw(int);", functionDecl(isNoThrow())));
844 EXPECT_TRUE(
845 notMatches("void f() noexcept(false);", functionDecl(isNoThrow())));
846 EXPECT_TRUE(matches("void f() throw();", functionDecl(isNoThrow())));
847 EXPECT_TRUE(matches("void f() noexcept;", functionDecl(isNoThrow())));
848}
849
850TEST(isConstexpr, MatchesConstexprDeclarations) {
851 EXPECT_TRUE(matches("constexpr int foo = 42;",
852 varDecl(hasName("foo"), isConstexpr())));
853 EXPECT_TRUE(matches("constexpr int bar();",
854 functionDecl(hasName("bar"), isConstexpr())));
855}
856
857TEST(TemplateArgumentCountIs, Matches) {
858 EXPECT_TRUE(
859 matches("template<typename T> struct C {}; C<int> c;",
860 classTemplateSpecializationDecl(templateArgumentCountIs(1))));
861 EXPECT_TRUE(
862 notMatches("template<typename T> struct C {}; C<int> c;",
863 classTemplateSpecializationDecl(templateArgumentCountIs(2))));
864
865 EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
866 templateSpecializationType(templateArgumentCountIs(1))));
867 EXPECT_TRUE(
868 notMatches("template<typename T> struct C {}; C<int> c;",
869 templateSpecializationType(templateArgumentCountIs(2))));
870}
871
872TEST(IsIntegral, Matches) {
873 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
874 classTemplateSpecializationDecl(
875 hasAnyTemplateArgument(isIntegral()))));
876 EXPECT_TRUE(notMatches("template<typename T> struct C {}; C<int> c;",
877 classTemplateSpecializationDecl(hasAnyTemplateArgument(
878 templateArgument(isIntegral())))));
879}
880
881TEST(EqualsIntegralValue, Matches) {
882 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
883 classTemplateSpecializationDecl(
884 hasAnyTemplateArgument(equalsIntegralValue("42")))));
885 EXPECT_TRUE(matches("template<int T> struct C {}; C<-42> c;",
886 classTemplateSpecializationDecl(
887 hasAnyTemplateArgument(equalsIntegralValue("-42")))));
888 EXPECT_TRUE(matches("template<int T> struct C {}; C<-0042> c;",
889 classTemplateSpecializationDecl(
890 hasAnyTemplateArgument(equalsIntegralValue("-34")))));
891 EXPECT_TRUE(notMatches("template<int T> struct C {}; C<42> c;",
892 classTemplateSpecializationDecl(hasAnyTemplateArgument(
893 equalsIntegralValue("0042")))));
894}
895
896TEST(Matcher, MatchesAccessSpecDecls) {
897 EXPECT_TRUE(matches("class C { public: int i; };", accessSpecDecl()));
898 EXPECT_TRUE(
899 matches("class C { public: int i; };", accessSpecDecl(isPublic())));
900 EXPECT_TRUE(
901 notMatches("class C { public: int i; };", accessSpecDecl(isProtected())));
902 EXPECT_TRUE(
903 notMatches("class C { public: int i; };", accessSpecDecl(isPrivate())));
904
905 EXPECT_TRUE(notMatches("class C { int i; };", accessSpecDecl()));
906}
907
908TEST(Matcher, MatchesFinal) {
909 EXPECT_TRUE(matches("class X final {};", cxxRecordDecl(isFinal())));
910 EXPECT_TRUE(matches("class X { virtual void f() final; };",
911 cxxMethodDecl(isFinal())));
912 EXPECT_TRUE(notMatches("class X {};", cxxRecordDecl(isFinal())));
913 EXPECT_TRUE(
914 notMatches("class X { virtual void f(); };", cxxMethodDecl(isFinal())));
915}
916
917TEST(Matcher, MatchesVirtualMethod) {
918 EXPECT_TRUE(matches("class X { virtual int f(); };",
919 cxxMethodDecl(isVirtual(), hasName("::X::f"))));
920 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isVirtual())));
921}
922
923TEST(Matcher, MatchesVirtualAsWrittenMethod) {
924 EXPECT_TRUE(matches("class A { virtual int f(); };"
925 "class B : public A { int f(); };",
926 cxxMethodDecl(isVirtualAsWritten(), hasName("::A::f"))));
927 EXPECT_TRUE(
928 notMatches("class A { virtual int f(); };"
929 "class B : public A { int f(); };",
930 cxxMethodDecl(isVirtualAsWritten(), hasName("::B::f"))));
931}
932
933TEST(Matcher, MatchesPureMethod) {
934 EXPECT_TRUE(matches("class X { virtual int f() = 0; };",
935 cxxMethodDecl(isPure(), hasName("::X::f"))));
936 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isPure())));
937}
938
939TEST(Matcher, MatchesCopyAssignmentOperator) {
940 EXPECT_TRUE(matches("class X { X &operator=(X); };",
941 cxxMethodDecl(isCopyAssignmentOperator())));
942 EXPECT_TRUE(matches("class X { X &operator=(X &); };",
943 cxxMethodDecl(isCopyAssignmentOperator())));
944 EXPECT_TRUE(matches("class X { X &operator=(const X &); };",
945 cxxMethodDecl(isCopyAssignmentOperator())));
946 EXPECT_TRUE(matches("class X { X &operator=(volatile X &); };",
947 cxxMethodDecl(isCopyAssignmentOperator())));
948 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &); };",
949 cxxMethodDecl(isCopyAssignmentOperator())));
950 EXPECT_TRUE(notMatches("class X { X &operator=(X &&); };",
951 cxxMethodDecl(isCopyAssignmentOperator())));
952}
953
954TEST(Matcher, MatchesMoveAssignmentOperator) {
955 EXPECT_TRUE(notMatches("class X { X &operator=(X); };",
956 cxxMethodDecl(isMoveAssignmentOperator())));
957 EXPECT_TRUE(matches("class X { X &operator=(X &&); };",
958 cxxMethodDecl(isMoveAssignmentOperator())));
959 EXPECT_TRUE(matches("class X { X &operator=(const X &&); };",
960 cxxMethodDecl(isMoveAssignmentOperator())));
961 EXPECT_TRUE(matches("class X { X &operator=(volatile X &&); };",
962 cxxMethodDecl(isMoveAssignmentOperator())));
963 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &&); };",
964 cxxMethodDecl(isMoveAssignmentOperator())));
965 EXPECT_TRUE(notMatches("class X { X &operator=(X &); };",
966 cxxMethodDecl(isMoveAssignmentOperator())));
967}
968
969TEST(Matcher, MatchesConstMethod) {
970 EXPECT_TRUE(
971 matches("struct A { void foo() const; };", cxxMethodDecl(isConst())));
972 EXPECT_TRUE(
973 notMatches("struct A { void foo(); };", cxxMethodDecl(isConst())));
974}
975
976TEST(Matcher, MatchesOverridingMethod) {
977 EXPECT_TRUE(matches("class X { virtual int f(); }; "
978 "class Y : public X { int f(); };",
979 cxxMethodDecl(isOverride(), hasName("::Y::f"))));
980 EXPECT_TRUE(notMatches("class X { virtual int f(); }; "
981 "class Y : public X { int f(); };",
982 cxxMethodDecl(isOverride(), hasName("::X::f"))));
983 EXPECT_TRUE(notMatches("class X { int f(); }; "
984 "class Y : public X { int f(); };",
985 cxxMethodDecl(isOverride())));
986 EXPECT_TRUE(notMatches("class X { int f(); int f(int); }; ",
987 cxxMethodDecl(isOverride())));
988 EXPECT_TRUE(
989 matches("template <typename Base> struct Y : Base { void f() override;};",
990 cxxMethodDecl(isOverride(), hasName("::Y::f"))));
991}
992
993TEST(Matcher, ConstructorArgument) {
994 StatementMatcher Constructor = cxxConstructExpr(
995 hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
996
997 EXPECT_TRUE(
998 matches("class X { public: X(int); }; void x() { int y; X x(y); }",
999 Constructor));
1000 EXPECT_TRUE(
1001 matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
1002 Constructor));
1003 EXPECT_TRUE(
1004 matches("class X { public: X(int); }; void x() { int y; X x = y; }",
1005 Constructor));
1006 EXPECT_TRUE(
1007 notMatches("class X { public: X(int); }; void x() { int z; X x(z); }",
1008 Constructor));
1009
1010 StatementMatcher WrongIndex = cxxConstructExpr(
1011 hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
1012 EXPECT_TRUE(
1013 notMatches("class X { public: X(int); }; void x() { int y; X x(y); }",
1014 WrongIndex));
1015}
1016
1017TEST(Matcher, ConstructorArgumentCount) {
1018 StatementMatcher Constructor1Arg = cxxConstructExpr(argumentCountIs(1));
1019
1020 EXPECT_TRUE(
1021 matches("class X { public: X(int); }; void x() { X x(0); }",
1022 Constructor1Arg));
1023 EXPECT_TRUE(
1024 matches("class X { public: X(int); }; void x() { X x = X(0); }",
1025 Constructor1Arg));
1026 EXPECT_TRUE(
1027 matches("class X { public: X(int); }; void x() { X x = 0; }",
1028 Constructor1Arg));
1029 EXPECT_TRUE(
1030 notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
1031 Constructor1Arg));
1032}
1033
1034TEST(Matcher, ConstructorListInitialization) {
1035 StatementMatcher ConstructorListInit =
1036 cxxConstructExpr(isListInitialization());
1037
1038 EXPECT_TRUE(
1039 matches("class X { public: X(int); }; void x() { X x{0}; }",
1040 ConstructorListInit));
1041 EXPECT_FALSE(
1042 matches("class X { public: X(int); }; void x() { X x(0); }",
1043 ConstructorListInit));
1044}
1045
1046TEST(ConstructorDeclaration, IsImplicit) {
1047 // This one doesn't match because the constructor is not added by the
1048 // compiler (it is not needed).
1049 EXPECT_TRUE(notMatches("class Foo { };",
1050 cxxConstructorDecl(isImplicit())));
1051 // The compiler added the implicit default constructor.
1052 EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
1053 cxxConstructorDecl(isImplicit())));
1054 EXPECT_TRUE(matches("class Foo { Foo(){} };",
1055 cxxConstructorDecl(unless(isImplicit()))));
1056 // The compiler added an implicit assignment operator.
1057 EXPECT_TRUE(matches("struct A { int x; } a = {0}, b = a; void f() { a = b; }",
1058 cxxMethodDecl(isImplicit(), hasName("operator="))));
1059}
1060
1061TEST(ConstructorDeclaration, IsExplicit) {
1062 EXPECT_TRUE(matches("struct S { explicit S(int); };",
1063 cxxConstructorDecl(isExplicit())));
1064 EXPECT_TRUE(notMatches("struct S { S(int); };",
1065 cxxConstructorDecl(isExplicit())));
1066}
1067
1068TEST(ConstructorDeclaration, Kinds) {
1069 EXPECT_TRUE(matches("struct S { S(); };",
1070 cxxConstructorDecl(isDefaultConstructor())));
1071 EXPECT_TRUE(notMatches("struct S { S(); };",
1072 cxxConstructorDecl(isCopyConstructor())));
1073 EXPECT_TRUE(notMatches("struct S { S(); };",
1074 cxxConstructorDecl(isMoveConstructor())));
1075
1076 EXPECT_TRUE(notMatches("struct S { S(const S&); };",
1077 cxxConstructorDecl(isDefaultConstructor())));
1078 EXPECT_TRUE(matches("struct S { S(const S&); };",
1079 cxxConstructorDecl(isCopyConstructor())));
1080 EXPECT_TRUE(notMatches("struct S { S(const S&); };",
1081 cxxConstructorDecl(isMoveConstructor())));
1082
1083 EXPECT_TRUE(notMatches("struct S { S(S&&); };",
1084 cxxConstructorDecl(isDefaultConstructor())));
1085 EXPECT_TRUE(notMatches("struct S { S(S&&); };",
1086 cxxConstructorDecl(isCopyConstructor())));
1087 EXPECT_TRUE(matches("struct S { S(S&&); };",
1088 cxxConstructorDecl(isMoveConstructor())));
1089}
1090
1091TEST(ConstructorDeclaration, IsUserProvided) {
1092 EXPECT_TRUE(notMatches("struct S { int X = 0; };",
1093 cxxConstructorDecl(isUserProvided())));
1094 EXPECT_TRUE(notMatches("struct S { S() = default; };",
1095 cxxConstructorDecl(isUserProvided())));
1096 EXPECT_TRUE(notMatches("struct S { S() = delete; };",
1097 cxxConstructorDecl(isUserProvided())));
1098 EXPECT_TRUE(
1099 matches("struct S { S(); };", cxxConstructorDecl(isUserProvided())));
1100 EXPECT_TRUE(matches("struct S { S(); }; S::S(){}",
1101 cxxConstructorDecl(isUserProvided())));
1102}
1103
1104TEST(ConstructorDeclaration, IsDelegatingConstructor) {
1105 EXPECT_TRUE(notMatches("struct S { S(); S(int); int X; };",
1106 cxxConstructorDecl(isDelegatingConstructor())));
1107 EXPECT_TRUE(notMatches("struct S { S(){} S(int X) : X(X) {} int X; };",
1108 cxxConstructorDecl(isDelegatingConstructor())));
1109 EXPECT_TRUE(matches(
1110 "struct S { S() : S(0) {} S(int X) : X(X) {} int X; };",
1111 cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(0))));
1112 EXPECT_TRUE(matches(
1113 "struct S { S(); S(int X); int X; }; S::S(int X) : S() {}",
1114 cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(1))));
1115}
1116
1117TEST(StringLiteral, HasSize) {
1118 StatementMatcher Literal = stringLiteral(hasSize(4));
1119 EXPECT_TRUE(matches("const char *s = \"abcd\";", Literal));
1120 // wide string
1121 EXPECT_TRUE(matches("const wchar_t *s = L\"abcd\";", Literal));
1122 // with escaped characters
1123 EXPECT_TRUE(matches("const char *s = \"\x05\x06\x07\x08\";", Literal));
1124 // no matching, too small
1125 EXPECT_TRUE(notMatches("const char *s = \"ab\";", Literal));
1126}
1127
1128TEST(Matcher, HasNameSupportsNamespaces) {
1129 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1130 recordDecl(hasName("a::b::C"))));
1131 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1132 recordDecl(hasName("::a::b::C"))));
1133 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1134 recordDecl(hasName("b::C"))));
1135 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1136 recordDecl(hasName("C"))));
1137 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1138 recordDecl(hasName("c::b::C"))));
1139 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1140 recordDecl(hasName("a::c::C"))));
1141 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1142 recordDecl(hasName("a::b::A"))));
1143 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1144 recordDecl(hasName("::C"))));
1145 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1146 recordDecl(hasName("::b::C"))));
1147 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1148 recordDecl(hasName("z::a::b::C"))));
1149 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1150 recordDecl(hasName("a+b::C"))));
1151 EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
1152 recordDecl(hasName("C"))));
1153}
1154
1155TEST(Matcher, HasNameSupportsOuterClasses) {
1156 EXPECT_TRUE(
1157 matches("class A { class B { class C; }; };",
1158 recordDecl(hasName("A::B::C"))));
1159 EXPECT_TRUE(
1160 matches("class A { class B { class C; }; };",
1161 recordDecl(hasName("::A::B::C"))));
1162 EXPECT_TRUE(
1163 matches("class A { class B { class C; }; };",
1164 recordDecl(hasName("B::C"))));
1165 EXPECT_TRUE(
1166 matches("class A { class B { class C; }; };",
1167 recordDecl(hasName("C"))));
1168 EXPECT_TRUE(
1169 notMatches("class A { class B { class C; }; };",
1170 recordDecl(hasName("c::B::C"))));
1171 EXPECT_TRUE(
1172 notMatches("class A { class B { class C; }; };",
1173 recordDecl(hasName("A::c::C"))));
1174 EXPECT_TRUE(
1175 notMatches("class A { class B { class C; }; };",
1176 recordDecl(hasName("A::B::A"))));
1177 EXPECT_TRUE(
1178 notMatches("class A { class B { class C; }; };",
1179 recordDecl(hasName("::C"))));
1180 EXPECT_TRUE(
1181 notMatches("class A { class B { class C; }; };",
1182 recordDecl(hasName("::B::C"))));
1183 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
1184 recordDecl(hasName("z::A::B::C"))));
1185 EXPECT_TRUE(
1186 notMatches("class A { class B { class C; }; };",
1187 recordDecl(hasName("A+B::C"))));
1188}
1189
1190TEST(Matcher, HasNameSupportsInlinedNamespaces) {
1191 std::string code = "namespace a { inline namespace b { class C; } }";
1192 EXPECT_TRUE(matches(code, recordDecl(hasName("a::b::C"))));
1193 EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
1194 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::b::C"))));
1195 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
1196}
1197
1198TEST(Matcher, HasNameSupportsAnonymousNamespaces) {
1199 std::string code = "namespace a { namespace { class C; } }";
1200 EXPECT_TRUE(
1201 matches(code, recordDecl(hasName("a::(anonymous namespace)::C"))));
1202 EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
1203 EXPECT_TRUE(
1204 matches(code, recordDecl(hasName("::a::(anonymous namespace)::C"))));
1205 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
1206}
1207
1208TEST(Matcher, HasNameSupportsAnonymousOuterClasses) {
1209 EXPECT_TRUE(matches("class A { class { class C; } x; };",
1210 recordDecl(hasName("A::(anonymous class)::C"))));
1211 EXPECT_TRUE(matches("class A { class { class C; } x; };",
1212 recordDecl(hasName("::A::(anonymous class)::C"))));
1213 EXPECT_FALSE(matches("class A { class { class C; } x; };",
1214 recordDecl(hasName("::A::C"))));
1215 EXPECT_TRUE(matches("class A { struct { class C; } x; };",
1216 recordDecl(hasName("A::(anonymous struct)::C"))));
1217 EXPECT_TRUE(matches("class A { struct { class C; } x; };",
1218 recordDecl(hasName("::A::(anonymous struct)::C"))));
1219 EXPECT_FALSE(matches("class A { struct { class C; } x; };",
1220 recordDecl(hasName("::A::C"))));
1221}
1222
1223TEST(Matcher, HasNameSupportsFunctionScope) {
1224 std::string code =
1225 "namespace a { void F(int a) { struct S { int m; }; int i; } }";
1226 EXPECT_TRUE(matches(code, varDecl(hasName("i"))));
1227 EXPECT_FALSE(matches(code, varDecl(hasName("F()::i"))));
1228
1229 EXPECT_TRUE(matches(code, fieldDecl(hasName("m"))));
1230 EXPECT_TRUE(matches(code, fieldDecl(hasName("S::m"))));
1231 EXPECT_TRUE(matches(code, fieldDecl(hasName("F(int)::S::m"))));
1232 EXPECT_TRUE(matches(code, fieldDecl(hasName("a::F(int)::S::m"))));
1233 EXPECT_TRUE(matches(code, fieldDecl(hasName("::a::F(int)::S::m"))));
1234}
1235
1236TEST(Matcher, HasAnyName) {
1237 const std::string Code = "namespace a { namespace b { class C; } }";
1238
1239 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "a::b::C"))));
1240 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("a::b::C", "XX"))));
1241 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX::C", "a::b::C"))));
1242 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "C"))));
1243
1244 EXPECT_TRUE(notMatches(Code, recordDecl(hasAnyName("::C", "::b::C"))));
1245 EXPECT_TRUE(
1246 matches(Code, recordDecl(hasAnyName("::C", "::b::C", "::a::b::C"))));
1247
1248 std::vector<StringRef> Names = {"::C", "::b::C", "::a::b::C"};
1249 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName(Names))));
1250}
1251
1252TEST(Matcher, IsDefinition) {
1253 DeclarationMatcher DefinitionOfClassA =
1254 recordDecl(hasName("A"), isDefinition());
1255 EXPECT_TRUE(matches("class A {};", DefinitionOfClassA));
1256 EXPECT_TRUE(notMatches("class A;", DefinitionOfClassA));
1257
1258 DeclarationMatcher DefinitionOfVariableA =
1259 varDecl(hasName("a"), isDefinition());
1260 EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));
1261 EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));
1262
1263 DeclarationMatcher DefinitionOfMethodA =
1264 cxxMethodDecl(hasName("a"), isDefinition());
1265 EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));
1266 EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));
1267}
1268
1269TEST(Matcher, HandlesNullQualTypes) {
1270 // FIXME: Add a Type matcher so we can replace uses of this
1271 // variable with Type(True())
1272 const TypeMatcher AnyType = anything();
1273
1274 // We don't really care whether this matcher succeeds; we're testing that
1275 // it completes without crashing.
1276 EXPECT_TRUE(matches(
1277 "struct A { };"
1278 "template <typename T>"
1279 "void f(T t) {"
1280 " T local_t(t /* this becomes a null QualType in the AST */);"
1281 "}"
1282 "void g() {"
1283 " f(0);"
1284 "}",
1285 expr(hasType(TypeMatcher(
1286 anyOf(
1287 TypeMatcher(hasDeclaration(anything())),
1288 pointsTo(AnyType),
1289 references(AnyType)
1290 // Other QualType matchers should go here.
1291 ))))));
1292}
1293
1294
1295TEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) {
1296 EXPECT_TRUE(matches("void f() { }",
1297 compoundStmt(statementCountIs(0))));
1298 EXPECT_TRUE(notMatches("void f() {}",
1299 compoundStmt(statementCountIs(1))));
1300}
1301
1302TEST(StatementCountIs, AppearsToMatchOnlyOneCount) {
1303 EXPECT_TRUE(matches("void f() { 1; }",
1304 compoundStmt(statementCountIs(1))));
1305 EXPECT_TRUE(notMatches("void f() { 1; }",
1306 compoundStmt(statementCountIs(0))));
1307 EXPECT_TRUE(notMatches("void f() { 1; }",
1308 compoundStmt(statementCountIs(2))));
1309}
1310
1311TEST(StatementCountIs, WorksWithMultipleStatements) {
1312 EXPECT_TRUE(matches("void f() { 1; 2; 3; }",
1313 compoundStmt(statementCountIs(3))));
1314}
1315
1316TEST(StatementCountIs, WorksWithNestedCompoundStatements) {
1317 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1318 compoundStmt(statementCountIs(1))));
1319 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1320 compoundStmt(statementCountIs(2))));
1321 EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
1322 compoundStmt(statementCountIs(3))));
1323 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1324 compoundStmt(statementCountIs(4))));
1325}
1326
1327TEST(Member, WorksInSimplestCase) {
1328 EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
1329 memberExpr(member(hasName("first")))));
1330}
1331
1332TEST(Member, DoesNotMatchTheBaseExpression) {
1333 // Don't pick out the wrong part of the member expression, this should
1334 // be checking the member (name) only.
1335 EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
1336 memberExpr(member(hasName("first")))));
1337}
1338
1339TEST(Member, MatchesInMemberFunctionCall) {
1340 EXPECT_TRUE(matches("void f() {"
1341 " struct { void first() {}; } s;"
1342 " s.first();"
1343 "};",
1344 memberExpr(member(hasName("first")))));
1345}
1346
1347TEST(Member, MatchesMember) {
1348 EXPECT_TRUE(matches(
1349 "struct A { int i; }; void f() { A a; a.i = 2; }",
1350 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
1351 EXPECT_TRUE(notMatches(
1352 "struct A { float f; }; void f() { A a; a.f = 2.0f; }",
1353 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
1354}
1355
1356
1357TEST(Member, UnderstandsAccess) {
1358 EXPECT_TRUE(matches(
1359 "struct A { int i; };", fieldDecl(isPublic(), hasName("i"))));
1360 EXPECT_TRUE(notMatches(
1361 "struct A { int i; };", fieldDecl(isProtected(), hasName("i"))));
1362 EXPECT_TRUE(notMatches(
1363 "struct A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
1364
1365 EXPECT_TRUE(notMatches(
1366 "class A { int i; };", fieldDecl(isPublic(), hasName("i"))));
1367 EXPECT_TRUE(notMatches(
1368 "class A { int i; };", fieldDecl(isProtected(), hasName("i"))));
1369 EXPECT_TRUE(matches(
1370 "class A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
1371
1372 EXPECT_TRUE(notMatches(
1373 "class A { protected: int i; };", fieldDecl(isPublic(), hasName("i"))));
1374 EXPECT_TRUE(matches("class A { protected: int i; };",
1375 fieldDecl(isProtected(), hasName("i"))));
1376 EXPECT_TRUE(notMatches(
1377 "class A { protected: int i; };", fieldDecl(isPrivate(), hasName("i"))));
1378
1379 // Non-member decls have the AccessSpecifier AS_none and thus aren't matched.
1380 EXPECT_TRUE(notMatches("int i;", varDecl(isPublic(), hasName("i"))));
1381 EXPECT_TRUE(notMatches("int i;", varDecl(isProtected(), hasName("i"))));
1382 EXPECT_TRUE(notMatches("int i;", varDecl(isPrivate(), hasName("i"))));
1383}
1384
1385TEST(hasDynamicExceptionSpec, MatchesDynamicExceptionSpecifications) {
1386 EXPECT_TRUE(notMatches("void f();", functionDecl(hasDynamicExceptionSpec())));
1387 EXPECT_TRUE(notMatches("void g() noexcept;",
1388 functionDecl(hasDynamicExceptionSpec())));
1389 EXPECT_TRUE(notMatches("void h() noexcept(true);",
1390 functionDecl(hasDynamicExceptionSpec())));
1391 EXPECT_TRUE(notMatches("void i() noexcept(false);",
1392 functionDecl(hasDynamicExceptionSpec())));
1393 EXPECT_TRUE(
1394 matches("void j() throw();", functionDecl(hasDynamicExceptionSpec())));
1395 EXPECT_TRUE(
1396 matches("void k() throw(int);", functionDecl(hasDynamicExceptionSpec())));
1397 EXPECT_TRUE(
1398 matches("void l() throw(...);", functionDecl(hasDynamicExceptionSpec())));
1399}
1400
1401TEST(HasObjectExpression, DoesNotMatchMember) {
1402 EXPECT_TRUE(notMatches(
1403 "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
1404 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
1405}
1406
1407TEST(HasObjectExpression, MatchesBaseOfVariable) {
1408 EXPECT_TRUE(matches(
1409 "struct X { int m; }; void f(X x) { x.m; }",
1410 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
1411 EXPECT_TRUE(matches(
1412 "struct X { int m; }; void f(X* x) { x->m; }",
1413 memberExpr(hasObjectExpression(
1414 hasType(pointsTo(recordDecl(hasName("X"))))))));
1415}
1416
1417TEST(HasObjectExpression,
1418 MatchesObjectExpressionOfImplicitlyFormedMemberExpression) {
1419 EXPECT_TRUE(matches(
1420 "class X {}; struct S { X m; void f() { this->m; } };",
1421 memberExpr(hasObjectExpression(
1422 hasType(pointsTo(recordDecl(hasName("S"))))))));
1423 EXPECT_TRUE(matches(
1424 "class X {}; struct S { X m; void f() { m; } };",
1425 memberExpr(hasObjectExpression(
1426 hasType(pointsTo(recordDecl(hasName("S"))))))));
1427}
1428
1429TEST(Field, DoesNotMatchNonFieldMembers) {
1430 EXPECT_TRUE(notMatches("class X { void m(); };", fieldDecl(hasName("m"))));
1431 EXPECT_TRUE(notMatches("class X { class m {}; };", fieldDecl(hasName("m"))));
1432 EXPECT_TRUE(notMatches("class X { enum { m }; };", fieldDecl(hasName("m"))));
1433 EXPECT_TRUE(notMatches("class X { enum m {}; };", fieldDecl(hasName("m"))));
1434}
1435
1436TEST(Field, MatchesField) {
1437 EXPECT_TRUE(matches("class X { int m; };", fieldDecl(hasName("m"))));
1438}
1439
1440TEST(IsVolatileQualified, QualifiersMatch) {
1441 EXPECT_TRUE(matches("volatile int i = 42;",
1442 varDecl(hasType(isVolatileQualified()))));
1443 EXPECT_TRUE(notMatches("volatile int *i;",
1444 varDecl(hasType(isVolatileQualified()))));
1445 EXPECT_TRUE(matches("typedef volatile int v_int; v_int i = 42;",
1446 varDecl(hasType(isVolatileQualified()))));
1447}
1448
1449TEST(IsConstQualified, MatchesConstInt) {
1450 EXPECT_TRUE(matches("const int i = 42;",
1451 varDecl(hasType(isConstQualified()))));
1452}
1453
1454TEST(IsConstQualified, MatchesConstPointer) {
1455 EXPECT_TRUE(matches("int i = 42; int* const p(&i);",
1456 varDecl(hasType(isConstQualified()))));
1457}
1458
1459TEST(IsConstQualified, MatchesThroughTypedef) {
1460 EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
1461 varDecl(hasType(isConstQualified()))));
1462 EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p(0);",
1463 varDecl(hasType(isConstQualified()))));
1464}
1465
1466TEST(IsConstQualified, DoesNotMatchInappropriately) {
1467 EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
1468 varDecl(hasType(isConstQualified()))));
1469 EXPECT_TRUE(notMatches("int const* p;",
1470 varDecl(hasType(isConstQualified()))));
1471}
1472
1473TEST(DeclCount, DeclCountIsCorrect) {
1474 EXPECT_TRUE(matches("void f() {int i,j;}",
1475 declStmt(declCountIs(2))));
1476 EXPECT_TRUE(notMatches("void f() {int i,j; int k;}",
1477 declStmt(declCountIs(3))));
1478 EXPECT_TRUE(notMatches("void f() {int i,j, k, l;}",
1479 declStmt(declCountIs(3))));
1480}
1481
1482
1483TEST(EachOf, TriggersForEachMatch) {
1484 EXPECT_TRUE(matchAndVerifyResultTrue(
1485 "class A { int a; int b; };",
1486 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
1487 has(fieldDecl(hasName("b")).bind("v")))),
1488 llvm::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 2)));
1489}
1490
1491TEST(EachOf, BehavesLikeAnyOfUnlessBothMatch) {
1492 EXPECT_TRUE(matchAndVerifyResultTrue(
1493 "class A { int a; int c; };",
1494 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
1495 has(fieldDecl(hasName("b")).bind("v")))),
1496 llvm::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 1)));
1497 EXPECT_TRUE(matchAndVerifyResultTrue(
1498 "class A { int c; int b; };",
1499 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
1500 has(fieldDecl(hasName("b")).bind("v")))),
1501 llvm::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 1)));
1502 EXPECT_TRUE(notMatches(
1503 "class A { int c; int d; };",
1504 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
1505 has(fieldDecl(hasName("b")).bind("v"))))));
1506}
1507
1508TEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) {
1509 // Make sure that we can both match the class by name (::X) and by the type
1510 // the template was instantiated with (via a field).
1511
1512 EXPECT_TRUE(matches(
1513 "template <typename T> class X {}; class A {}; X<A> x;",
1514 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
1515
1516 EXPECT_TRUE(matches(
1517 "template <typename T> class X { T t; }; class A {}; X<A> x;",
1518 cxxRecordDecl(isTemplateInstantiation(), hasDescendant(
1519 fieldDecl(hasType(recordDecl(hasName("A"))))))));
1520}
1521
1522TEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) {
1523 EXPECT_TRUE(matches(
1524 "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
1525 functionDecl(hasParameter(0, hasType(recordDecl(hasName("A")))),
1526 isTemplateInstantiation())));
1527}
1528
1529TEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) {
1530 EXPECT_TRUE(matches(
1531 "template <typename T> class X { T t; }; class A {};"
1532 "template class X<A>;",
1533 cxxRecordDecl(isTemplateInstantiation(), hasDescendant(
1534 fieldDecl(hasType(recordDecl(hasName("A"))))))));
1535}
1536
1537TEST(IsTemplateInstantiation,
1538 MatchesInstantiationOfPartiallySpecializedClassTemplate) {
1539 EXPECT_TRUE(matches(
1540 "template <typename T> class X {};"
1541 "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
1542 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
1543}
1544
1545TEST(IsTemplateInstantiation,
1546 MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
1547 EXPECT_TRUE(matches(
1548 "class A {};"
1549 "class X {"
1550 " template <typename U> class Y { U u; };"
1551 " Y<A> y;"
1552 "};",
1553 cxxRecordDecl(hasName("::X::Y"), isTemplateInstantiation())));
1554}
1555
1556TEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) {
1557 // FIXME: Figure out whether this makes sense. It doesn't affect the
1558 // normal use case as long as the uppermost instantiation always is marked
1559 // as template instantiation, but it might be confusing as a predicate.
1560 EXPECT_TRUE(matches(
1561 "class A {};"
1562 "template <typename T> class X {"
1563 " template <typename U> class Y { U u; };"
1564 " Y<T> y;"
1565 "}; X<A> x;",
1566 cxxRecordDecl(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
1567}
1568
1569TEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) {
1570 EXPECT_TRUE(notMatches(
1571 "template <typename T> class X {}; class A {};"
1572 "template <> class X<A> {}; X<A> x;",
1573 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
1574}
1575
1576TEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) {
1577 EXPECT_TRUE(notMatches(
1578 "class A {}; class Y { A a; };",
1579 cxxRecordDecl(isTemplateInstantiation())));
1580}
1581
1582TEST(IsInstantiated, MatchesInstantiation) {
1583 EXPECT_TRUE(
1584 matches("template<typename T> class A { T i; }; class Y { A<int> a; };",
1585 cxxRecordDecl(isInstantiated())));
1586}
1587
1588TEST(IsInstantiated, NotMatchesDefinition) {
1589 EXPECT_TRUE(notMatches("template<typename T> class A { T i; };",
1590 cxxRecordDecl(isInstantiated())));
1591}
1592
1593TEST(IsInTemplateInstantiation, MatchesInstantiationStmt) {
1594 EXPECT_TRUE(matches("template<typename T> struct A { A() { T i; } };"
1595 "class Y { A<int> a; }; Y y;",
1596 declStmt(isInTemplateInstantiation())));
1597}
1598
1599TEST(IsInTemplateInstantiation, NotMatchesDefinitionStmt) {
1600 EXPECT_TRUE(notMatches("template<typename T> struct A { void x() { T i; } };",
1601 declStmt(isInTemplateInstantiation())));
1602}
1603
1604TEST(IsInstantiated, MatchesFunctionInstantiation) {
1605 EXPECT_TRUE(
1606 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
1607 functionDecl(isInstantiated())));
1608}
1609
1610TEST(IsInstantiated, NotMatchesFunctionDefinition) {
1611 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
1612 varDecl(isInstantiated())));
1613}
1614
1615TEST(IsInTemplateInstantiation, MatchesFunctionInstantiationStmt) {
1616 EXPECT_TRUE(
1617 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
1618 declStmt(isInTemplateInstantiation())));
1619}
1620
1621TEST(IsInTemplateInstantiation, NotMatchesFunctionDefinitionStmt) {
1622 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
1623 declStmt(isInTemplateInstantiation())));
1624}
1625
1626TEST(IsInTemplateInstantiation, Sharing) {
1627 auto Matcher = binaryOperator(unless(isInTemplateInstantiation()));
1628 // FIXME: Node sharing is an implementation detail, exposing it is ugly
1629 // and makes the matcher behave in non-obvious ways.
1630 EXPECT_TRUE(notMatches(
1631 "int j; template<typename T> void A(T t) { j += 42; } void x() { A(0); }",
1632 Matcher));
1633 EXPECT_TRUE(matches(
1634 "int j; template<typename T> void A(T t) { j += t; } void x() { A(0); }",
1635 Matcher));
1636}
1637
1638TEST(IsExplicitTemplateSpecialization,
1639 DoesNotMatchPrimaryTemplate) {
1640 EXPECT_TRUE(notMatches(
1641 "template <typename T> class X {};",
1642 cxxRecordDecl(isExplicitTemplateSpecialization())));
1643 EXPECT_TRUE(notMatches(
1644 "template <typename T> void f(T t);",
1645 functionDecl(isExplicitTemplateSpecialization())));
1646}
1647
1648TEST(IsExplicitTemplateSpecialization,
1649 DoesNotMatchExplicitTemplateInstantiations) {
1650 EXPECT_TRUE(notMatches(
1651 "template <typename T> class X {};"
1652 "template class X<int>; extern template class X<long>;",
1653 cxxRecordDecl(isExplicitTemplateSpecialization())));
1654 EXPECT_TRUE(notMatches(
1655 "template <typename T> void f(T t) {}"
1656 "template void f(int t); extern template void f(long t);",
1657 functionDecl(isExplicitTemplateSpecialization())));
1658}
1659
1660TEST(IsExplicitTemplateSpecialization,
1661 DoesNotMatchImplicitTemplateInstantiations) {
1662 EXPECT_TRUE(notMatches(
1663 "template <typename T> class X {}; X<int> x;",
1664 cxxRecordDecl(isExplicitTemplateSpecialization())));
1665 EXPECT_TRUE(notMatches(
1666 "template <typename T> void f(T t); void g() { f(10); }",
1667 functionDecl(isExplicitTemplateSpecialization())));
1668}
1669
1670TEST(IsExplicitTemplateSpecialization,
1671 MatchesExplicitTemplateSpecializations) {
1672 EXPECT_TRUE(matches(
1673 "template <typename T> class X {};"
1674 "template<> class X<int> {};",
1675 cxxRecordDecl(isExplicitTemplateSpecialization())));
1676 EXPECT_TRUE(matches(
1677 "template <typename T> void f(T t) {}"
1678 "template<> void f(int t) {}",
1679 functionDecl(isExplicitTemplateSpecialization())));
1680}
1681
1682TEST(TypeMatching, MatchesBool) {
1683 EXPECT_TRUE(matches("struct S { bool func(); };",
1684 cxxMethodDecl(returns(booleanType()))));
1685 EXPECT_TRUE(notMatches("struct S { void func(); };",
1686 cxxMethodDecl(returns(booleanType()))));
1687}
1688
1689TEST(TypeMatching, MatchesVoid) {
1690 EXPECT_TRUE(matches("struct S { void func(); };",
1691 cxxMethodDecl(returns(voidType()))));
1692}
1693
1694TEST(TypeMatching, MatchesRealFloats) {
1695 EXPECT_TRUE(matches("struct S { float func(); };",
1696 cxxMethodDecl(returns(realFloatingPointType()))));
1697 EXPECT_TRUE(notMatches("struct S { int func(); };",
1698 cxxMethodDecl(returns(realFloatingPointType()))));
1699 EXPECT_TRUE(matches("struct S { long double func(); };",
1700 cxxMethodDecl(returns(realFloatingPointType()))));
1701}
1702
1703TEST(TypeMatching, MatchesArrayTypes) {
1704 EXPECT_TRUE(matches("int a[] = {2,3};", arrayType()));
1705 EXPECT_TRUE(matches("int a[42];", arrayType()));
1706 EXPECT_TRUE(matches("void f(int b) { int a[b]; }", arrayType()));
1707
1708 EXPECT_TRUE(notMatches("struct A {}; A a[7];",
1709 arrayType(hasElementType(builtinType()))));
1710
1711 EXPECT_TRUE(matches(
1712 "int const a[] = { 2, 3 };",
1713 qualType(arrayType(hasElementType(builtinType())))));
1714 EXPECT_TRUE(matches(
1715 "int const a[] = { 2, 3 };",
1716 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
1717 EXPECT_TRUE(matches(
1718 "typedef const int T; T x[] = { 1, 2 };",
1719 qualType(isConstQualified(), arrayType())));
1720
1721 EXPECT_TRUE(notMatches(
1722 "int a[] = { 2, 3 };",
1723 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
1724 EXPECT_TRUE(notMatches(
1725 "int a[] = { 2, 3 };",
1726 qualType(arrayType(hasElementType(isConstQualified(), builtinType())))));
1727 EXPECT_TRUE(notMatches(
1728 "int const a[] = { 2, 3 };",
1729 qualType(arrayType(hasElementType(builtinType())),
1730 unless(isConstQualified()))));
1731
1732 EXPECT_TRUE(matches("int a[2];",
1733 constantArrayType(hasElementType(builtinType()))));
1734 EXPECT_TRUE(matches("const int a = 0;", qualType(isInteger())));
1735}
1736
1737TEST(TypeMatching, DecayedType) {
1738 EXPECT_TRUE(matches("void f(int i[]);", valueDecl(hasType(decayedType(hasDecayedType(pointerType()))))));
1739 EXPECT_TRUE(notMatches("int i[7];", decayedType()));
1740}
1741
1742TEST(TypeMatching, MatchesComplexTypes) {
1743 EXPECT_TRUE(matches("_Complex float f;", complexType()));
1744 EXPECT_TRUE(matches(
1745 "_Complex float f;",
1746 complexType(hasElementType(builtinType()))));
1747 EXPECT_TRUE(notMatches(
1748 "_Complex float f;",
1749 complexType(hasElementType(isInteger()))));
1750}
1751
1752TEST(NS, Anonymous) {
1753 EXPECT_TRUE(notMatches("namespace N {}", namespaceDecl(isAnonymous())));
1754 EXPECT_TRUE(matches("namespace {}", namespaceDecl(isAnonymous())));
1755}
1756
1757TEST(EqualsBoundNodeMatcher, QualType) {
1758 EXPECT_TRUE(matches(
1759 "int i = 1;", varDecl(hasType(qualType().bind("type")),
1760 hasInitializer(ignoringParenImpCasts(
1761 hasType(qualType(equalsBoundNode("type"))))))));
1762 EXPECT_TRUE(notMatches("int i = 1.f;",
1763 varDecl(hasType(qualType().bind("type")),
1764 hasInitializer(ignoringParenImpCasts(hasType(
1765 qualType(equalsBoundNode("type"))))))));
1766}
1767
1768TEST(EqualsBoundNodeMatcher, NonMatchingTypes) {
1769 EXPECT_TRUE(notMatches(
1770 "int i = 1;", varDecl(namedDecl(hasName("i")).bind("name"),
1771 hasInitializer(ignoringParenImpCasts(
1772 hasType(qualType(equalsBoundNode("type"))))))));
1773}
1774
1775TEST(EqualsBoundNodeMatcher, Stmt) {
1776 EXPECT_TRUE(
1777 matches("void f() { if(true) {} }",
1778 stmt(allOf(ifStmt().bind("if"),
1779 hasParent(stmt(has(stmt(equalsBoundNode("if")))))))));
1780
1781 EXPECT_TRUE(notMatches(
1782 "void f() { if(true) { if (true) {} } }",
1783 stmt(allOf(ifStmt().bind("if"), has(stmt(equalsBoundNode("if")))))));
1784}
1785
1786TEST(EqualsBoundNodeMatcher, Decl) {
1787 EXPECT_TRUE(matches(
1788 "class X { class Y {}; };",
1789 decl(allOf(recordDecl(hasName("::X::Y")).bind("record"),
1790 hasParent(decl(has(decl(equalsBoundNode("record")))))))));
1791
1792 EXPECT_TRUE(notMatches("class X { class Y {}; };",
1793 decl(allOf(recordDecl(hasName("::X")).bind("record"),
1794 has(decl(equalsBoundNode("record")))))));
1795}
1796
1797TEST(EqualsBoundNodeMatcher, Type) {
1798 EXPECT_TRUE(matches(
1799 "class X { int a; int b; };",
1800 recordDecl(
1801 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
1802 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
1803
1804 EXPECT_TRUE(notMatches(
1805 "class X { int a; double b; };",
1806 recordDecl(
1807 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
1808 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
1809}
1810
1811TEST(EqualsBoundNodeMatcher, UsingForEachDescendant) {
1812 EXPECT_TRUE(matchAndVerifyResultTrue(
1813 "int f() {"
1814 " if (1) {"
1815 " int i = 9;"
1816 " }"
1817 " int j = 10;"
1818 " {"
1819 " float k = 9.0;"
1820 " }"
1821 " return 0;"
1822 "}",
1823 // Look for variable declarations within functions whose type is the same
1824 // as the function return type.
1825 functionDecl(returns(qualType().bind("type")),
1826 forEachDescendant(varDecl(hasType(
1827 qualType(equalsBoundNode("type")))).bind("decl"))),
1828 // Only i and j should match, not k.
1829 llvm::make_unique<VerifyIdIsBoundTo<VarDecl>>("decl", 2)));
1830}
1831
1832TEST(EqualsBoundNodeMatcher, FiltersMatchedCombinations) {
1833 EXPECT_TRUE(matchAndVerifyResultTrue(
1834 "void f() {"
1835 " int x;"
1836 " double d;"
1837 " x = d + x - d + x;"
1838 "}",
1839 functionDecl(
1840 hasName("f"), forEachDescendant(varDecl().bind("d")),
1841 forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d")))))),
1842 llvm::make_unique<VerifyIdIsBoundTo<VarDecl>>("d", 5)));
1843}
1844
1845TEST(EqualsBoundNodeMatcher, UnlessDescendantsOfAncestorsMatch) {
1846 EXPECT_TRUE(matchAndVerifyResultTrue(
1847 "struct StringRef { int size() const; const char* data() const; };"
1848 "void f(StringRef v) {"
1849 " v.data();"
1850 "}",
1851 cxxMemberCallExpr(
1852 callee(cxxMethodDecl(hasName("data"))),
1853 on(declRefExpr(to(
1854 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
1855 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
1856 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
1857 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
1858 .bind("data"),
1859 llvm::make_unique<VerifyIdIsBoundTo<Expr>>("data", 1)));
1860
1861 EXPECT_FALSE(matches(
1862 "struct StringRef { int size() const; const char* data() const; };"
1863 "void f(StringRef v) {"
1864 " v.data();"
1865 " v.size();"
1866 "}",
1867 cxxMemberCallExpr(
1868 callee(cxxMethodDecl(hasName("data"))),
1869 on(declRefExpr(to(
1870 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
1871 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
1872 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
1873 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
1874 .bind("data")));
1875}
1876
1877TEST(NullPointerConstants, Basic) {
1878 EXPECT_TRUE(matches("#define NULL ((void *)0)\n"
1879 "void *v1 = NULL;", expr(nullPointerConstant())));
1880 EXPECT_TRUE(matches("void *v2 = nullptr;", expr(nullPointerConstant())));
1881 EXPECT_TRUE(matches("void *v3 = __null;", expr(nullPointerConstant())));
1882 EXPECT_TRUE(matches("char *cp = (char *)0;", expr(nullPointerConstant())));
1883 EXPECT_TRUE(matches("int *ip = 0;", expr(nullPointerConstant())));
1884 EXPECT_TRUE(notMatches("int i = 0;", expr(nullPointerConstant())));
1885}
1886
1887} // namespace ast_matchers
1888} // namespace clang