blob: dba9b7d6074a0ad6668c5118b359c9ab2f580c32 [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
2032TEST(ReinterpretCast, MatchesSimpleCase) {
2033 EXPECT_TRUE(matches("char* p = reinterpret_cast<char*>(&p);",
2034 expression(reinterpretCast())));
2035}
2036
2037TEST(ReinterpretCast, DoesNotMatchOtherCasts) {
2038 EXPECT_TRUE(notMatches("char* p = (char*)(&p);",
2039 expression(reinterpretCast())));
2040 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
2041 expression(reinterpretCast())));
2042 EXPECT_TRUE(notMatches("void* p = static_cast<void*>(&p);",
2043 expression(reinterpretCast())));
2044 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
2045 "B b;"
2046 "D* p = dynamic_cast<D*>(&b);",
2047 expression(reinterpretCast())));
2048}
2049
2050TEST(FunctionalCast, MatchesSimpleCase) {
2051 std::string foo_class = "class Foo { public: Foo(char*); };";
2052 EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",
2053 expression(functionalCast())));
2054}
2055
2056TEST(FunctionalCast, DoesNotMatchOtherCasts) {
2057 std::string FooClass = "class Foo { public: Foo(char*); };";
2058 EXPECT_TRUE(
2059 notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",
2060 expression(functionalCast())));
2061 EXPECT_TRUE(
2062 notMatches(FooClass + "void r() { Foo f = \"hello world\"; }",
2063 expression(functionalCast())));
2064}
2065
2066TEST(DynamicCast, MatchesSimpleCase) {
2067 EXPECT_TRUE(matches("struct B { virtual ~B() {} }; struct D : B {};"
2068 "B b;"
2069 "D* p = dynamic_cast<D*>(&b);",
2070 expression(dynamicCast())));
2071}
2072
2073TEST(StaticCast, MatchesSimpleCase) {
2074 EXPECT_TRUE(matches("void* p(static_cast<void*>(&p));",
2075 expression(staticCast())));
2076}
2077
2078TEST(StaticCast, DoesNotMatchOtherCasts) {
2079 EXPECT_TRUE(notMatches("char* p = (char*)(&p);",
2080 expression(staticCast())));
2081 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
2082 expression(staticCast())));
2083 EXPECT_TRUE(notMatches("void* p = reinterpret_cast<char*>(&p);",
2084 expression(staticCast())));
2085 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
2086 "B b;"
2087 "D* p = dynamic_cast<D*>(&b);",
2088 expression(staticCast())));
2089}
2090
2091TEST(HasDestinationType, MatchesSimpleCase) {
2092 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
2093 expression(
2094 staticCast(hasDestinationType(
2095 pointsTo(TypeMatcher(anything())))))));
2096}
2097
Manuel Klimek715c9562012-07-25 10:02:02 +00002098TEST(HasSourceExpression, MatchesImplicitCasts) {
Manuel Klimek4da21662012-07-06 05:48:52 +00002099 EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
2100 "void r() {string a_string; URL url = a_string; }",
2101 expression(implicitCast(
2102 hasSourceExpression(constructorCall())))));
2103}
2104
Manuel Klimek715c9562012-07-25 10:02:02 +00002105TEST(HasSourceExpression, MatchesExplicitCasts) {
2106 EXPECT_TRUE(matches("float x = static_cast<float>(42);",
2107 expression(explicitCast(
2108 hasSourceExpression(hasDescendant(
2109 expression(integerLiteral())))))));
2110}
2111
Manuel Klimek4da21662012-07-06 05:48:52 +00002112TEST(Statement, DoesNotMatchDeclarations) {
2113 EXPECT_TRUE(notMatches("class X {};", statement()));
2114}
2115
2116TEST(Statement, MatchesCompoundStatments) {
2117 EXPECT_TRUE(matches("void x() {}", statement()));
2118}
2119
2120TEST(DeclarationStatement, DoesNotMatchCompoundStatements) {
2121 EXPECT_TRUE(notMatches("void x() {}", declarationStatement()));
2122}
2123
2124TEST(DeclarationStatement, MatchesVariableDeclarationStatements) {
2125 EXPECT_TRUE(matches("void x() { int a; }", declarationStatement()));
2126}
2127
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002128TEST(InitListExpression, MatchesInitListExpression) {
2129 EXPECT_TRUE(matches("int a[] = { 1, 2 };",
2130 initListExpr(hasType(asString("int [2]")))));
2131 EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };",
2132 initListExpr(hasType(record(hasName("B"))))));
2133}
2134
2135TEST(UsingDeclaration, MatchesUsingDeclarations) {
2136 EXPECT_TRUE(matches("namespace X { int x; } using X::x;",
2137 usingDecl()));
2138}
2139
2140TEST(UsingDeclaration, MatchesShadowUsingDelcarations) {
2141 EXPECT_TRUE(matches("namespace f { int a; } using f::a;",
2142 usingDecl(hasAnyUsingShadowDecl(hasName("a")))));
2143}
2144
2145TEST(UsingDeclaration, MatchesSpecificTarget) {
2146 EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
2147 usingDecl(hasAnyUsingShadowDecl(
2148 hasTargetDecl(function())))));
2149 EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
2150 usingDecl(hasAnyUsingShadowDecl(
2151 hasTargetDecl(function())))));
2152}
2153
2154TEST(UsingDeclaration, ThroughUsingDeclaration) {
2155 EXPECT_TRUE(matches(
2156 "namespace a { void f(); } using a::f; void g() { f(); }",
2157 declarationReference(throughUsingDecl(anything()))));
2158 EXPECT_TRUE(notMatches(
2159 "namespace a { void f(); } using a::f; void g() { a::f(); }",
2160 declarationReference(throughUsingDecl(anything()))));
2161}
2162
Manuel Klimek4da21662012-07-06 05:48:52 +00002163TEST(While, MatchesWhileLoops) {
2164 EXPECT_TRUE(notMatches("void x() {}", whileStmt()));
2165 EXPECT_TRUE(matches("void x() { while(true); }", whileStmt()));
2166 EXPECT_TRUE(notMatches("void x() { do {} while(true); }", whileStmt()));
2167}
2168
2169TEST(Do, MatchesDoLoops) {
2170 EXPECT_TRUE(matches("void x() { do {} while(true); }", doStmt()));
2171 EXPECT_TRUE(matches("void x() { do ; while(false); }", doStmt()));
2172}
2173
2174TEST(Do, DoesNotMatchWhileLoops) {
2175 EXPECT_TRUE(notMatches("void x() { while(true) {} }", doStmt()));
2176}
2177
2178TEST(SwitchCase, MatchesCase) {
2179 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchCase()));
2180 EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchCase()));
2181 EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchCase()));
2182 EXPECT_TRUE(notMatches("void x() { switch(42) {} }", switchCase()));
2183}
2184
2185TEST(HasConditionVariableStatement, DoesNotMatchCondition) {
2186 EXPECT_TRUE(notMatches(
2187 "void x() { if(true) {} }",
2188 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2189 EXPECT_TRUE(notMatches(
2190 "void x() { int x; if((x = 42)) {} }",
2191 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2192}
2193
2194TEST(HasConditionVariableStatement, MatchesConditionVariables) {
2195 EXPECT_TRUE(matches(
2196 "void x() { if(int* a = 0) {} }",
2197 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2198}
2199
2200TEST(ForEach, BindsOneNode) {
2201 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002202 record(hasName("C"), forEach(field(hasName("x")).bind("x"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002203 new VerifyIdIsBoundToDecl<FieldDecl>("x", 1)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002204}
2205
2206TEST(ForEach, BindsMultipleNodes) {
2207 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002208 record(hasName("C"), forEach(field().bind("f"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002209 new VerifyIdIsBoundToDecl<FieldDecl>("f", 3)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002210}
2211
2212TEST(ForEach, BindsRecursiveCombinations) {
2213 EXPECT_TRUE(matchAndVerifyResultTrue(
2214 "class C { class D { int x; int y; }; class E { int y; int z; }; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002215 record(hasName("C"), forEach(record(forEach(field().bind("f"))))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002216 new VerifyIdIsBoundToDecl<FieldDecl>("f", 4)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002217}
2218
2219TEST(ForEachDescendant, BindsOneNode) {
2220 EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002221 record(hasName("C"), forEachDescendant(field(hasName("x")).bind("x"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002222 new VerifyIdIsBoundToDecl<FieldDecl>("x", 1)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002223}
2224
2225TEST(ForEachDescendant, BindsMultipleNodes) {
2226 EXPECT_TRUE(matchAndVerifyResultTrue(
2227 "class C { class D { int x; int y; }; "
2228 " class E { class F { int y; int z; }; }; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002229 record(hasName("C"), forEachDescendant(field().bind("f"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002230 new VerifyIdIsBoundToDecl<FieldDecl>("f", 4)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002231}
2232
2233TEST(ForEachDescendant, BindsRecursiveCombinations) {
2234 EXPECT_TRUE(matchAndVerifyResultTrue(
2235 "class C { class D { "
2236 " class E { class F { class G { int y; int z; }; }; }; }; };",
2237 record(hasName("C"), forEachDescendant(record(
Manuel Klimek9f174082012-07-24 13:37:29 +00002238 forEachDescendant(field().bind("f"))))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002239 new VerifyIdIsBoundToDecl<FieldDecl>("f", 8)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002240}
2241
2242
2243TEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) {
2244 // Make sure that we can both match the class by name (::X) and by the type
2245 // the template was instantiated with (via a field).
2246
2247 EXPECT_TRUE(matches(
2248 "template <typename T> class X {}; class A {}; X<A> x;",
2249 record(hasName("::X"), isTemplateInstantiation())));
2250
2251 EXPECT_TRUE(matches(
2252 "template <typename T> class X { T t; }; class A {}; X<A> x;",
2253 record(isTemplateInstantiation(), hasDescendant(
2254 field(hasType(record(hasName("A"))))))));
2255}
2256
2257TEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) {
2258 EXPECT_TRUE(matches(
2259 "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
2260 function(hasParameter(0, hasType(record(hasName("A")))),
2261 isTemplateInstantiation())));
2262}
2263
2264TEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) {
2265 EXPECT_TRUE(matches(
2266 "template <typename T> class X { T t; }; class A {};"
2267 "template class X<A>;",
2268 record(isTemplateInstantiation(), hasDescendant(
2269 field(hasType(record(hasName("A"))))))));
2270}
2271
2272TEST(IsTemplateInstantiation,
2273 MatchesInstantiationOfPartiallySpecializedClassTemplate) {
2274 EXPECT_TRUE(matches(
2275 "template <typename T> class X {};"
2276 "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
2277 record(hasName("::X"), isTemplateInstantiation())));
2278}
2279
2280TEST(IsTemplateInstantiation,
2281 MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
2282 EXPECT_TRUE(matches(
2283 "class A {};"
2284 "class X {"
2285 " template <typename U> class Y { U u; };"
2286 " Y<A> y;"
2287 "};",
2288 record(hasName("::X::Y"), isTemplateInstantiation())));
2289}
2290
2291TEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) {
2292 // FIXME: Figure out whether this makes sense. It doesn't affect the
2293 // normal use case as long as the uppermost instantiation always is marked
2294 // as template instantiation, but it might be confusing as a predicate.
2295 EXPECT_TRUE(matches(
2296 "class A {};"
2297 "template <typename T> class X {"
2298 " template <typename U> class Y { U u; };"
2299 " Y<T> y;"
2300 "}; X<A> x;",
2301 record(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
2302}
2303
2304TEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) {
2305 EXPECT_TRUE(notMatches(
2306 "template <typename T> class X {}; class A {};"
2307 "template <> class X<A> {}; X<A> x;",
2308 record(hasName("::X"), isTemplateInstantiation())));
2309}
2310
2311TEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) {
2312 EXPECT_TRUE(notMatches(
2313 "class A {}; class Y { A a; };",
2314 record(isTemplateInstantiation())));
2315}
2316
2317} // end namespace ast_matchers
2318} // end namespace clang