blob: 7f1f08312921bfebb6ad721f906ffec62addc0a3 [file] [log] [blame]
Manuel Klimek4da21662012-07-06 05:48:52 +00001//===- unittest/Tooling/ASTMatchersTest.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/ASTMatchers/ASTMatchers.h"
12#include "clang/ASTMatchers/ASTMatchFinder.h"
13#include "clang/Tooling/Tooling.h"
14#include "gtest/gtest.h"
15
16namespace clang {
17namespace ast_matchers {
18
Benjamin Kramer78a0ce42012-07-10 17:30:44 +000019#if GTEST_HAS_DEATH_TEST
Manuel Klimek4da21662012-07-06 05:48:52 +000020TEST(HasNameDeathTest, DiesOnEmptyName) {
21 ASSERT_DEBUG_DEATH({
22 DeclarationMatcher HasEmptyName = record(hasName(""));
23 EXPECT_TRUE(notMatches("class X {};", HasEmptyName));
24 }, "");
25}
26
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +000027TEST(HasNameDeathTest, DiesOnEmptyPattern) {
28 ASSERT_DEBUG_DEATH({
29 DeclarationMatcher HasEmptyName = record(matchesName(""));
30 EXPECT_TRUE(notMatches("class X {};", HasEmptyName));
31 }, "");
32}
33
Manuel Klimek4da21662012-07-06 05:48:52 +000034TEST(IsDerivedFromDeathTest, DiesOnEmptyBaseName) {
35 ASSERT_DEBUG_DEATH({
36 DeclarationMatcher IsDerivedFromEmpty = record(isDerivedFrom(""));
37 EXPECT_TRUE(notMatches("class X {};", IsDerivedFromEmpty));
38 }, "");
39}
Benjamin Kramer78a0ce42012-07-10 17:30:44 +000040#endif
Manuel Klimek4da21662012-07-06 05:48:52 +000041
Manuel Klimek715c9562012-07-25 10:02:02 +000042TEST(Decl, MatchesDeclarations) {
43 EXPECT_TRUE(notMatches("", decl(usingDecl())));
44 EXPECT_TRUE(matches("namespace x { class X {}; } using x::X;",
45 decl(usingDecl())));
46}
47
Manuel Klimek4da21662012-07-06 05:48:52 +000048TEST(NameableDeclaration, MatchesVariousDecls) {
49 DeclarationMatcher NamedX = nameableDeclaration(hasName("X"));
50 EXPECT_TRUE(matches("typedef int X;", NamedX));
51 EXPECT_TRUE(matches("int X;", NamedX));
52 EXPECT_TRUE(matches("class foo { virtual void X(); };", NamedX));
53 EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", NamedX));
54 EXPECT_TRUE(matches("void foo() { int X; }", NamedX));
55 EXPECT_TRUE(matches("namespace X { }", NamedX));
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +000056 EXPECT_TRUE(matches("enum X { A, B, C };", NamedX));
Manuel Klimek4da21662012-07-06 05:48:52 +000057
58 EXPECT_TRUE(notMatches("#define X 1", NamedX));
59}
60
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +000061TEST(NameableDeclaration, REMatchesVariousDecls) {
62 DeclarationMatcher NamedX = nameableDeclaration(matchesName("::X"));
63 EXPECT_TRUE(matches("typedef int Xa;", NamedX));
64 EXPECT_TRUE(matches("int Xb;", NamedX));
65 EXPECT_TRUE(matches("class foo { virtual void Xc(); };", NamedX));
66 EXPECT_TRUE(matches("void foo() try { } catch(int Xdef) { }", NamedX));
67 EXPECT_TRUE(matches("void foo() { int Xgh; }", NamedX));
68 EXPECT_TRUE(matches("namespace Xij { }", NamedX));
69 EXPECT_TRUE(matches("enum X { A, B, C };", NamedX));
70
71 EXPECT_TRUE(notMatches("#define Xkl 1", NamedX));
72
73 DeclarationMatcher StartsWithNo = nameableDeclaration(matchesName("::no"));
74 EXPECT_TRUE(matches("int no_foo;", StartsWithNo));
75 EXPECT_TRUE(matches("class foo { virtual void nobody(); };", StartsWithNo));
76
77 DeclarationMatcher Abc = nameableDeclaration(matchesName("a.*b.*c"));
78 EXPECT_TRUE(matches("int abc;", Abc));
79 EXPECT_TRUE(matches("int aFOObBARc;", Abc));
80 EXPECT_TRUE(notMatches("int cab;", Abc));
81 EXPECT_TRUE(matches("int cabc;", Abc));
82}
83
Manuel Klimek4da21662012-07-06 05:48:52 +000084TEST(DeclarationMatcher, MatchClass) {
85 DeclarationMatcher ClassMatcher(record());
Manuel Klimeke265c872012-07-10 14:21:30 +000086#if !defined(_MSC_VER)
Manuel Klimek4da21662012-07-06 05:48:52 +000087 EXPECT_FALSE(matches("", ClassMatcher));
Manuel Klimeke265c872012-07-10 14:21:30 +000088#else
89 // Matches class type_info.
90 EXPECT_TRUE(matches("", ClassMatcher));
91#endif
Manuel Klimek4da21662012-07-06 05:48:52 +000092
93 DeclarationMatcher ClassX = record(record(hasName("X")));
94 EXPECT_TRUE(matches("class X;", ClassX));
95 EXPECT_TRUE(matches("class X {};", ClassX));
96 EXPECT_TRUE(matches("template<class T> class X {};", ClassX));
97 EXPECT_TRUE(notMatches("", ClassX));
98}
99
100TEST(DeclarationMatcher, ClassIsDerived) {
101 DeclarationMatcher IsDerivedFromX = record(isDerivedFrom("X"));
102
103 EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsDerivedFromX));
104 EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsDerivedFromX));
105 EXPECT_TRUE(matches("class X {};", IsDerivedFromX));
106 EXPECT_TRUE(matches("class X;", IsDerivedFromX));
107 EXPECT_TRUE(notMatches("class Y;", IsDerivedFromX));
108 EXPECT_TRUE(notMatches("", IsDerivedFromX));
109
110 DeclarationMatcher ZIsDerivedFromX =
111 record(hasName("Z"), isDerivedFrom("X"));
112 EXPECT_TRUE(
113 matches("class X {}; class Y : public X {}; class Z : public Y {};",
114 ZIsDerivedFromX));
115 EXPECT_TRUE(
116 matches("class X {};"
117 "template<class T> class Y : public X {};"
118 "class Z : public Y<int> {};", ZIsDerivedFromX));
119 EXPECT_TRUE(matches("class X {}; template<class T> class Z : public X {};",
120 ZIsDerivedFromX));
121 EXPECT_TRUE(
122 matches("template<class T> class X {}; "
123 "template<class T> class Z : public X<T> {};",
124 ZIsDerivedFromX));
125 EXPECT_TRUE(
126 matches("template<class T, class U=T> class X {}; "
127 "template<class T> class Z : public X<T> {};",
128 ZIsDerivedFromX));
129 EXPECT_TRUE(
130 notMatches("template<class X> class A { class Z : public X {}; };",
131 ZIsDerivedFromX));
132 EXPECT_TRUE(
133 matches("template<class X> class A { public: class Z : public X {}; }; "
134 "class X{}; void y() { A<X>::Z z; }", ZIsDerivedFromX));
135 EXPECT_TRUE(
136 matches("template <class T> class X {}; "
137 "template<class Y> class A { class Z : public X<Y> {}; };",
138 ZIsDerivedFromX));
139 EXPECT_TRUE(
140 notMatches("template<template<class T> class X> class A { "
141 " class Z : public X<int> {}; };", ZIsDerivedFromX));
142 EXPECT_TRUE(
143 matches("template<template<class T> class X> class A { "
144 " public: class Z : public X<int> {}; }; "
145 "template<class T> class X {}; void y() { A<X>::Z z; }",
146 ZIsDerivedFromX));
147 EXPECT_TRUE(
148 notMatches("template<class X> class A { class Z : public X::D {}; };",
149 ZIsDerivedFromX));
150 EXPECT_TRUE(
151 matches("template<class X> class A { public: "
152 " class Z : public X::D {}; }; "
153 "class Y { public: class X {}; typedef X D; }; "
154 "void y() { A<Y>::Z z; }", ZIsDerivedFromX));
155 EXPECT_TRUE(
156 matches("class X {}; typedef X Y; class Z : public Y {};",
157 ZIsDerivedFromX));
158 EXPECT_TRUE(
159 matches("template<class T> class Y { typedef typename T::U X; "
160 " class Z : public X {}; };", ZIsDerivedFromX));
161 EXPECT_TRUE(matches("class X {}; class Z : public ::X {};",
162 ZIsDerivedFromX));
163 EXPECT_TRUE(
164 notMatches("template<class T> class X {}; "
165 "template<class T> class A { class Z : public X<T>::D {}; };",
166 ZIsDerivedFromX));
167 EXPECT_TRUE(
168 matches("template<class T> class X { public: typedef X<T> D; }; "
169 "template<class T> class A { public: "
170 " class Z : public X<T>::D {}; }; void y() { A<int>::Z z; }",
171 ZIsDerivedFromX));
172 EXPECT_TRUE(
173 notMatches("template<class X> class A { class Z : public X::D::E {}; };",
174 ZIsDerivedFromX));
175 EXPECT_TRUE(
176 matches("class X {}; typedef X V; typedef V W; class Z : public W {};",
177 ZIsDerivedFromX));
178 EXPECT_TRUE(
179 matches("class X {}; class Y : public X {}; "
180 "typedef Y V; typedef V W; class Z : public W {};",
181 ZIsDerivedFromX));
182 EXPECT_TRUE(
183 matches("template<class T, class U> class X {}; "
184 "template<class T> class A { class Z : public X<T, int> {}; };",
185 ZIsDerivedFromX));
186 EXPECT_TRUE(
187 notMatches("template<class X> class D { typedef X A; typedef A B; "
188 " typedef B C; class Z : public C {}; };",
189 ZIsDerivedFromX));
190 EXPECT_TRUE(
191 matches("class X {}; typedef X A; typedef A B; "
192 "class Z : public B {};", ZIsDerivedFromX));
193 EXPECT_TRUE(
194 matches("class X {}; typedef X A; typedef A B; typedef B C; "
195 "class Z : public C {};", ZIsDerivedFromX));
196 EXPECT_TRUE(
197 matches("class U {}; typedef U X; typedef X V; "
198 "class Z : public V {};", ZIsDerivedFromX));
199 EXPECT_TRUE(
200 matches("class Base {}; typedef Base X; "
201 "class Z : public Base {};", ZIsDerivedFromX));
202 EXPECT_TRUE(
203 matches("class Base {}; typedef Base Base2; typedef Base2 X; "
204 "class Z : public Base {};", ZIsDerivedFromX));
205 EXPECT_TRUE(
206 notMatches("class Base {}; class Base2 {}; typedef Base2 X; "
207 "class Z : public Base {};", ZIsDerivedFromX));
208 EXPECT_TRUE(
209 matches("class A {}; typedef A X; typedef A Y; "
210 "class Z : public Y {};", ZIsDerivedFromX));
211 EXPECT_TRUE(
212 notMatches("template <typename T> class Z;"
213 "template <> class Z<void> {};"
214 "template <typename T> class Z : public Z<void> {};",
215 IsDerivedFromX));
216 EXPECT_TRUE(
217 matches("template <typename T> class X;"
218 "template <> class X<void> {};"
219 "template <typename T> class X : public X<void> {};",
220 IsDerivedFromX));
221 EXPECT_TRUE(matches(
222 "class X {};"
223 "template <typename T> class Z;"
224 "template <> class Z<void> {};"
225 "template <typename T> class Z : public Z<void>, public X {};",
226 ZIsDerivedFromX));
227
228 // FIXME: Once we have better matchers for template type matching,
229 // get rid of the Variable(...) matching and match the right template
230 // declarations directly.
231 const char *RecursiveTemplateOneParameter =
232 "class Base1 {}; class Base2 {};"
233 "template <typename T> class Z;"
234 "template <> class Z<void> : public Base1 {};"
235 "template <> class Z<int> : public Base2 {};"
236 "template <> class Z<float> : public Z<void> {};"
237 "template <> class Z<double> : public Z<int> {};"
238 "template <typename T> class Z : public Z<float>, public Z<double> {};"
239 "void f() { Z<float> z_float; Z<double> z_double; Z<char> z_char; }";
240 EXPECT_TRUE(matches(
241 RecursiveTemplateOneParameter,
242 variable(hasName("z_float"),
243 hasInitializer(hasType(record(isDerivedFrom("Base1")))))));
244 EXPECT_TRUE(notMatches(
245 RecursiveTemplateOneParameter,
246 variable(
247 hasName("z_float"),
248 hasInitializer(hasType(record(isDerivedFrom("Base2")))))));
249 EXPECT_TRUE(matches(
250 RecursiveTemplateOneParameter,
251 variable(
252 hasName("z_char"),
253 hasInitializer(hasType(record(isDerivedFrom("Base1"),
Daniel Jasper20b802d2012-07-17 07:39:27 +0000254 isDerivedFrom("Base2")))))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000255
256 const char *RecursiveTemplateTwoParameters =
257 "class Base1 {}; class Base2 {};"
258 "template <typename T1, typename T2> class Z;"
259 "template <typename T> class Z<void, T> : public Base1 {};"
260 "template <typename T> class Z<int, T> : public Base2 {};"
261 "template <typename T> class Z<float, T> : public Z<void, T> {};"
262 "template <typename T> class Z<double, T> : public Z<int, T> {};"
263 "template <typename T1, typename T2> class Z : "
264 " public Z<float, T2>, public Z<double, T2> {};"
265 "void f() { Z<float, void> z_float; Z<double, void> z_double; "
266 " Z<char, void> z_char; }";
267 EXPECT_TRUE(matches(
268 RecursiveTemplateTwoParameters,
269 variable(
270 hasName("z_float"),
271 hasInitializer(hasType(record(isDerivedFrom("Base1")))))));
272 EXPECT_TRUE(notMatches(
273 RecursiveTemplateTwoParameters,
274 variable(
275 hasName("z_float"),
276 hasInitializer(hasType(record(isDerivedFrom("Base2")))))));
277 EXPECT_TRUE(matches(
278 RecursiveTemplateTwoParameters,
279 variable(
280 hasName("z_char"),
281 hasInitializer(hasType(record(isDerivedFrom("Base1"),
Daniel Jasper20b802d2012-07-17 07:39:27 +0000282 isDerivedFrom("Base2")))))));
283 EXPECT_TRUE(matches(
284 "namespace ns { class X {}; class Y : public X {}; }",
285 record(isDerivedFrom("::ns::X"))));
286 EXPECT_TRUE(notMatches(
287 "class X {}; class Y : public X {};",
288 record(isDerivedFrom("::ns::X"))));
289
290 EXPECT_TRUE(matches(
291 "class X {}; class Y : public X {};",
Manuel Klimek9f174082012-07-24 13:37:29 +0000292 record(isDerivedFrom(record(hasName("X")).bind("test")))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000293}
294
Dmitri Gribenko8456ae62012-08-17 18:42:47 +0000295TEST(ClassTemplate, DoesNotMatchClass) {
296 DeclarationMatcher ClassX = classTemplate(hasName("X"));
297 EXPECT_TRUE(notMatches("class X;", ClassX));
298 EXPECT_TRUE(notMatches("class X {};", ClassX));
299}
300
301TEST(ClassTemplate, MatchesClassTemplate) {
302 DeclarationMatcher ClassX = classTemplate(hasName("X"));
303 EXPECT_TRUE(matches("template<typename T> class X {};", ClassX));
304 EXPECT_TRUE(matches("class Z { template<class T> class X {}; };", ClassX));
305}
306
307TEST(ClassTemplate, DoesNotMatchClassTemplateExplicitSpecialization) {
308 EXPECT_TRUE(notMatches("template<typename T> class X { };"
309 "template<> class X<int> { int a; };",
310 classTemplate(hasName("X"),
311 hasDescendant(field(hasName("a"))))));
312}
313
314TEST(ClassTemplate, DoesNotMatchClassTemplatePartialSpecialization) {
315 EXPECT_TRUE(notMatches("template<typename T, typename U> class X { };"
316 "template<typename T> class X<T, int> { int a; };",
317 classTemplate(hasName("X"),
318 hasDescendant(field(hasName("a"))))));
319}
320
Daniel Jasper6a124492012-07-12 08:50:38 +0000321TEST(AllOf, AllOverloadsWork) {
322 const char Program[] =
323 "struct T { }; int f(int, T*); void g(int x) { T t; f(x, &t); }";
324 EXPECT_TRUE(matches(Program,
325 call(allOf(callee(function(hasName("f"))),
326 hasArgument(0, declarationReference(to(variable())))))));
327 EXPECT_TRUE(matches(Program,
328 call(allOf(callee(function(hasName("f"))),
329 hasArgument(0, declarationReference(to(variable()))),
330 hasArgument(1, hasType(pointsTo(record(hasName("T")))))))));
331}
332
Manuel Klimek4da21662012-07-06 05:48:52 +0000333TEST(DeclarationMatcher, MatchAnyOf) {
334 DeclarationMatcher YOrZDerivedFromX =
335 record(anyOf(hasName("Y"), allOf(isDerivedFrom("X"), hasName("Z"))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000336 EXPECT_TRUE(
337 matches("class X {}; class Z : public X {};", YOrZDerivedFromX));
338 EXPECT_TRUE(matches("class Y {};", YOrZDerivedFromX));
339 EXPECT_TRUE(
340 notMatches("class X {}; class W : public X {};", YOrZDerivedFromX));
341 EXPECT_TRUE(notMatches("class Z {};", YOrZDerivedFromX));
342
Daniel Jasperff2fcb82012-07-15 19:57:12 +0000343 DeclarationMatcher XOrYOrZOrU =
344 record(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U")));
345 EXPECT_TRUE(matches("class X {};", XOrYOrZOrU));
346 EXPECT_TRUE(notMatches("class V {};", XOrYOrZOrU));
347
Manuel Klimek4da21662012-07-06 05:48:52 +0000348 DeclarationMatcher XOrYOrZOrUOrV =
349 record(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U"),
Daniel Jasperff2fcb82012-07-15 19:57:12 +0000350 hasName("V")));
Manuel Klimek4da21662012-07-06 05:48:52 +0000351 EXPECT_TRUE(matches("class X {};", XOrYOrZOrUOrV));
352 EXPECT_TRUE(matches("class Y {};", XOrYOrZOrUOrV));
353 EXPECT_TRUE(matches("class Z {};", XOrYOrZOrUOrV));
354 EXPECT_TRUE(matches("class U {};", XOrYOrZOrUOrV));
355 EXPECT_TRUE(matches("class V {};", XOrYOrZOrUOrV));
356 EXPECT_TRUE(notMatches("class A {};", XOrYOrZOrUOrV));
357}
358
359TEST(DeclarationMatcher, MatchHas) {
360 DeclarationMatcher HasClassX = record(has(record(hasName("X"))));
361
362 EXPECT_TRUE(matches("class Y { class X {}; };", HasClassX));
363 EXPECT_TRUE(matches("class X {};", HasClassX));
364
365 DeclarationMatcher YHasClassX =
366 record(hasName("Y"), has(record(hasName("X"))));
367 EXPECT_TRUE(matches("class Y { class X {}; };", YHasClassX));
368 EXPECT_TRUE(notMatches("class X {};", YHasClassX));
369 EXPECT_TRUE(
370 notMatches("class Y { class Z { class X {}; }; };", YHasClassX));
371}
372
373TEST(DeclarationMatcher, MatchHasRecursiveAllOf) {
374 DeclarationMatcher Recursive =
375 record(
376 has(record(
377 has(record(hasName("X"))),
378 has(record(hasName("Y"))),
379 hasName("Z"))),
380 has(record(
381 has(record(hasName("A"))),
382 has(record(hasName("B"))),
383 hasName("C"))),
384 hasName("F"));
385
386 EXPECT_TRUE(matches(
387 "class F {"
388 " class Z {"
389 " class X {};"
390 " class Y {};"
391 " };"
392 " class C {"
393 " class A {};"
394 " class B {};"
395 " };"
396 "};", Recursive));
397
398 EXPECT_TRUE(matches(
399 "class F {"
400 " class Z {"
401 " class A {};"
402 " class X {};"
403 " class Y {};"
404 " };"
405 " class C {"
406 " class X {};"
407 " class A {};"
408 " class B {};"
409 " };"
410 "};", Recursive));
411
412 EXPECT_TRUE(matches(
413 "class O1 {"
414 " class O2 {"
415 " class F {"
416 " class Z {"
417 " class A {};"
418 " class X {};"
419 " class Y {};"
420 " };"
421 " class C {"
422 " class X {};"
423 " class A {};"
424 " class B {};"
425 " };"
426 " };"
427 " };"
428 "};", Recursive));
429}
430
431TEST(DeclarationMatcher, MatchHasRecursiveAnyOf) {
432 DeclarationMatcher Recursive =
433 record(
434 anyOf(
435 has(record(
436 anyOf(
437 has(record(
438 hasName("X"))),
439 has(record(
440 hasName("Y"))),
441 hasName("Z")))),
442 has(record(
443 anyOf(
444 hasName("C"),
445 has(record(
446 hasName("A"))),
447 has(record(
448 hasName("B")))))),
449 hasName("F")));
450
451 EXPECT_TRUE(matches("class F {};", Recursive));
452 EXPECT_TRUE(matches("class Z {};", Recursive));
453 EXPECT_TRUE(matches("class C {};", Recursive));
454 EXPECT_TRUE(matches("class M { class N { class X {}; }; };", Recursive));
455 EXPECT_TRUE(matches("class M { class N { class B {}; }; };", Recursive));
456 EXPECT_TRUE(
457 matches("class O1 { class O2 {"
458 " class M { class N { class B {}; }; }; "
459 "}; };", Recursive));
460}
461
462TEST(DeclarationMatcher, MatchNot) {
463 DeclarationMatcher NotClassX =
464 record(
465 isDerivedFrom("Y"),
466 unless(hasName("Y")),
467 unless(hasName("X")));
468 EXPECT_TRUE(notMatches("", NotClassX));
469 EXPECT_TRUE(notMatches("class Y {};", NotClassX));
470 EXPECT_TRUE(matches("class Y {}; class Z : public Y {};", NotClassX));
471 EXPECT_TRUE(notMatches("class Y {}; class X : public Y {};", NotClassX));
472 EXPECT_TRUE(
473 notMatches("class Y {}; class Z {}; class X : public Y {};",
474 NotClassX));
475
476 DeclarationMatcher ClassXHasNotClassY =
477 record(
478 hasName("X"),
479 has(record(hasName("Z"))),
480 unless(
481 has(record(hasName("Y")))));
482 EXPECT_TRUE(matches("class X { class Z {}; };", ClassXHasNotClassY));
483 EXPECT_TRUE(notMatches("class X { class Y {}; class Z {}; };",
484 ClassXHasNotClassY));
485}
486
487TEST(DeclarationMatcher, HasDescendant) {
488 DeclarationMatcher ZDescendantClassX =
489 record(
490 hasDescendant(record(hasName("X"))),
491 hasName("Z"));
492 EXPECT_TRUE(matches("class Z { class X {}; };", ZDescendantClassX));
493 EXPECT_TRUE(
494 matches("class Z { class Y { class X {}; }; };", ZDescendantClassX));
495 EXPECT_TRUE(
496 matches("class Z { class A { class Y { class X {}; }; }; };",
497 ZDescendantClassX));
498 EXPECT_TRUE(
499 matches("class Z { class A { class B { class Y { class X {}; }; }; }; };",
500 ZDescendantClassX));
501 EXPECT_TRUE(notMatches("class Z {};", ZDescendantClassX));
502
503 DeclarationMatcher ZDescendantClassXHasClassY =
504 record(
505 hasDescendant(record(has(record(hasName("Y"))),
506 hasName("X"))),
507 hasName("Z"));
508 EXPECT_TRUE(matches("class Z { class X { class Y {}; }; };",
509 ZDescendantClassXHasClassY));
510 EXPECT_TRUE(
511 matches("class Z { class A { class B { class X { class Y {}; }; }; }; };",
512 ZDescendantClassXHasClassY));
513 EXPECT_TRUE(notMatches(
514 "class Z {"
515 " class A {"
516 " class B {"
517 " class X {"
518 " class C {"
519 " class Y {};"
520 " };"
521 " };"
522 " }; "
523 " };"
524 "};", ZDescendantClassXHasClassY));
525
526 DeclarationMatcher ZDescendantClassXDescendantClassY =
527 record(
528 hasDescendant(record(hasDescendant(record(hasName("Y"))),
529 hasName("X"))),
530 hasName("Z"));
531 EXPECT_TRUE(
532 matches("class Z { class A { class X { class B { class Y {}; }; }; }; };",
533 ZDescendantClassXDescendantClassY));
534 EXPECT_TRUE(matches(
535 "class Z {"
536 " class A {"
537 " class X {"
538 " class B {"
539 " class Y {};"
540 " };"
541 " class Y {};"
542 " };"
543 " };"
544 "};", ZDescendantClassXDescendantClassY));
545}
546
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000547TEST(Enum, DoesNotMatchClasses) {
548 EXPECT_TRUE(notMatches("class X {};", enumDecl(hasName("X"))));
549}
550
551TEST(Enum, MatchesEnums) {
552 EXPECT_TRUE(matches("enum X {};", enumDecl(hasName("X"))));
553}
554
555TEST(EnumConstant, Matches) {
556 DeclarationMatcher Matcher = enumConstant(hasName("A"));
557 EXPECT_TRUE(matches("enum X{ A };", Matcher));
558 EXPECT_TRUE(notMatches("enum X{ B };", Matcher));
559 EXPECT_TRUE(notMatches("enum X {};", Matcher));
560}
561
Manuel Klimek4da21662012-07-06 05:48:52 +0000562TEST(StatementMatcher, Has) {
563 StatementMatcher HasVariableI =
564 expression(
565 hasType(pointsTo(record(hasName("X")))),
566 has(declarationReference(to(variable(hasName("i"))))));
567
568 EXPECT_TRUE(matches(
569 "class X; X *x(int); void c() { int i; x(i); }", HasVariableI));
570 EXPECT_TRUE(notMatches(
571 "class X; X *x(int); void c() { int i; x(42); }", HasVariableI));
572}
573
574TEST(StatementMatcher, HasDescendant) {
575 StatementMatcher HasDescendantVariableI =
576 expression(
577 hasType(pointsTo(record(hasName("X")))),
578 hasDescendant(declarationReference(to(variable(hasName("i"))))));
579
580 EXPECT_TRUE(matches(
581 "class X; X *x(bool); bool b(int); void c() { int i; x(b(i)); }",
582 HasDescendantVariableI));
583 EXPECT_TRUE(notMatches(
584 "class X; X *x(bool); bool b(int); void c() { int i; x(b(42)); }",
585 HasDescendantVariableI));
586}
587
588TEST(TypeMatcher, MatchesClassType) {
589 TypeMatcher TypeA = hasDeclaration(record(hasName("A")));
590
591 EXPECT_TRUE(matches("class A { public: A *a; };", TypeA));
592 EXPECT_TRUE(notMatches("class A {};", TypeA));
593
594 TypeMatcher TypeDerivedFromA = hasDeclaration(record(isDerivedFrom("A")));
595
596 EXPECT_TRUE(matches("class A {}; class B : public A { public: B *b; };",
597 TypeDerivedFromA));
598 EXPECT_TRUE(notMatches("class A {};", TypeA));
599
600 TypeMatcher TypeAHasClassB = hasDeclaration(
601 record(hasName("A"), has(record(hasName("B")))));
602
603 EXPECT_TRUE(
604 matches("class A { public: A *a; class B {}; };", TypeAHasClassB));
605}
606
607// Returns from Run whether 'bound_nodes' contain a Decl bound to 'Id', which
608// can be dynamically casted to T.
609// Optionally checks that the check succeeded a specific number of times.
610template <typename T>
611class VerifyIdIsBoundToDecl : public BoundNodesCallback {
612public:
613 // Create an object that checks that a node of type 'T' was bound to 'Id'.
614 // Does not check for a certain number of matches.
615 explicit VerifyIdIsBoundToDecl(const std::string& Id)
616 : Id(Id), ExpectedCount(-1), Count(0) {}
617
618 // Create an object that checks that a node of type 'T' was bound to 'Id'.
619 // Checks that there were exactly 'ExpectedCount' matches.
620 explicit VerifyIdIsBoundToDecl(const std::string& Id, int ExpectedCount)
621 : Id(Id), ExpectedCount(ExpectedCount), Count(0) {}
622
623 ~VerifyIdIsBoundToDecl() {
624 if (ExpectedCount != -1) {
625 EXPECT_EQ(ExpectedCount, Count);
626 }
627 }
628
629 virtual bool run(const BoundNodes *Nodes) {
630 if (Nodes->getDeclAs<T>(Id) != NULL) {
631 ++Count;
632 return true;
633 }
634 return false;
635 }
636
637private:
638 const std::string Id;
639 const int ExpectedCount;
640 int Count;
641};
642template <typename T>
643class VerifyIdIsBoundToStmt : public BoundNodesCallback {
644public:
645 explicit VerifyIdIsBoundToStmt(const std::string &Id) : Id(Id) {}
646 virtual bool run(const BoundNodes *Nodes) {
647 const T *Node = Nodes->getStmtAs<T>(Id);
648 return Node != NULL;
649 }
650private:
651 const std::string Id;
652};
653
654TEST(Matcher, BindMatchedNodes) {
Manuel Klimek9f174082012-07-24 13:37:29 +0000655 DeclarationMatcher ClassX = has(record(hasName("::X")).bind("x"));
Manuel Klimek4da21662012-07-06 05:48:52 +0000656
657 EXPECT_TRUE(matchAndVerifyResultTrue("class X {};",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000658 ClassX, new VerifyIdIsBoundToDecl<CXXRecordDecl>("x")));
Manuel Klimek4da21662012-07-06 05:48:52 +0000659
660 EXPECT_TRUE(matchAndVerifyResultFalse("class X {};",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000661 ClassX, new VerifyIdIsBoundToDecl<CXXRecordDecl>("other-id")));
Manuel Klimek4da21662012-07-06 05:48:52 +0000662
663 TypeMatcher TypeAHasClassB = hasDeclaration(
Manuel Klimek9f174082012-07-24 13:37:29 +0000664 record(hasName("A"), has(record(hasName("B")).bind("b"))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000665
666 EXPECT_TRUE(matchAndVerifyResultTrue("class A { public: A *a; class B {}; };",
667 TypeAHasClassB,
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000668 new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +0000669
Manuel Klimek9f174082012-07-24 13:37:29 +0000670 StatementMatcher MethodX = call(callee(method(hasName("x")))).bind("x");
Manuel Klimek4da21662012-07-06 05:48:52 +0000671
672 EXPECT_TRUE(matchAndVerifyResultTrue("class A { void x() { x(); } };",
673 MethodX,
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000674 new VerifyIdIsBoundToStmt<CXXMemberCallExpr>("x")));
675}
676
677TEST(Matcher, BindTheSameNameInAlternatives) {
678 StatementMatcher matcher = anyOf(
679 binaryOperator(hasOperatorName("+"),
Manuel Klimek9f174082012-07-24 13:37:29 +0000680 hasLHS(expression().bind("x")),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000681 hasRHS(integerLiteral(equals(0)))),
682 binaryOperator(hasOperatorName("+"),
683 hasLHS(integerLiteral(equals(0))),
Manuel Klimek9f174082012-07-24 13:37:29 +0000684 hasRHS(expression().bind("x"))));
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000685
686 EXPECT_TRUE(matchAndVerifyResultTrue(
687 // The first branch of the matcher binds x to 0 but then fails.
688 // The second branch binds x to f() and succeeds.
689 "int f() { return 0 + f(); }",
690 matcher,
691 new VerifyIdIsBoundToStmt<CallExpr>("x")));
Manuel Klimek4da21662012-07-06 05:48:52 +0000692}
693
694TEST(HasType, TakesQualTypeMatcherAndMatchesExpr) {
695 TypeMatcher ClassX = hasDeclaration(record(hasName("X")));
696 EXPECT_TRUE(
697 matches("class X {}; void y(X &x) { x; }", expression(hasType(ClassX))));
698 EXPECT_TRUE(
699 notMatches("class X {}; void y(X *x) { x; }",
700 expression(hasType(ClassX))));
701 EXPECT_TRUE(
702 matches("class X {}; void y(X *x) { x; }",
703 expression(hasType(pointsTo(ClassX)))));
704}
705
706TEST(HasType, TakesQualTypeMatcherAndMatchesValueDecl) {
707 TypeMatcher ClassX = hasDeclaration(record(hasName("X")));
708 EXPECT_TRUE(
709 matches("class X {}; void y() { X x; }", variable(hasType(ClassX))));
710 EXPECT_TRUE(
711 notMatches("class X {}; void y() { X *x; }", variable(hasType(ClassX))));
712 EXPECT_TRUE(
713 matches("class X {}; void y() { X *x; }",
714 variable(hasType(pointsTo(ClassX)))));
715}
716
717TEST(HasType, TakesDeclMatcherAndMatchesExpr) {
718 DeclarationMatcher ClassX = record(hasName("X"));
719 EXPECT_TRUE(
720 matches("class X {}; void y(X &x) { x; }", expression(hasType(ClassX))));
721 EXPECT_TRUE(
722 notMatches("class X {}; void y(X *x) { x; }",
723 expression(hasType(ClassX))));
724}
725
726TEST(HasType, TakesDeclMatcherAndMatchesValueDecl) {
727 DeclarationMatcher ClassX = record(hasName("X"));
728 EXPECT_TRUE(
729 matches("class X {}; void y() { X x; }", variable(hasType(ClassX))));
730 EXPECT_TRUE(
731 notMatches("class X {}; void y() { X *x; }", variable(hasType(ClassX))));
732}
733
734TEST(Matcher, Call) {
735 // FIXME: Do we want to overload Call() to directly take
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000736 // Matcher<Decl>, too?
Manuel Klimek4da21662012-07-06 05:48:52 +0000737 StatementMatcher MethodX = call(hasDeclaration(method(hasName("x"))));
738
739 EXPECT_TRUE(matches("class Y { void x() { x(); } };", MethodX));
740 EXPECT_TRUE(notMatches("class Y { void x() {} };", MethodX));
741
Manuel Klimek9f174082012-07-24 13:37:29 +0000742 StatementMatcher MethodOnY = memberCall(on(hasType(record(hasName("Y")))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000743
744 EXPECT_TRUE(
745 matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
746 MethodOnY));
747 EXPECT_TRUE(
748 matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
749 MethodOnY));
750 EXPECT_TRUE(
751 notMatches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
752 MethodOnY));
753 EXPECT_TRUE(
754 notMatches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
755 MethodOnY));
756 EXPECT_TRUE(
757 notMatches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
758 MethodOnY));
759
760 StatementMatcher MethodOnYPointer =
Manuel Klimek9f174082012-07-24 13:37:29 +0000761 memberCall(on(hasType(pointsTo(record(hasName("Y"))))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000762
763 EXPECT_TRUE(
764 matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
765 MethodOnYPointer));
766 EXPECT_TRUE(
767 matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
768 MethodOnYPointer));
769 EXPECT_TRUE(
770 matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
771 MethodOnYPointer));
772 EXPECT_TRUE(
773 notMatches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
774 MethodOnYPointer));
775 EXPECT_TRUE(
776 notMatches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
777 MethodOnYPointer));
778}
779
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000780TEST(HasType, MatchesAsString) {
781 EXPECT_TRUE(
782 matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }",
Manuel Klimek9f174082012-07-24 13:37:29 +0000783 memberCall(on(hasType(asString("class Y *"))))));
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000784 EXPECT_TRUE(matches("class X { void x(int x) {} };",
785 method(hasParameter(0, hasType(asString("int"))))));
786 EXPECT_TRUE(matches("namespace ns { struct A {}; } struct B { ns::A a; };",
787 field(hasType(asString("ns::A")))));
788 EXPECT_TRUE(matches("namespace { struct A {}; } struct B { A a; };",
789 field(hasType(asString("struct <anonymous>::A")))));
790}
791
Manuel Klimek4da21662012-07-06 05:48:52 +0000792TEST(Matcher, OverloadedOperatorCall) {
793 StatementMatcher OpCall = overloadedOperatorCall();
794 // Unary operator
795 EXPECT_TRUE(matches("class Y { }; "
796 "bool operator!(Y x) { return false; }; "
797 "Y y; bool c = !y;", OpCall));
798 // No match -- special operators like "new", "delete"
799 // FIXME: operator new takes size_t, for which we need stddef.h, for which
800 // we need to figure out include paths in the test.
801 // EXPECT_TRUE(NotMatches("#include <stddef.h>\n"
802 // "class Y { }; "
803 // "void *operator new(size_t size) { return 0; } "
804 // "Y *y = new Y;", OpCall));
805 EXPECT_TRUE(notMatches("class Y { }; "
806 "void operator delete(void *p) { } "
807 "void a() {Y *y = new Y; delete y;}", OpCall));
808 // Binary operator
809 EXPECT_TRUE(matches("class Y { }; "
810 "bool operator&&(Y x, Y y) { return true; }; "
811 "Y a; Y b; bool c = a && b;",
812 OpCall));
813 // No match -- normal operator, not an overloaded one.
814 EXPECT_TRUE(notMatches("bool x = true, y = true; bool t = x && y;", OpCall));
815 EXPECT_TRUE(notMatches("int t = 5 << 2;", OpCall));
816}
817
818TEST(Matcher, HasOperatorNameForOverloadedOperatorCall) {
819 StatementMatcher OpCallAndAnd =
820 overloadedOperatorCall(hasOverloadedOperatorName("&&"));
821 EXPECT_TRUE(matches("class Y { }; "
822 "bool operator&&(Y x, Y y) { return true; }; "
823 "Y a; Y b; bool c = a && b;", OpCallAndAnd));
824 StatementMatcher OpCallLessLess =
825 overloadedOperatorCall(hasOverloadedOperatorName("<<"));
826 EXPECT_TRUE(notMatches("class Y { }; "
827 "bool operator&&(Y x, Y y) { return true; }; "
828 "Y a; Y b; bool c = a && b;",
829 OpCallLessLess));
830}
831
832TEST(Matcher, ThisPointerType) {
Manuel Klimek9f174082012-07-24 13:37:29 +0000833 StatementMatcher MethodOnY =
834 memberCall(thisPointerType(record(hasName("Y"))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000835
836 EXPECT_TRUE(
837 matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
838 MethodOnY));
839 EXPECT_TRUE(
840 matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
841 MethodOnY));
842 EXPECT_TRUE(
843 matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
844 MethodOnY));
845 EXPECT_TRUE(
846 matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
847 MethodOnY));
848 EXPECT_TRUE(
849 matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
850 MethodOnY));
851
852 EXPECT_TRUE(matches(
853 "class Y {"
854 " public: virtual void x();"
855 "};"
856 "class X : public Y {"
857 " public: virtual void x();"
858 "};"
859 "void z() { X *x; x->Y::x(); }", MethodOnY));
860}
861
862TEST(Matcher, VariableUsage) {
863 StatementMatcher Reference =
864 declarationReference(to(
865 variable(hasInitializer(
Manuel Klimek9f174082012-07-24 13:37:29 +0000866 memberCall(thisPointerType(record(hasName("Y"))))))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000867
868 EXPECT_TRUE(matches(
869 "class Y {"
870 " public:"
871 " bool x() const;"
872 "};"
873 "void z(const Y &y) {"
874 " bool b = y.x();"
875 " if (b) {}"
876 "}", Reference));
877
878 EXPECT_TRUE(notMatches(
879 "class Y {"
880 " public:"
881 " bool x() const;"
882 "};"
883 "void z(const Y &y) {"
884 " bool b = y.x();"
885 "}", Reference));
886}
887
Daniel Jasper9bd28092012-07-30 05:03:25 +0000888TEST(Matcher, FindsVarDeclInFuncitonParameter) {
889 EXPECT_TRUE(matches(
890 "void f(int i) {}",
891 variable(hasName("i"))));
892}
893
Manuel Klimek4da21662012-07-06 05:48:52 +0000894TEST(Matcher, CalledVariable) {
895 StatementMatcher CallOnVariableY = expression(
Manuel Klimek9f174082012-07-24 13:37:29 +0000896 memberCall(on(declarationReference(to(variable(hasName("y")))))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000897
898 EXPECT_TRUE(matches(
899 "class Y { public: void x() { Y y; y.x(); } };", CallOnVariableY));
900 EXPECT_TRUE(matches(
901 "class Y { public: void x() const { Y y; y.x(); } };", CallOnVariableY));
902 EXPECT_TRUE(matches(
903 "class Y { public: void x(); };"
904 "class X : public Y { void z() { X y; y.x(); } };", CallOnVariableY));
905 EXPECT_TRUE(matches(
906 "class Y { public: void x(); };"
907 "class X : public Y { void z() { X *y; y->x(); } };", CallOnVariableY));
908 EXPECT_TRUE(notMatches(
909 "class Y { public: void x(); };"
910 "class X : public Y { void z() { unsigned long y; ((X*)y)->x(); } };",
911 CallOnVariableY));
912}
913
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000914TEST(UnaryExprOrTypeTraitExpr, MatchesSizeOfAndAlignOf) {
915 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }",
916 unaryExprOrTypeTraitExpr()));
917 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }",
918 alignOfExpr(anything())));
919 // FIXME: Uncomment once alignof is enabled.
920 // EXPECT_TRUE(matches("void x() { int a = alignof(a); }",
921 // unaryExprOrTypeTraitExpr()));
922 // EXPECT_TRUE(notMatches("void x() { int a = alignof(a); }",
923 // sizeOfExpr()));
924}
925
926TEST(UnaryExpressionOrTypeTraitExpression, MatchesCorrectType) {
927 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }", sizeOfExpr(
928 hasArgumentOfType(asString("int")))));
929 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
930 hasArgumentOfType(asString("float")))));
931 EXPECT_TRUE(matches(
932 "struct A {}; void x() { A a; int b = sizeof(a); }",
933 sizeOfExpr(hasArgumentOfType(hasDeclaration(record(hasName("A")))))));
934 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
935 hasArgumentOfType(hasDeclaration(record(hasName("string")))))));
936}
937
Manuel Klimek4da21662012-07-06 05:48:52 +0000938TEST(MemberExpression, DoesNotMatchClasses) {
939 EXPECT_TRUE(notMatches("class Y { void x() {} };", memberExpression()));
940}
941
942TEST(MemberExpression, MatchesMemberFunctionCall) {
943 EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpression()));
944}
945
946TEST(MemberExpression, MatchesVariable) {
947 EXPECT_TRUE(
948 matches("class Y { void x() { this->y; } int y; };", memberExpression()));
949 EXPECT_TRUE(
950 matches("class Y { void x() { y; } int y; };", memberExpression()));
951 EXPECT_TRUE(
952 matches("class Y { void x() { Y y; y.y; } int y; };",
953 memberExpression()));
954}
955
956TEST(MemberExpression, MatchesStaticVariable) {
957 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
958 memberExpression()));
959 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
960 memberExpression()));
961 EXPECT_TRUE(notMatches("class Y { void x() { Y::y; } static int y; };",
962 memberExpression()));
963}
964
Daniel Jasper6a124492012-07-12 08:50:38 +0000965TEST(IsInteger, MatchesIntegers) {
966 EXPECT_TRUE(matches("int i = 0;", variable(hasType(isInteger()))));
967 EXPECT_TRUE(matches("long long i = 0; void f(long long) { }; void g() {f(i);}",
968 call(hasArgument(0, declarationReference(
969 to(variable(hasType(isInteger()))))))));
970}
971
972TEST(IsInteger, ReportsNoFalsePositives) {
973 EXPECT_TRUE(notMatches("int *i;", variable(hasType(isInteger()))));
974 EXPECT_TRUE(notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}",
975 call(hasArgument(0, declarationReference(
976 to(variable(hasType(isInteger()))))))));
977}
978
Manuel Klimek4da21662012-07-06 05:48:52 +0000979TEST(IsArrow, MatchesMemberVariablesViaArrow) {
980 EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };",
981 memberExpression(isArrow())));
982 EXPECT_TRUE(matches("class Y { void x() { y; } int y; };",
983 memberExpression(isArrow())));
984 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };",
985 memberExpression(isArrow())));
986}
987
988TEST(IsArrow, MatchesStaticMemberVariablesViaArrow) {
989 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
990 memberExpression(isArrow())));
991 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
992 memberExpression(isArrow())));
993 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } static int y; };",
994 memberExpression(isArrow())));
995}
996
997TEST(IsArrow, MatchesMemberCallsViaArrow) {
998 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
999 memberExpression(isArrow())));
1000 EXPECT_TRUE(matches("class Y { void x() { x(); } };",
1001 memberExpression(isArrow())));
1002 EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",
1003 memberExpression(isArrow())));
1004}
1005
1006TEST(Callee, MatchesDeclarations) {
1007 StatementMatcher CallMethodX = call(callee(method(hasName("x"))));
1008
1009 EXPECT_TRUE(matches("class Y { void x() { x(); } };", CallMethodX));
1010 EXPECT_TRUE(notMatches("class Y { void x() {} };", CallMethodX));
1011}
1012
1013TEST(Callee, MatchesMemberExpressions) {
1014 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
1015 call(callee(memberExpression()))));
1016 EXPECT_TRUE(
1017 notMatches("class Y { void x() { this->x(); } };", call(callee(call()))));
1018}
1019
1020TEST(Function, MatchesFunctionDeclarations) {
1021 StatementMatcher CallFunctionF = call(callee(function(hasName("f"))));
1022
1023 EXPECT_TRUE(matches("void f() { f(); }", CallFunctionF));
1024 EXPECT_TRUE(notMatches("void f() { }", CallFunctionF));
1025
Manuel Klimeke265c872012-07-10 14:21:30 +00001026#if !defined(_MSC_VER)
1027 // FIXME: Make this work for MSVC.
Manuel Klimek4da21662012-07-06 05:48:52 +00001028 // Dependent contexts, but a non-dependent call.
1029 EXPECT_TRUE(matches("void f(); template <int N> void g() { f(); }",
1030 CallFunctionF));
1031 EXPECT_TRUE(
1032 matches("void f(); template <int N> struct S { void g() { f(); } };",
1033 CallFunctionF));
Manuel Klimeke265c872012-07-10 14:21:30 +00001034#endif
Manuel Klimek4da21662012-07-06 05:48:52 +00001035
1036 // Depedent calls don't match.
1037 EXPECT_TRUE(
1038 notMatches("void f(int); template <typename T> void g(T t) { f(t); }",
1039 CallFunctionF));
1040 EXPECT_TRUE(
1041 notMatches("void f(int);"
1042 "template <typename T> struct S { void g(T t) { f(t); } };",
1043 CallFunctionF));
1044}
1045
Dmitri Gribenko8456ae62012-08-17 18:42:47 +00001046TEST(FunctionTemplate, MatchesFunctionTemplateDeclarations) {
1047 EXPECT_TRUE(
1048 matches("template <typename T> void f(T t) {}",
1049 functionTemplate(hasName("f"))));
1050}
1051
1052TEST(FunctionTemplate, DoesNotMatchFunctionDeclarations) {
1053 EXPECT_TRUE(
1054 notMatches("void f(double d); void f(int t) {}",
1055 functionTemplate(hasName("f"))));
1056}
1057
1058TEST(FunctionTemplate, DoesNotMatchFunctionTemplateSpecializations) {
1059 EXPECT_TRUE(
1060 notMatches("void g(); template <typename T> void f(T t) {}"
1061 "template <> void f(int t) { g(); }",
1062 functionTemplate(hasName("f"),
1063 hasDescendant(declarationReference(
1064 to(function(hasName("g"))))))));
1065}
1066
Manuel Klimek4da21662012-07-06 05:48:52 +00001067TEST(Matcher, Argument) {
1068 StatementMatcher CallArgumentY = expression(call(
1069 hasArgument(0, declarationReference(to(variable(hasName("y")))))));
1070
1071 EXPECT_TRUE(matches("void x(int) { int y; x(y); }", CallArgumentY));
1072 EXPECT_TRUE(
1073 matches("class X { void x(int) { int y; x(y); } };", CallArgumentY));
1074 EXPECT_TRUE(notMatches("void x(int) { int z; x(z); }", CallArgumentY));
1075
1076 StatementMatcher WrongIndex = expression(call(
1077 hasArgument(42, declarationReference(to(variable(hasName("y")))))));
1078 EXPECT_TRUE(notMatches("void x(int) { int y; x(y); }", WrongIndex));
1079}
1080
1081TEST(Matcher, AnyArgument) {
1082 StatementMatcher CallArgumentY = expression(call(
1083 hasAnyArgument(declarationReference(to(variable(hasName("y")))))));
1084 EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
1085 EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
1086 EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
1087}
1088
1089TEST(Matcher, ArgumentCount) {
1090 StatementMatcher Call1Arg = expression(call(argumentCountIs(1)));
1091
1092 EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg));
1093 EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg));
1094 EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg));
1095}
1096
1097TEST(Matcher, References) {
1098 DeclarationMatcher ReferenceClassX = variable(
1099 hasType(references(record(hasName("X")))));
1100 EXPECT_TRUE(matches("class X {}; void y(X y) { X &x = y; }",
1101 ReferenceClassX));
1102 EXPECT_TRUE(
1103 matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
1104 EXPECT_TRUE(
1105 notMatches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
1106 EXPECT_TRUE(
1107 notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
1108}
1109
1110TEST(HasParameter, CallsInnerMatcher) {
1111 EXPECT_TRUE(matches("class X { void x(int) {} };",
1112 method(hasParameter(0, variable()))));
1113 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
1114 method(hasParameter(0, hasName("x")))));
1115}
1116
1117TEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) {
1118 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
1119 method(hasParameter(42, variable()))));
1120}
1121
1122TEST(HasType, MatchesParameterVariableTypesStrictly) {
1123 EXPECT_TRUE(matches("class X { void x(X x) {} };",
1124 method(hasParameter(0, hasType(record(hasName("X")))))));
1125 EXPECT_TRUE(notMatches("class X { void x(const X &x) {} };",
1126 method(hasParameter(0, hasType(record(hasName("X")))))));
1127 EXPECT_TRUE(matches("class X { void x(const X *x) {} };",
1128 method(hasParameter(0, hasType(pointsTo(record(hasName("X"))))))));
1129 EXPECT_TRUE(matches("class X { void x(const X &x) {} };",
1130 method(hasParameter(0, hasType(references(record(hasName("X"))))))));
1131}
1132
1133TEST(HasAnyParameter, MatchesIndependentlyOfPosition) {
1134 EXPECT_TRUE(matches("class Y {}; class X { void x(X x, Y y) {} };",
1135 method(hasAnyParameter(hasType(record(hasName("X")))))));
1136 EXPECT_TRUE(matches("class Y {}; class X { void x(Y y, X x) {} };",
1137 method(hasAnyParameter(hasType(record(hasName("X")))))));
1138}
1139
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001140TEST(Returns, MatchesReturnTypes) {
1141 EXPECT_TRUE(matches("class Y { int f() { return 1; } };",
1142 function(returns(asString("int")))));
1143 EXPECT_TRUE(notMatches("class Y { int f() { return 1; } };",
1144 function(returns(asString("float")))));
1145 EXPECT_TRUE(matches("class Y { Y getMe() { return *this; } };",
1146 function(returns(hasDeclaration(record(hasName("Y")))))));
1147}
1148
Daniel Jasper8cc7efa2012-08-15 18:52:19 +00001149TEST(IsExternC, MatchesExternCFunctionDeclarations) {
1150 EXPECT_TRUE(matches("extern \"C\" void f() {}", function(isExternC())));
1151 EXPECT_TRUE(matches("extern \"C\" { void f() {} }", function(isExternC())));
1152 EXPECT_TRUE(notMatches("void f() {}", function(isExternC())));
1153}
1154
Manuel Klimek4da21662012-07-06 05:48:52 +00001155TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
1156 EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
1157 method(hasAnyParameter(hasType(record(hasName("X")))))));
1158}
1159
1160TEST(HasAnyParameter, DoesNotMatchThisPointer) {
1161 EXPECT_TRUE(notMatches("class Y {}; class X { void x() {} };",
1162 method(hasAnyParameter(hasType(pointsTo(record(hasName("X"))))))));
1163}
1164
1165TEST(HasName, MatchesParameterVariableDeclartions) {
1166 EXPECT_TRUE(matches("class Y {}; class X { void x(int x) {} };",
1167 method(hasAnyParameter(hasName("x")))));
1168 EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
1169 method(hasAnyParameter(hasName("x")))));
1170}
1171
Daniel Jasper371f9392012-08-01 08:40:24 +00001172TEST(Matcher, MatchesClassTemplateSpecialization) {
1173 EXPECT_TRUE(matches("template<typename T> struct A {};"
1174 "template<> struct A<int> {};",
1175 classTemplateSpecialization()));
1176 EXPECT_TRUE(matches("template<typename T> struct A {}; A<int> a;",
1177 classTemplateSpecialization()));
1178 EXPECT_TRUE(notMatches("template<typename T> struct A {};",
1179 classTemplateSpecialization()));
1180}
1181
1182TEST(Matcher, MatchesTypeTemplateArgument) {
1183 EXPECT_TRUE(matches(
1184 "template<typename T> struct B {};"
1185 "B<int> b;",
1186 classTemplateSpecialization(hasAnyTemplateArgument(refersToType(
1187 asString("int"))))));
1188}
1189
1190TEST(Matcher, MatchesDeclarationReferenceTemplateArgument) {
1191 EXPECT_TRUE(matches(
1192 "struct B { int next; };"
1193 "template<int(B::*next_ptr)> struct A {};"
1194 "A<&B::next> a;",
1195 classTemplateSpecialization(hasAnyTemplateArgument(
1196 refersToDeclaration(field(hasName("next")))))));
1197}
1198
1199TEST(Matcher, MatchesSpecificArgument) {
1200 EXPECT_TRUE(matches(
1201 "template<typename T, typename U> class A {};"
1202 "A<bool, int> a;",
1203 classTemplateSpecialization(hasTemplateArgument(
1204 1, refersToType(asString("int"))))));
1205 EXPECT_TRUE(notMatches(
1206 "template<typename T, typename U> class A {};"
1207 "A<int, bool> a;",
1208 classTemplateSpecialization(hasTemplateArgument(
1209 1, refersToType(asString("int"))))));
1210}
1211
Manuel Klimek4da21662012-07-06 05:48:52 +00001212TEST(Matcher, ConstructorCall) {
1213 StatementMatcher Constructor = expression(constructorCall());
1214
1215 EXPECT_TRUE(
1216 matches("class X { public: X(); }; void x() { X x; }", Constructor));
1217 EXPECT_TRUE(
1218 matches("class X { public: X(); }; void x() { X x = X(); }",
1219 Constructor));
1220 EXPECT_TRUE(
1221 matches("class X { public: X(int); }; void x() { X x = 0; }",
1222 Constructor));
1223 EXPECT_TRUE(matches("class X {}; void x(int) { X x; }", Constructor));
1224}
1225
1226TEST(Matcher, ConstructorArgument) {
1227 StatementMatcher Constructor = expression(constructorCall(
1228 hasArgument(0, declarationReference(to(variable(hasName("y")))))));
1229
1230 EXPECT_TRUE(
1231 matches("class X { public: X(int); }; void x() { int y; X x(y); }",
1232 Constructor));
1233 EXPECT_TRUE(
1234 matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
1235 Constructor));
1236 EXPECT_TRUE(
1237 matches("class X { public: X(int); }; void x() { int y; X x = y; }",
1238 Constructor));
1239 EXPECT_TRUE(
1240 notMatches("class X { public: X(int); }; void x() { int z; X x(z); }",
1241 Constructor));
1242
1243 StatementMatcher WrongIndex = expression(constructorCall(
1244 hasArgument(42, declarationReference(to(variable(hasName("y")))))));
1245 EXPECT_TRUE(
1246 notMatches("class X { public: X(int); }; void x() { int y; X x(y); }",
1247 WrongIndex));
1248}
1249
1250TEST(Matcher, ConstructorArgumentCount) {
1251 StatementMatcher Constructor1Arg =
1252 expression(constructorCall(argumentCountIs(1)));
1253
1254 EXPECT_TRUE(
1255 matches("class X { public: X(int); }; void x() { X x(0); }",
1256 Constructor1Arg));
1257 EXPECT_TRUE(
1258 matches("class X { public: X(int); }; void x() { X x = X(0); }",
1259 Constructor1Arg));
1260 EXPECT_TRUE(
1261 matches("class X { public: X(int); }; void x() { X x = 0; }",
1262 Constructor1Arg));
1263 EXPECT_TRUE(
1264 notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
1265 Constructor1Arg));
1266}
1267
1268TEST(Matcher, BindTemporaryExpression) {
1269 StatementMatcher TempExpression = expression(bindTemporaryExpression());
1270
1271 std::string ClassString = "class string { public: string(); ~string(); }; ";
1272
1273 EXPECT_TRUE(
1274 matches(ClassString +
1275 "string GetStringByValue();"
1276 "void FunctionTakesString(string s);"
1277 "void run() { FunctionTakesString(GetStringByValue()); }",
1278 TempExpression));
1279
1280 EXPECT_TRUE(
1281 notMatches(ClassString +
1282 "string* GetStringPointer(); "
1283 "void FunctionTakesStringPtr(string* s);"
1284 "void run() {"
1285 " string* s = GetStringPointer();"
1286 " FunctionTakesStringPtr(GetStringPointer());"
1287 " FunctionTakesStringPtr(s);"
1288 "}",
1289 TempExpression));
1290
1291 EXPECT_TRUE(
1292 notMatches("class no_dtor {};"
1293 "no_dtor GetObjByValue();"
1294 "void ConsumeObj(no_dtor param);"
1295 "void run() { ConsumeObj(GetObjByValue()); }",
1296 TempExpression));
1297}
1298
1299TEST(ConstructorDeclaration, SimpleCase) {
1300 EXPECT_TRUE(matches("class Foo { Foo(int i); };",
1301 constructor(ofClass(hasName("Foo")))));
1302 EXPECT_TRUE(notMatches("class Foo { Foo(int i); };",
1303 constructor(ofClass(hasName("Bar")))));
1304}
1305
1306TEST(ConstructorDeclaration, IsImplicit) {
1307 // This one doesn't match because the constructor is not added by the
1308 // compiler (it is not needed).
1309 EXPECT_TRUE(notMatches("class Foo { };",
1310 constructor(isImplicit())));
1311 // The compiler added the implicit default constructor.
1312 EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
1313 constructor(isImplicit())));
1314 EXPECT_TRUE(matches("class Foo { Foo(){} };",
1315 constructor(unless(isImplicit()))));
1316}
1317
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001318TEST(DestructorDeclaration, MatchesVirtualDestructor) {
1319 EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };",
1320 destructor(ofClass(hasName("Foo")))));
1321}
1322
1323TEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) {
1324 EXPECT_TRUE(notMatches("class Foo {};", destructor(ofClass(hasName("Foo")))));
1325}
1326
Manuel Klimek4da21662012-07-06 05:48:52 +00001327TEST(HasAnyConstructorInitializer, SimpleCase) {
1328 EXPECT_TRUE(notMatches(
1329 "class Foo { Foo() { } };",
1330 constructor(hasAnyConstructorInitializer(anything()))));
1331 EXPECT_TRUE(matches(
1332 "class Foo {"
1333 " Foo() : foo_() { }"
1334 " int foo_;"
1335 "};",
1336 constructor(hasAnyConstructorInitializer(anything()))));
1337}
1338
1339TEST(HasAnyConstructorInitializer, ForField) {
1340 static const char Code[] =
1341 "class Baz { };"
1342 "class Foo {"
1343 " Foo() : foo_() { }"
1344 " Baz foo_;"
1345 " Baz bar_;"
1346 "};";
1347 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1348 forField(hasType(record(hasName("Baz"))))))));
1349 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1350 forField(hasName("foo_"))))));
1351 EXPECT_TRUE(notMatches(Code, constructor(hasAnyConstructorInitializer(
1352 forField(hasType(record(hasName("Bar"))))))));
1353}
1354
1355TEST(HasAnyConstructorInitializer, WithInitializer) {
1356 static const char Code[] =
1357 "class Foo {"
1358 " Foo() : foo_(0) { }"
1359 " int foo_;"
1360 "};";
1361 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1362 withInitializer(integerLiteral(equals(0)))))));
1363 EXPECT_TRUE(notMatches(Code, constructor(hasAnyConstructorInitializer(
1364 withInitializer(integerLiteral(equals(1)))))));
1365}
1366
1367TEST(HasAnyConstructorInitializer, IsWritten) {
1368 static const char Code[] =
1369 "struct Bar { Bar(){} };"
1370 "class Foo {"
1371 " Foo() : foo_() { }"
1372 " Bar foo_;"
1373 " Bar bar_;"
1374 "};";
1375 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1376 allOf(forField(hasName("foo_")), isWritten())))));
1377 EXPECT_TRUE(notMatches(Code, constructor(hasAnyConstructorInitializer(
1378 allOf(forField(hasName("bar_")), isWritten())))));
1379 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1380 allOf(forField(hasName("bar_")), unless(isWritten()))))));
1381}
1382
1383TEST(Matcher, NewExpression) {
1384 StatementMatcher New = expression(newExpression());
1385
1386 EXPECT_TRUE(matches("class X { public: X(); }; void x() { new X; }", New));
1387 EXPECT_TRUE(
1388 matches("class X { public: X(); }; void x() { new X(); }", New));
1389 EXPECT_TRUE(
1390 matches("class X { public: X(int); }; void x() { new X(0); }", New));
1391 EXPECT_TRUE(matches("class X {}; void x(int) { new X; }", New));
1392}
1393
1394TEST(Matcher, NewExpressionArgument) {
1395 StatementMatcher New = expression(constructorCall(
1396 hasArgument(
1397 0, declarationReference(to(variable(hasName("y")))))));
1398
1399 EXPECT_TRUE(
1400 matches("class X { public: X(int); }; void x() { int y; new X(y); }",
1401 New));
1402 EXPECT_TRUE(
1403 matches("class X { public: X(int); }; void x() { int y; new X(y); }",
1404 New));
1405 EXPECT_TRUE(
1406 notMatches("class X { public: X(int); }; void x() { int z; new X(z); }",
1407 New));
1408
1409 StatementMatcher WrongIndex = expression(constructorCall(
1410 hasArgument(
1411 42, declarationReference(to(variable(hasName("y")))))));
1412 EXPECT_TRUE(
1413 notMatches("class X { public: X(int); }; void x() { int y; new X(y); }",
1414 WrongIndex));
1415}
1416
1417TEST(Matcher, NewExpressionArgumentCount) {
1418 StatementMatcher New = constructorCall(argumentCountIs(1));
1419
1420 EXPECT_TRUE(
1421 matches("class X { public: X(int); }; void x() { new X(0); }", New));
1422 EXPECT_TRUE(
1423 notMatches("class X { public: X(int, int); }; void x() { new X(0, 0); }",
1424 New));
1425}
1426
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001427TEST(Matcher, DeleteExpression) {
1428 EXPECT_TRUE(matches("struct A {}; void f(A* a) { delete a; }",
1429 deleteExpression()));
1430}
1431
Manuel Klimek4da21662012-07-06 05:48:52 +00001432TEST(Matcher, DefaultArgument) {
1433 StatementMatcher Arg = defaultArgument();
1434
1435 EXPECT_TRUE(matches("void x(int, int = 0) { int y; x(y); }", Arg));
1436 EXPECT_TRUE(
1437 matches("class X { void x(int, int = 0) { int y; x(y); } };", Arg));
1438 EXPECT_TRUE(notMatches("void x(int, int = 0) { int y; x(y, 0); }", Arg));
1439}
1440
1441TEST(Matcher, StringLiterals) {
1442 StatementMatcher Literal = expression(stringLiteral());
1443 EXPECT_TRUE(matches("const char *s = \"string\";", Literal));
1444 // wide string
1445 EXPECT_TRUE(matches("const wchar_t *s = L\"string\";", Literal));
1446 // with escaped characters
1447 EXPECT_TRUE(matches("const char *s = \"\x05five\";", Literal));
1448 // no matching -- though the data type is the same, there is no string literal
1449 EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));
1450}
1451
1452TEST(Matcher, CharacterLiterals) {
1453 StatementMatcher CharLiteral = expression(characterLiteral());
1454 EXPECT_TRUE(matches("const char c = 'c';", CharLiteral));
1455 // wide character
1456 EXPECT_TRUE(matches("const char c = L'c';", CharLiteral));
1457 // wide character, Hex encoded, NOT MATCHED!
1458 EXPECT_TRUE(notMatches("const wchar_t c = 0x2126;", CharLiteral));
1459 EXPECT_TRUE(notMatches("const char c = 0x1;", CharLiteral));
1460}
1461
1462TEST(Matcher, IntegerLiterals) {
1463 StatementMatcher HasIntLiteral = expression(integerLiteral());
1464 EXPECT_TRUE(matches("int i = 10;", HasIntLiteral));
1465 EXPECT_TRUE(matches("int i = 0x1AB;", HasIntLiteral));
1466 EXPECT_TRUE(matches("int i = 10L;", HasIntLiteral));
1467 EXPECT_TRUE(matches("int i = 10U;", HasIntLiteral));
1468
1469 // Non-matching cases (character literals, float and double)
1470 EXPECT_TRUE(notMatches("int i = L'a';",
1471 HasIntLiteral)); // this is actually a character
1472 // literal cast to int
1473 EXPECT_TRUE(notMatches("int i = 'a';", HasIntLiteral));
1474 EXPECT_TRUE(notMatches("int i = 1e10;", HasIntLiteral));
1475 EXPECT_TRUE(notMatches("int i = 10.0;", HasIntLiteral));
1476}
1477
1478TEST(Matcher, Conditions) {
1479 StatementMatcher Condition = ifStmt(hasCondition(boolLiteral(equals(true))));
1480
1481 EXPECT_TRUE(matches("void x() { if (true) {} }", Condition));
1482 EXPECT_TRUE(notMatches("void x() { if (false) {} }", Condition));
1483 EXPECT_TRUE(notMatches("void x() { bool a = true; if (a) {} }", Condition));
1484 EXPECT_TRUE(notMatches("void x() { if (true || false) {} }", Condition));
1485 EXPECT_TRUE(notMatches("void x() { if (1) {} }", Condition));
1486}
1487
1488TEST(MatchBinaryOperator, HasOperatorName) {
1489 StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
1490
1491 EXPECT_TRUE(matches("void x() { true || false; }", OperatorOr));
1492 EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
1493}
1494
1495TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
1496 StatementMatcher OperatorTrueFalse =
1497 binaryOperator(hasLHS(boolLiteral(equals(true))),
1498 hasRHS(boolLiteral(equals(false))));
1499
1500 EXPECT_TRUE(matches("void x() { true || false; }", OperatorTrueFalse));
1501 EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse));
1502 EXPECT_TRUE(notMatches("void x() { false || true; }", OperatorTrueFalse));
1503}
1504
1505TEST(MatchBinaryOperator, HasEitherOperand) {
1506 StatementMatcher HasOperand =
1507 binaryOperator(hasEitherOperand(boolLiteral(equals(false))));
1508
1509 EXPECT_TRUE(matches("void x() { true || false; }", HasOperand));
1510 EXPECT_TRUE(matches("void x() { false && true; }", HasOperand));
1511 EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand));
1512}
1513
1514TEST(Matcher, BinaryOperatorTypes) {
1515 // Integration test that verifies the AST provides all binary operators in
1516 // a way we expect.
1517 // FIXME: Operator ','
1518 EXPECT_TRUE(
1519 matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(","))));
1520 EXPECT_TRUE(
1521 matches("bool b; bool c = (b = true);",
1522 binaryOperator(hasOperatorName("="))));
1523 EXPECT_TRUE(
1524 matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!="))));
1525 EXPECT_TRUE(
1526 matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("=="))));
1527 EXPECT_TRUE(matches("bool b = 1 < 2;", binaryOperator(hasOperatorName("<"))));
1528 EXPECT_TRUE(
1529 matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<="))));
1530 EXPECT_TRUE(
1531 matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<"))));
1532 EXPECT_TRUE(
1533 matches("int i = 1; int j = (i <<= 2);",
1534 binaryOperator(hasOperatorName("<<="))));
1535 EXPECT_TRUE(matches("bool b = 1 > 2;", binaryOperator(hasOperatorName(">"))));
1536 EXPECT_TRUE(
1537 matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">="))));
1538 EXPECT_TRUE(
1539 matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>"))));
1540 EXPECT_TRUE(
1541 matches("int i = 1; int j = (i >>= 2);",
1542 binaryOperator(hasOperatorName(">>="))));
1543 EXPECT_TRUE(
1544 matches("int i = 42 ^ 23;", binaryOperator(hasOperatorName("^"))));
1545 EXPECT_TRUE(
1546 matches("int i = 42; int j = (i ^= 42);",
1547 binaryOperator(hasOperatorName("^="))));
1548 EXPECT_TRUE(
1549 matches("int i = 42 % 23;", binaryOperator(hasOperatorName("%"))));
1550 EXPECT_TRUE(
1551 matches("int i = 42; int j = (i %= 42);",
1552 binaryOperator(hasOperatorName("%="))));
1553 EXPECT_TRUE(
1554 matches("bool b = 42 &23;", binaryOperator(hasOperatorName("&"))));
1555 EXPECT_TRUE(
1556 matches("bool b = true && false;",
1557 binaryOperator(hasOperatorName("&&"))));
1558 EXPECT_TRUE(
1559 matches("bool b = true; bool c = (b &= false);",
1560 binaryOperator(hasOperatorName("&="))));
1561 EXPECT_TRUE(
1562 matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|"))));
1563 EXPECT_TRUE(
1564 matches("bool b = true || false;",
1565 binaryOperator(hasOperatorName("||"))));
1566 EXPECT_TRUE(
1567 matches("bool b = true; bool c = (b |= false);",
1568 binaryOperator(hasOperatorName("|="))));
1569 EXPECT_TRUE(
1570 matches("int i = 42 *23;", binaryOperator(hasOperatorName("*"))));
1571 EXPECT_TRUE(
1572 matches("int i = 42; int j = (i *= 23);",
1573 binaryOperator(hasOperatorName("*="))));
1574 EXPECT_TRUE(
1575 matches("int i = 42 / 23;", binaryOperator(hasOperatorName("/"))));
1576 EXPECT_TRUE(
1577 matches("int i = 42; int j = (i /= 23);",
1578 binaryOperator(hasOperatorName("/="))));
1579 EXPECT_TRUE(
1580 matches("int i = 42 + 23;", binaryOperator(hasOperatorName("+"))));
1581 EXPECT_TRUE(
1582 matches("int i = 42; int j = (i += 23);",
1583 binaryOperator(hasOperatorName("+="))));
1584 EXPECT_TRUE(
1585 matches("int i = 42 - 23;", binaryOperator(hasOperatorName("-"))));
1586 EXPECT_TRUE(
1587 matches("int i = 42; int j = (i -= 23);",
1588 binaryOperator(hasOperatorName("-="))));
1589 EXPECT_TRUE(
1590 matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };",
1591 binaryOperator(hasOperatorName("->*"))));
1592 EXPECT_TRUE(
1593 matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };",
1594 binaryOperator(hasOperatorName(".*"))));
1595
1596 // Member expressions as operators are not supported in matches.
1597 EXPECT_TRUE(
1598 notMatches("struct A { void x(A *a) { a->x(this); } };",
1599 binaryOperator(hasOperatorName("->"))));
1600
1601 // Initializer assignments are not represented as operator equals.
1602 EXPECT_TRUE(
1603 notMatches("bool b = true;", binaryOperator(hasOperatorName("="))));
1604
1605 // Array indexing is not represented as operator.
1606 EXPECT_TRUE(notMatches("int a[42]; void x() { a[23]; }", unaryOperator()));
1607
1608 // Overloaded operators do not match at all.
1609 EXPECT_TRUE(notMatches(
1610 "struct A { bool operator&&(const A &a) const { return false; } };"
1611 "void x() { A a, b; a && b; }",
1612 binaryOperator()));
1613}
1614
1615TEST(MatchUnaryOperator, HasOperatorName) {
1616 StatementMatcher OperatorNot = unaryOperator(hasOperatorName("!"));
1617
1618 EXPECT_TRUE(matches("void x() { !true; } ", OperatorNot));
1619 EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
1620}
1621
1622TEST(MatchUnaryOperator, HasUnaryOperand) {
1623 StatementMatcher OperatorOnFalse =
1624 unaryOperator(hasUnaryOperand(boolLiteral(equals(false))));
1625
1626 EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse));
1627 EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse));
1628}
1629
1630TEST(Matcher, UnaryOperatorTypes) {
1631 // Integration test that verifies the AST provides all unary operators in
1632 // a way we expect.
1633 EXPECT_TRUE(matches("bool b = !true;", unaryOperator(hasOperatorName("!"))));
1634 EXPECT_TRUE(
1635 matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&"))));
1636 EXPECT_TRUE(matches("int i = ~ 1;", unaryOperator(hasOperatorName("~"))));
1637 EXPECT_TRUE(
1638 matches("bool *p; bool b = *p;", unaryOperator(hasOperatorName("*"))));
1639 EXPECT_TRUE(
1640 matches("int i; int j = +i;", unaryOperator(hasOperatorName("+"))));
1641 EXPECT_TRUE(
1642 matches("int i; int j = -i;", unaryOperator(hasOperatorName("-"))));
1643 EXPECT_TRUE(
1644 matches("int i; int j = ++i;", unaryOperator(hasOperatorName("++"))));
1645 EXPECT_TRUE(
1646 matches("int i; int j = i++;", unaryOperator(hasOperatorName("++"))));
1647 EXPECT_TRUE(
1648 matches("int i; int j = --i;", unaryOperator(hasOperatorName("--"))));
1649 EXPECT_TRUE(
1650 matches("int i; int j = i--;", unaryOperator(hasOperatorName("--"))));
1651
1652 // We don't match conversion operators.
1653 EXPECT_TRUE(notMatches("int i; double d = (double)i;", unaryOperator()));
1654
1655 // Function calls are not represented as operator.
1656 EXPECT_TRUE(notMatches("void f(); void x() { f(); }", unaryOperator()));
1657
1658 // Overloaded operators do not match at all.
1659 // FIXME: We probably want to add that.
1660 EXPECT_TRUE(notMatches(
1661 "struct A { bool operator!() const { return false; } };"
1662 "void x() { A a; !a; }", unaryOperator(hasOperatorName("!"))));
1663}
1664
1665TEST(Matcher, ConditionalOperator) {
1666 StatementMatcher Conditional = conditionalOperator(
1667 hasCondition(boolLiteral(equals(true))),
1668 hasTrueExpression(boolLiteral(equals(false))));
1669
1670 EXPECT_TRUE(matches("void x() { true ? false : true; }", Conditional));
1671 EXPECT_TRUE(notMatches("void x() { false ? false : true; }", Conditional));
1672 EXPECT_TRUE(notMatches("void x() { true ? true : false; }", Conditional));
1673
1674 StatementMatcher ConditionalFalse = conditionalOperator(
1675 hasFalseExpression(boolLiteral(equals(false))));
1676
1677 EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
1678 EXPECT_TRUE(
1679 notMatches("void x() { true ? false : true; }", ConditionalFalse));
1680}
1681
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001682TEST(ArraySubscriptMatchers, ArraySubscripts) {
1683 EXPECT_TRUE(matches("int i[2]; void f() { i[1] = 1; }",
1684 arraySubscriptExpr()));
1685 EXPECT_TRUE(notMatches("int i; void f() { i = 1; }",
1686 arraySubscriptExpr()));
1687}
1688
1689TEST(ArraySubscriptMatchers, ArrayIndex) {
1690 EXPECT_TRUE(matches(
1691 "int i[2]; void f() { i[1] = 1; }",
1692 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
1693 EXPECT_TRUE(matches(
1694 "int i[2]; void f() { 1[i] = 1; }",
1695 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
1696 EXPECT_TRUE(notMatches(
1697 "int i[2]; void f() { i[1] = 1; }",
1698 arraySubscriptExpr(hasIndex(integerLiteral(equals(0))))));
1699}
1700
1701TEST(ArraySubscriptMatchers, MatchesArrayBase) {
1702 EXPECT_TRUE(matches(
1703 "int i[2]; void f() { i[1] = 2; }",
1704 arraySubscriptExpr(hasBase(implicitCast(
1705 hasSourceExpression(declarationReference()))))));
1706}
1707
Manuel Klimek4da21662012-07-06 05:48:52 +00001708TEST(Matcher, HasNameSupportsNamespaces) {
1709 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1710 record(hasName("a::b::C"))));
1711 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1712 record(hasName("::a::b::C"))));
1713 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1714 record(hasName("b::C"))));
1715 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1716 record(hasName("C"))));
1717 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1718 record(hasName("c::b::C"))));
1719 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1720 record(hasName("a::c::C"))));
1721 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1722 record(hasName("a::b::A"))));
1723 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1724 record(hasName("::C"))));
1725 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1726 record(hasName("::b::C"))));
1727 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1728 record(hasName("z::a::b::C"))));
1729 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1730 record(hasName("a+b::C"))));
1731 EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
1732 record(hasName("C"))));
1733}
1734
1735TEST(Matcher, HasNameSupportsOuterClasses) {
1736 EXPECT_TRUE(
1737 matches("class A { class B { class C; }; };", record(hasName("A::B::C"))));
1738 EXPECT_TRUE(
1739 matches("class A { class B { class C; }; };",
1740 record(hasName("::A::B::C"))));
1741 EXPECT_TRUE(
1742 matches("class A { class B { class C; }; };", record(hasName("B::C"))));
1743 EXPECT_TRUE(
1744 matches("class A { class B { class C; }; };", record(hasName("C"))));
1745 EXPECT_TRUE(
1746 notMatches("class A { class B { class C; }; };",
1747 record(hasName("c::B::C"))));
1748 EXPECT_TRUE(
1749 notMatches("class A { class B { class C; }; };",
1750 record(hasName("A::c::C"))));
1751 EXPECT_TRUE(
1752 notMatches("class A { class B { class C; }; };",
1753 record(hasName("A::B::A"))));
1754 EXPECT_TRUE(
1755 notMatches("class A { class B { class C; }; };", record(hasName("::C"))));
1756 EXPECT_TRUE(
1757 notMatches("class A { class B { class C; }; };",
1758 record(hasName("::B::C"))));
1759 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
1760 record(hasName("z::A::B::C"))));
1761 EXPECT_TRUE(
1762 notMatches("class A { class B { class C; }; };",
1763 record(hasName("A+B::C"))));
1764}
1765
1766TEST(Matcher, IsDefinition) {
1767 DeclarationMatcher DefinitionOfClassA =
1768 record(hasName("A"), isDefinition());
1769 EXPECT_TRUE(matches("class A {};", DefinitionOfClassA));
1770 EXPECT_TRUE(notMatches("class A;", DefinitionOfClassA));
1771
1772 DeclarationMatcher DefinitionOfVariableA =
1773 variable(hasName("a"), isDefinition());
1774 EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));
1775 EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));
1776
1777 DeclarationMatcher DefinitionOfMethodA =
1778 method(hasName("a"), isDefinition());
1779 EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));
1780 EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));
1781}
1782
1783TEST(Matcher, OfClass) {
1784 StatementMatcher Constructor = constructorCall(hasDeclaration(method(
1785 ofClass(hasName("X")))));
1786
1787 EXPECT_TRUE(
1788 matches("class X { public: X(); }; void x(int) { X x; }", Constructor));
1789 EXPECT_TRUE(
1790 matches("class X { public: X(); }; void x(int) { X x = X(); }",
1791 Constructor));
1792 EXPECT_TRUE(
1793 notMatches("class Y { public: Y(); }; void x(int) { Y y; }",
1794 Constructor));
1795}
1796
1797TEST(Matcher, VisitsTemplateInstantiations) {
1798 EXPECT_TRUE(matches(
1799 "class A { public: void x(); };"
1800 "template <typename T> class B { public: void y() { T t; t.x(); } };"
1801 "void f() { B<A> b; b.y(); }", call(callee(method(hasName("x"))))));
1802
1803 EXPECT_TRUE(matches(
1804 "class A { public: void x(); };"
1805 "class C {"
1806 " public:"
1807 " template <typename T> class B { public: void y() { T t; t.x(); } };"
1808 "};"
1809 "void f() {"
1810 " C::B<A> b; b.y();"
1811 "}", record(hasName("C"),
1812 hasDescendant(call(callee(method(hasName("x"))))))));
1813}
1814
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001815TEST(Matcher, HandlesNullQualTypes) {
1816 // FIXME: Add a Type matcher so we can replace uses of this
1817 // variable with Type(True())
1818 const TypeMatcher AnyType = anything();
1819
1820 // We don't really care whether this matcher succeeds; we're testing that
1821 // it completes without crashing.
1822 EXPECT_TRUE(matches(
1823 "struct A { };"
1824 "template <typename T>"
1825 "void f(T t) {"
1826 " T local_t(t /* this becomes a null QualType in the AST */);"
1827 "}"
1828 "void g() {"
1829 " f(0);"
1830 "}",
1831 expression(hasType(TypeMatcher(
1832 anyOf(
1833 TypeMatcher(hasDeclaration(anything())),
1834 pointsTo(AnyType),
1835 references(AnyType)
1836 // Other QualType matchers should go here.
1837 ))))));
1838}
1839
Manuel Klimek4da21662012-07-06 05:48:52 +00001840// For testing AST_MATCHER_P().
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001841AST_MATCHER_P(Decl, just, internal::Matcher<Decl>, AMatcher) {
Manuel Klimek4da21662012-07-06 05:48:52 +00001842 // Make sure all special variables are used: node, match_finder,
1843 // bound_nodes_builder, and the parameter named 'AMatcher'.
1844 return AMatcher.matches(Node, Finder, Builder);
1845}
1846
1847TEST(AstMatcherPMacro, Works) {
Manuel Klimek9f174082012-07-24 13:37:29 +00001848 DeclarationMatcher HasClassB = just(has(record(hasName("B")).bind("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001849
1850 EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001851 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001852
1853 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001854 HasClassB, new VerifyIdIsBoundToDecl<Decl>("a")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001855
1856 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001857 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001858}
1859
1860AST_POLYMORPHIC_MATCHER_P(
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001861 polymorphicHas, internal::Matcher<Decl>, AMatcher) {
1862 TOOLING_COMPILE_ASSERT((llvm::is_same<NodeType, Decl>::value) ||
1863 (llvm::is_same<NodeType, Stmt>::value),
Manuel Klimek4da21662012-07-06 05:48:52 +00001864 assert_node_type_is_accessible);
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001865 internal::TypedBaseMatcher<Decl> ChildMatcher(AMatcher);
Manuel Klimek4da21662012-07-06 05:48:52 +00001866 return Finder->matchesChildOf(
1867 Node, ChildMatcher, Builder,
1868 ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
1869 ASTMatchFinder::BK_First);
1870}
1871
1872TEST(AstPolymorphicMatcherPMacro, Works) {
Manuel Klimek9f174082012-07-24 13:37:29 +00001873 DeclarationMatcher HasClassB = polymorphicHas(record(hasName("B")).bind("b"));
Manuel Klimek4da21662012-07-06 05:48:52 +00001874
1875 EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001876 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001877
1878 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001879 HasClassB, new VerifyIdIsBoundToDecl<Decl>("a")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001880
1881 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001882 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001883
1884 StatementMatcher StatementHasClassB =
1885 polymorphicHas(record(hasName("B")));
1886
1887 EXPECT_TRUE(matches("void x() { class B {}; }", StatementHasClassB));
1888}
1889
1890TEST(For, FindsForLoops) {
1891 EXPECT_TRUE(matches("void f() { for(;;); }", forStmt()));
1892 EXPECT_TRUE(matches("void f() { if(true) for(;;); }", forStmt()));
1893}
1894
Daniel Jasper6a124492012-07-12 08:50:38 +00001895TEST(For, ForLoopInternals) {
1896 EXPECT_TRUE(matches("void f(){ int i; for (; i < 3 ; ); }",
1897 forStmt(hasCondition(anything()))));
1898 EXPECT_TRUE(matches("void f() { for (int i = 0; ;); }",
1899 forStmt(hasLoopInit(anything()))));
1900}
1901
1902TEST(For, NegativeForLoopInternals) {
1903 EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }",
1904 forStmt(hasCondition(expression()))));
1905 EXPECT_TRUE(notMatches("void f() {int i; for (; i < 4; ++i) {} }",
1906 forStmt(hasLoopInit(anything()))));
1907}
1908
Manuel Klimek4da21662012-07-06 05:48:52 +00001909TEST(For, ReportsNoFalsePositives) {
1910 EXPECT_TRUE(notMatches("void f() { ; }", forStmt()));
1911 EXPECT_TRUE(notMatches("void f() { if(true); }", forStmt()));
1912}
1913
1914TEST(CompoundStatement, HandlesSimpleCases) {
1915 EXPECT_TRUE(notMatches("void f();", compoundStatement()));
1916 EXPECT_TRUE(matches("void f() {}", compoundStatement()));
1917 EXPECT_TRUE(matches("void f() {{}}", compoundStatement()));
1918}
1919
1920TEST(CompoundStatement, DoesNotMatchEmptyStruct) {
1921 // It's not a compound statement just because there's "{}" in the source
1922 // text. This is an AST search, not grep.
1923 EXPECT_TRUE(notMatches("namespace n { struct S {}; }",
1924 compoundStatement()));
1925 EXPECT_TRUE(matches("namespace n { struct S { void f() {{}} }; }",
1926 compoundStatement()));
1927}
1928
Daniel Jasper6a124492012-07-12 08:50:38 +00001929TEST(HasBody, FindsBodyOfForWhileDoLoops) {
Manuel Klimek4da21662012-07-06 05:48:52 +00001930 EXPECT_TRUE(matches("void f() { for(;;) {} }",
Daniel Jasper6a124492012-07-12 08:50:38 +00001931 forStmt(hasBody(compoundStatement()))));
Manuel Klimek4da21662012-07-06 05:48:52 +00001932 EXPECT_TRUE(notMatches("void f() { for(;;); }",
Daniel Jasper6a124492012-07-12 08:50:38 +00001933 forStmt(hasBody(compoundStatement()))));
1934 EXPECT_TRUE(matches("void f() { while(true) {} }",
1935 whileStmt(hasBody(compoundStatement()))));
1936 EXPECT_TRUE(matches("void f() { do {} while(true); }",
1937 doStmt(hasBody(compoundStatement()))));
Manuel Klimek4da21662012-07-06 05:48:52 +00001938}
1939
1940TEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
1941 // The simplest case: every compound statement is in a function
1942 // definition, and the function body itself must be a compound
1943 // statement.
1944 EXPECT_TRUE(matches("void f() { for (;;); }",
1945 compoundStatement(hasAnySubstatement(forStmt()))));
1946}
1947
1948TEST(HasAnySubstatement, IsNotRecursive) {
1949 // It's really "has any immediate substatement".
1950 EXPECT_TRUE(notMatches("void f() { if (true) for (;;); }",
1951 compoundStatement(hasAnySubstatement(forStmt()))));
1952}
1953
1954TEST(HasAnySubstatement, MatchesInNestedCompoundStatements) {
1955 EXPECT_TRUE(matches("void f() { if (true) { for (;;); } }",
1956 compoundStatement(hasAnySubstatement(forStmt()))));
1957}
1958
1959TEST(HasAnySubstatement, FindsSubstatementBetweenOthers) {
1960 EXPECT_TRUE(matches("void f() { 1; 2; 3; for (;;); 4; 5; 6; }",
1961 compoundStatement(hasAnySubstatement(forStmt()))));
1962}
1963
1964TEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) {
1965 EXPECT_TRUE(matches("void f() { }",
1966 compoundStatement(statementCountIs(0))));
1967 EXPECT_TRUE(notMatches("void f() {}",
1968 compoundStatement(statementCountIs(1))));
1969}
1970
1971TEST(StatementCountIs, AppearsToMatchOnlyOneCount) {
1972 EXPECT_TRUE(matches("void f() { 1; }",
1973 compoundStatement(statementCountIs(1))));
1974 EXPECT_TRUE(notMatches("void f() { 1; }",
1975 compoundStatement(statementCountIs(0))));
1976 EXPECT_TRUE(notMatches("void f() { 1; }",
1977 compoundStatement(statementCountIs(2))));
1978}
1979
1980TEST(StatementCountIs, WorksWithMultipleStatements) {
1981 EXPECT_TRUE(matches("void f() { 1; 2; 3; }",
1982 compoundStatement(statementCountIs(3))));
1983}
1984
1985TEST(StatementCountIs, WorksWithNestedCompoundStatements) {
1986 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1987 compoundStatement(statementCountIs(1))));
1988 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1989 compoundStatement(statementCountIs(2))));
1990 EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
1991 compoundStatement(statementCountIs(3))));
1992 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1993 compoundStatement(statementCountIs(4))));
1994}
1995
1996TEST(Member, WorksInSimplestCase) {
1997 EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
1998 memberExpression(member(hasName("first")))));
1999}
2000
2001TEST(Member, DoesNotMatchTheBaseExpression) {
2002 // Don't pick out the wrong part of the member expression, this should
2003 // be checking the member (name) only.
2004 EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
2005 memberExpression(member(hasName("first")))));
2006}
2007
2008TEST(Member, MatchesInMemberFunctionCall) {
2009 EXPECT_TRUE(matches("void f() {"
2010 " struct { void first() {}; } s;"
2011 " s.first();"
2012 "};",
2013 memberExpression(member(hasName("first")))));
2014}
2015
Dmitri Gribenko671a0452012-08-18 00:29:27 +00002016TEST(Member, MatchesMemberAllocationFunction) {
2017 EXPECT_TRUE(matches("namespace std { typedef unsigned long size_t; }"
2018 "class X { void *operator new(std::size_t); };",
2019 method(ofClass(hasName("X")))));
2020
2021 EXPECT_TRUE(matches("class X { void operator delete(void*); };",
2022 method(ofClass(hasName("X")))));
2023
2024 EXPECT_TRUE(matches("namespace std { typedef unsigned long size_t; }"
2025 "class X { void operator delete[](void*, std::size_t); };",
2026 method(ofClass(hasName("X")))));
2027}
2028
Manuel Klimek4da21662012-07-06 05:48:52 +00002029TEST(HasObjectExpression, DoesNotMatchMember) {
2030 EXPECT_TRUE(notMatches(
2031 "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
2032 memberExpression(hasObjectExpression(hasType(record(hasName("X")))))));
2033}
2034
2035TEST(HasObjectExpression, MatchesBaseOfVariable) {
2036 EXPECT_TRUE(matches(
2037 "struct X { int m; }; void f(X x) { x.m; }",
2038 memberExpression(hasObjectExpression(hasType(record(hasName("X")))))));
2039 EXPECT_TRUE(matches(
2040 "struct X { int m; }; void f(X* x) { x->m; }",
2041 memberExpression(hasObjectExpression(
2042 hasType(pointsTo(record(hasName("X"))))))));
2043}
2044
2045TEST(HasObjectExpression,
2046 MatchesObjectExpressionOfImplicitlyFormedMemberExpression) {
2047 EXPECT_TRUE(matches(
2048 "class X {}; struct S { X m; void f() { this->m; } };",
2049 memberExpression(hasObjectExpression(
2050 hasType(pointsTo(record(hasName("S"))))))));
2051 EXPECT_TRUE(matches(
2052 "class X {}; struct S { X m; void f() { m; } };",
2053 memberExpression(hasObjectExpression(
2054 hasType(pointsTo(record(hasName("S"))))))));
2055}
2056
2057TEST(Field, DoesNotMatchNonFieldMembers) {
2058 EXPECT_TRUE(notMatches("class X { void m(); };", field(hasName("m"))));
2059 EXPECT_TRUE(notMatches("class X { class m {}; };", field(hasName("m"))));
2060 EXPECT_TRUE(notMatches("class X { enum { m }; };", field(hasName("m"))));
2061 EXPECT_TRUE(notMatches("class X { enum m {}; };", field(hasName("m"))));
2062}
2063
2064TEST(Field, MatchesField) {
2065 EXPECT_TRUE(matches("class X { int m; };", field(hasName("m"))));
2066}
2067
2068TEST(IsConstQualified, MatchesConstInt) {
2069 EXPECT_TRUE(matches("const int i = 42;",
2070 variable(hasType(isConstQualified()))));
2071}
2072
2073TEST(IsConstQualified, MatchesConstPointer) {
2074 EXPECT_TRUE(matches("int i = 42; int* const p(&i);",
2075 variable(hasType(isConstQualified()))));
2076}
2077
2078TEST(IsConstQualified, MatchesThroughTypedef) {
2079 EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
2080 variable(hasType(isConstQualified()))));
2081 EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p(0);",
2082 variable(hasType(isConstQualified()))));
2083}
2084
2085TEST(IsConstQualified, DoesNotMatchInappropriately) {
2086 EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
2087 variable(hasType(isConstQualified()))));
2088 EXPECT_TRUE(notMatches("int const* p;",
2089 variable(hasType(isConstQualified()))));
2090}
2091
Sam Panzer089e5b32012-08-16 16:58:10 +00002092TEST(CastExpression, MatchesExplicitCasts) {
2093 EXPECT_TRUE(matches("char *p = reinterpret_cast<char *>(&p);",
2094 expression(castExpr())));
2095 EXPECT_TRUE(matches("void *p = (void *)(&p);", expression(castExpr())));
2096 EXPECT_TRUE(matches("char q, *p = const_cast<char *>(&q);",
2097 expression(castExpr())));
2098 EXPECT_TRUE(matches("char c = char(0);", expression(castExpr())));
2099}
2100TEST(CastExpression, MatchesImplicitCasts) {
2101 // This test creates an implicit cast from int to char.
2102 EXPECT_TRUE(matches("char c = 0;", expression(castExpr())));
2103 // This test creates an implicit cast from lvalue to rvalue.
2104 EXPECT_TRUE(matches("char c = 0, d = c;", expression(castExpr())));
2105}
2106
2107TEST(CastExpression, DoesNotMatchNonCasts) {
2108 EXPECT_TRUE(notMatches("char c = '0';", expression(castExpr())));
2109 EXPECT_TRUE(notMatches("char c, &q = c;", expression(castExpr())));
2110 EXPECT_TRUE(notMatches("int i = (0);", expression(castExpr())));
2111 EXPECT_TRUE(notMatches("int i = 0;", expression(castExpr())));
2112}
2113
Manuel Klimek4da21662012-07-06 05:48:52 +00002114TEST(ReinterpretCast, MatchesSimpleCase) {
2115 EXPECT_TRUE(matches("char* p = reinterpret_cast<char*>(&p);",
2116 expression(reinterpretCast())));
2117}
2118
2119TEST(ReinterpretCast, DoesNotMatchOtherCasts) {
2120 EXPECT_TRUE(notMatches("char* p = (char*)(&p);",
2121 expression(reinterpretCast())));
2122 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
2123 expression(reinterpretCast())));
2124 EXPECT_TRUE(notMatches("void* p = static_cast<void*>(&p);",
2125 expression(reinterpretCast())));
2126 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
2127 "B b;"
2128 "D* p = dynamic_cast<D*>(&b);",
2129 expression(reinterpretCast())));
2130}
2131
2132TEST(FunctionalCast, MatchesSimpleCase) {
2133 std::string foo_class = "class Foo { public: Foo(char*); };";
2134 EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",
2135 expression(functionalCast())));
2136}
2137
2138TEST(FunctionalCast, DoesNotMatchOtherCasts) {
2139 std::string FooClass = "class Foo { public: Foo(char*); };";
2140 EXPECT_TRUE(
2141 notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",
2142 expression(functionalCast())));
2143 EXPECT_TRUE(
2144 notMatches(FooClass + "void r() { Foo f = \"hello world\"; }",
2145 expression(functionalCast())));
2146}
2147
2148TEST(DynamicCast, MatchesSimpleCase) {
2149 EXPECT_TRUE(matches("struct B { virtual ~B() {} }; struct D : B {};"
2150 "B b;"
2151 "D* p = dynamic_cast<D*>(&b);",
2152 expression(dynamicCast())));
2153}
2154
2155TEST(StaticCast, MatchesSimpleCase) {
2156 EXPECT_TRUE(matches("void* p(static_cast<void*>(&p));",
2157 expression(staticCast())));
2158}
2159
2160TEST(StaticCast, DoesNotMatchOtherCasts) {
2161 EXPECT_TRUE(notMatches("char* p = (char*)(&p);",
2162 expression(staticCast())));
2163 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
2164 expression(staticCast())));
2165 EXPECT_TRUE(notMatches("void* p = reinterpret_cast<char*>(&p);",
2166 expression(staticCast())));
2167 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
2168 "B b;"
2169 "D* p = dynamic_cast<D*>(&b);",
2170 expression(staticCast())));
2171}
2172
2173TEST(HasDestinationType, MatchesSimpleCase) {
2174 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
2175 expression(
2176 staticCast(hasDestinationType(
2177 pointsTo(TypeMatcher(anything())))))));
2178}
2179
Sam Panzer089e5b32012-08-16 16:58:10 +00002180TEST(HasImplicitDestinationType, MatchesSimpleCase) {
2181 // This test creates an implicit const cast.
2182 EXPECT_TRUE(matches("int x; const int i = x;",
2183 expression(implicitCast(
2184 hasImplicitDestinationType(isInteger())))));
2185 // This test creates an implicit array-to-pointer cast.
2186 EXPECT_TRUE(matches("int arr[3]; int *p = arr;",
2187 expression(implicitCast(hasImplicitDestinationType(
2188 pointsTo(TypeMatcher(anything())))))));
2189}
2190
2191TEST(HasImplicitDestinationType, DoesNotMatchIncorrectly) {
2192 // This test creates an implicit cast from int to char.
2193 EXPECT_TRUE(notMatches("char c = 0;",
2194 expression(implicitCast(hasImplicitDestinationType(
2195 unless(anything()))))));
2196 // This test creates an implicit array-to-pointer cast.
2197 EXPECT_TRUE(notMatches("int arr[3]; int *p = arr;",
2198 expression(implicitCast(hasImplicitDestinationType(
2199 unless(anything()))))));
2200}
2201
2202TEST(ImplicitCast, MatchesSimpleCase) {
2203 // This test creates an implicit const cast.
2204 EXPECT_TRUE(matches("int x = 0; const int y = x;",
2205 variable(hasInitializer(implicitCast()))));
2206 // This test creates an implicit cast from int to char.
2207 EXPECT_TRUE(matches("char c = 0;",
2208 variable(hasInitializer(implicitCast()))));
2209 // This test creates an implicit array-to-pointer cast.
2210 EXPECT_TRUE(matches("int arr[6]; int *p = arr;",
2211 variable(hasInitializer(implicitCast()))));
2212}
2213
2214TEST(ImplicitCast, DoesNotMatchIncorrectly) {
2215 // This test verifies that implicitCast() matches exactly when implicit casts
2216 // are present, and that it ignores explicit and paren casts.
2217
2218 // These two test cases have no casts.
2219 EXPECT_TRUE(notMatches("int x = 0;",
2220 variable(hasInitializer(implicitCast()))));
2221 EXPECT_TRUE(notMatches("int x = 0, &y = x;",
2222 variable(hasInitializer(implicitCast()))));
2223
2224 EXPECT_TRUE(notMatches("int x = 0; double d = (double) x;",
2225 variable(hasInitializer(implicitCast()))));
2226 EXPECT_TRUE(notMatches("const int *p; int *q = const_cast<int *>(p);",
2227 variable(hasInitializer(implicitCast()))));
2228
2229 EXPECT_TRUE(notMatches("int x = (0);",
2230 variable(hasInitializer(implicitCast()))));
2231}
2232
2233TEST(IgnoringImpCasts, MatchesImpCasts) {
2234 // This test checks that ignoringImpCasts matches when implicit casts are
2235 // present and its inner matcher alone does not match.
2236 // Note that this test creates an implicit const cast.
2237 EXPECT_TRUE(matches("int x = 0; const int y = x;",
2238 variable(hasInitializer(ignoringImpCasts(
2239 declarationReference(to(variable(hasName("x")))))))));
2240 // This test creates an implict cast from int to char.
2241 EXPECT_TRUE(matches("char x = 0;",
2242 variable(hasInitializer(ignoringImpCasts(
2243 integerLiteral(equals(0)))))));
2244}
2245
2246TEST(IgnoringImpCasts, DoesNotMatchIncorrectly) {
2247 // These tests verify that ignoringImpCasts does not match if the inner
2248 // matcher does not match.
2249 // Note that the first test creates an implicit const cast.
2250 EXPECT_TRUE(notMatches("int x; const int y = x;",
2251 variable(hasInitializer(ignoringImpCasts(
2252 unless(anything()))))));
2253 EXPECT_TRUE(notMatches("int x; int y = x;",
2254 variable(hasInitializer(ignoringImpCasts(
2255 unless(anything()))))));
2256
2257 // These tests verify that ignoringImplictCasts does not look through explicit
2258 // casts or parentheses.
2259 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
2260 variable(hasInitializer(ignoringImpCasts(
2261 integerLiteral())))));
2262 EXPECT_TRUE(notMatches("int i = (0);",
2263 variable(hasInitializer(ignoringImpCasts(
2264 integerLiteral())))));
2265 EXPECT_TRUE(notMatches("float i = (float)0;",
2266 variable(hasInitializer(ignoringImpCasts(
2267 integerLiteral())))));
2268 EXPECT_TRUE(notMatches("float i = float(0);",
2269 variable(hasInitializer(ignoringImpCasts(
2270 integerLiteral())))));
2271}
2272
2273TEST(IgnoringImpCasts, MatchesWithoutImpCasts) {
2274 // This test verifies that expressions that do not have implicit casts
2275 // still match the inner matcher.
2276 EXPECT_TRUE(matches("int x = 0; int &y = x;",
2277 variable(hasInitializer(ignoringImpCasts(
2278 declarationReference(to(variable(hasName("x")))))))));
2279}
2280
2281TEST(IgnoringParenCasts, MatchesParenCasts) {
2282 // This test checks that ignoringParenCasts matches when parentheses and/or
2283 // casts are present and its inner matcher alone does not match.
2284 EXPECT_TRUE(matches("int x = (0);",
2285 variable(hasInitializer(ignoringParenCasts(
2286 integerLiteral(equals(0)))))));
2287 EXPECT_TRUE(matches("int x = (((((0)))));",
2288 variable(hasInitializer(ignoringParenCasts(
2289 integerLiteral(equals(0)))))));
2290
2291 // This test creates an implict cast from int to char in addition to the
2292 // parentheses.
2293 EXPECT_TRUE(matches("char x = (0);",
2294 variable(hasInitializer(ignoringParenCasts(
2295 integerLiteral(equals(0)))))));
2296
2297 EXPECT_TRUE(matches("char x = (char)0;",
2298 variable(hasInitializer(ignoringParenCasts(
2299 integerLiteral(equals(0)))))));
2300 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
2301 variable(hasInitializer(ignoringParenCasts(
2302 integerLiteral(equals(0)))))));
2303}
2304
2305TEST(IgnoringParenCasts, MatchesWithoutParenCasts) {
2306 // This test verifies that expressions that do not have any casts still match.
2307 EXPECT_TRUE(matches("int x = 0;",
2308 variable(hasInitializer(ignoringParenCasts(
2309 integerLiteral(equals(0)))))));
2310}
2311
2312TEST(IgnoringParenCasts, DoesNotMatchIncorrectly) {
2313 // These tests verify that ignoringImpCasts does not match if the inner
2314 // matcher does not match.
2315 EXPECT_TRUE(notMatches("int x = ((0));",
2316 variable(hasInitializer(ignoringParenCasts(
2317 unless(anything()))))));
2318
2319 // This test creates an implicit cast from int to char in addition to the
2320 // parentheses.
2321 EXPECT_TRUE(notMatches("char x = ((0));",
2322 variable(hasInitializer(ignoringParenCasts(
2323 unless(anything()))))));
2324
2325 EXPECT_TRUE(notMatches("char *x = static_cast<char *>((0));",
2326 variable(hasInitializer(ignoringParenCasts(
2327 unless(anything()))))));
2328}
2329
2330TEST(IgnoringParenAndImpCasts, MatchesParenImpCasts) {
2331 // This test checks that ignoringParenAndImpCasts matches when
2332 // parentheses and/or implicit casts are present and its inner matcher alone
2333 // does not match.
2334 // Note that this test creates an implicit const cast.
2335 EXPECT_TRUE(matches("int x = 0; const int y = x;",
2336 variable(hasInitializer(ignoringParenImpCasts(
2337 declarationReference(to(variable(hasName("x")))))))));
2338 // This test creates an implicit cast from int to char.
2339 EXPECT_TRUE(matches("const char x = (0);",
2340 variable(hasInitializer(ignoringParenImpCasts(
2341 integerLiteral(equals(0)))))));
2342}
2343
2344TEST(IgnoringParenAndImpCasts, MatchesWithoutParenImpCasts) {
2345 // This test verifies that expressions that do not have parentheses or
2346 // implicit casts still match.
2347 EXPECT_TRUE(matches("int x = 0; int &y = x;",
2348 variable(hasInitializer(ignoringParenImpCasts(
2349 declarationReference(to(variable(hasName("x")))))))));
2350 EXPECT_TRUE(matches("int x = 0;",
2351 variable(hasInitializer(ignoringParenImpCasts(
2352 integerLiteral(equals(0)))))));
2353}
2354
2355TEST(IgnoringParenAndImpCasts, DoesNotMatchIncorrectly) {
2356 // These tests verify that ignoringParenImpCasts does not match if
2357 // the inner matcher does not match.
2358 // This test creates an implicit cast.
2359 EXPECT_TRUE(notMatches("char c = ((3));",
2360 variable(hasInitializer(ignoringParenImpCasts(
2361 unless(anything()))))));
2362 // These tests verify that ignoringParenAndImplictCasts does not look
2363 // through explicit casts.
2364 EXPECT_TRUE(notMatches("float y = (float(0));",
2365 variable(hasInitializer(ignoringParenImpCasts(
2366 integerLiteral())))));
2367 EXPECT_TRUE(notMatches("float y = (float)0;",
2368 variable(hasInitializer(ignoringParenImpCasts(
2369 integerLiteral())))));
2370 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
2371 variable(hasInitializer(ignoringParenImpCasts(
2372 integerLiteral())))));
2373}
2374
Manuel Klimek715c9562012-07-25 10:02:02 +00002375TEST(HasSourceExpression, MatchesImplicitCasts) {
Manuel Klimek4da21662012-07-06 05:48:52 +00002376 EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
2377 "void r() {string a_string; URL url = a_string; }",
2378 expression(implicitCast(
2379 hasSourceExpression(constructorCall())))));
2380}
2381
Manuel Klimek715c9562012-07-25 10:02:02 +00002382TEST(HasSourceExpression, MatchesExplicitCasts) {
2383 EXPECT_TRUE(matches("float x = static_cast<float>(42);",
2384 expression(explicitCast(
2385 hasSourceExpression(hasDescendant(
2386 expression(integerLiteral())))))));
2387}
2388
Manuel Klimek4da21662012-07-06 05:48:52 +00002389TEST(Statement, DoesNotMatchDeclarations) {
2390 EXPECT_TRUE(notMatches("class X {};", statement()));
2391}
2392
2393TEST(Statement, MatchesCompoundStatments) {
2394 EXPECT_TRUE(matches("void x() {}", statement()));
2395}
2396
2397TEST(DeclarationStatement, DoesNotMatchCompoundStatements) {
2398 EXPECT_TRUE(notMatches("void x() {}", declarationStatement()));
2399}
2400
2401TEST(DeclarationStatement, MatchesVariableDeclarationStatements) {
2402 EXPECT_TRUE(matches("void x() { int a; }", declarationStatement()));
2403}
2404
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002405TEST(InitListExpression, MatchesInitListExpression) {
2406 EXPECT_TRUE(matches("int a[] = { 1, 2 };",
2407 initListExpr(hasType(asString("int [2]")))));
2408 EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };",
2409 initListExpr(hasType(record(hasName("B"))))));
2410}
2411
2412TEST(UsingDeclaration, MatchesUsingDeclarations) {
2413 EXPECT_TRUE(matches("namespace X { int x; } using X::x;",
2414 usingDecl()));
2415}
2416
2417TEST(UsingDeclaration, MatchesShadowUsingDelcarations) {
2418 EXPECT_TRUE(matches("namespace f { int a; } using f::a;",
2419 usingDecl(hasAnyUsingShadowDecl(hasName("a")))));
2420}
2421
2422TEST(UsingDeclaration, MatchesSpecificTarget) {
2423 EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
2424 usingDecl(hasAnyUsingShadowDecl(
2425 hasTargetDecl(function())))));
2426 EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
2427 usingDecl(hasAnyUsingShadowDecl(
2428 hasTargetDecl(function())))));
2429}
2430
2431TEST(UsingDeclaration, ThroughUsingDeclaration) {
2432 EXPECT_TRUE(matches(
2433 "namespace a { void f(); } using a::f; void g() { f(); }",
2434 declarationReference(throughUsingDecl(anything()))));
2435 EXPECT_TRUE(notMatches(
2436 "namespace a { void f(); } using a::f; void g() { a::f(); }",
2437 declarationReference(throughUsingDecl(anything()))));
2438}
2439
Sam Panzer425f41b2012-08-16 17:20:59 +00002440TEST(SingleDecl, IsSingleDecl) {
2441 StatementMatcher SingleDeclStmt =
2442 declarationStatement(hasSingleDecl(variable(hasInitializer(anything()))));
2443 EXPECT_TRUE(matches("void f() {int a = 4;}", SingleDeclStmt));
2444 EXPECT_TRUE(notMatches("void f() {int a;}", SingleDeclStmt));
2445 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
2446 SingleDeclStmt));
2447}
2448
2449TEST(DeclStmt, ContainsDeclaration) {
2450 DeclarationMatcher MatchesInit = variable(hasInitializer(anything()));
2451
2452 EXPECT_TRUE(matches("void f() {int a = 4;}",
2453 declarationStatement(containsDeclaration(0,
2454 MatchesInit))));
2455 EXPECT_TRUE(matches("void f() {int a = 4, b = 3;}",
2456 declarationStatement(containsDeclaration(0, MatchesInit),
2457 containsDeclaration(1,
2458 MatchesInit))));
2459 unsigned WrongIndex = 42;
2460 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
2461 declarationStatement(containsDeclaration(WrongIndex,
2462 MatchesInit))));
2463}
2464
2465TEST(DeclCount, DeclCountIsCorrect) {
2466 EXPECT_TRUE(matches("void f() {int i,j;}",
2467 declarationStatement(declCountIs(2))));
2468 EXPECT_TRUE(notMatches("void f() {int i,j; int k;}",
2469 declarationStatement(declCountIs(3))));
2470 EXPECT_TRUE(notMatches("void f() {int i,j, k, l;}",
2471 declarationStatement(declCountIs(3))));
2472}
2473
Manuel Klimek4da21662012-07-06 05:48:52 +00002474TEST(While, MatchesWhileLoops) {
2475 EXPECT_TRUE(notMatches("void x() {}", whileStmt()));
2476 EXPECT_TRUE(matches("void x() { while(true); }", whileStmt()));
2477 EXPECT_TRUE(notMatches("void x() { do {} while(true); }", whileStmt()));
2478}
2479
2480TEST(Do, MatchesDoLoops) {
2481 EXPECT_TRUE(matches("void x() { do {} while(true); }", doStmt()));
2482 EXPECT_TRUE(matches("void x() { do ; while(false); }", doStmt()));
2483}
2484
2485TEST(Do, DoesNotMatchWhileLoops) {
2486 EXPECT_TRUE(notMatches("void x() { while(true) {} }", doStmt()));
2487}
2488
2489TEST(SwitchCase, MatchesCase) {
2490 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchCase()));
2491 EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchCase()));
2492 EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchCase()));
2493 EXPECT_TRUE(notMatches("void x() { switch(42) {} }", switchCase()));
2494}
2495
2496TEST(HasConditionVariableStatement, DoesNotMatchCondition) {
2497 EXPECT_TRUE(notMatches(
2498 "void x() { if(true) {} }",
2499 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2500 EXPECT_TRUE(notMatches(
2501 "void x() { int x; if((x = 42)) {} }",
2502 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2503}
2504
2505TEST(HasConditionVariableStatement, MatchesConditionVariables) {
2506 EXPECT_TRUE(matches(
2507 "void x() { if(int* a = 0) {} }",
2508 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2509}
2510
2511TEST(ForEach, BindsOneNode) {
2512 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002513 record(hasName("C"), forEach(field(hasName("x")).bind("x"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002514 new VerifyIdIsBoundToDecl<FieldDecl>("x", 1)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002515}
2516
2517TEST(ForEach, BindsMultipleNodes) {
2518 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002519 record(hasName("C"), forEach(field().bind("f"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002520 new VerifyIdIsBoundToDecl<FieldDecl>("f", 3)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002521}
2522
2523TEST(ForEach, BindsRecursiveCombinations) {
2524 EXPECT_TRUE(matchAndVerifyResultTrue(
2525 "class C { class D { int x; int y; }; class E { int y; int z; }; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002526 record(hasName("C"), forEach(record(forEach(field().bind("f"))))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002527 new VerifyIdIsBoundToDecl<FieldDecl>("f", 4)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002528}
2529
2530TEST(ForEachDescendant, BindsOneNode) {
2531 EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002532 record(hasName("C"), forEachDescendant(field(hasName("x")).bind("x"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002533 new VerifyIdIsBoundToDecl<FieldDecl>("x", 1)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002534}
2535
2536TEST(ForEachDescendant, BindsMultipleNodes) {
2537 EXPECT_TRUE(matchAndVerifyResultTrue(
2538 "class C { class D { int x; int y; }; "
2539 " class E { class F { int y; int z; }; }; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002540 record(hasName("C"), forEachDescendant(field().bind("f"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002541 new VerifyIdIsBoundToDecl<FieldDecl>("f", 4)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002542}
2543
2544TEST(ForEachDescendant, BindsRecursiveCombinations) {
2545 EXPECT_TRUE(matchAndVerifyResultTrue(
2546 "class C { class D { "
2547 " class E { class F { class G { int y; int z; }; }; }; }; };",
2548 record(hasName("C"), forEachDescendant(record(
Manuel Klimek9f174082012-07-24 13:37:29 +00002549 forEachDescendant(field().bind("f"))))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002550 new VerifyIdIsBoundToDecl<FieldDecl>("f", 8)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002551}
2552
2553
2554TEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) {
2555 // Make sure that we can both match the class by name (::X) and by the type
2556 // the template was instantiated with (via a field).
2557
2558 EXPECT_TRUE(matches(
2559 "template <typename T> class X {}; class A {}; X<A> x;",
2560 record(hasName("::X"), isTemplateInstantiation())));
2561
2562 EXPECT_TRUE(matches(
2563 "template <typename T> class X { T t; }; class A {}; X<A> x;",
2564 record(isTemplateInstantiation(), hasDescendant(
2565 field(hasType(record(hasName("A"))))))));
2566}
2567
2568TEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) {
2569 EXPECT_TRUE(matches(
2570 "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
2571 function(hasParameter(0, hasType(record(hasName("A")))),
2572 isTemplateInstantiation())));
2573}
2574
2575TEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) {
2576 EXPECT_TRUE(matches(
2577 "template <typename T> class X { T t; }; class A {};"
2578 "template class X<A>;",
2579 record(isTemplateInstantiation(), hasDescendant(
2580 field(hasType(record(hasName("A"))))))));
2581}
2582
2583TEST(IsTemplateInstantiation,
2584 MatchesInstantiationOfPartiallySpecializedClassTemplate) {
2585 EXPECT_TRUE(matches(
2586 "template <typename T> class X {};"
2587 "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
2588 record(hasName("::X"), isTemplateInstantiation())));
2589}
2590
2591TEST(IsTemplateInstantiation,
2592 MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
2593 EXPECT_TRUE(matches(
2594 "class A {};"
2595 "class X {"
2596 " template <typename U> class Y { U u; };"
2597 " Y<A> y;"
2598 "};",
2599 record(hasName("::X::Y"), isTemplateInstantiation())));
2600}
2601
2602TEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) {
2603 // FIXME: Figure out whether this makes sense. It doesn't affect the
2604 // normal use case as long as the uppermost instantiation always is marked
2605 // as template instantiation, but it might be confusing as a predicate.
2606 EXPECT_TRUE(matches(
2607 "class A {};"
2608 "template <typename T> class X {"
2609 " template <typename U> class Y { U u; };"
2610 " Y<T> y;"
2611 "}; X<A> x;",
2612 record(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
2613}
2614
2615TEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) {
2616 EXPECT_TRUE(notMatches(
2617 "template <typename T> class X {}; class A {};"
2618 "template <> class X<A> {}; X<A> x;",
2619 record(hasName("::X"), isTemplateInstantiation())));
2620}
2621
2622TEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) {
2623 EXPECT_TRUE(notMatches(
2624 "class A {}; class Y { A a; };",
2625 record(isTemplateInstantiation())));
2626}
2627
Dmitri Gribenko8456ae62012-08-17 18:42:47 +00002628TEST(IsExplicitTemplateSpecialization,
2629 DoesNotMatchPrimaryTemplate) {
2630 EXPECT_TRUE(notMatches(
2631 "template <typename T> class X {};",
2632 record(isExplicitTemplateSpecialization())));
2633 EXPECT_TRUE(notMatches(
2634 "template <typename T> void f(T t);",
2635 function(isExplicitTemplateSpecialization())));
2636}
2637
2638TEST(IsExplicitTemplateSpecialization,
2639 DoesNotMatchExplicitTemplateInstantiations) {
2640 EXPECT_TRUE(notMatches(
2641 "template <typename T> class X {};"
2642 "template class X<int>; extern template class X<long>;",
2643 record(isExplicitTemplateSpecialization())));
2644 EXPECT_TRUE(notMatches(
2645 "template <typename T> void f(T t) {}"
2646 "template void f(int t); extern template void f(long t);",
2647 function(isExplicitTemplateSpecialization())));
2648}
2649
2650TEST(IsExplicitTemplateSpecialization,
2651 DoesNotMatchImplicitTemplateInstantiations) {
2652 EXPECT_TRUE(notMatches(
2653 "template <typename T> class X {}; X<int> x;",
2654 record(isExplicitTemplateSpecialization())));
2655 EXPECT_TRUE(notMatches(
2656 "template <typename T> void f(T t); void g() { f(10); }",
2657 function(isExplicitTemplateSpecialization())));
2658}
2659
2660TEST(IsExplicitTemplateSpecialization,
2661 MatchesExplicitTemplateSpecializations) {
2662 EXPECT_TRUE(matches(
2663 "template <typename T> class X {};"
2664 "template<> class X<int> {};",
2665 record(isExplicitTemplateSpecialization())));
2666 EXPECT_TRUE(matches(
2667 "template <typename T> void f(T t) {}"
2668 "template<> void f(int t) {}",
2669 function(isExplicitTemplateSpecialization())));
2670}
2671
Manuel Klimek4da21662012-07-06 05:48:52 +00002672} // end namespace ast_matchers
2673} // end namespace clang