blob: dcebbc9f3d6e290129259242c1b46bb79bf1fa56 [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
2016TEST(HasObjectExpression, DoesNotMatchMember) {
2017 EXPECT_TRUE(notMatches(
2018 "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
2019 memberExpression(hasObjectExpression(hasType(record(hasName("X")))))));
2020}
2021
2022TEST(HasObjectExpression, MatchesBaseOfVariable) {
2023 EXPECT_TRUE(matches(
2024 "struct X { int m; }; void f(X x) { x.m; }",
2025 memberExpression(hasObjectExpression(hasType(record(hasName("X")))))));
2026 EXPECT_TRUE(matches(
2027 "struct X { int m; }; void f(X* x) { x->m; }",
2028 memberExpression(hasObjectExpression(
2029 hasType(pointsTo(record(hasName("X"))))))));
2030}
2031
2032TEST(HasObjectExpression,
2033 MatchesObjectExpressionOfImplicitlyFormedMemberExpression) {
2034 EXPECT_TRUE(matches(
2035 "class X {}; struct S { X m; void f() { this->m; } };",
2036 memberExpression(hasObjectExpression(
2037 hasType(pointsTo(record(hasName("S"))))))));
2038 EXPECT_TRUE(matches(
2039 "class X {}; struct S { X m; void f() { m; } };",
2040 memberExpression(hasObjectExpression(
2041 hasType(pointsTo(record(hasName("S"))))))));
2042}
2043
2044TEST(Field, DoesNotMatchNonFieldMembers) {
2045 EXPECT_TRUE(notMatches("class X { void m(); };", field(hasName("m"))));
2046 EXPECT_TRUE(notMatches("class X { class m {}; };", field(hasName("m"))));
2047 EXPECT_TRUE(notMatches("class X { enum { m }; };", field(hasName("m"))));
2048 EXPECT_TRUE(notMatches("class X { enum m {}; };", field(hasName("m"))));
2049}
2050
2051TEST(Field, MatchesField) {
2052 EXPECT_TRUE(matches("class X { int m; };", field(hasName("m"))));
2053}
2054
2055TEST(IsConstQualified, MatchesConstInt) {
2056 EXPECT_TRUE(matches("const int i = 42;",
2057 variable(hasType(isConstQualified()))));
2058}
2059
2060TEST(IsConstQualified, MatchesConstPointer) {
2061 EXPECT_TRUE(matches("int i = 42; int* const p(&i);",
2062 variable(hasType(isConstQualified()))));
2063}
2064
2065TEST(IsConstQualified, MatchesThroughTypedef) {
2066 EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
2067 variable(hasType(isConstQualified()))));
2068 EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p(0);",
2069 variable(hasType(isConstQualified()))));
2070}
2071
2072TEST(IsConstQualified, DoesNotMatchInappropriately) {
2073 EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
2074 variable(hasType(isConstQualified()))));
2075 EXPECT_TRUE(notMatches("int const* p;",
2076 variable(hasType(isConstQualified()))));
2077}
2078
Sam Panzer089e5b32012-08-16 16:58:10 +00002079TEST(CastExpression, MatchesExplicitCasts) {
2080 EXPECT_TRUE(matches("char *p = reinterpret_cast<char *>(&p);",
2081 expression(castExpr())));
2082 EXPECT_TRUE(matches("void *p = (void *)(&p);", expression(castExpr())));
2083 EXPECT_TRUE(matches("char q, *p = const_cast<char *>(&q);",
2084 expression(castExpr())));
2085 EXPECT_TRUE(matches("char c = char(0);", expression(castExpr())));
2086}
2087TEST(CastExpression, MatchesImplicitCasts) {
2088 // This test creates an implicit cast from int to char.
2089 EXPECT_TRUE(matches("char c = 0;", expression(castExpr())));
2090 // This test creates an implicit cast from lvalue to rvalue.
2091 EXPECT_TRUE(matches("char c = 0, d = c;", expression(castExpr())));
2092}
2093
2094TEST(CastExpression, DoesNotMatchNonCasts) {
2095 EXPECT_TRUE(notMatches("char c = '0';", expression(castExpr())));
2096 EXPECT_TRUE(notMatches("char c, &q = c;", expression(castExpr())));
2097 EXPECT_TRUE(notMatches("int i = (0);", expression(castExpr())));
2098 EXPECT_TRUE(notMatches("int i = 0;", expression(castExpr())));
2099}
2100
Manuel Klimek4da21662012-07-06 05:48:52 +00002101TEST(ReinterpretCast, MatchesSimpleCase) {
2102 EXPECT_TRUE(matches("char* p = reinterpret_cast<char*>(&p);",
2103 expression(reinterpretCast())));
2104}
2105
2106TEST(ReinterpretCast, DoesNotMatchOtherCasts) {
2107 EXPECT_TRUE(notMatches("char* p = (char*)(&p);",
2108 expression(reinterpretCast())));
2109 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
2110 expression(reinterpretCast())));
2111 EXPECT_TRUE(notMatches("void* p = static_cast<void*>(&p);",
2112 expression(reinterpretCast())));
2113 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
2114 "B b;"
2115 "D* p = dynamic_cast<D*>(&b);",
2116 expression(reinterpretCast())));
2117}
2118
2119TEST(FunctionalCast, MatchesSimpleCase) {
2120 std::string foo_class = "class Foo { public: Foo(char*); };";
2121 EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",
2122 expression(functionalCast())));
2123}
2124
2125TEST(FunctionalCast, DoesNotMatchOtherCasts) {
2126 std::string FooClass = "class Foo { public: Foo(char*); };";
2127 EXPECT_TRUE(
2128 notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",
2129 expression(functionalCast())));
2130 EXPECT_TRUE(
2131 notMatches(FooClass + "void r() { Foo f = \"hello world\"; }",
2132 expression(functionalCast())));
2133}
2134
2135TEST(DynamicCast, MatchesSimpleCase) {
2136 EXPECT_TRUE(matches("struct B { virtual ~B() {} }; struct D : B {};"
2137 "B b;"
2138 "D* p = dynamic_cast<D*>(&b);",
2139 expression(dynamicCast())));
2140}
2141
2142TEST(StaticCast, MatchesSimpleCase) {
2143 EXPECT_TRUE(matches("void* p(static_cast<void*>(&p));",
2144 expression(staticCast())));
2145}
2146
2147TEST(StaticCast, DoesNotMatchOtherCasts) {
2148 EXPECT_TRUE(notMatches("char* p = (char*)(&p);",
2149 expression(staticCast())));
2150 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
2151 expression(staticCast())));
2152 EXPECT_TRUE(notMatches("void* p = reinterpret_cast<char*>(&p);",
2153 expression(staticCast())));
2154 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
2155 "B b;"
2156 "D* p = dynamic_cast<D*>(&b);",
2157 expression(staticCast())));
2158}
2159
2160TEST(HasDestinationType, MatchesSimpleCase) {
2161 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
2162 expression(
2163 staticCast(hasDestinationType(
2164 pointsTo(TypeMatcher(anything())))))));
2165}
2166
Sam Panzer089e5b32012-08-16 16:58:10 +00002167TEST(HasImplicitDestinationType, MatchesSimpleCase) {
2168 // This test creates an implicit const cast.
2169 EXPECT_TRUE(matches("int x; const int i = x;",
2170 expression(implicitCast(
2171 hasImplicitDestinationType(isInteger())))));
2172 // This test creates an implicit array-to-pointer cast.
2173 EXPECT_TRUE(matches("int arr[3]; int *p = arr;",
2174 expression(implicitCast(hasImplicitDestinationType(
2175 pointsTo(TypeMatcher(anything())))))));
2176}
2177
2178TEST(HasImplicitDestinationType, DoesNotMatchIncorrectly) {
2179 // This test creates an implicit cast from int to char.
2180 EXPECT_TRUE(notMatches("char c = 0;",
2181 expression(implicitCast(hasImplicitDestinationType(
2182 unless(anything()))))));
2183 // This test creates an implicit array-to-pointer cast.
2184 EXPECT_TRUE(notMatches("int arr[3]; int *p = arr;",
2185 expression(implicitCast(hasImplicitDestinationType(
2186 unless(anything()))))));
2187}
2188
2189TEST(ImplicitCast, MatchesSimpleCase) {
2190 // This test creates an implicit const cast.
2191 EXPECT_TRUE(matches("int x = 0; const int y = x;",
2192 variable(hasInitializer(implicitCast()))));
2193 // This test creates an implicit cast from int to char.
2194 EXPECT_TRUE(matches("char c = 0;",
2195 variable(hasInitializer(implicitCast()))));
2196 // This test creates an implicit array-to-pointer cast.
2197 EXPECT_TRUE(matches("int arr[6]; int *p = arr;",
2198 variable(hasInitializer(implicitCast()))));
2199}
2200
2201TEST(ImplicitCast, DoesNotMatchIncorrectly) {
2202 // This test verifies that implicitCast() matches exactly when implicit casts
2203 // are present, and that it ignores explicit and paren casts.
2204
2205 // These two test cases have no casts.
2206 EXPECT_TRUE(notMatches("int x = 0;",
2207 variable(hasInitializer(implicitCast()))));
2208 EXPECT_TRUE(notMatches("int x = 0, &y = x;",
2209 variable(hasInitializer(implicitCast()))));
2210
2211 EXPECT_TRUE(notMatches("int x = 0; double d = (double) x;",
2212 variable(hasInitializer(implicitCast()))));
2213 EXPECT_TRUE(notMatches("const int *p; int *q = const_cast<int *>(p);",
2214 variable(hasInitializer(implicitCast()))));
2215
2216 EXPECT_TRUE(notMatches("int x = (0);",
2217 variable(hasInitializer(implicitCast()))));
2218}
2219
2220TEST(IgnoringImpCasts, MatchesImpCasts) {
2221 // This test checks that ignoringImpCasts matches when implicit casts are
2222 // present and its inner matcher alone does not match.
2223 // Note that this test creates an implicit const cast.
2224 EXPECT_TRUE(matches("int x = 0; const int y = x;",
2225 variable(hasInitializer(ignoringImpCasts(
2226 declarationReference(to(variable(hasName("x")))))))));
2227 // This test creates an implict cast from int to char.
2228 EXPECT_TRUE(matches("char x = 0;",
2229 variable(hasInitializer(ignoringImpCasts(
2230 integerLiteral(equals(0)))))));
2231}
2232
2233TEST(IgnoringImpCasts, DoesNotMatchIncorrectly) {
2234 // These tests verify that ignoringImpCasts does not match if the inner
2235 // matcher does not match.
2236 // Note that the first test creates an implicit const cast.
2237 EXPECT_TRUE(notMatches("int x; const int y = x;",
2238 variable(hasInitializer(ignoringImpCasts(
2239 unless(anything()))))));
2240 EXPECT_TRUE(notMatches("int x; int y = x;",
2241 variable(hasInitializer(ignoringImpCasts(
2242 unless(anything()))))));
2243
2244 // These tests verify that ignoringImplictCasts does not look through explicit
2245 // casts or parentheses.
2246 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
2247 variable(hasInitializer(ignoringImpCasts(
2248 integerLiteral())))));
2249 EXPECT_TRUE(notMatches("int i = (0);",
2250 variable(hasInitializer(ignoringImpCasts(
2251 integerLiteral())))));
2252 EXPECT_TRUE(notMatches("float i = (float)0;",
2253 variable(hasInitializer(ignoringImpCasts(
2254 integerLiteral())))));
2255 EXPECT_TRUE(notMatches("float i = float(0);",
2256 variable(hasInitializer(ignoringImpCasts(
2257 integerLiteral())))));
2258}
2259
2260TEST(IgnoringImpCasts, MatchesWithoutImpCasts) {
2261 // This test verifies that expressions that do not have implicit casts
2262 // still match the inner matcher.
2263 EXPECT_TRUE(matches("int x = 0; int &y = x;",
2264 variable(hasInitializer(ignoringImpCasts(
2265 declarationReference(to(variable(hasName("x")))))))));
2266}
2267
2268TEST(IgnoringParenCasts, MatchesParenCasts) {
2269 // This test checks that ignoringParenCasts matches when parentheses and/or
2270 // casts are present and its inner matcher alone does not match.
2271 EXPECT_TRUE(matches("int x = (0);",
2272 variable(hasInitializer(ignoringParenCasts(
2273 integerLiteral(equals(0)))))));
2274 EXPECT_TRUE(matches("int x = (((((0)))));",
2275 variable(hasInitializer(ignoringParenCasts(
2276 integerLiteral(equals(0)))))));
2277
2278 // This test creates an implict cast from int to char in addition to the
2279 // parentheses.
2280 EXPECT_TRUE(matches("char x = (0);",
2281 variable(hasInitializer(ignoringParenCasts(
2282 integerLiteral(equals(0)))))));
2283
2284 EXPECT_TRUE(matches("char x = (char)0;",
2285 variable(hasInitializer(ignoringParenCasts(
2286 integerLiteral(equals(0)))))));
2287 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
2288 variable(hasInitializer(ignoringParenCasts(
2289 integerLiteral(equals(0)))))));
2290}
2291
2292TEST(IgnoringParenCasts, MatchesWithoutParenCasts) {
2293 // This test verifies that expressions that do not have any casts still match.
2294 EXPECT_TRUE(matches("int x = 0;",
2295 variable(hasInitializer(ignoringParenCasts(
2296 integerLiteral(equals(0)))))));
2297}
2298
2299TEST(IgnoringParenCasts, DoesNotMatchIncorrectly) {
2300 // These tests verify that ignoringImpCasts does not match if the inner
2301 // matcher does not match.
2302 EXPECT_TRUE(notMatches("int x = ((0));",
2303 variable(hasInitializer(ignoringParenCasts(
2304 unless(anything()))))));
2305
2306 // This test creates an implicit cast from int to char in addition to the
2307 // parentheses.
2308 EXPECT_TRUE(notMatches("char x = ((0));",
2309 variable(hasInitializer(ignoringParenCasts(
2310 unless(anything()))))));
2311
2312 EXPECT_TRUE(notMatches("char *x = static_cast<char *>((0));",
2313 variable(hasInitializer(ignoringParenCasts(
2314 unless(anything()))))));
2315}
2316
2317TEST(IgnoringParenAndImpCasts, MatchesParenImpCasts) {
2318 // This test checks that ignoringParenAndImpCasts matches when
2319 // parentheses and/or implicit casts are present and its inner matcher alone
2320 // does not match.
2321 // Note that this test creates an implicit const cast.
2322 EXPECT_TRUE(matches("int x = 0; const int y = x;",
2323 variable(hasInitializer(ignoringParenImpCasts(
2324 declarationReference(to(variable(hasName("x")))))))));
2325 // This test creates an implicit cast from int to char.
2326 EXPECT_TRUE(matches("const char x = (0);",
2327 variable(hasInitializer(ignoringParenImpCasts(
2328 integerLiteral(equals(0)))))));
2329}
2330
2331TEST(IgnoringParenAndImpCasts, MatchesWithoutParenImpCasts) {
2332 // This test verifies that expressions that do not have parentheses or
2333 // implicit casts still match.
2334 EXPECT_TRUE(matches("int x = 0; int &y = x;",
2335 variable(hasInitializer(ignoringParenImpCasts(
2336 declarationReference(to(variable(hasName("x")))))))));
2337 EXPECT_TRUE(matches("int x = 0;",
2338 variable(hasInitializer(ignoringParenImpCasts(
2339 integerLiteral(equals(0)))))));
2340}
2341
2342TEST(IgnoringParenAndImpCasts, DoesNotMatchIncorrectly) {
2343 // These tests verify that ignoringParenImpCasts does not match if
2344 // the inner matcher does not match.
2345 // This test creates an implicit cast.
2346 EXPECT_TRUE(notMatches("char c = ((3));",
2347 variable(hasInitializer(ignoringParenImpCasts(
2348 unless(anything()))))));
2349 // These tests verify that ignoringParenAndImplictCasts does not look
2350 // through explicit casts.
2351 EXPECT_TRUE(notMatches("float y = (float(0));",
2352 variable(hasInitializer(ignoringParenImpCasts(
2353 integerLiteral())))));
2354 EXPECT_TRUE(notMatches("float y = (float)0;",
2355 variable(hasInitializer(ignoringParenImpCasts(
2356 integerLiteral())))));
2357 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
2358 variable(hasInitializer(ignoringParenImpCasts(
2359 integerLiteral())))));
2360}
2361
Manuel Klimek715c9562012-07-25 10:02:02 +00002362TEST(HasSourceExpression, MatchesImplicitCasts) {
Manuel Klimek4da21662012-07-06 05:48:52 +00002363 EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
2364 "void r() {string a_string; URL url = a_string; }",
2365 expression(implicitCast(
2366 hasSourceExpression(constructorCall())))));
2367}
2368
Manuel Klimek715c9562012-07-25 10:02:02 +00002369TEST(HasSourceExpression, MatchesExplicitCasts) {
2370 EXPECT_TRUE(matches("float x = static_cast<float>(42);",
2371 expression(explicitCast(
2372 hasSourceExpression(hasDescendant(
2373 expression(integerLiteral())))))));
2374}
2375
Manuel Klimek4da21662012-07-06 05:48:52 +00002376TEST(Statement, DoesNotMatchDeclarations) {
2377 EXPECT_TRUE(notMatches("class X {};", statement()));
2378}
2379
2380TEST(Statement, MatchesCompoundStatments) {
2381 EXPECT_TRUE(matches("void x() {}", statement()));
2382}
2383
2384TEST(DeclarationStatement, DoesNotMatchCompoundStatements) {
2385 EXPECT_TRUE(notMatches("void x() {}", declarationStatement()));
2386}
2387
2388TEST(DeclarationStatement, MatchesVariableDeclarationStatements) {
2389 EXPECT_TRUE(matches("void x() { int a; }", declarationStatement()));
2390}
2391
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002392TEST(InitListExpression, MatchesInitListExpression) {
2393 EXPECT_TRUE(matches("int a[] = { 1, 2 };",
2394 initListExpr(hasType(asString("int [2]")))));
2395 EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };",
2396 initListExpr(hasType(record(hasName("B"))))));
2397}
2398
2399TEST(UsingDeclaration, MatchesUsingDeclarations) {
2400 EXPECT_TRUE(matches("namespace X { int x; } using X::x;",
2401 usingDecl()));
2402}
2403
2404TEST(UsingDeclaration, MatchesShadowUsingDelcarations) {
2405 EXPECT_TRUE(matches("namespace f { int a; } using f::a;",
2406 usingDecl(hasAnyUsingShadowDecl(hasName("a")))));
2407}
2408
2409TEST(UsingDeclaration, MatchesSpecificTarget) {
2410 EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
2411 usingDecl(hasAnyUsingShadowDecl(
2412 hasTargetDecl(function())))));
2413 EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
2414 usingDecl(hasAnyUsingShadowDecl(
2415 hasTargetDecl(function())))));
2416}
2417
2418TEST(UsingDeclaration, ThroughUsingDeclaration) {
2419 EXPECT_TRUE(matches(
2420 "namespace a { void f(); } using a::f; void g() { f(); }",
2421 declarationReference(throughUsingDecl(anything()))));
2422 EXPECT_TRUE(notMatches(
2423 "namespace a { void f(); } using a::f; void g() { a::f(); }",
2424 declarationReference(throughUsingDecl(anything()))));
2425}
2426
Sam Panzer425f41b2012-08-16 17:20:59 +00002427TEST(SingleDecl, IsSingleDecl) {
2428 StatementMatcher SingleDeclStmt =
2429 declarationStatement(hasSingleDecl(variable(hasInitializer(anything()))));
2430 EXPECT_TRUE(matches("void f() {int a = 4;}", SingleDeclStmt));
2431 EXPECT_TRUE(notMatches("void f() {int a;}", SingleDeclStmt));
2432 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
2433 SingleDeclStmt));
2434}
2435
2436TEST(DeclStmt, ContainsDeclaration) {
2437 DeclarationMatcher MatchesInit = variable(hasInitializer(anything()));
2438
2439 EXPECT_TRUE(matches("void f() {int a = 4;}",
2440 declarationStatement(containsDeclaration(0,
2441 MatchesInit))));
2442 EXPECT_TRUE(matches("void f() {int a = 4, b = 3;}",
2443 declarationStatement(containsDeclaration(0, MatchesInit),
2444 containsDeclaration(1,
2445 MatchesInit))));
2446 unsigned WrongIndex = 42;
2447 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
2448 declarationStatement(containsDeclaration(WrongIndex,
2449 MatchesInit))));
2450}
2451
2452TEST(DeclCount, DeclCountIsCorrect) {
2453 EXPECT_TRUE(matches("void f() {int i,j;}",
2454 declarationStatement(declCountIs(2))));
2455 EXPECT_TRUE(notMatches("void f() {int i,j; int k;}",
2456 declarationStatement(declCountIs(3))));
2457 EXPECT_TRUE(notMatches("void f() {int i,j, k, l;}",
2458 declarationStatement(declCountIs(3))));
2459}
2460
Manuel Klimek4da21662012-07-06 05:48:52 +00002461TEST(While, MatchesWhileLoops) {
2462 EXPECT_TRUE(notMatches("void x() {}", whileStmt()));
2463 EXPECT_TRUE(matches("void x() { while(true); }", whileStmt()));
2464 EXPECT_TRUE(notMatches("void x() { do {} while(true); }", whileStmt()));
2465}
2466
2467TEST(Do, MatchesDoLoops) {
2468 EXPECT_TRUE(matches("void x() { do {} while(true); }", doStmt()));
2469 EXPECT_TRUE(matches("void x() { do ; while(false); }", doStmt()));
2470}
2471
2472TEST(Do, DoesNotMatchWhileLoops) {
2473 EXPECT_TRUE(notMatches("void x() { while(true) {} }", doStmt()));
2474}
2475
2476TEST(SwitchCase, MatchesCase) {
2477 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchCase()));
2478 EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchCase()));
2479 EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchCase()));
2480 EXPECT_TRUE(notMatches("void x() { switch(42) {} }", switchCase()));
2481}
2482
2483TEST(HasConditionVariableStatement, DoesNotMatchCondition) {
2484 EXPECT_TRUE(notMatches(
2485 "void x() { if(true) {} }",
2486 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2487 EXPECT_TRUE(notMatches(
2488 "void x() { int x; if((x = 42)) {} }",
2489 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2490}
2491
2492TEST(HasConditionVariableStatement, MatchesConditionVariables) {
2493 EXPECT_TRUE(matches(
2494 "void x() { if(int* a = 0) {} }",
2495 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2496}
2497
2498TEST(ForEach, BindsOneNode) {
2499 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002500 record(hasName("C"), forEach(field(hasName("x")).bind("x"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002501 new VerifyIdIsBoundToDecl<FieldDecl>("x", 1)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002502}
2503
2504TEST(ForEach, BindsMultipleNodes) {
2505 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002506 record(hasName("C"), forEach(field().bind("f"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002507 new VerifyIdIsBoundToDecl<FieldDecl>("f", 3)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002508}
2509
2510TEST(ForEach, BindsRecursiveCombinations) {
2511 EXPECT_TRUE(matchAndVerifyResultTrue(
2512 "class C { class D { int x; int y; }; class E { int y; int z; }; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002513 record(hasName("C"), forEach(record(forEach(field().bind("f"))))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002514 new VerifyIdIsBoundToDecl<FieldDecl>("f", 4)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002515}
2516
2517TEST(ForEachDescendant, BindsOneNode) {
2518 EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002519 record(hasName("C"), forEachDescendant(field(hasName("x")).bind("x"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002520 new VerifyIdIsBoundToDecl<FieldDecl>("x", 1)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002521}
2522
2523TEST(ForEachDescendant, BindsMultipleNodes) {
2524 EXPECT_TRUE(matchAndVerifyResultTrue(
2525 "class C { class D { int x; int y; }; "
2526 " class E { class F { int y; int z; }; }; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002527 record(hasName("C"), forEachDescendant(field().bind("f"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002528 new VerifyIdIsBoundToDecl<FieldDecl>("f", 4)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002529}
2530
2531TEST(ForEachDescendant, BindsRecursiveCombinations) {
2532 EXPECT_TRUE(matchAndVerifyResultTrue(
2533 "class C { class D { "
2534 " class E { class F { class G { int y; int z; }; }; }; }; };",
2535 record(hasName("C"), forEachDescendant(record(
Manuel Klimek9f174082012-07-24 13:37:29 +00002536 forEachDescendant(field().bind("f"))))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002537 new VerifyIdIsBoundToDecl<FieldDecl>("f", 8)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002538}
2539
2540
2541TEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) {
2542 // Make sure that we can both match the class by name (::X) and by the type
2543 // the template was instantiated with (via a field).
2544
2545 EXPECT_TRUE(matches(
2546 "template <typename T> class X {}; class A {}; X<A> x;",
2547 record(hasName("::X"), isTemplateInstantiation())));
2548
2549 EXPECT_TRUE(matches(
2550 "template <typename T> class X { T t; }; class A {}; X<A> x;",
2551 record(isTemplateInstantiation(), hasDescendant(
2552 field(hasType(record(hasName("A"))))))));
2553}
2554
2555TEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) {
2556 EXPECT_TRUE(matches(
2557 "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
2558 function(hasParameter(0, hasType(record(hasName("A")))),
2559 isTemplateInstantiation())));
2560}
2561
2562TEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) {
2563 EXPECT_TRUE(matches(
2564 "template <typename T> class X { T t; }; class A {};"
2565 "template class X<A>;",
2566 record(isTemplateInstantiation(), hasDescendant(
2567 field(hasType(record(hasName("A"))))))));
2568}
2569
2570TEST(IsTemplateInstantiation,
2571 MatchesInstantiationOfPartiallySpecializedClassTemplate) {
2572 EXPECT_TRUE(matches(
2573 "template <typename T> class X {};"
2574 "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
2575 record(hasName("::X"), isTemplateInstantiation())));
2576}
2577
2578TEST(IsTemplateInstantiation,
2579 MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
2580 EXPECT_TRUE(matches(
2581 "class A {};"
2582 "class X {"
2583 " template <typename U> class Y { U u; };"
2584 " Y<A> y;"
2585 "};",
2586 record(hasName("::X::Y"), isTemplateInstantiation())));
2587}
2588
2589TEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) {
2590 // FIXME: Figure out whether this makes sense. It doesn't affect the
2591 // normal use case as long as the uppermost instantiation always is marked
2592 // as template instantiation, but it might be confusing as a predicate.
2593 EXPECT_TRUE(matches(
2594 "class A {};"
2595 "template <typename T> class X {"
2596 " template <typename U> class Y { U u; };"
2597 " Y<T> y;"
2598 "}; X<A> x;",
2599 record(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
2600}
2601
2602TEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) {
2603 EXPECT_TRUE(notMatches(
2604 "template <typename T> class X {}; class A {};"
2605 "template <> class X<A> {}; X<A> x;",
2606 record(hasName("::X"), isTemplateInstantiation())));
2607}
2608
2609TEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) {
2610 EXPECT_TRUE(notMatches(
2611 "class A {}; class Y { A a; };",
2612 record(isTemplateInstantiation())));
2613}
2614
Dmitri Gribenko8456ae62012-08-17 18:42:47 +00002615TEST(IsExplicitTemplateSpecialization,
2616 DoesNotMatchPrimaryTemplate) {
2617 EXPECT_TRUE(notMatches(
2618 "template <typename T> class X {};",
2619 record(isExplicitTemplateSpecialization())));
2620 EXPECT_TRUE(notMatches(
2621 "template <typename T> void f(T t);",
2622 function(isExplicitTemplateSpecialization())));
2623}
2624
2625TEST(IsExplicitTemplateSpecialization,
2626 DoesNotMatchExplicitTemplateInstantiations) {
2627 EXPECT_TRUE(notMatches(
2628 "template <typename T> class X {};"
2629 "template class X<int>; extern template class X<long>;",
2630 record(isExplicitTemplateSpecialization())));
2631 EXPECT_TRUE(notMatches(
2632 "template <typename T> void f(T t) {}"
2633 "template void f(int t); extern template void f(long t);",
2634 function(isExplicitTemplateSpecialization())));
2635}
2636
2637TEST(IsExplicitTemplateSpecialization,
2638 DoesNotMatchImplicitTemplateInstantiations) {
2639 EXPECT_TRUE(notMatches(
2640 "template <typename T> class X {}; X<int> x;",
2641 record(isExplicitTemplateSpecialization())));
2642 EXPECT_TRUE(notMatches(
2643 "template <typename T> void f(T t); void g() { f(10); }",
2644 function(isExplicitTemplateSpecialization())));
2645}
2646
2647TEST(IsExplicitTemplateSpecialization,
2648 MatchesExplicitTemplateSpecializations) {
2649 EXPECT_TRUE(matches(
2650 "template <typename T> class X {};"
2651 "template<> class X<int> {};",
2652 record(isExplicitTemplateSpecialization())));
2653 EXPECT_TRUE(matches(
2654 "template <typename T> void f(T t) {}"
2655 "template<> void f(int t) {}",
2656 function(isExplicitTemplateSpecialization())));
2657}
2658
Manuel Klimek4da21662012-07-06 05:48:52 +00002659} // end namespace ast_matchers
2660} // end namespace clang