blob: adf0e9479f08b0b43972c832f34fda936ed7bb9b [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
Daniel Jasper6a124492012-07-12 08:50:38 +0000295TEST(AllOf, AllOverloadsWork) {
296 const char Program[] =
297 "struct T { }; int f(int, T*); void g(int x) { T t; f(x, &t); }";
298 EXPECT_TRUE(matches(Program,
299 call(allOf(callee(function(hasName("f"))),
300 hasArgument(0, declarationReference(to(variable())))))));
301 EXPECT_TRUE(matches(Program,
302 call(allOf(callee(function(hasName("f"))),
303 hasArgument(0, declarationReference(to(variable()))),
304 hasArgument(1, hasType(pointsTo(record(hasName("T")))))))));
305}
306
Manuel Klimek4da21662012-07-06 05:48:52 +0000307TEST(DeclarationMatcher, MatchAnyOf) {
308 DeclarationMatcher YOrZDerivedFromX =
309 record(anyOf(hasName("Y"), allOf(isDerivedFrom("X"), hasName("Z"))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000310 EXPECT_TRUE(
311 matches("class X {}; class Z : public X {};", YOrZDerivedFromX));
312 EXPECT_TRUE(matches("class Y {};", YOrZDerivedFromX));
313 EXPECT_TRUE(
314 notMatches("class X {}; class W : public X {};", YOrZDerivedFromX));
315 EXPECT_TRUE(notMatches("class Z {};", YOrZDerivedFromX));
316
Daniel Jasperff2fcb82012-07-15 19:57:12 +0000317 DeclarationMatcher XOrYOrZOrU =
318 record(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U")));
319 EXPECT_TRUE(matches("class X {};", XOrYOrZOrU));
320 EXPECT_TRUE(notMatches("class V {};", XOrYOrZOrU));
321
Manuel Klimek4da21662012-07-06 05:48:52 +0000322 DeclarationMatcher XOrYOrZOrUOrV =
323 record(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U"),
Daniel Jasperff2fcb82012-07-15 19:57:12 +0000324 hasName("V")));
Manuel Klimek4da21662012-07-06 05:48:52 +0000325 EXPECT_TRUE(matches("class X {};", XOrYOrZOrUOrV));
326 EXPECT_TRUE(matches("class Y {};", XOrYOrZOrUOrV));
327 EXPECT_TRUE(matches("class Z {};", XOrYOrZOrUOrV));
328 EXPECT_TRUE(matches("class U {};", XOrYOrZOrUOrV));
329 EXPECT_TRUE(matches("class V {};", XOrYOrZOrUOrV));
330 EXPECT_TRUE(notMatches("class A {};", XOrYOrZOrUOrV));
331}
332
333TEST(DeclarationMatcher, MatchHas) {
334 DeclarationMatcher HasClassX = record(has(record(hasName("X"))));
335
336 EXPECT_TRUE(matches("class Y { class X {}; };", HasClassX));
337 EXPECT_TRUE(matches("class X {};", HasClassX));
338
339 DeclarationMatcher YHasClassX =
340 record(hasName("Y"), has(record(hasName("X"))));
341 EXPECT_TRUE(matches("class Y { class X {}; };", YHasClassX));
342 EXPECT_TRUE(notMatches("class X {};", YHasClassX));
343 EXPECT_TRUE(
344 notMatches("class Y { class Z { class X {}; }; };", YHasClassX));
345}
346
347TEST(DeclarationMatcher, MatchHasRecursiveAllOf) {
348 DeclarationMatcher Recursive =
349 record(
350 has(record(
351 has(record(hasName("X"))),
352 has(record(hasName("Y"))),
353 hasName("Z"))),
354 has(record(
355 has(record(hasName("A"))),
356 has(record(hasName("B"))),
357 hasName("C"))),
358 hasName("F"));
359
360 EXPECT_TRUE(matches(
361 "class F {"
362 " class Z {"
363 " class X {};"
364 " class Y {};"
365 " };"
366 " class C {"
367 " class A {};"
368 " class B {};"
369 " };"
370 "};", Recursive));
371
372 EXPECT_TRUE(matches(
373 "class F {"
374 " class Z {"
375 " class A {};"
376 " class X {};"
377 " class Y {};"
378 " };"
379 " class C {"
380 " class X {};"
381 " class A {};"
382 " class B {};"
383 " };"
384 "};", Recursive));
385
386 EXPECT_TRUE(matches(
387 "class O1 {"
388 " class O2 {"
389 " class F {"
390 " class Z {"
391 " class A {};"
392 " class X {};"
393 " class Y {};"
394 " };"
395 " class C {"
396 " class X {};"
397 " class A {};"
398 " class B {};"
399 " };"
400 " };"
401 " };"
402 "};", Recursive));
403}
404
405TEST(DeclarationMatcher, MatchHasRecursiveAnyOf) {
406 DeclarationMatcher Recursive =
407 record(
408 anyOf(
409 has(record(
410 anyOf(
411 has(record(
412 hasName("X"))),
413 has(record(
414 hasName("Y"))),
415 hasName("Z")))),
416 has(record(
417 anyOf(
418 hasName("C"),
419 has(record(
420 hasName("A"))),
421 has(record(
422 hasName("B")))))),
423 hasName("F")));
424
425 EXPECT_TRUE(matches("class F {};", Recursive));
426 EXPECT_TRUE(matches("class Z {};", Recursive));
427 EXPECT_TRUE(matches("class C {};", Recursive));
428 EXPECT_TRUE(matches("class M { class N { class X {}; }; };", Recursive));
429 EXPECT_TRUE(matches("class M { class N { class B {}; }; };", Recursive));
430 EXPECT_TRUE(
431 matches("class O1 { class O2 {"
432 " class M { class N { class B {}; }; }; "
433 "}; };", Recursive));
434}
435
436TEST(DeclarationMatcher, MatchNot) {
437 DeclarationMatcher NotClassX =
438 record(
439 isDerivedFrom("Y"),
440 unless(hasName("Y")),
441 unless(hasName("X")));
442 EXPECT_TRUE(notMatches("", NotClassX));
443 EXPECT_TRUE(notMatches("class Y {};", NotClassX));
444 EXPECT_TRUE(matches("class Y {}; class Z : public Y {};", NotClassX));
445 EXPECT_TRUE(notMatches("class Y {}; class X : public Y {};", NotClassX));
446 EXPECT_TRUE(
447 notMatches("class Y {}; class Z {}; class X : public Y {};",
448 NotClassX));
449
450 DeclarationMatcher ClassXHasNotClassY =
451 record(
452 hasName("X"),
453 has(record(hasName("Z"))),
454 unless(
455 has(record(hasName("Y")))));
456 EXPECT_TRUE(matches("class X { class Z {}; };", ClassXHasNotClassY));
457 EXPECT_TRUE(notMatches("class X { class Y {}; class Z {}; };",
458 ClassXHasNotClassY));
459}
460
461TEST(DeclarationMatcher, HasDescendant) {
462 DeclarationMatcher ZDescendantClassX =
463 record(
464 hasDescendant(record(hasName("X"))),
465 hasName("Z"));
466 EXPECT_TRUE(matches("class Z { class X {}; };", ZDescendantClassX));
467 EXPECT_TRUE(
468 matches("class Z { class Y { class X {}; }; };", ZDescendantClassX));
469 EXPECT_TRUE(
470 matches("class Z { class A { class Y { class X {}; }; }; };",
471 ZDescendantClassX));
472 EXPECT_TRUE(
473 matches("class Z { class A { class B { class Y { class X {}; }; }; }; };",
474 ZDescendantClassX));
475 EXPECT_TRUE(notMatches("class Z {};", ZDescendantClassX));
476
477 DeclarationMatcher ZDescendantClassXHasClassY =
478 record(
479 hasDescendant(record(has(record(hasName("Y"))),
480 hasName("X"))),
481 hasName("Z"));
482 EXPECT_TRUE(matches("class Z { class X { class Y {}; }; };",
483 ZDescendantClassXHasClassY));
484 EXPECT_TRUE(
485 matches("class Z { class A { class B { class X { class Y {}; }; }; }; };",
486 ZDescendantClassXHasClassY));
487 EXPECT_TRUE(notMatches(
488 "class Z {"
489 " class A {"
490 " class B {"
491 " class X {"
492 " class C {"
493 " class Y {};"
494 " };"
495 " };"
496 " }; "
497 " };"
498 "};", ZDescendantClassXHasClassY));
499
500 DeclarationMatcher ZDescendantClassXDescendantClassY =
501 record(
502 hasDescendant(record(hasDescendant(record(hasName("Y"))),
503 hasName("X"))),
504 hasName("Z"));
505 EXPECT_TRUE(
506 matches("class Z { class A { class X { class B { class Y {}; }; }; }; };",
507 ZDescendantClassXDescendantClassY));
508 EXPECT_TRUE(matches(
509 "class Z {"
510 " class A {"
511 " class X {"
512 " class B {"
513 " class Y {};"
514 " };"
515 " class Y {};"
516 " };"
517 " };"
518 "};", ZDescendantClassXDescendantClassY));
519}
520
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000521TEST(Enum, DoesNotMatchClasses) {
522 EXPECT_TRUE(notMatches("class X {};", enumDecl(hasName("X"))));
523}
524
525TEST(Enum, MatchesEnums) {
526 EXPECT_TRUE(matches("enum X {};", enumDecl(hasName("X"))));
527}
528
529TEST(EnumConstant, Matches) {
530 DeclarationMatcher Matcher = enumConstant(hasName("A"));
531 EXPECT_TRUE(matches("enum X{ A };", Matcher));
532 EXPECT_TRUE(notMatches("enum X{ B };", Matcher));
533 EXPECT_TRUE(notMatches("enum X {};", Matcher));
534}
535
Manuel Klimek4da21662012-07-06 05:48:52 +0000536TEST(StatementMatcher, Has) {
537 StatementMatcher HasVariableI =
538 expression(
539 hasType(pointsTo(record(hasName("X")))),
540 has(declarationReference(to(variable(hasName("i"))))));
541
542 EXPECT_TRUE(matches(
543 "class X; X *x(int); void c() { int i; x(i); }", HasVariableI));
544 EXPECT_TRUE(notMatches(
545 "class X; X *x(int); void c() { int i; x(42); }", HasVariableI));
546}
547
548TEST(StatementMatcher, HasDescendant) {
549 StatementMatcher HasDescendantVariableI =
550 expression(
551 hasType(pointsTo(record(hasName("X")))),
552 hasDescendant(declarationReference(to(variable(hasName("i"))))));
553
554 EXPECT_TRUE(matches(
555 "class X; X *x(bool); bool b(int); void c() { int i; x(b(i)); }",
556 HasDescendantVariableI));
557 EXPECT_TRUE(notMatches(
558 "class X; X *x(bool); bool b(int); void c() { int i; x(b(42)); }",
559 HasDescendantVariableI));
560}
561
562TEST(TypeMatcher, MatchesClassType) {
563 TypeMatcher TypeA = hasDeclaration(record(hasName("A")));
564
565 EXPECT_TRUE(matches("class A { public: A *a; };", TypeA));
566 EXPECT_TRUE(notMatches("class A {};", TypeA));
567
568 TypeMatcher TypeDerivedFromA = hasDeclaration(record(isDerivedFrom("A")));
569
570 EXPECT_TRUE(matches("class A {}; class B : public A { public: B *b; };",
571 TypeDerivedFromA));
572 EXPECT_TRUE(notMatches("class A {};", TypeA));
573
574 TypeMatcher TypeAHasClassB = hasDeclaration(
575 record(hasName("A"), has(record(hasName("B")))));
576
577 EXPECT_TRUE(
578 matches("class A { public: A *a; class B {}; };", TypeAHasClassB));
579}
580
581// Returns from Run whether 'bound_nodes' contain a Decl bound to 'Id', which
582// can be dynamically casted to T.
583// Optionally checks that the check succeeded a specific number of times.
584template <typename T>
585class VerifyIdIsBoundToDecl : public BoundNodesCallback {
586public:
587 // Create an object that checks that a node of type 'T' was bound to 'Id'.
588 // Does not check for a certain number of matches.
589 explicit VerifyIdIsBoundToDecl(const std::string& Id)
590 : Id(Id), ExpectedCount(-1), Count(0) {}
591
592 // Create an object that checks that a node of type 'T' was bound to 'Id'.
593 // Checks that there were exactly 'ExpectedCount' matches.
594 explicit VerifyIdIsBoundToDecl(const std::string& Id, int ExpectedCount)
595 : Id(Id), ExpectedCount(ExpectedCount), Count(0) {}
596
597 ~VerifyIdIsBoundToDecl() {
598 if (ExpectedCount != -1) {
599 EXPECT_EQ(ExpectedCount, Count);
600 }
601 }
602
603 virtual bool run(const BoundNodes *Nodes) {
604 if (Nodes->getDeclAs<T>(Id) != NULL) {
605 ++Count;
606 return true;
607 }
608 return false;
609 }
610
611private:
612 const std::string Id;
613 const int ExpectedCount;
614 int Count;
615};
616template <typename T>
617class VerifyIdIsBoundToStmt : public BoundNodesCallback {
618public:
619 explicit VerifyIdIsBoundToStmt(const std::string &Id) : Id(Id) {}
620 virtual bool run(const BoundNodes *Nodes) {
621 const T *Node = Nodes->getStmtAs<T>(Id);
622 return Node != NULL;
623 }
624private:
625 const std::string Id;
626};
627
628TEST(Matcher, BindMatchedNodes) {
Manuel Klimek9f174082012-07-24 13:37:29 +0000629 DeclarationMatcher ClassX = has(record(hasName("::X")).bind("x"));
Manuel Klimek4da21662012-07-06 05:48:52 +0000630
631 EXPECT_TRUE(matchAndVerifyResultTrue("class X {};",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000632 ClassX, new VerifyIdIsBoundToDecl<CXXRecordDecl>("x")));
Manuel Klimek4da21662012-07-06 05:48:52 +0000633
634 EXPECT_TRUE(matchAndVerifyResultFalse("class X {};",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000635 ClassX, new VerifyIdIsBoundToDecl<CXXRecordDecl>("other-id")));
Manuel Klimek4da21662012-07-06 05:48:52 +0000636
637 TypeMatcher TypeAHasClassB = hasDeclaration(
Manuel Klimek9f174082012-07-24 13:37:29 +0000638 record(hasName("A"), has(record(hasName("B")).bind("b"))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000639
640 EXPECT_TRUE(matchAndVerifyResultTrue("class A { public: A *a; class B {}; };",
641 TypeAHasClassB,
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000642 new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +0000643
Manuel Klimek9f174082012-07-24 13:37:29 +0000644 StatementMatcher MethodX = call(callee(method(hasName("x")))).bind("x");
Manuel Klimek4da21662012-07-06 05:48:52 +0000645
646 EXPECT_TRUE(matchAndVerifyResultTrue("class A { void x() { x(); } };",
647 MethodX,
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000648 new VerifyIdIsBoundToStmt<CXXMemberCallExpr>("x")));
649}
650
651TEST(Matcher, BindTheSameNameInAlternatives) {
652 StatementMatcher matcher = anyOf(
653 binaryOperator(hasOperatorName("+"),
Manuel Klimek9f174082012-07-24 13:37:29 +0000654 hasLHS(expression().bind("x")),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000655 hasRHS(integerLiteral(equals(0)))),
656 binaryOperator(hasOperatorName("+"),
657 hasLHS(integerLiteral(equals(0))),
Manuel Klimek9f174082012-07-24 13:37:29 +0000658 hasRHS(expression().bind("x"))));
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000659
660 EXPECT_TRUE(matchAndVerifyResultTrue(
661 // The first branch of the matcher binds x to 0 but then fails.
662 // The second branch binds x to f() and succeeds.
663 "int f() { return 0 + f(); }",
664 matcher,
665 new VerifyIdIsBoundToStmt<CallExpr>("x")));
Manuel Klimek4da21662012-07-06 05:48:52 +0000666}
667
668TEST(HasType, TakesQualTypeMatcherAndMatchesExpr) {
669 TypeMatcher ClassX = hasDeclaration(record(hasName("X")));
670 EXPECT_TRUE(
671 matches("class X {}; void y(X &x) { x; }", expression(hasType(ClassX))));
672 EXPECT_TRUE(
673 notMatches("class X {}; void y(X *x) { x; }",
674 expression(hasType(ClassX))));
675 EXPECT_TRUE(
676 matches("class X {}; void y(X *x) { x; }",
677 expression(hasType(pointsTo(ClassX)))));
678}
679
680TEST(HasType, TakesQualTypeMatcherAndMatchesValueDecl) {
681 TypeMatcher ClassX = hasDeclaration(record(hasName("X")));
682 EXPECT_TRUE(
683 matches("class X {}; void y() { X x; }", variable(hasType(ClassX))));
684 EXPECT_TRUE(
685 notMatches("class X {}; void y() { X *x; }", variable(hasType(ClassX))));
686 EXPECT_TRUE(
687 matches("class X {}; void y() { X *x; }",
688 variable(hasType(pointsTo(ClassX)))));
689}
690
691TEST(HasType, TakesDeclMatcherAndMatchesExpr) {
692 DeclarationMatcher ClassX = record(hasName("X"));
693 EXPECT_TRUE(
694 matches("class X {}; void y(X &x) { x; }", expression(hasType(ClassX))));
695 EXPECT_TRUE(
696 notMatches("class X {}; void y(X *x) { x; }",
697 expression(hasType(ClassX))));
698}
699
700TEST(HasType, TakesDeclMatcherAndMatchesValueDecl) {
701 DeclarationMatcher ClassX = record(hasName("X"));
702 EXPECT_TRUE(
703 matches("class X {}; void y() { X x; }", variable(hasType(ClassX))));
704 EXPECT_TRUE(
705 notMatches("class X {}; void y() { X *x; }", variable(hasType(ClassX))));
706}
707
708TEST(Matcher, Call) {
709 // FIXME: Do we want to overload Call() to directly take
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000710 // Matcher<Decl>, too?
Manuel Klimek4da21662012-07-06 05:48:52 +0000711 StatementMatcher MethodX = call(hasDeclaration(method(hasName("x"))));
712
713 EXPECT_TRUE(matches("class Y { void x() { x(); } };", MethodX));
714 EXPECT_TRUE(notMatches("class Y { void x() {} };", MethodX));
715
Manuel Klimek9f174082012-07-24 13:37:29 +0000716 StatementMatcher MethodOnY = memberCall(on(hasType(record(hasName("Y")))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000717
718 EXPECT_TRUE(
719 matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
720 MethodOnY));
721 EXPECT_TRUE(
722 matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
723 MethodOnY));
724 EXPECT_TRUE(
725 notMatches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
726 MethodOnY));
727 EXPECT_TRUE(
728 notMatches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
729 MethodOnY));
730 EXPECT_TRUE(
731 notMatches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
732 MethodOnY));
733
734 StatementMatcher MethodOnYPointer =
Manuel Klimek9f174082012-07-24 13:37:29 +0000735 memberCall(on(hasType(pointsTo(record(hasName("Y"))))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000736
737 EXPECT_TRUE(
738 matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
739 MethodOnYPointer));
740 EXPECT_TRUE(
741 matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
742 MethodOnYPointer));
743 EXPECT_TRUE(
744 matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
745 MethodOnYPointer));
746 EXPECT_TRUE(
747 notMatches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
748 MethodOnYPointer));
749 EXPECT_TRUE(
750 notMatches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
751 MethodOnYPointer));
752}
753
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000754TEST(HasType, MatchesAsString) {
755 EXPECT_TRUE(
756 matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }",
Manuel Klimek9f174082012-07-24 13:37:29 +0000757 memberCall(on(hasType(asString("class Y *"))))));
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000758 EXPECT_TRUE(matches("class X { void x(int x) {} };",
759 method(hasParameter(0, hasType(asString("int"))))));
760 EXPECT_TRUE(matches("namespace ns { struct A {}; } struct B { ns::A a; };",
761 field(hasType(asString("ns::A")))));
762 EXPECT_TRUE(matches("namespace { struct A {}; } struct B { A a; };",
763 field(hasType(asString("struct <anonymous>::A")))));
764}
765
Manuel Klimek4da21662012-07-06 05:48:52 +0000766TEST(Matcher, OverloadedOperatorCall) {
767 StatementMatcher OpCall = overloadedOperatorCall();
768 // Unary operator
769 EXPECT_TRUE(matches("class Y { }; "
770 "bool operator!(Y x) { return false; }; "
771 "Y y; bool c = !y;", OpCall));
772 // No match -- special operators like "new", "delete"
773 // FIXME: operator new takes size_t, for which we need stddef.h, for which
774 // we need to figure out include paths in the test.
775 // EXPECT_TRUE(NotMatches("#include <stddef.h>\n"
776 // "class Y { }; "
777 // "void *operator new(size_t size) { return 0; } "
778 // "Y *y = new Y;", OpCall));
779 EXPECT_TRUE(notMatches("class Y { }; "
780 "void operator delete(void *p) { } "
781 "void a() {Y *y = new Y; delete y;}", OpCall));
782 // Binary operator
783 EXPECT_TRUE(matches("class Y { }; "
784 "bool operator&&(Y x, Y y) { return true; }; "
785 "Y a; Y b; bool c = a && b;",
786 OpCall));
787 // No match -- normal operator, not an overloaded one.
788 EXPECT_TRUE(notMatches("bool x = true, y = true; bool t = x && y;", OpCall));
789 EXPECT_TRUE(notMatches("int t = 5 << 2;", OpCall));
790}
791
792TEST(Matcher, HasOperatorNameForOverloadedOperatorCall) {
793 StatementMatcher OpCallAndAnd =
794 overloadedOperatorCall(hasOverloadedOperatorName("&&"));
795 EXPECT_TRUE(matches("class Y { }; "
796 "bool operator&&(Y x, Y y) { return true; }; "
797 "Y a; Y b; bool c = a && b;", OpCallAndAnd));
798 StatementMatcher OpCallLessLess =
799 overloadedOperatorCall(hasOverloadedOperatorName("<<"));
800 EXPECT_TRUE(notMatches("class Y { }; "
801 "bool operator&&(Y x, Y y) { return true; }; "
802 "Y a; Y b; bool c = a && b;",
803 OpCallLessLess));
804}
805
806TEST(Matcher, ThisPointerType) {
Manuel Klimek9f174082012-07-24 13:37:29 +0000807 StatementMatcher MethodOnY =
808 memberCall(thisPointerType(record(hasName("Y"))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000809
810 EXPECT_TRUE(
811 matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
812 MethodOnY));
813 EXPECT_TRUE(
814 matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
815 MethodOnY));
816 EXPECT_TRUE(
817 matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
818 MethodOnY));
819 EXPECT_TRUE(
820 matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
821 MethodOnY));
822 EXPECT_TRUE(
823 matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
824 MethodOnY));
825
826 EXPECT_TRUE(matches(
827 "class Y {"
828 " public: virtual void x();"
829 "};"
830 "class X : public Y {"
831 " public: virtual void x();"
832 "};"
833 "void z() { X *x; x->Y::x(); }", MethodOnY));
834}
835
836TEST(Matcher, VariableUsage) {
837 StatementMatcher Reference =
838 declarationReference(to(
839 variable(hasInitializer(
Manuel Klimek9f174082012-07-24 13:37:29 +0000840 memberCall(thisPointerType(record(hasName("Y"))))))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000841
842 EXPECT_TRUE(matches(
843 "class Y {"
844 " public:"
845 " bool x() const;"
846 "};"
847 "void z(const Y &y) {"
848 " bool b = y.x();"
849 " if (b) {}"
850 "}", Reference));
851
852 EXPECT_TRUE(notMatches(
853 "class Y {"
854 " public:"
855 " bool x() const;"
856 "};"
857 "void z(const Y &y) {"
858 " bool b = y.x();"
859 "}", Reference));
860}
861
Daniel Jasper9bd28092012-07-30 05:03:25 +0000862TEST(Matcher, FindsVarDeclInFuncitonParameter) {
863 EXPECT_TRUE(matches(
864 "void f(int i) {}",
865 variable(hasName("i"))));
866}
867
Manuel Klimek4da21662012-07-06 05:48:52 +0000868TEST(Matcher, CalledVariable) {
869 StatementMatcher CallOnVariableY = expression(
Manuel Klimek9f174082012-07-24 13:37:29 +0000870 memberCall(on(declarationReference(to(variable(hasName("y")))))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000871
872 EXPECT_TRUE(matches(
873 "class Y { public: void x() { Y y; y.x(); } };", CallOnVariableY));
874 EXPECT_TRUE(matches(
875 "class Y { public: void x() const { Y y; y.x(); } };", CallOnVariableY));
876 EXPECT_TRUE(matches(
877 "class Y { public: void x(); };"
878 "class X : public Y { void z() { X y; y.x(); } };", CallOnVariableY));
879 EXPECT_TRUE(matches(
880 "class Y { public: void x(); };"
881 "class X : public Y { void z() { X *y; y->x(); } };", CallOnVariableY));
882 EXPECT_TRUE(notMatches(
883 "class Y { public: void x(); };"
884 "class X : public Y { void z() { unsigned long y; ((X*)y)->x(); } };",
885 CallOnVariableY));
886}
887
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000888TEST(UnaryExprOrTypeTraitExpr, MatchesSizeOfAndAlignOf) {
889 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }",
890 unaryExprOrTypeTraitExpr()));
891 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }",
892 alignOfExpr(anything())));
893 // FIXME: Uncomment once alignof is enabled.
894 // EXPECT_TRUE(matches("void x() { int a = alignof(a); }",
895 // unaryExprOrTypeTraitExpr()));
896 // EXPECT_TRUE(notMatches("void x() { int a = alignof(a); }",
897 // sizeOfExpr()));
898}
899
900TEST(UnaryExpressionOrTypeTraitExpression, MatchesCorrectType) {
901 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }", sizeOfExpr(
902 hasArgumentOfType(asString("int")))));
903 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
904 hasArgumentOfType(asString("float")))));
905 EXPECT_TRUE(matches(
906 "struct A {}; void x() { A a; int b = sizeof(a); }",
907 sizeOfExpr(hasArgumentOfType(hasDeclaration(record(hasName("A")))))));
908 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
909 hasArgumentOfType(hasDeclaration(record(hasName("string")))))));
910}
911
Manuel Klimek4da21662012-07-06 05:48:52 +0000912TEST(MemberExpression, DoesNotMatchClasses) {
913 EXPECT_TRUE(notMatches("class Y { void x() {} };", memberExpression()));
914}
915
916TEST(MemberExpression, MatchesMemberFunctionCall) {
917 EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpression()));
918}
919
920TEST(MemberExpression, MatchesVariable) {
921 EXPECT_TRUE(
922 matches("class Y { void x() { this->y; } int y; };", memberExpression()));
923 EXPECT_TRUE(
924 matches("class Y { void x() { y; } int y; };", memberExpression()));
925 EXPECT_TRUE(
926 matches("class Y { void x() { Y y; y.y; } int y; };",
927 memberExpression()));
928}
929
930TEST(MemberExpression, MatchesStaticVariable) {
931 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
932 memberExpression()));
933 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
934 memberExpression()));
935 EXPECT_TRUE(notMatches("class Y { void x() { Y::y; } static int y; };",
936 memberExpression()));
937}
938
Daniel Jasper6a124492012-07-12 08:50:38 +0000939TEST(IsInteger, MatchesIntegers) {
940 EXPECT_TRUE(matches("int i = 0;", variable(hasType(isInteger()))));
941 EXPECT_TRUE(matches("long long i = 0; void f(long long) { }; void g() {f(i);}",
942 call(hasArgument(0, declarationReference(
943 to(variable(hasType(isInteger()))))))));
944}
945
946TEST(IsInteger, ReportsNoFalsePositives) {
947 EXPECT_TRUE(notMatches("int *i;", variable(hasType(isInteger()))));
948 EXPECT_TRUE(notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}",
949 call(hasArgument(0, declarationReference(
950 to(variable(hasType(isInteger()))))))));
951}
952
Manuel Klimek4da21662012-07-06 05:48:52 +0000953TEST(IsArrow, MatchesMemberVariablesViaArrow) {
954 EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };",
955 memberExpression(isArrow())));
956 EXPECT_TRUE(matches("class Y { void x() { y; } int y; };",
957 memberExpression(isArrow())));
958 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };",
959 memberExpression(isArrow())));
960}
961
962TEST(IsArrow, MatchesStaticMemberVariablesViaArrow) {
963 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
964 memberExpression(isArrow())));
965 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
966 memberExpression(isArrow())));
967 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } static int y; };",
968 memberExpression(isArrow())));
969}
970
971TEST(IsArrow, MatchesMemberCallsViaArrow) {
972 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
973 memberExpression(isArrow())));
974 EXPECT_TRUE(matches("class Y { void x() { x(); } };",
975 memberExpression(isArrow())));
976 EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",
977 memberExpression(isArrow())));
978}
979
980TEST(Callee, MatchesDeclarations) {
981 StatementMatcher CallMethodX = call(callee(method(hasName("x"))));
982
983 EXPECT_TRUE(matches("class Y { void x() { x(); } };", CallMethodX));
984 EXPECT_TRUE(notMatches("class Y { void x() {} };", CallMethodX));
985}
986
987TEST(Callee, MatchesMemberExpressions) {
988 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
989 call(callee(memberExpression()))));
990 EXPECT_TRUE(
991 notMatches("class Y { void x() { this->x(); } };", call(callee(call()))));
992}
993
994TEST(Function, MatchesFunctionDeclarations) {
995 StatementMatcher CallFunctionF = call(callee(function(hasName("f"))));
996
997 EXPECT_TRUE(matches("void f() { f(); }", CallFunctionF));
998 EXPECT_TRUE(notMatches("void f() { }", CallFunctionF));
999
Manuel Klimeke265c872012-07-10 14:21:30 +00001000#if !defined(_MSC_VER)
1001 // FIXME: Make this work for MSVC.
Manuel Klimek4da21662012-07-06 05:48:52 +00001002 // Dependent contexts, but a non-dependent call.
1003 EXPECT_TRUE(matches("void f(); template <int N> void g() { f(); }",
1004 CallFunctionF));
1005 EXPECT_TRUE(
1006 matches("void f(); template <int N> struct S { void g() { f(); } };",
1007 CallFunctionF));
Manuel Klimeke265c872012-07-10 14:21:30 +00001008#endif
Manuel Klimek4da21662012-07-06 05:48:52 +00001009
1010 // Depedent calls don't match.
1011 EXPECT_TRUE(
1012 notMatches("void f(int); template <typename T> void g(T t) { f(t); }",
1013 CallFunctionF));
1014 EXPECT_TRUE(
1015 notMatches("void f(int);"
1016 "template <typename T> struct S { void g(T t) { f(t); } };",
1017 CallFunctionF));
1018}
1019
1020TEST(Matcher, Argument) {
1021 StatementMatcher CallArgumentY = expression(call(
1022 hasArgument(0, declarationReference(to(variable(hasName("y")))))));
1023
1024 EXPECT_TRUE(matches("void x(int) { int y; x(y); }", CallArgumentY));
1025 EXPECT_TRUE(
1026 matches("class X { void x(int) { int y; x(y); } };", CallArgumentY));
1027 EXPECT_TRUE(notMatches("void x(int) { int z; x(z); }", CallArgumentY));
1028
1029 StatementMatcher WrongIndex = expression(call(
1030 hasArgument(42, declarationReference(to(variable(hasName("y")))))));
1031 EXPECT_TRUE(notMatches("void x(int) { int y; x(y); }", WrongIndex));
1032}
1033
1034TEST(Matcher, AnyArgument) {
1035 StatementMatcher CallArgumentY = expression(call(
1036 hasAnyArgument(declarationReference(to(variable(hasName("y")))))));
1037 EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
1038 EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
1039 EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
1040}
1041
1042TEST(Matcher, ArgumentCount) {
1043 StatementMatcher Call1Arg = expression(call(argumentCountIs(1)));
1044
1045 EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg));
1046 EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg));
1047 EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg));
1048}
1049
1050TEST(Matcher, References) {
1051 DeclarationMatcher ReferenceClassX = variable(
1052 hasType(references(record(hasName("X")))));
1053 EXPECT_TRUE(matches("class X {}; void y(X y) { X &x = y; }",
1054 ReferenceClassX));
1055 EXPECT_TRUE(
1056 matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
1057 EXPECT_TRUE(
1058 notMatches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
1059 EXPECT_TRUE(
1060 notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
1061}
1062
1063TEST(HasParameter, CallsInnerMatcher) {
1064 EXPECT_TRUE(matches("class X { void x(int) {} };",
1065 method(hasParameter(0, variable()))));
1066 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
1067 method(hasParameter(0, hasName("x")))));
1068}
1069
1070TEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) {
1071 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
1072 method(hasParameter(42, variable()))));
1073}
1074
1075TEST(HasType, MatchesParameterVariableTypesStrictly) {
1076 EXPECT_TRUE(matches("class X { void x(X x) {} };",
1077 method(hasParameter(0, hasType(record(hasName("X")))))));
1078 EXPECT_TRUE(notMatches("class X { void x(const X &x) {} };",
1079 method(hasParameter(0, hasType(record(hasName("X")))))));
1080 EXPECT_TRUE(matches("class X { void x(const X *x) {} };",
1081 method(hasParameter(0, hasType(pointsTo(record(hasName("X"))))))));
1082 EXPECT_TRUE(matches("class X { void x(const X &x) {} };",
1083 method(hasParameter(0, hasType(references(record(hasName("X"))))))));
1084}
1085
1086TEST(HasAnyParameter, MatchesIndependentlyOfPosition) {
1087 EXPECT_TRUE(matches("class Y {}; class X { void x(X x, Y y) {} };",
1088 method(hasAnyParameter(hasType(record(hasName("X")))))));
1089 EXPECT_TRUE(matches("class Y {}; class X { void x(Y y, X x) {} };",
1090 method(hasAnyParameter(hasType(record(hasName("X")))))));
1091}
1092
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001093TEST(Returns, MatchesReturnTypes) {
1094 EXPECT_TRUE(matches("class Y { int f() { return 1; } };",
1095 function(returns(asString("int")))));
1096 EXPECT_TRUE(notMatches("class Y { int f() { return 1; } };",
1097 function(returns(asString("float")))));
1098 EXPECT_TRUE(matches("class Y { Y getMe() { return *this; } };",
1099 function(returns(hasDeclaration(record(hasName("Y")))))));
1100}
1101
Daniel Jasper8cc7efa2012-08-15 18:52:19 +00001102TEST(IsExternC, MatchesExternCFunctionDeclarations) {
1103 EXPECT_TRUE(matches("extern \"C\" void f() {}", function(isExternC())));
1104 EXPECT_TRUE(matches("extern \"C\" { void f() {} }", function(isExternC())));
1105 EXPECT_TRUE(notMatches("void f() {}", function(isExternC())));
1106}
1107
Manuel Klimek4da21662012-07-06 05:48:52 +00001108TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
1109 EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
1110 method(hasAnyParameter(hasType(record(hasName("X")))))));
1111}
1112
1113TEST(HasAnyParameter, DoesNotMatchThisPointer) {
1114 EXPECT_TRUE(notMatches("class Y {}; class X { void x() {} };",
1115 method(hasAnyParameter(hasType(pointsTo(record(hasName("X"))))))));
1116}
1117
1118TEST(HasName, MatchesParameterVariableDeclartions) {
1119 EXPECT_TRUE(matches("class Y {}; class X { void x(int x) {} };",
1120 method(hasAnyParameter(hasName("x")))));
1121 EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
1122 method(hasAnyParameter(hasName("x")))));
1123}
1124
Daniel Jasper371f9392012-08-01 08:40:24 +00001125TEST(Matcher, MatchesClassTemplateSpecialization) {
1126 EXPECT_TRUE(matches("template<typename T> struct A {};"
1127 "template<> struct A<int> {};",
1128 classTemplateSpecialization()));
1129 EXPECT_TRUE(matches("template<typename T> struct A {}; A<int> a;",
1130 classTemplateSpecialization()));
1131 EXPECT_TRUE(notMatches("template<typename T> struct A {};",
1132 classTemplateSpecialization()));
1133}
1134
1135TEST(Matcher, MatchesTypeTemplateArgument) {
1136 EXPECT_TRUE(matches(
1137 "template<typename T> struct B {};"
1138 "B<int> b;",
1139 classTemplateSpecialization(hasAnyTemplateArgument(refersToType(
1140 asString("int"))))));
1141}
1142
1143TEST(Matcher, MatchesDeclarationReferenceTemplateArgument) {
1144 EXPECT_TRUE(matches(
1145 "struct B { int next; };"
1146 "template<int(B::*next_ptr)> struct A {};"
1147 "A<&B::next> a;",
1148 classTemplateSpecialization(hasAnyTemplateArgument(
1149 refersToDeclaration(field(hasName("next")))))));
1150}
1151
1152TEST(Matcher, MatchesSpecificArgument) {
1153 EXPECT_TRUE(matches(
1154 "template<typename T, typename U> class A {};"
1155 "A<bool, int> a;",
1156 classTemplateSpecialization(hasTemplateArgument(
1157 1, refersToType(asString("int"))))));
1158 EXPECT_TRUE(notMatches(
1159 "template<typename T, typename U> class A {};"
1160 "A<int, bool> a;",
1161 classTemplateSpecialization(hasTemplateArgument(
1162 1, refersToType(asString("int"))))));
1163}
1164
Manuel Klimek4da21662012-07-06 05:48:52 +00001165TEST(Matcher, ConstructorCall) {
1166 StatementMatcher Constructor = expression(constructorCall());
1167
1168 EXPECT_TRUE(
1169 matches("class X { public: X(); }; void x() { X x; }", Constructor));
1170 EXPECT_TRUE(
1171 matches("class X { public: X(); }; void x() { X x = X(); }",
1172 Constructor));
1173 EXPECT_TRUE(
1174 matches("class X { public: X(int); }; void x() { X x = 0; }",
1175 Constructor));
1176 EXPECT_TRUE(matches("class X {}; void x(int) { X x; }", Constructor));
1177}
1178
1179TEST(Matcher, ConstructorArgument) {
1180 StatementMatcher Constructor = expression(constructorCall(
1181 hasArgument(0, declarationReference(to(variable(hasName("y")))))));
1182
1183 EXPECT_TRUE(
1184 matches("class X { public: X(int); }; void x() { int y; X x(y); }",
1185 Constructor));
1186 EXPECT_TRUE(
1187 matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
1188 Constructor));
1189 EXPECT_TRUE(
1190 matches("class X { public: X(int); }; void x() { int y; X x = y; }",
1191 Constructor));
1192 EXPECT_TRUE(
1193 notMatches("class X { public: X(int); }; void x() { int z; X x(z); }",
1194 Constructor));
1195
1196 StatementMatcher WrongIndex = expression(constructorCall(
1197 hasArgument(42, declarationReference(to(variable(hasName("y")))))));
1198 EXPECT_TRUE(
1199 notMatches("class X { public: X(int); }; void x() { int y; X x(y); }",
1200 WrongIndex));
1201}
1202
1203TEST(Matcher, ConstructorArgumentCount) {
1204 StatementMatcher Constructor1Arg =
1205 expression(constructorCall(argumentCountIs(1)));
1206
1207 EXPECT_TRUE(
1208 matches("class X { public: X(int); }; void x() { X x(0); }",
1209 Constructor1Arg));
1210 EXPECT_TRUE(
1211 matches("class X { public: X(int); }; void x() { X x = X(0); }",
1212 Constructor1Arg));
1213 EXPECT_TRUE(
1214 matches("class X { public: X(int); }; void x() { X x = 0; }",
1215 Constructor1Arg));
1216 EXPECT_TRUE(
1217 notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
1218 Constructor1Arg));
1219}
1220
1221TEST(Matcher, BindTemporaryExpression) {
1222 StatementMatcher TempExpression = expression(bindTemporaryExpression());
1223
1224 std::string ClassString = "class string { public: string(); ~string(); }; ";
1225
1226 EXPECT_TRUE(
1227 matches(ClassString +
1228 "string GetStringByValue();"
1229 "void FunctionTakesString(string s);"
1230 "void run() { FunctionTakesString(GetStringByValue()); }",
1231 TempExpression));
1232
1233 EXPECT_TRUE(
1234 notMatches(ClassString +
1235 "string* GetStringPointer(); "
1236 "void FunctionTakesStringPtr(string* s);"
1237 "void run() {"
1238 " string* s = GetStringPointer();"
1239 " FunctionTakesStringPtr(GetStringPointer());"
1240 " FunctionTakesStringPtr(s);"
1241 "}",
1242 TempExpression));
1243
1244 EXPECT_TRUE(
1245 notMatches("class no_dtor {};"
1246 "no_dtor GetObjByValue();"
1247 "void ConsumeObj(no_dtor param);"
1248 "void run() { ConsumeObj(GetObjByValue()); }",
1249 TempExpression));
1250}
1251
1252TEST(ConstructorDeclaration, SimpleCase) {
1253 EXPECT_TRUE(matches("class Foo { Foo(int i); };",
1254 constructor(ofClass(hasName("Foo")))));
1255 EXPECT_TRUE(notMatches("class Foo { Foo(int i); };",
1256 constructor(ofClass(hasName("Bar")))));
1257}
1258
1259TEST(ConstructorDeclaration, IsImplicit) {
1260 // This one doesn't match because the constructor is not added by the
1261 // compiler (it is not needed).
1262 EXPECT_TRUE(notMatches("class Foo { };",
1263 constructor(isImplicit())));
1264 // The compiler added the implicit default constructor.
1265 EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
1266 constructor(isImplicit())));
1267 EXPECT_TRUE(matches("class Foo { Foo(){} };",
1268 constructor(unless(isImplicit()))));
1269}
1270
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001271TEST(DestructorDeclaration, MatchesVirtualDestructor) {
1272 EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };",
1273 destructor(ofClass(hasName("Foo")))));
1274}
1275
1276TEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) {
1277 EXPECT_TRUE(notMatches("class Foo {};", destructor(ofClass(hasName("Foo")))));
1278}
1279
Manuel Klimek4da21662012-07-06 05:48:52 +00001280TEST(HasAnyConstructorInitializer, SimpleCase) {
1281 EXPECT_TRUE(notMatches(
1282 "class Foo { Foo() { } };",
1283 constructor(hasAnyConstructorInitializer(anything()))));
1284 EXPECT_TRUE(matches(
1285 "class Foo {"
1286 " Foo() : foo_() { }"
1287 " int foo_;"
1288 "};",
1289 constructor(hasAnyConstructorInitializer(anything()))));
1290}
1291
1292TEST(HasAnyConstructorInitializer, ForField) {
1293 static const char Code[] =
1294 "class Baz { };"
1295 "class Foo {"
1296 " Foo() : foo_() { }"
1297 " Baz foo_;"
1298 " Baz bar_;"
1299 "};";
1300 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1301 forField(hasType(record(hasName("Baz"))))))));
1302 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1303 forField(hasName("foo_"))))));
1304 EXPECT_TRUE(notMatches(Code, constructor(hasAnyConstructorInitializer(
1305 forField(hasType(record(hasName("Bar"))))))));
1306}
1307
1308TEST(HasAnyConstructorInitializer, WithInitializer) {
1309 static const char Code[] =
1310 "class Foo {"
1311 " Foo() : foo_(0) { }"
1312 " int foo_;"
1313 "};";
1314 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1315 withInitializer(integerLiteral(equals(0)))))));
1316 EXPECT_TRUE(notMatches(Code, constructor(hasAnyConstructorInitializer(
1317 withInitializer(integerLiteral(equals(1)))))));
1318}
1319
1320TEST(HasAnyConstructorInitializer, IsWritten) {
1321 static const char Code[] =
1322 "struct Bar { Bar(){} };"
1323 "class Foo {"
1324 " Foo() : foo_() { }"
1325 " Bar foo_;"
1326 " Bar bar_;"
1327 "};";
1328 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1329 allOf(forField(hasName("foo_")), isWritten())))));
1330 EXPECT_TRUE(notMatches(Code, constructor(hasAnyConstructorInitializer(
1331 allOf(forField(hasName("bar_")), isWritten())))));
1332 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1333 allOf(forField(hasName("bar_")), unless(isWritten()))))));
1334}
1335
1336TEST(Matcher, NewExpression) {
1337 StatementMatcher New = expression(newExpression());
1338
1339 EXPECT_TRUE(matches("class X { public: X(); }; void x() { new X; }", New));
1340 EXPECT_TRUE(
1341 matches("class X { public: X(); }; void x() { new X(); }", New));
1342 EXPECT_TRUE(
1343 matches("class X { public: X(int); }; void x() { new X(0); }", New));
1344 EXPECT_TRUE(matches("class X {}; void x(int) { new X; }", New));
1345}
1346
1347TEST(Matcher, NewExpressionArgument) {
1348 StatementMatcher New = expression(constructorCall(
1349 hasArgument(
1350 0, declarationReference(to(variable(hasName("y")))))));
1351
1352 EXPECT_TRUE(
1353 matches("class X { public: X(int); }; void x() { int y; new X(y); }",
1354 New));
1355 EXPECT_TRUE(
1356 matches("class X { public: X(int); }; void x() { int y; new X(y); }",
1357 New));
1358 EXPECT_TRUE(
1359 notMatches("class X { public: X(int); }; void x() { int z; new X(z); }",
1360 New));
1361
1362 StatementMatcher WrongIndex = expression(constructorCall(
1363 hasArgument(
1364 42, declarationReference(to(variable(hasName("y")))))));
1365 EXPECT_TRUE(
1366 notMatches("class X { public: X(int); }; void x() { int y; new X(y); }",
1367 WrongIndex));
1368}
1369
1370TEST(Matcher, NewExpressionArgumentCount) {
1371 StatementMatcher New = constructorCall(argumentCountIs(1));
1372
1373 EXPECT_TRUE(
1374 matches("class X { public: X(int); }; void x() { new X(0); }", New));
1375 EXPECT_TRUE(
1376 notMatches("class X { public: X(int, int); }; void x() { new X(0, 0); }",
1377 New));
1378}
1379
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001380TEST(Matcher, DeleteExpression) {
1381 EXPECT_TRUE(matches("struct A {}; void f(A* a) { delete a; }",
1382 deleteExpression()));
1383}
1384
Manuel Klimek4da21662012-07-06 05:48:52 +00001385TEST(Matcher, DefaultArgument) {
1386 StatementMatcher Arg = defaultArgument();
1387
1388 EXPECT_TRUE(matches("void x(int, int = 0) { int y; x(y); }", Arg));
1389 EXPECT_TRUE(
1390 matches("class X { void x(int, int = 0) { int y; x(y); } };", Arg));
1391 EXPECT_TRUE(notMatches("void x(int, int = 0) { int y; x(y, 0); }", Arg));
1392}
1393
1394TEST(Matcher, StringLiterals) {
1395 StatementMatcher Literal = expression(stringLiteral());
1396 EXPECT_TRUE(matches("const char *s = \"string\";", Literal));
1397 // wide string
1398 EXPECT_TRUE(matches("const wchar_t *s = L\"string\";", Literal));
1399 // with escaped characters
1400 EXPECT_TRUE(matches("const char *s = \"\x05five\";", Literal));
1401 // no matching -- though the data type is the same, there is no string literal
1402 EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));
1403}
1404
1405TEST(Matcher, CharacterLiterals) {
1406 StatementMatcher CharLiteral = expression(characterLiteral());
1407 EXPECT_TRUE(matches("const char c = 'c';", CharLiteral));
1408 // wide character
1409 EXPECT_TRUE(matches("const char c = L'c';", CharLiteral));
1410 // wide character, Hex encoded, NOT MATCHED!
1411 EXPECT_TRUE(notMatches("const wchar_t c = 0x2126;", CharLiteral));
1412 EXPECT_TRUE(notMatches("const char c = 0x1;", CharLiteral));
1413}
1414
1415TEST(Matcher, IntegerLiterals) {
1416 StatementMatcher HasIntLiteral = expression(integerLiteral());
1417 EXPECT_TRUE(matches("int i = 10;", HasIntLiteral));
1418 EXPECT_TRUE(matches("int i = 0x1AB;", HasIntLiteral));
1419 EXPECT_TRUE(matches("int i = 10L;", HasIntLiteral));
1420 EXPECT_TRUE(matches("int i = 10U;", HasIntLiteral));
1421
1422 // Non-matching cases (character literals, float and double)
1423 EXPECT_TRUE(notMatches("int i = L'a';",
1424 HasIntLiteral)); // this is actually a character
1425 // literal cast to int
1426 EXPECT_TRUE(notMatches("int i = 'a';", HasIntLiteral));
1427 EXPECT_TRUE(notMatches("int i = 1e10;", HasIntLiteral));
1428 EXPECT_TRUE(notMatches("int i = 10.0;", HasIntLiteral));
1429}
1430
1431TEST(Matcher, Conditions) {
1432 StatementMatcher Condition = ifStmt(hasCondition(boolLiteral(equals(true))));
1433
1434 EXPECT_TRUE(matches("void x() { if (true) {} }", Condition));
1435 EXPECT_TRUE(notMatches("void x() { if (false) {} }", Condition));
1436 EXPECT_TRUE(notMatches("void x() { bool a = true; if (a) {} }", Condition));
1437 EXPECT_TRUE(notMatches("void x() { if (true || false) {} }", Condition));
1438 EXPECT_TRUE(notMatches("void x() { if (1) {} }", Condition));
1439}
1440
1441TEST(MatchBinaryOperator, HasOperatorName) {
1442 StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
1443
1444 EXPECT_TRUE(matches("void x() { true || false; }", OperatorOr));
1445 EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
1446}
1447
1448TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
1449 StatementMatcher OperatorTrueFalse =
1450 binaryOperator(hasLHS(boolLiteral(equals(true))),
1451 hasRHS(boolLiteral(equals(false))));
1452
1453 EXPECT_TRUE(matches("void x() { true || false; }", OperatorTrueFalse));
1454 EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse));
1455 EXPECT_TRUE(notMatches("void x() { false || true; }", OperatorTrueFalse));
1456}
1457
1458TEST(MatchBinaryOperator, HasEitherOperand) {
1459 StatementMatcher HasOperand =
1460 binaryOperator(hasEitherOperand(boolLiteral(equals(false))));
1461
1462 EXPECT_TRUE(matches("void x() { true || false; }", HasOperand));
1463 EXPECT_TRUE(matches("void x() { false && true; }", HasOperand));
1464 EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand));
1465}
1466
1467TEST(Matcher, BinaryOperatorTypes) {
1468 // Integration test that verifies the AST provides all binary operators in
1469 // a way we expect.
1470 // FIXME: Operator ','
1471 EXPECT_TRUE(
1472 matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(","))));
1473 EXPECT_TRUE(
1474 matches("bool b; bool c = (b = true);",
1475 binaryOperator(hasOperatorName("="))));
1476 EXPECT_TRUE(
1477 matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!="))));
1478 EXPECT_TRUE(
1479 matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("=="))));
1480 EXPECT_TRUE(matches("bool b = 1 < 2;", binaryOperator(hasOperatorName("<"))));
1481 EXPECT_TRUE(
1482 matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<="))));
1483 EXPECT_TRUE(
1484 matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<"))));
1485 EXPECT_TRUE(
1486 matches("int i = 1; int j = (i <<= 2);",
1487 binaryOperator(hasOperatorName("<<="))));
1488 EXPECT_TRUE(matches("bool b = 1 > 2;", binaryOperator(hasOperatorName(">"))));
1489 EXPECT_TRUE(
1490 matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">="))));
1491 EXPECT_TRUE(
1492 matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>"))));
1493 EXPECT_TRUE(
1494 matches("int i = 1; int j = (i >>= 2);",
1495 binaryOperator(hasOperatorName(">>="))));
1496 EXPECT_TRUE(
1497 matches("int i = 42 ^ 23;", binaryOperator(hasOperatorName("^"))));
1498 EXPECT_TRUE(
1499 matches("int i = 42; int j = (i ^= 42);",
1500 binaryOperator(hasOperatorName("^="))));
1501 EXPECT_TRUE(
1502 matches("int i = 42 % 23;", binaryOperator(hasOperatorName("%"))));
1503 EXPECT_TRUE(
1504 matches("int i = 42; int j = (i %= 42);",
1505 binaryOperator(hasOperatorName("%="))));
1506 EXPECT_TRUE(
1507 matches("bool b = 42 &23;", binaryOperator(hasOperatorName("&"))));
1508 EXPECT_TRUE(
1509 matches("bool b = true && false;",
1510 binaryOperator(hasOperatorName("&&"))));
1511 EXPECT_TRUE(
1512 matches("bool b = true; bool c = (b &= false);",
1513 binaryOperator(hasOperatorName("&="))));
1514 EXPECT_TRUE(
1515 matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|"))));
1516 EXPECT_TRUE(
1517 matches("bool b = true || false;",
1518 binaryOperator(hasOperatorName("||"))));
1519 EXPECT_TRUE(
1520 matches("bool b = true; bool c = (b |= false);",
1521 binaryOperator(hasOperatorName("|="))));
1522 EXPECT_TRUE(
1523 matches("int i = 42 *23;", binaryOperator(hasOperatorName("*"))));
1524 EXPECT_TRUE(
1525 matches("int i = 42; int j = (i *= 23);",
1526 binaryOperator(hasOperatorName("*="))));
1527 EXPECT_TRUE(
1528 matches("int i = 42 / 23;", binaryOperator(hasOperatorName("/"))));
1529 EXPECT_TRUE(
1530 matches("int i = 42; int j = (i /= 23);",
1531 binaryOperator(hasOperatorName("/="))));
1532 EXPECT_TRUE(
1533 matches("int i = 42 + 23;", binaryOperator(hasOperatorName("+"))));
1534 EXPECT_TRUE(
1535 matches("int i = 42; int j = (i += 23);",
1536 binaryOperator(hasOperatorName("+="))));
1537 EXPECT_TRUE(
1538 matches("int i = 42 - 23;", binaryOperator(hasOperatorName("-"))));
1539 EXPECT_TRUE(
1540 matches("int i = 42; int j = (i -= 23);",
1541 binaryOperator(hasOperatorName("-="))));
1542 EXPECT_TRUE(
1543 matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };",
1544 binaryOperator(hasOperatorName("->*"))));
1545 EXPECT_TRUE(
1546 matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };",
1547 binaryOperator(hasOperatorName(".*"))));
1548
1549 // Member expressions as operators are not supported in matches.
1550 EXPECT_TRUE(
1551 notMatches("struct A { void x(A *a) { a->x(this); } };",
1552 binaryOperator(hasOperatorName("->"))));
1553
1554 // Initializer assignments are not represented as operator equals.
1555 EXPECT_TRUE(
1556 notMatches("bool b = true;", binaryOperator(hasOperatorName("="))));
1557
1558 // Array indexing is not represented as operator.
1559 EXPECT_TRUE(notMatches("int a[42]; void x() { a[23]; }", unaryOperator()));
1560
1561 // Overloaded operators do not match at all.
1562 EXPECT_TRUE(notMatches(
1563 "struct A { bool operator&&(const A &a) const { return false; } };"
1564 "void x() { A a, b; a && b; }",
1565 binaryOperator()));
1566}
1567
1568TEST(MatchUnaryOperator, HasOperatorName) {
1569 StatementMatcher OperatorNot = unaryOperator(hasOperatorName("!"));
1570
1571 EXPECT_TRUE(matches("void x() { !true; } ", OperatorNot));
1572 EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
1573}
1574
1575TEST(MatchUnaryOperator, HasUnaryOperand) {
1576 StatementMatcher OperatorOnFalse =
1577 unaryOperator(hasUnaryOperand(boolLiteral(equals(false))));
1578
1579 EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse));
1580 EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse));
1581}
1582
1583TEST(Matcher, UnaryOperatorTypes) {
1584 // Integration test that verifies the AST provides all unary operators in
1585 // a way we expect.
1586 EXPECT_TRUE(matches("bool b = !true;", unaryOperator(hasOperatorName("!"))));
1587 EXPECT_TRUE(
1588 matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&"))));
1589 EXPECT_TRUE(matches("int i = ~ 1;", unaryOperator(hasOperatorName("~"))));
1590 EXPECT_TRUE(
1591 matches("bool *p; bool b = *p;", unaryOperator(hasOperatorName("*"))));
1592 EXPECT_TRUE(
1593 matches("int i; int j = +i;", unaryOperator(hasOperatorName("+"))));
1594 EXPECT_TRUE(
1595 matches("int i; int j = -i;", unaryOperator(hasOperatorName("-"))));
1596 EXPECT_TRUE(
1597 matches("int i; int j = ++i;", unaryOperator(hasOperatorName("++"))));
1598 EXPECT_TRUE(
1599 matches("int i; int j = i++;", unaryOperator(hasOperatorName("++"))));
1600 EXPECT_TRUE(
1601 matches("int i; int j = --i;", unaryOperator(hasOperatorName("--"))));
1602 EXPECT_TRUE(
1603 matches("int i; int j = i--;", unaryOperator(hasOperatorName("--"))));
1604
1605 // We don't match conversion operators.
1606 EXPECT_TRUE(notMatches("int i; double d = (double)i;", unaryOperator()));
1607
1608 // Function calls are not represented as operator.
1609 EXPECT_TRUE(notMatches("void f(); void x() { f(); }", unaryOperator()));
1610
1611 // Overloaded operators do not match at all.
1612 // FIXME: We probably want to add that.
1613 EXPECT_TRUE(notMatches(
1614 "struct A { bool operator!() const { return false; } };"
1615 "void x() { A a; !a; }", unaryOperator(hasOperatorName("!"))));
1616}
1617
1618TEST(Matcher, ConditionalOperator) {
1619 StatementMatcher Conditional = conditionalOperator(
1620 hasCondition(boolLiteral(equals(true))),
1621 hasTrueExpression(boolLiteral(equals(false))));
1622
1623 EXPECT_TRUE(matches("void x() { true ? false : true; }", Conditional));
1624 EXPECT_TRUE(notMatches("void x() { false ? false : true; }", Conditional));
1625 EXPECT_TRUE(notMatches("void x() { true ? true : false; }", Conditional));
1626
1627 StatementMatcher ConditionalFalse = conditionalOperator(
1628 hasFalseExpression(boolLiteral(equals(false))));
1629
1630 EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
1631 EXPECT_TRUE(
1632 notMatches("void x() { true ? false : true; }", ConditionalFalse));
1633}
1634
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001635TEST(ArraySubscriptMatchers, ArraySubscripts) {
1636 EXPECT_TRUE(matches("int i[2]; void f() { i[1] = 1; }",
1637 arraySubscriptExpr()));
1638 EXPECT_TRUE(notMatches("int i; void f() { i = 1; }",
1639 arraySubscriptExpr()));
1640}
1641
1642TEST(ArraySubscriptMatchers, ArrayIndex) {
1643 EXPECT_TRUE(matches(
1644 "int i[2]; void f() { i[1] = 1; }",
1645 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
1646 EXPECT_TRUE(matches(
1647 "int i[2]; void f() { 1[i] = 1; }",
1648 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
1649 EXPECT_TRUE(notMatches(
1650 "int i[2]; void f() { i[1] = 1; }",
1651 arraySubscriptExpr(hasIndex(integerLiteral(equals(0))))));
1652}
1653
1654TEST(ArraySubscriptMatchers, MatchesArrayBase) {
1655 EXPECT_TRUE(matches(
1656 "int i[2]; void f() { i[1] = 2; }",
1657 arraySubscriptExpr(hasBase(implicitCast(
1658 hasSourceExpression(declarationReference()))))));
1659}
1660
Manuel Klimek4da21662012-07-06 05:48:52 +00001661TEST(Matcher, HasNameSupportsNamespaces) {
1662 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1663 record(hasName("a::b::C"))));
1664 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1665 record(hasName("::a::b::C"))));
1666 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1667 record(hasName("b::C"))));
1668 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1669 record(hasName("C"))));
1670 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1671 record(hasName("c::b::C"))));
1672 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1673 record(hasName("a::c::C"))));
1674 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1675 record(hasName("a::b::A"))));
1676 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1677 record(hasName("::C"))));
1678 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1679 record(hasName("::b::C"))));
1680 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1681 record(hasName("z::a::b::C"))));
1682 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1683 record(hasName("a+b::C"))));
1684 EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
1685 record(hasName("C"))));
1686}
1687
1688TEST(Matcher, HasNameSupportsOuterClasses) {
1689 EXPECT_TRUE(
1690 matches("class A { class B { class C; }; };", record(hasName("A::B::C"))));
1691 EXPECT_TRUE(
1692 matches("class A { class B { class C; }; };",
1693 record(hasName("::A::B::C"))));
1694 EXPECT_TRUE(
1695 matches("class A { class B { class C; }; };", record(hasName("B::C"))));
1696 EXPECT_TRUE(
1697 matches("class A { class B { class C; }; };", record(hasName("C"))));
1698 EXPECT_TRUE(
1699 notMatches("class A { class B { class C; }; };",
1700 record(hasName("c::B::C"))));
1701 EXPECT_TRUE(
1702 notMatches("class A { class B { class C; }; };",
1703 record(hasName("A::c::C"))));
1704 EXPECT_TRUE(
1705 notMatches("class A { class B { class C; }; };",
1706 record(hasName("A::B::A"))));
1707 EXPECT_TRUE(
1708 notMatches("class A { class B { class C; }; };", record(hasName("::C"))));
1709 EXPECT_TRUE(
1710 notMatches("class A { class B { class C; }; };",
1711 record(hasName("::B::C"))));
1712 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
1713 record(hasName("z::A::B::C"))));
1714 EXPECT_TRUE(
1715 notMatches("class A { class B { class C; }; };",
1716 record(hasName("A+B::C"))));
1717}
1718
1719TEST(Matcher, IsDefinition) {
1720 DeclarationMatcher DefinitionOfClassA =
1721 record(hasName("A"), isDefinition());
1722 EXPECT_TRUE(matches("class A {};", DefinitionOfClassA));
1723 EXPECT_TRUE(notMatches("class A;", DefinitionOfClassA));
1724
1725 DeclarationMatcher DefinitionOfVariableA =
1726 variable(hasName("a"), isDefinition());
1727 EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));
1728 EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));
1729
1730 DeclarationMatcher DefinitionOfMethodA =
1731 method(hasName("a"), isDefinition());
1732 EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));
1733 EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));
1734}
1735
1736TEST(Matcher, OfClass) {
1737 StatementMatcher Constructor = constructorCall(hasDeclaration(method(
1738 ofClass(hasName("X")))));
1739
1740 EXPECT_TRUE(
1741 matches("class X { public: X(); }; void x(int) { X x; }", Constructor));
1742 EXPECT_TRUE(
1743 matches("class X { public: X(); }; void x(int) { X x = X(); }",
1744 Constructor));
1745 EXPECT_TRUE(
1746 notMatches("class Y { public: Y(); }; void x(int) { Y y; }",
1747 Constructor));
1748}
1749
1750TEST(Matcher, VisitsTemplateInstantiations) {
1751 EXPECT_TRUE(matches(
1752 "class A { public: void x(); };"
1753 "template <typename T> class B { public: void y() { T t; t.x(); } };"
1754 "void f() { B<A> b; b.y(); }", call(callee(method(hasName("x"))))));
1755
1756 EXPECT_TRUE(matches(
1757 "class A { public: void x(); };"
1758 "class C {"
1759 " public:"
1760 " template <typename T> class B { public: void y() { T t; t.x(); } };"
1761 "};"
1762 "void f() {"
1763 " C::B<A> b; b.y();"
1764 "}", record(hasName("C"),
1765 hasDescendant(call(callee(method(hasName("x"))))))));
1766}
1767
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001768TEST(Matcher, HandlesNullQualTypes) {
1769 // FIXME: Add a Type matcher so we can replace uses of this
1770 // variable with Type(True())
1771 const TypeMatcher AnyType = anything();
1772
1773 // We don't really care whether this matcher succeeds; we're testing that
1774 // it completes without crashing.
1775 EXPECT_TRUE(matches(
1776 "struct A { };"
1777 "template <typename T>"
1778 "void f(T t) {"
1779 " T local_t(t /* this becomes a null QualType in the AST */);"
1780 "}"
1781 "void g() {"
1782 " f(0);"
1783 "}",
1784 expression(hasType(TypeMatcher(
1785 anyOf(
1786 TypeMatcher(hasDeclaration(anything())),
1787 pointsTo(AnyType),
1788 references(AnyType)
1789 // Other QualType matchers should go here.
1790 ))))));
1791}
1792
Manuel Klimek4da21662012-07-06 05:48:52 +00001793// For testing AST_MATCHER_P().
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001794AST_MATCHER_P(Decl, just, internal::Matcher<Decl>, AMatcher) {
Manuel Klimek4da21662012-07-06 05:48:52 +00001795 // Make sure all special variables are used: node, match_finder,
1796 // bound_nodes_builder, and the parameter named 'AMatcher'.
1797 return AMatcher.matches(Node, Finder, Builder);
1798}
1799
1800TEST(AstMatcherPMacro, Works) {
Manuel Klimek9f174082012-07-24 13:37:29 +00001801 DeclarationMatcher HasClassB = just(has(record(hasName("B")).bind("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001802
1803 EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001804 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001805
1806 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001807 HasClassB, new VerifyIdIsBoundToDecl<Decl>("a")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001808
1809 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001810 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001811}
1812
1813AST_POLYMORPHIC_MATCHER_P(
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001814 polymorphicHas, internal::Matcher<Decl>, AMatcher) {
1815 TOOLING_COMPILE_ASSERT((llvm::is_same<NodeType, Decl>::value) ||
1816 (llvm::is_same<NodeType, Stmt>::value),
Manuel Klimek4da21662012-07-06 05:48:52 +00001817 assert_node_type_is_accessible);
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001818 internal::TypedBaseMatcher<Decl> ChildMatcher(AMatcher);
Manuel Klimek4da21662012-07-06 05:48:52 +00001819 return Finder->matchesChildOf(
1820 Node, ChildMatcher, Builder,
1821 ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
1822 ASTMatchFinder::BK_First);
1823}
1824
1825TEST(AstPolymorphicMatcherPMacro, Works) {
Manuel Klimek9f174082012-07-24 13:37:29 +00001826 DeclarationMatcher HasClassB = polymorphicHas(record(hasName("B")).bind("b"));
Manuel Klimek4da21662012-07-06 05:48:52 +00001827
1828 EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001829 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001830
1831 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001832 HasClassB, new VerifyIdIsBoundToDecl<Decl>("a")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001833
1834 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001835 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001836
1837 StatementMatcher StatementHasClassB =
1838 polymorphicHas(record(hasName("B")));
1839
1840 EXPECT_TRUE(matches("void x() { class B {}; }", StatementHasClassB));
1841}
1842
1843TEST(For, FindsForLoops) {
1844 EXPECT_TRUE(matches("void f() { for(;;); }", forStmt()));
1845 EXPECT_TRUE(matches("void f() { if(true) for(;;); }", forStmt()));
1846}
1847
Daniel Jasper6a124492012-07-12 08:50:38 +00001848TEST(For, ForLoopInternals) {
1849 EXPECT_TRUE(matches("void f(){ int i; for (; i < 3 ; ); }",
1850 forStmt(hasCondition(anything()))));
1851 EXPECT_TRUE(matches("void f() { for (int i = 0; ;); }",
1852 forStmt(hasLoopInit(anything()))));
1853}
1854
1855TEST(For, NegativeForLoopInternals) {
1856 EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }",
1857 forStmt(hasCondition(expression()))));
1858 EXPECT_TRUE(notMatches("void f() {int i; for (; i < 4; ++i) {} }",
1859 forStmt(hasLoopInit(anything()))));
1860}
1861
Manuel Klimek4da21662012-07-06 05:48:52 +00001862TEST(For, ReportsNoFalsePositives) {
1863 EXPECT_TRUE(notMatches("void f() { ; }", forStmt()));
1864 EXPECT_TRUE(notMatches("void f() { if(true); }", forStmt()));
1865}
1866
1867TEST(CompoundStatement, HandlesSimpleCases) {
1868 EXPECT_TRUE(notMatches("void f();", compoundStatement()));
1869 EXPECT_TRUE(matches("void f() {}", compoundStatement()));
1870 EXPECT_TRUE(matches("void f() {{}}", compoundStatement()));
1871}
1872
1873TEST(CompoundStatement, DoesNotMatchEmptyStruct) {
1874 // It's not a compound statement just because there's "{}" in the source
1875 // text. This is an AST search, not grep.
1876 EXPECT_TRUE(notMatches("namespace n { struct S {}; }",
1877 compoundStatement()));
1878 EXPECT_TRUE(matches("namespace n { struct S { void f() {{}} }; }",
1879 compoundStatement()));
1880}
1881
Daniel Jasper6a124492012-07-12 08:50:38 +00001882TEST(HasBody, FindsBodyOfForWhileDoLoops) {
Manuel Klimek4da21662012-07-06 05:48:52 +00001883 EXPECT_TRUE(matches("void f() { for(;;) {} }",
Daniel Jasper6a124492012-07-12 08:50:38 +00001884 forStmt(hasBody(compoundStatement()))));
Manuel Klimek4da21662012-07-06 05:48:52 +00001885 EXPECT_TRUE(notMatches("void f() { for(;;); }",
Daniel Jasper6a124492012-07-12 08:50:38 +00001886 forStmt(hasBody(compoundStatement()))));
1887 EXPECT_TRUE(matches("void f() { while(true) {} }",
1888 whileStmt(hasBody(compoundStatement()))));
1889 EXPECT_TRUE(matches("void f() { do {} while(true); }",
1890 doStmt(hasBody(compoundStatement()))));
Manuel Klimek4da21662012-07-06 05:48:52 +00001891}
1892
1893TEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
1894 // The simplest case: every compound statement is in a function
1895 // definition, and the function body itself must be a compound
1896 // statement.
1897 EXPECT_TRUE(matches("void f() { for (;;); }",
1898 compoundStatement(hasAnySubstatement(forStmt()))));
1899}
1900
1901TEST(HasAnySubstatement, IsNotRecursive) {
1902 // It's really "has any immediate substatement".
1903 EXPECT_TRUE(notMatches("void f() { if (true) for (;;); }",
1904 compoundStatement(hasAnySubstatement(forStmt()))));
1905}
1906
1907TEST(HasAnySubstatement, MatchesInNestedCompoundStatements) {
1908 EXPECT_TRUE(matches("void f() { if (true) { for (;;); } }",
1909 compoundStatement(hasAnySubstatement(forStmt()))));
1910}
1911
1912TEST(HasAnySubstatement, FindsSubstatementBetweenOthers) {
1913 EXPECT_TRUE(matches("void f() { 1; 2; 3; for (;;); 4; 5; 6; }",
1914 compoundStatement(hasAnySubstatement(forStmt()))));
1915}
1916
1917TEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) {
1918 EXPECT_TRUE(matches("void f() { }",
1919 compoundStatement(statementCountIs(0))));
1920 EXPECT_TRUE(notMatches("void f() {}",
1921 compoundStatement(statementCountIs(1))));
1922}
1923
1924TEST(StatementCountIs, AppearsToMatchOnlyOneCount) {
1925 EXPECT_TRUE(matches("void f() { 1; }",
1926 compoundStatement(statementCountIs(1))));
1927 EXPECT_TRUE(notMatches("void f() { 1; }",
1928 compoundStatement(statementCountIs(0))));
1929 EXPECT_TRUE(notMatches("void f() { 1; }",
1930 compoundStatement(statementCountIs(2))));
1931}
1932
1933TEST(StatementCountIs, WorksWithMultipleStatements) {
1934 EXPECT_TRUE(matches("void f() { 1; 2; 3; }",
1935 compoundStatement(statementCountIs(3))));
1936}
1937
1938TEST(StatementCountIs, WorksWithNestedCompoundStatements) {
1939 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1940 compoundStatement(statementCountIs(1))));
1941 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1942 compoundStatement(statementCountIs(2))));
1943 EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
1944 compoundStatement(statementCountIs(3))));
1945 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1946 compoundStatement(statementCountIs(4))));
1947}
1948
1949TEST(Member, WorksInSimplestCase) {
1950 EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
1951 memberExpression(member(hasName("first")))));
1952}
1953
1954TEST(Member, DoesNotMatchTheBaseExpression) {
1955 // Don't pick out the wrong part of the member expression, this should
1956 // be checking the member (name) only.
1957 EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
1958 memberExpression(member(hasName("first")))));
1959}
1960
1961TEST(Member, MatchesInMemberFunctionCall) {
1962 EXPECT_TRUE(matches("void f() {"
1963 " struct { void first() {}; } s;"
1964 " s.first();"
1965 "};",
1966 memberExpression(member(hasName("first")))));
1967}
1968
1969TEST(HasObjectExpression, DoesNotMatchMember) {
1970 EXPECT_TRUE(notMatches(
1971 "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
1972 memberExpression(hasObjectExpression(hasType(record(hasName("X")))))));
1973}
1974
1975TEST(HasObjectExpression, MatchesBaseOfVariable) {
1976 EXPECT_TRUE(matches(
1977 "struct X { int m; }; void f(X x) { x.m; }",
1978 memberExpression(hasObjectExpression(hasType(record(hasName("X")))))));
1979 EXPECT_TRUE(matches(
1980 "struct X { int m; }; void f(X* x) { x->m; }",
1981 memberExpression(hasObjectExpression(
1982 hasType(pointsTo(record(hasName("X"))))))));
1983}
1984
1985TEST(HasObjectExpression,
1986 MatchesObjectExpressionOfImplicitlyFormedMemberExpression) {
1987 EXPECT_TRUE(matches(
1988 "class X {}; struct S { X m; void f() { this->m; } };",
1989 memberExpression(hasObjectExpression(
1990 hasType(pointsTo(record(hasName("S"))))))));
1991 EXPECT_TRUE(matches(
1992 "class X {}; struct S { X m; void f() { m; } };",
1993 memberExpression(hasObjectExpression(
1994 hasType(pointsTo(record(hasName("S"))))))));
1995}
1996
1997TEST(Field, DoesNotMatchNonFieldMembers) {
1998 EXPECT_TRUE(notMatches("class X { void m(); };", field(hasName("m"))));
1999 EXPECT_TRUE(notMatches("class X { class m {}; };", field(hasName("m"))));
2000 EXPECT_TRUE(notMatches("class X { enum { m }; };", field(hasName("m"))));
2001 EXPECT_TRUE(notMatches("class X { enum m {}; };", field(hasName("m"))));
2002}
2003
2004TEST(Field, MatchesField) {
2005 EXPECT_TRUE(matches("class X { int m; };", field(hasName("m"))));
2006}
2007
2008TEST(IsConstQualified, MatchesConstInt) {
2009 EXPECT_TRUE(matches("const int i = 42;",
2010 variable(hasType(isConstQualified()))));
2011}
2012
2013TEST(IsConstQualified, MatchesConstPointer) {
2014 EXPECT_TRUE(matches("int i = 42; int* const p(&i);",
2015 variable(hasType(isConstQualified()))));
2016}
2017
2018TEST(IsConstQualified, MatchesThroughTypedef) {
2019 EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
2020 variable(hasType(isConstQualified()))));
2021 EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p(0);",
2022 variable(hasType(isConstQualified()))));
2023}
2024
2025TEST(IsConstQualified, DoesNotMatchInappropriately) {
2026 EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
2027 variable(hasType(isConstQualified()))));
2028 EXPECT_TRUE(notMatches("int const* p;",
2029 variable(hasType(isConstQualified()))));
2030}
2031
Sam Panzer089e5b32012-08-16 16:58:10 +00002032TEST(CastExpression, MatchesExplicitCasts) {
2033 EXPECT_TRUE(matches("char *p = reinterpret_cast<char *>(&p);",
2034 expression(castExpr())));
2035 EXPECT_TRUE(matches("void *p = (void *)(&p);", expression(castExpr())));
2036 EXPECT_TRUE(matches("char q, *p = const_cast<char *>(&q);",
2037 expression(castExpr())));
2038 EXPECT_TRUE(matches("char c = char(0);", expression(castExpr())));
2039}
2040TEST(CastExpression, MatchesImplicitCasts) {
2041 // This test creates an implicit cast from int to char.
2042 EXPECT_TRUE(matches("char c = 0;", expression(castExpr())));
2043 // This test creates an implicit cast from lvalue to rvalue.
2044 EXPECT_TRUE(matches("char c = 0, d = c;", expression(castExpr())));
2045}
2046
2047TEST(CastExpression, DoesNotMatchNonCasts) {
2048 EXPECT_TRUE(notMatches("char c = '0';", expression(castExpr())));
2049 EXPECT_TRUE(notMatches("char c, &q = c;", expression(castExpr())));
2050 EXPECT_TRUE(notMatches("int i = (0);", expression(castExpr())));
2051 EXPECT_TRUE(notMatches("int i = 0;", expression(castExpr())));
2052}
2053
Manuel Klimek4da21662012-07-06 05:48:52 +00002054TEST(ReinterpretCast, MatchesSimpleCase) {
2055 EXPECT_TRUE(matches("char* p = reinterpret_cast<char*>(&p);",
2056 expression(reinterpretCast())));
2057}
2058
2059TEST(ReinterpretCast, DoesNotMatchOtherCasts) {
2060 EXPECT_TRUE(notMatches("char* p = (char*)(&p);",
2061 expression(reinterpretCast())));
2062 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
2063 expression(reinterpretCast())));
2064 EXPECT_TRUE(notMatches("void* p = static_cast<void*>(&p);",
2065 expression(reinterpretCast())));
2066 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
2067 "B b;"
2068 "D* p = dynamic_cast<D*>(&b);",
2069 expression(reinterpretCast())));
2070}
2071
2072TEST(FunctionalCast, MatchesSimpleCase) {
2073 std::string foo_class = "class Foo { public: Foo(char*); };";
2074 EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",
2075 expression(functionalCast())));
2076}
2077
2078TEST(FunctionalCast, DoesNotMatchOtherCasts) {
2079 std::string FooClass = "class Foo { public: Foo(char*); };";
2080 EXPECT_TRUE(
2081 notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",
2082 expression(functionalCast())));
2083 EXPECT_TRUE(
2084 notMatches(FooClass + "void r() { Foo f = \"hello world\"; }",
2085 expression(functionalCast())));
2086}
2087
2088TEST(DynamicCast, MatchesSimpleCase) {
2089 EXPECT_TRUE(matches("struct B { virtual ~B() {} }; struct D : B {};"
2090 "B b;"
2091 "D* p = dynamic_cast<D*>(&b);",
2092 expression(dynamicCast())));
2093}
2094
2095TEST(StaticCast, MatchesSimpleCase) {
2096 EXPECT_TRUE(matches("void* p(static_cast<void*>(&p));",
2097 expression(staticCast())));
2098}
2099
2100TEST(StaticCast, DoesNotMatchOtherCasts) {
2101 EXPECT_TRUE(notMatches("char* p = (char*)(&p);",
2102 expression(staticCast())));
2103 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
2104 expression(staticCast())));
2105 EXPECT_TRUE(notMatches("void* p = reinterpret_cast<char*>(&p);",
2106 expression(staticCast())));
2107 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
2108 "B b;"
2109 "D* p = dynamic_cast<D*>(&b);",
2110 expression(staticCast())));
2111}
2112
2113TEST(HasDestinationType, MatchesSimpleCase) {
2114 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
2115 expression(
2116 staticCast(hasDestinationType(
2117 pointsTo(TypeMatcher(anything())))))));
2118}
2119
Sam Panzer089e5b32012-08-16 16:58:10 +00002120TEST(HasImplicitDestinationType, MatchesSimpleCase) {
2121 // This test creates an implicit const cast.
2122 EXPECT_TRUE(matches("int x; const int i = x;",
2123 expression(implicitCast(
2124 hasImplicitDestinationType(isInteger())))));
2125 // This test creates an implicit array-to-pointer cast.
2126 EXPECT_TRUE(matches("int arr[3]; int *p = arr;",
2127 expression(implicitCast(hasImplicitDestinationType(
2128 pointsTo(TypeMatcher(anything())))))));
2129}
2130
2131TEST(HasImplicitDestinationType, DoesNotMatchIncorrectly) {
2132 // This test creates an implicit cast from int to char.
2133 EXPECT_TRUE(notMatches("char c = 0;",
2134 expression(implicitCast(hasImplicitDestinationType(
2135 unless(anything()))))));
2136 // This test creates an implicit array-to-pointer cast.
2137 EXPECT_TRUE(notMatches("int arr[3]; int *p = arr;",
2138 expression(implicitCast(hasImplicitDestinationType(
2139 unless(anything()))))));
2140}
2141
2142TEST(ImplicitCast, MatchesSimpleCase) {
2143 // This test creates an implicit const cast.
2144 EXPECT_TRUE(matches("int x = 0; const int y = x;",
2145 variable(hasInitializer(implicitCast()))));
2146 // This test creates an implicit cast from int to char.
2147 EXPECT_TRUE(matches("char c = 0;",
2148 variable(hasInitializer(implicitCast()))));
2149 // This test creates an implicit array-to-pointer cast.
2150 EXPECT_TRUE(matches("int arr[6]; int *p = arr;",
2151 variable(hasInitializer(implicitCast()))));
2152}
2153
2154TEST(ImplicitCast, DoesNotMatchIncorrectly) {
2155 // This test verifies that implicitCast() matches exactly when implicit casts
2156 // are present, and that it ignores explicit and paren casts.
2157
2158 // These two test cases have no casts.
2159 EXPECT_TRUE(notMatches("int x = 0;",
2160 variable(hasInitializer(implicitCast()))));
2161 EXPECT_TRUE(notMatches("int x = 0, &y = x;",
2162 variable(hasInitializer(implicitCast()))));
2163
2164 EXPECT_TRUE(notMatches("int x = 0; double d = (double) x;",
2165 variable(hasInitializer(implicitCast()))));
2166 EXPECT_TRUE(notMatches("const int *p; int *q = const_cast<int *>(p);",
2167 variable(hasInitializer(implicitCast()))));
2168
2169 EXPECT_TRUE(notMatches("int x = (0);",
2170 variable(hasInitializer(implicitCast()))));
2171}
2172
2173TEST(IgnoringImpCasts, MatchesImpCasts) {
2174 // This test checks that ignoringImpCasts matches when implicit casts are
2175 // present and its inner matcher alone does not match.
2176 // Note that this test creates an implicit const cast.
2177 EXPECT_TRUE(matches("int x = 0; const int y = x;",
2178 variable(hasInitializer(ignoringImpCasts(
2179 declarationReference(to(variable(hasName("x")))))))));
2180 // This test creates an implict cast from int to char.
2181 EXPECT_TRUE(matches("char x = 0;",
2182 variable(hasInitializer(ignoringImpCasts(
2183 integerLiteral(equals(0)))))));
2184}
2185
2186TEST(IgnoringImpCasts, DoesNotMatchIncorrectly) {
2187 // These tests verify that ignoringImpCasts does not match if the inner
2188 // matcher does not match.
2189 // Note that the first test creates an implicit const cast.
2190 EXPECT_TRUE(notMatches("int x; const int y = x;",
2191 variable(hasInitializer(ignoringImpCasts(
2192 unless(anything()))))));
2193 EXPECT_TRUE(notMatches("int x; int y = x;",
2194 variable(hasInitializer(ignoringImpCasts(
2195 unless(anything()))))));
2196
2197 // These tests verify that ignoringImplictCasts does not look through explicit
2198 // casts or parentheses.
2199 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
2200 variable(hasInitializer(ignoringImpCasts(
2201 integerLiteral())))));
2202 EXPECT_TRUE(notMatches("int i = (0);",
2203 variable(hasInitializer(ignoringImpCasts(
2204 integerLiteral())))));
2205 EXPECT_TRUE(notMatches("float i = (float)0;",
2206 variable(hasInitializer(ignoringImpCasts(
2207 integerLiteral())))));
2208 EXPECT_TRUE(notMatches("float i = float(0);",
2209 variable(hasInitializer(ignoringImpCasts(
2210 integerLiteral())))));
2211}
2212
2213TEST(IgnoringImpCasts, MatchesWithoutImpCasts) {
2214 // This test verifies that expressions that do not have implicit casts
2215 // still match the inner matcher.
2216 EXPECT_TRUE(matches("int x = 0; int &y = x;",
2217 variable(hasInitializer(ignoringImpCasts(
2218 declarationReference(to(variable(hasName("x")))))))));
2219}
2220
2221TEST(IgnoringParenCasts, MatchesParenCasts) {
2222 // This test checks that ignoringParenCasts matches when parentheses and/or
2223 // casts are present and its inner matcher alone does not match.
2224 EXPECT_TRUE(matches("int x = (0);",
2225 variable(hasInitializer(ignoringParenCasts(
2226 integerLiteral(equals(0)))))));
2227 EXPECT_TRUE(matches("int x = (((((0)))));",
2228 variable(hasInitializer(ignoringParenCasts(
2229 integerLiteral(equals(0)))))));
2230
2231 // This test creates an implict cast from int to char in addition to the
2232 // parentheses.
2233 EXPECT_TRUE(matches("char x = (0);",
2234 variable(hasInitializer(ignoringParenCasts(
2235 integerLiteral(equals(0)))))));
2236
2237 EXPECT_TRUE(matches("char x = (char)0;",
2238 variable(hasInitializer(ignoringParenCasts(
2239 integerLiteral(equals(0)))))));
2240 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
2241 variable(hasInitializer(ignoringParenCasts(
2242 integerLiteral(equals(0)))))));
2243}
2244
2245TEST(IgnoringParenCasts, MatchesWithoutParenCasts) {
2246 // This test verifies that expressions that do not have any casts still match.
2247 EXPECT_TRUE(matches("int x = 0;",
2248 variable(hasInitializer(ignoringParenCasts(
2249 integerLiteral(equals(0)))))));
2250}
2251
2252TEST(IgnoringParenCasts, DoesNotMatchIncorrectly) {
2253 // These tests verify that ignoringImpCasts does not match if the inner
2254 // matcher does not match.
2255 EXPECT_TRUE(notMatches("int x = ((0));",
2256 variable(hasInitializer(ignoringParenCasts(
2257 unless(anything()))))));
2258
2259 // This test creates an implicit cast from int to char in addition to the
2260 // parentheses.
2261 EXPECT_TRUE(notMatches("char x = ((0));",
2262 variable(hasInitializer(ignoringParenCasts(
2263 unless(anything()))))));
2264
2265 EXPECT_TRUE(notMatches("char *x = static_cast<char *>((0));",
2266 variable(hasInitializer(ignoringParenCasts(
2267 unless(anything()))))));
2268}
2269
2270TEST(IgnoringParenAndImpCasts, MatchesParenImpCasts) {
2271 // This test checks that ignoringParenAndImpCasts matches when
2272 // parentheses and/or implicit casts are present and its inner matcher alone
2273 // does not match.
2274 // Note that this test creates an implicit const cast.
2275 EXPECT_TRUE(matches("int x = 0; const int y = x;",
2276 variable(hasInitializer(ignoringParenImpCasts(
2277 declarationReference(to(variable(hasName("x")))))))));
2278 // This test creates an implicit cast from int to char.
2279 EXPECT_TRUE(matches("const char x = (0);",
2280 variable(hasInitializer(ignoringParenImpCasts(
2281 integerLiteral(equals(0)))))));
2282}
2283
2284TEST(IgnoringParenAndImpCasts, MatchesWithoutParenImpCasts) {
2285 // This test verifies that expressions that do not have parentheses or
2286 // implicit casts still match.
2287 EXPECT_TRUE(matches("int x = 0; int &y = x;",
2288 variable(hasInitializer(ignoringParenImpCasts(
2289 declarationReference(to(variable(hasName("x")))))))));
2290 EXPECT_TRUE(matches("int x = 0;",
2291 variable(hasInitializer(ignoringParenImpCasts(
2292 integerLiteral(equals(0)))))));
2293}
2294
2295TEST(IgnoringParenAndImpCasts, DoesNotMatchIncorrectly) {
2296 // These tests verify that ignoringParenImpCasts does not match if
2297 // the inner matcher does not match.
2298 // This test creates an implicit cast.
2299 EXPECT_TRUE(notMatches("char c = ((3));",
2300 variable(hasInitializer(ignoringParenImpCasts(
2301 unless(anything()))))));
2302 // These tests verify that ignoringParenAndImplictCasts does not look
2303 // through explicit casts.
2304 EXPECT_TRUE(notMatches("float y = (float(0));",
2305 variable(hasInitializer(ignoringParenImpCasts(
2306 integerLiteral())))));
2307 EXPECT_TRUE(notMatches("float y = (float)0;",
2308 variable(hasInitializer(ignoringParenImpCasts(
2309 integerLiteral())))));
2310 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
2311 variable(hasInitializer(ignoringParenImpCasts(
2312 integerLiteral())))));
2313}
2314
Manuel Klimek715c9562012-07-25 10:02:02 +00002315TEST(HasSourceExpression, MatchesImplicitCasts) {
Manuel Klimek4da21662012-07-06 05:48:52 +00002316 EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
2317 "void r() {string a_string; URL url = a_string; }",
2318 expression(implicitCast(
2319 hasSourceExpression(constructorCall())))));
2320}
2321
Manuel Klimek715c9562012-07-25 10:02:02 +00002322TEST(HasSourceExpression, MatchesExplicitCasts) {
2323 EXPECT_TRUE(matches("float x = static_cast<float>(42);",
2324 expression(explicitCast(
2325 hasSourceExpression(hasDescendant(
2326 expression(integerLiteral())))))));
2327}
2328
Manuel Klimek4da21662012-07-06 05:48:52 +00002329TEST(Statement, DoesNotMatchDeclarations) {
2330 EXPECT_TRUE(notMatches("class X {};", statement()));
2331}
2332
2333TEST(Statement, MatchesCompoundStatments) {
2334 EXPECT_TRUE(matches("void x() {}", statement()));
2335}
2336
2337TEST(DeclarationStatement, DoesNotMatchCompoundStatements) {
2338 EXPECT_TRUE(notMatches("void x() {}", declarationStatement()));
2339}
2340
2341TEST(DeclarationStatement, MatchesVariableDeclarationStatements) {
2342 EXPECT_TRUE(matches("void x() { int a; }", declarationStatement()));
2343}
2344
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002345TEST(InitListExpression, MatchesInitListExpression) {
2346 EXPECT_TRUE(matches("int a[] = { 1, 2 };",
2347 initListExpr(hasType(asString("int [2]")))));
2348 EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };",
2349 initListExpr(hasType(record(hasName("B"))))));
2350}
2351
2352TEST(UsingDeclaration, MatchesUsingDeclarations) {
2353 EXPECT_TRUE(matches("namespace X { int x; } using X::x;",
2354 usingDecl()));
2355}
2356
2357TEST(UsingDeclaration, MatchesShadowUsingDelcarations) {
2358 EXPECT_TRUE(matches("namespace f { int a; } using f::a;",
2359 usingDecl(hasAnyUsingShadowDecl(hasName("a")))));
2360}
2361
2362TEST(UsingDeclaration, MatchesSpecificTarget) {
2363 EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
2364 usingDecl(hasAnyUsingShadowDecl(
2365 hasTargetDecl(function())))));
2366 EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
2367 usingDecl(hasAnyUsingShadowDecl(
2368 hasTargetDecl(function())))));
2369}
2370
2371TEST(UsingDeclaration, ThroughUsingDeclaration) {
2372 EXPECT_TRUE(matches(
2373 "namespace a { void f(); } using a::f; void g() { f(); }",
2374 declarationReference(throughUsingDecl(anything()))));
2375 EXPECT_TRUE(notMatches(
2376 "namespace a { void f(); } using a::f; void g() { a::f(); }",
2377 declarationReference(throughUsingDecl(anything()))));
2378}
2379
Sam Panzer425f41b2012-08-16 17:20:59 +00002380TEST(SingleDecl, IsSingleDecl) {
2381 StatementMatcher SingleDeclStmt =
2382 declarationStatement(hasSingleDecl(variable(hasInitializer(anything()))));
2383 EXPECT_TRUE(matches("void f() {int a = 4;}", SingleDeclStmt));
2384 EXPECT_TRUE(notMatches("void f() {int a;}", SingleDeclStmt));
2385 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
2386 SingleDeclStmt));
2387}
2388
2389TEST(DeclStmt, ContainsDeclaration) {
2390 DeclarationMatcher MatchesInit = variable(hasInitializer(anything()));
2391
2392 EXPECT_TRUE(matches("void f() {int a = 4;}",
2393 declarationStatement(containsDeclaration(0,
2394 MatchesInit))));
2395 EXPECT_TRUE(matches("void f() {int a = 4, b = 3;}",
2396 declarationStatement(containsDeclaration(0, MatchesInit),
2397 containsDeclaration(1,
2398 MatchesInit))));
2399 unsigned WrongIndex = 42;
2400 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
2401 declarationStatement(containsDeclaration(WrongIndex,
2402 MatchesInit))));
2403}
2404
2405TEST(DeclCount, DeclCountIsCorrect) {
2406 EXPECT_TRUE(matches("void f() {int i,j;}",
2407 declarationStatement(declCountIs(2))));
2408 EXPECT_TRUE(notMatches("void f() {int i,j; int k;}",
2409 declarationStatement(declCountIs(3))));
2410 EXPECT_TRUE(notMatches("void f() {int i,j, k, l;}",
2411 declarationStatement(declCountIs(3))));
2412}
2413
Manuel Klimek4da21662012-07-06 05:48:52 +00002414TEST(While, MatchesWhileLoops) {
2415 EXPECT_TRUE(notMatches("void x() {}", whileStmt()));
2416 EXPECT_TRUE(matches("void x() { while(true); }", whileStmt()));
2417 EXPECT_TRUE(notMatches("void x() { do {} while(true); }", whileStmt()));
2418}
2419
2420TEST(Do, MatchesDoLoops) {
2421 EXPECT_TRUE(matches("void x() { do {} while(true); }", doStmt()));
2422 EXPECT_TRUE(matches("void x() { do ; while(false); }", doStmt()));
2423}
2424
2425TEST(Do, DoesNotMatchWhileLoops) {
2426 EXPECT_TRUE(notMatches("void x() { while(true) {} }", doStmt()));
2427}
2428
2429TEST(SwitchCase, MatchesCase) {
2430 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchCase()));
2431 EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchCase()));
2432 EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchCase()));
2433 EXPECT_TRUE(notMatches("void x() { switch(42) {} }", switchCase()));
2434}
2435
2436TEST(HasConditionVariableStatement, DoesNotMatchCondition) {
2437 EXPECT_TRUE(notMatches(
2438 "void x() { if(true) {} }",
2439 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2440 EXPECT_TRUE(notMatches(
2441 "void x() { int x; if((x = 42)) {} }",
2442 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2443}
2444
2445TEST(HasConditionVariableStatement, MatchesConditionVariables) {
2446 EXPECT_TRUE(matches(
2447 "void x() { if(int* a = 0) {} }",
2448 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2449}
2450
2451TEST(ForEach, BindsOneNode) {
2452 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002453 record(hasName("C"), forEach(field(hasName("x")).bind("x"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002454 new VerifyIdIsBoundToDecl<FieldDecl>("x", 1)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002455}
2456
2457TEST(ForEach, BindsMultipleNodes) {
2458 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002459 record(hasName("C"), forEach(field().bind("f"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002460 new VerifyIdIsBoundToDecl<FieldDecl>("f", 3)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002461}
2462
2463TEST(ForEach, BindsRecursiveCombinations) {
2464 EXPECT_TRUE(matchAndVerifyResultTrue(
2465 "class C { class D { int x; int y; }; class E { int y; int z; }; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002466 record(hasName("C"), forEach(record(forEach(field().bind("f"))))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002467 new VerifyIdIsBoundToDecl<FieldDecl>("f", 4)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002468}
2469
2470TEST(ForEachDescendant, BindsOneNode) {
2471 EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002472 record(hasName("C"), forEachDescendant(field(hasName("x")).bind("x"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002473 new VerifyIdIsBoundToDecl<FieldDecl>("x", 1)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002474}
2475
2476TEST(ForEachDescendant, BindsMultipleNodes) {
2477 EXPECT_TRUE(matchAndVerifyResultTrue(
2478 "class C { class D { int x; int y; }; "
2479 " class E { class F { int y; int z; }; }; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002480 record(hasName("C"), forEachDescendant(field().bind("f"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002481 new VerifyIdIsBoundToDecl<FieldDecl>("f", 4)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002482}
2483
2484TEST(ForEachDescendant, BindsRecursiveCombinations) {
2485 EXPECT_TRUE(matchAndVerifyResultTrue(
2486 "class C { class D { "
2487 " class E { class F { class G { int y; int z; }; }; }; }; };",
2488 record(hasName("C"), forEachDescendant(record(
Manuel Klimek9f174082012-07-24 13:37:29 +00002489 forEachDescendant(field().bind("f"))))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002490 new VerifyIdIsBoundToDecl<FieldDecl>("f", 8)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002491}
2492
2493
2494TEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) {
2495 // Make sure that we can both match the class by name (::X) and by the type
2496 // the template was instantiated with (via a field).
2497
2498 EXPECT_TRUE(matches(
2499 "template <typename T> class X {}; class A {}; X<A> x;",
2500 record(hasName("::X"), isTemplateInstantiation())));
2501
2502 EXPECT_TRUE(matches(
2503 "template <typename T> class X { T t; }; class A {}; X<A> x;",
2504 record(isTemplateInstantiation(), hasDescendant(
2505 field(hasType(record(hasName("A"))))))));
2506}
2507
2508TEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) {
2509 EXPECT_TRUE(matches(
2510 "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
2511 function(hasParameter(0, hasType(record(hasName("A")))),
2512 isTemplateInstantiation())));
2513}
2514
2515TEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) {
2516 EXPECT_TRUE(matches(
2517 "template <typename T> class X { T t; }; class A {};"
2518 "template class X<A>;",
2519 record(isTemplateInstantiation(), hasDescendant(
2520 field(hasType(record(hasName("A"))))))));
2521}
2522
2523TEST(IsTemplateInstantiation,
2524 MatchesInstantiationOfPartiallySpecializedClassTemplate) {
2525 EXPECT_TRUE(matches(
2526 "template <typename T> class X {};"
2527 "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
2528 record(hasName("::X"), isTemplateInstantiation())));
2529}
2530
2531TEST(IsTemplateInstantiation,
2532 MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
2533 EXPECT_TRUE(matches(
2534 "class A {};"
2535 "class X {"
2536 " template <typename U> class Y { U u; };"
2537 " Y<A> y;"
2538 "};",
2539 record(hasName("::X::Y"), isTemplateInstantiation())));
2540}
2541
2542TEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) {
2543 // FIXME: Figure out whether this makes sense. It doesn't affect the
2544 // normal use case as long as the uppermost instantiation always is marked
2545 // as template instantiation, but it might be confusing as a predicate.
2546 EXPECT_TRUE(matches(
2547 "class A {};"
2548 "template <typename T> class X {"
2549 " template <typename U> class Y { U u; };"
2550 " Y<T> y;"
2551 "}; X<A> x;",
2552 record(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
2553}
2554
2555TEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) {
2556 EXPECT_TRUE(notMatches(
2557 "template <typename T> class X {}; class A {};"
2558 "template <> class X<A> {}; X<A> x;",
2559 record(hasName("::X"), isTemplateInstantiation())));
2560}
2561
2562TEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) {
2563 EXPECT_TRUE(notMatches(
2564 "class A {}; class Y { A a; };",
2565 record(isTemplateInstantiation())));
2566}
2567
2568} // end namespace ast_matchers
2569} // end namespace clang