blob: 91095eb3ff1e3f4c1e247b8644da60b510e13993 [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
862TEST(Matcher, CalledVariable) {
863 StatementMatcher CallOnVariableY = expression(
Manuel Klimek9f174082012-07-24 13:37:29 +0000864 memberCall(on(declarationReference(to(variable(hasName("y")))))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000865
866 EXPECT_TRUE(matches(
867 "class Y { public: void x() { Y y; y.x(); } };", CallOnVariableY));
868 EXPECT_TRUE(matches(
869 "class Y { public: void x() const { Y y; y.x(); } };", CallOnVariableY));
870 EXPECT_TRUE(matches(
871 "class Y { public: void x(); };"
872 "class X : public Y { void z() { X y; y.x(); } };", CallOnVariableY));
873 EXPECT_TRUE(matches(
874 "class Y { public: void x(); };"
875 "class X : public Y { void z() { X *y; y->x(); } };", CallOnVariableY));
876 EXPECT_TRUE(notMatches(
877 "class Y { public: void x(); };"
878 "class X : public Y { void z() { unsigned long y; ((X*)y)->x(); } };",
879 CallOnVariableY));
880}
881
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000882TEST(UnaryExprOrTypeTraitExpr, MatchesSizeOfAndAlignOf) {
883 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }",
884 unaryExprOrTypeTraitExpr()));
885 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }",
886 alignOfExpr(anything())));
887 // FIXME: Uncomment once alignof is enabled.
888 // EXPECT_TRUE(matches("void x() { int a = alignof(a); }",
889 // unaryExprOrTypeTraitExpr()));
890 // EXPECT_TRUE(notMatches("void x() { int a = alignof(a); }",
891 // sizeOfExpr()));
892}
893
894TEST(UnaryExpressionOrTypeTraitExpression, MatchesCorrectType) {
895 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }", sizeOfExpr(
896 hasArgumentOfType(asString("int")))));
897 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
898 hasArgumentOfType(asString("float")))));
899 EXPECT_TRUE(matches(
900 "struct A {}; void x() { A a; int b = sizeof(a); }",
901 sizeOfExpr(hasArgumentOfType(hasDeclaration(record(hasName("A")))))));
902 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
903 hasArgumentOfType(hasDeclaration(record(hasName("string")))))));
904}
905
Manuel Klimek4da21662012-07-06 05:48:52 +0000906TEST(MemberExpression, DoesNotMatchClasses) {
907 EXPECT_TRUE(notMatches("class Y { void x() {} };", memberExpression()));
908}
909
910TEST(MemberExpression, MatchesMemberFunctionCall) {
911 EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpression()));
912}
913
914TEST(MemberExpression, MatchesVariable) {
915 EXPECT_TRUE(
916 matches("class Y { void x() { this->y; } int y; };", memberExpression()));
917 EXPECT_TRUE(
918 matches("class Y { void x() { y; } int y; };", memberExpression()));
919 EXPECT_TRUE(
920 matches("class Y { void x() { Y y; y.y; } int y; };",
921 memberExpression()));
922}
923
924TEST(MemberExpression, MatchesStaticVariable) {
925 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
926 memberExpression()));
927 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
928 memberExpression()));
929 EXPECT_TRUE(notMatches("class Y { void x() { Y::y; } static int y; };",
930 memberExpression()));
931}
932
Daniel Jasper6a124492012-07-12 08:50:38 +0000933TEST(IsInteger, MatchesIntegers) {
934 EXPECT_TRUE(matches("int i = 0;", variable(hasType(isInteger()))));
935 EXPECT_TRUE(matches("long long i = 0; void f(long long) { }; void g() {f(i);}",
936 call(hasArgument(0, declarationReference(
937 to(variable(hasType(isInteger()))))))));
938}
939
940TEST(IsInteger, ReportsNoFalsePositives) {
941 EXPECT_TRUE(notMatches("int *i;", variable(hasType(isInteger()))));
942 EXPECT_TRUE(notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}",
943 call(hasArgument(0, declarationReference(
944 to(variable(hasType(isInteger()))))))));
945}
946
Manuel Klimek4da21662012-07-06 05:48:52 +0000947TEST(IsArrow, MatchesMemberVariablesViaArrow) {
948 EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };",
949 memberExpression(isArrow())));
950 EXPECT_TRUE(matches("class Y { void x() { y; } int y; };",
951 memberExpression(isArrow())));
952 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };",
953 memberExpression(isArrow())));
954}
955
956TEST(IsArrow, MatchesStaticMemberVariablesViaArrow) {
957 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
958 memberExpression(isArrow())));
959 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
960 memberExpression(isArrow())));
961 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } static int y; };",
962 memberExpression(isArrow())));
963}
964
965TEST(IsArrow, MatchesMemberCallsViaArrow) {
966 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
967 memberExpression(isArrow())));
968 EXPECT_TRUE(matches("class Y { void x() { x(); } };",
969 memberExpression(isArrow())));
970 EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",
971 memberExpression(isArrow())));
972}
973
974TEST(Callee, MatchesDeclarations) {
975 StatementMatcher CallMethodX = call(callee(method(hasName("x"))));
976
977 EXPECT_TRUE(matches("class Y { void x() { x(); } };", CallMethodX));
978 EXPECT_TRUE(notMatches("class Y { void x() {} };", CallMethodX));
979}
980
981TEST(Callee, MatchesMemberExpressions) {
982 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
983 call(callee(memberExpression()))));
984 EXPECT_TRUE(
985 notMatches("class Y { void x() { this->x(); } };", call(callee(call()))));
986}
987
988TEST(Function, MatchesFunctionDeclarations) {
989 StatementMatcher CallFunctionF = call(callee(function(hasName("f"))));
990
991 EXPECT_TRUE(matches("void f() { f(); }", CallFunctionF));
992 EXPECT_TRUE(notMatches("void f() { }", CallFunctionF));
993
Manuel Klimeke265c872012-07-10 14:21:30 +0000994#if !defined(_MSC_VER)
995 // FIXME: Make this work for MSVC.
Manuel Klimek4da21662012-07-06 05:48:52 +0000996 // Dependent contexts, but a non-dependent call.
997 EXPECT_TRUE(matches("void f(); template <int N> void g() { f(); }",
998 CallFunctionF));
999 EXPECT_TRUE(
1000 matches("void f(); template <int N> struct S { void g() { f(); } };",
1001 CallFunctionF));
Manuel Klimeke265c872012-07-10 14:21:30 +00001002#endif
Manuel Klimek4da21662012-07-06 05:48:52 +00001003
1004 // Depedent calls don't match.
1005 EXPECT_TRUE(
1006 notMatches("void f(int); template <typename T> void g(T t) { f(t); }",
1007 CallFunctionF));
1008 EXPECT_TRUE(
1009 notMatches("void f(int);"
1010 "template <typename T> struct S { void g(T t) { f(t); } };",
1011 CallFunctionF));
1012}
1013
1014TEST(Matcher, Argument) {
1015 StatementMatcher CallArgumentY = expression(call(
1016 hasArgument(0, declarationReference(to(variable(hasName("y")))))));
1017
1018 EXPECT_TRUE(matches("void x(int) { int y; x(y); }", CallArgumentY));
1019 EXPECT_TRUE(
1020 matches("class X { void x(int) { int y; x(y); } };", CallArgumentY));
1021 EXPECT_TRUE(notMatches("void x(int) { int z; x(z); }", CallArgumentY));
1022
1023 StatementMatcher WrongIndex = expression(call(
1024 hasArgument(42, declarationReference(to(variable(hasName("y")))))));
1025 EXPECT_TRUE(notMatches("void x(int) { int y; x(y); }", WrongIndex));
1026}
1027
1028TEST(Matcher, AnyArgument) {
1029 StatementMatcher CallArgumentY = expression(call(
1030 hasAnyArgument(declarationReference(to(variable(hasName("y")))))));
1031 EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
1032 EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
1033 EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
1034}
1035
1036TEST(Matcher, ArgumentCount) {
1037 StatementMatcher Call1Arg = expression(call(argumentCountIs(1)));
1038
1039 EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg));
1040 EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg));
1041 EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg));
1042}
1043
1044TEST(Matcher, References) {
1045 DeclarationMatcher ReferenceClassX = variable(
1046 hasType(references(record(hasName("X")))));
1047 EXPECT_TRUE(matches("class X {}; void y(X y) { X &x = y; }",
1048 ReferenceClassX));
1049 EXPECT_TRUE(
1050 matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
1051 EXPECT_TRUE(
1052 notMatches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
1053 EXPECT_TRUE(
1054 notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
1055}
1056
1057TEST(HasParameter, CallsInnerMatcher) {
1058 EXPECT_TRUE(matches("class X { void x(int) {} };",
1059 method(hasParameter(0, variable()))));
1060 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
1061 method(hasParameter(0, hasName("x")))));
1062}
1063
1064TEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) {
1065 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
1066 method(hasParameter(42, variable()))));
1067}
1068
1069TEST(HasType, MatchesParameterVariableTypesStrictly) {
1070 EXPECT_TRUE(matches("class X { void x(X x) {} };",
1071 method(hasParameter(0, hasType(record(hasName("X")))))));
1072 EXPECT_TRUE(notMatches("class X { void x(const X &x) {} };",
1073 method(hasParameter(0, hasType(record(hasName("X")))))));
1074 EXPECT_TRUE(matches("class X { void x(const X *x) {} };",
1075 method(hasParameter(0, hasType(pointsTo(record(hasName("X"))))))));
1076 EXPECT_TRUE(matches("class X { void x(const X &x) {} };",
1077 method(hasParameter(0, hasType(references(record(hasName("X"))))))));
1078}
1079
1080TEST(HasAnyParameter, MatchesIndependentlyOfPosition) {
1081 EXPECT_TRUE(matches("class Y {}; class X { void x(X x, Y y) {} };",
1082 method(hasAnyParameter(hasType(record(hasName("X")))))));
1083 EXPECT_TRUE(matches("class Y {}; class X { void x(Y y, X x) {} };",
1084 method(hasAnyParameter(hasType(record(hasName("X")))))));
1085}
1086
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001087TEST(Returns, MatchesReturnTypes) {
1088 EXPECT_TRUE(matches("class Y { int f() { return 1; } };",
1089 function(returns(asString("int")))));
1090 EXPECT_TRUE(notMatches("class Y { int f() { return 1; } };",
1091 function(returns(asString("float")))));
1092 EXPECT_TRUE(matches("class Y { Y getMe() { return *this; } };",
1093 function(returns(hasDeclaration(record(hasName("Y")))))));
1094}
1095
Manuel Klimek4da21662012-07-06 05:48:52 +00001096TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
1097 EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
1098 method(hasAnyParameter(hasType(record(hasName("X")))))));
1099}
1100
1101TEST(HasAnyParameter, DoesNotMatchThisPointer) {
1102 EXPECT_TRUE(notMatches("class Y {}; class X { void x() {} };",
1103 method(hasAnyParameter(hasType(pointsTo(record(hasName("X"))))))));
1104}
1105
1106TEST(HasName, MatchesParameterVariableDeclartions) {
1107 EXPECT_TRUE(matches("class Y {}; class X { void x(int x) {} };",
1108 method(hasAnyParameter(hasName("x")))));
1109 EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
1110 method(hasAnyParameter(hasName("x")))));
1111}
1112
1113TEST(Matcher, ConstructorCall) {
1114 StatementMatcher Constructor = expression(constructorCall());
1115
1116 EXPECT_TRUE(
1117 matches("class X { public: X(); }; void x() { X x; }", Constructor));
1118 EXPECT_TRUE(
1119 matches("class X { public: X(); }; void x() { X x = X(); }",
1120 Constructor));
1121 EXPECT_TRUE(
1122 matches("class X { public: X(int); }; void x() { X x = 0; }",
1123 Constructor));
1124 EXPECT_TRUE(matches("class X {}; void x(int) { X x; }", Constructor));
1125}
1126
1127TEST(Matcher, ConstructorArgument) {
1128 StatementMatcher Constructor = expression(constructorCall(
1129 hasArgument(0, declarationReference(to(variable(hasName("y")))))));
1130
1131 EXPECT_TRUE(
1132 matches("class X { public: X(int); }; void x() { int y; X x(y); }",
1133 Constructor));
1134 EXPECT_TRUE(
1135 matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
1136 Constructor));
1137 EXPECT_TRUE(
1138 matches("class X { public: X(int); }; void x() { int y; X x = y; }",
1139 Constructor));
1140 EXPECT_TRUE(
1141 notMatches("class X { public: X(int); }; void x() { int z; X x(z); }",
1142 Constructor));
1143
1144 StatementMatcher WrongIndex = expression(constructorCall(
1145 hasArgument(42, declarationReference(to(variable(hasName("y")))))));
1146 EXPECT_TRUE(
1147 notMatches("class X { public: X(int); }; void x() { int y; X x(y); }",
1148 WrongIndex));
1149}
1150
1151TEST(Matcher, ConstructorArgumentCount) {
1152 StatementMatcher Constructor1Arg =
1153 expression(constructorCall(argumentCountIs(1)));
1154
1155 EXPECT_TRUE(
1156 matches("class X { public: X(int); }; void x() { X x(0); }",
1157 Constructor1Arg));
1158 EXPECT_TRUE(
1159 matches("class X { public: X(int); }; void x() { X x = X(0); }",
1160 Constructor1Arg));
1161 EXPECT_TRUE(
1162 matches("class X { public: X(int); }; void x() { X x = 0; }",
1163 Constructor1Arg));
1164 EXPECT_TRUE(
1165 notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
1166 Constructor1Arg));
1167}
1168
1169TEST(Matcher, BindTemporaryExpression) {
1170 StatementMatcher TempExpression = expression(bindTemporaryExpression());
1171
1172 std::string ClassString = "class string { public: string(); ~string(); }; ";
1173
1174 EXPECT_TRUE(
1175 matches(ClassString +
1176 "string GetStringByValue();"
1177 "void FunctionTakesString(string s);"
1178 "void run() { FunctionTakesString(GetStringByValue()); }",
1179 TempExpression));
1180
1181 EXPECT_TRUE(
1182 notMatches(ClassString +
1183 "string* GetStringPointer(); "
1184 "void FunctionTakesStringPtr(string* s);"
1185 "void run() {"
1186 " string* s = GetStringPointer();"
1187 " FunctionTakesStringPtr(GetStringPointer());"
1188 " FunctionTakesStringPtr(s);"
1189 "}",
1190 TempExpression));
1191
1192 EXPECT_TRUE(
1193 notMatches("class no_dtor {};"
1194 "no_dtor GetObjByValue();"
1195 "void ConsumeObj(no_dtor param);"
1196 "void run() { ConsumeObj(GetObjByValue()); }",
1197 TempExpression));
1198}
1199
1200TEST(ConstructorDeclaration, SimpleCase) {
1201 EXPECT_TRUE(matches("class Foo { Foo(int i); };",
1202 constructor(ofClass(hasName("Foo")))));
1203 EXPECT_TRUE(notMatches("class Foo { Foo(int i); };",
1204 constructor(ofClass(hasName("Bar")))));
1205}
1206
1207TEST(ConstructorDeclaration, IsImplicit) {
1208 // This one doesn't match because the constructor is not added by the
1209 // compiler (it is not needed).
1210 EXPECT_TRUE(notMatches("class Foo { };",
1211 constructor(isImplicit())));
1212 // The compiler added the implicit default constructor.
1213 EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
1214 constructor(isImplicit())));
1215 EXPECT_TRUE(matches("class Foo { Foo(){} };",
1216 constructor(unless(isImplicit()))));
1217}
1218
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001219TEST(DestructorDeclaration, MatchesVirtualDestructor) {
1220 EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };",
1221 destructor(ofClass(hasName("Foo")))));
1222}
1223
1224TEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) {
1225 EXPECT_TRUE(notMatches("class Foo {};", destructor(ofClass(hasName("Foo")))));
1226}
1227
Manuel Klimek4da21662012-07-06 05:48:52 +00001228TEST(HasAnyConstructorInitializer, SimpleCase) {
1229 EXPECT_TRUE(notMatches(
1230 "class Foo { Foo() { } };",
1231 constructor(hasAnyConstructorInitializer(anything()))));
1232 EXPECT_TRUE(matches(
1233 "class Foo {"
1234 " Foo() : foo_() { }"
1235 " int foo_;"
1236 "};",
1237 constructor(hasAnyConstructorInitializer(anything()))));
1238}
1239
1240TEST(HasAnyConstructorInitializer, ForField) {
1241 static const char Code[] =
1242 "class Baz { };"
1243 "class Foo {"
1244 " Foo() : foo_() { }"
1245 " Baz foo_;"
1246 " Baz bar_;"
1247 "};";
1248 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1249 forField(hasType(record(hasName("Baz"))))))));
1250 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1251 forField(hasName("foo_"))))));
1252 EXPECT_TRUE(notMatches(Code, constructor(hasAnyConstructorInitializer(
1253 forField(hasType(record(hasName("Bar"))))))));
1254}
1255
1256TEST(HasAnyConstructorInitializer, WithInitializer) {
1257 static const char Code[] =
1258 "class Foo {"
1259 " Foo() : foo_(0) { }"
1260 " int foo_;"
1261 "};";
1262 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1263 withInitializer(integerLiteral(equals(0)))))));
1264 EXPECT_TRUE(notMatches(Code, constructor(hasAnyConstructorInitializer(
1265 withInitializer(integerLiteral(equals(1)))))));
1266}
1267
1268TEST(HasAnyConstructorInitializer, IsWritten) {
1269 static const char Code[] =
1270 "struct Bar { Bar(){} };"
1271 "class Foo {"
1272 " Foo() : foo_() { }"
1273 " Bar foo_;"
1274 " Bar bar_;"
1275 "};";
1276 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1277 allOf(forField(hasName("foo_")), isWritten())))));
1278 EXPECT_TRUE(notMatches(Code, constructor(hasAnyConstructorInitializer(
1279 allOf(forField(hasName("bar_")), isWritten())))));
1280 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1281 allOf(forField(hasName("bar_")), unless(isWritten()))))));
1282}
1283
1284TEST(Matcher, NewExpression) {
1285 StatementMatcher New = expression(newExpression());
1286
1287 EXPECT_TRUE(matches("class X { public: X(); }; void x() { new X; }", New));
1288 EXPECT_TRUE(
1289 matches("class X { public: X(); }; void x() { new X(); }", New));
1290 EXPECT_TRUE(
1291 matches("class X { public: X(int); }; void x() { new X(0); }", New));
1292 EXPECT_TRUE(matches("class X {}; void x(int) { new X; }", New));
1293}
1294
1295TEST(Matcher, NewExpressionArgument) {
1296 StatementMatcher New = expression(constructorCall(
1297 hasArgument(
1298 0, declarationReference(to(variable(hasName("y")))))));
1299
1300 EXPECT_TRUE(
1301 matches("class X { public: X(int); }; void x() { int y; new X(y); }",
1302 New));
1303 EXPECT_TRUE(
1304 matches("class X { public: X(int); }; void x() { int y; new X(y); }",
1305 New));
1306 EXPECT_TRUE(
1307 notMatches("class X { public: X(int); }; void x() { int z; new X(z); }",
1308 New));
1309
1310 StatementMatcher WrongIndex = expression(constructorCall(
1311 hasArgument(
1312 42, declarationReference(to(variable(hasName("y")))))));
1313 EXPECT_TRUE(
1314 notMatches("class X { public: X(int); }; void x() { int y; new X(y); }",
1315 WrongIndex));
1316}
1317
1318TEST(Matcher, NewExpressionArgumentCount) {
1319 StatementMatcher New = constructorCall(argumentCountIs(1));
1320
1321 EXPECT_TRUE(
1322 matches("class X { public: X(int); }; void x() { new X(0); }", New));
1323 EXPECT_TRUE(
1324 notMatches("class X { public: X(int, int); }; void x() { new X(0, 0); }",
1325 New));
1326}
1327
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001328TEST(Matcher, DeleteExpression) {
1329 EXPECT_TRUE(matches("struct A {}; void f(A* a) { delete a; }",
1330 deleteExpression()));
1331}
1332
Manuel Klimek4da21662012-07-06 05:48:52 +00001333TEST(Matcher, DefaultArgument) {
1334 StatementMatcher Arg = defaultArgument();
1335
1336 EXPECT_TRUE(matches("void x(int, int = 0) { int y; x(y); }", Arg));
1337 EXPECT_TRUE(
1338 matches("class X { void x(int, int = 0) { int y; x(y); } };", Arg));
1339 EXPECT_TRUE(notMatches("void x(int, int = 0) { int y; x(y, 0); }", Arg));
1340}
1341
1342TEST(Matcher, StringLiterals) {
1343 StatementMatcher Literal = expression(stringLiteral());
1344 EXPECT_TRUE(matches("const char *s = \"string\";", Literal));
1345 // wide string
1346 EXPECT_TRUE(matches("const wchar_t *s = L\"string\";", Literal));
1347 // with escaped characters
1348 EXPECT_TRUE(matches("const char *s = \"\x05five\";", Literal));
1349 // no matching -- though the data type is the same, there is no string literal
1350 EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));
1351}
1352
1353TEST(Matcher, CharacterLiterals) {
1354 StatementMatcher CharLiteral = expression(characterLiteral());
1355 EXPECT_TRUE(matches("const char c = 'c';", CharLiteral));
1356 // wide character
1357 EXPECT_TRUE(matches("const char c = L'c';", CharLiteral));
1358 // wide character, Hex encoded, NOT MATCHED!
1359 EXPECT_TRUE(notMatches("const wchar_t c = 0x2126;", CharLiteral));
1360 EXPECT_TRUE(notMatches("const char c = 0x1;", CharLiteral));
1361}
1362
1363TEST(Matcher, IntegerLiterals) {
1364 StatementMatcher HasIntLiteral = expression(integerLiteral());
1365 EXPECT_TRUE(matches("int i = 10;", HasIntLiteral));
1366 EXPECT_TRUE(matches("int i = 0x1AB;", HasIntLiteral));
1367 EXPECT_TRUE(matches("int i = 10L;", HasIntLiteral));
1368 EXPECT_TRUE(matches("int i = 10U;", HasIntLiteral));
1369
1370 // Non-matching cases (character literals, float and double)
1371 EXPECT_TRUE(notMatches("int i = L'a';",
1372 HasIntLiteral)); // this is actually a character
1373 // literal cast to int
1374 EXPECT_TRUE(notMatches("int i = 'a';", HasIntLiteral));
1375 EXPECT_TRUE(notMatches("int i = 1e10;", HasIntLiteral));
1376 EXPECT_TRUE(notMatches("int i = 10.0;", HasIntLiteral));
1377}
1378
1379TEST(Matcher, Conditions) {
1380 StatementMatcher Condition = ifStmt(hasCondition(boolLiteral(equals(true))));
1381
1382 EXPECT_TRUE(matches("void x() { if (true) {} }", Condition));
1383 EXPECT_TRUE(notMatches("void x() { if (false) {} }", Condition));
1384 EXPECT_TRUE(notMatches("void x() { bool a = true; if (a) {} }", Condition));
1385 EXPECT_TRUE(notMatches("void x() { if (true || false) {} }", Condition));
1386 EXPECT_TRUE(notMatches("void x() { if (1) {} }", Condition));
1387}
1388
1389TEST(MatchBinaryOperator, HasOperatorName) {
1390 StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
1391
1392 EXPECT_TRUE(matches("void x() { true || false; }", OperatorOr));
1393 EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
1394}
1395
1396TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
1397 StatementMatcher OperatorTrueFalse =
1398 binaryOperator(hasLHS(boolLiteral(equals(true))),
1399 hasRHS(boolLiteral(equals(false))));
1400
1401 EXPECT_TRUE(matches("void x() { true || false; }", OperatorTrueFalse));
1402 EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse));
1403 EXPECT_TRUE(notMatches("void x() { false || true; }", OperatorTrueFalse));
1404}
1405
1406TEST(MatchBinaryOperator, HasEitherOperand) {
1407 StatementMatcher HasOperand =
1408 binaryOperator(hasEitherOperand(boolLiteral(equals(false))));
1409
1410 EXPECT_TRUE(matches("void x() { true || false; }", HasOperand));
1411 EXPECT_TRUE(matches("void x() { false && true; }", HasOperand));
1412 EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand));
1413}
1414
1415TEST(Matcher, BinaryOperatorTypes) {
1416 // Integration test that verifies the AST provides all binary operators in
1417 // a way we expect.
1418 // FIXME: Operator ','
1419 EXPECT_TRUE(
1420 matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(","))));
1421 EXPECT_TRUE(
1422 matches("bool b; bool c = (b = true);",
1423 binaryOperator(hasOperatorName("="))));
1424 EXPECT_TRUE(
1425 matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!="))));
1426 EXPECT_TRUE(
1427 matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("=="))));
1428 EXPECT_TRUE(matches("bool b = 1 < 2;", binaryOperator(hasOperatorName("<"))));
1429 EXPECT_TRUE(
1430 matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<="))));
1431 EXPECT_TRUE(
1432 matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<"))));
1433 EXPECT_TRUE(
1434 matches("int i = 1; int j = (i <<= 2);",
1435 binaryOperator(hasOperatorName("<<="))));
1436 EXPECT_TRUE(matches("bool b = 1 > 2;", binaryOperator(hasOperatorName(">"))));
1437 EXPECT_TRUE(
1438 matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">="))));
1439 EXPECT_TRUE(
1440 matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>"))));
1441 EXPECT_TRUE(
1442 matches("int i = 1; int j = (i >>= 2);",
1443 binaryOperator(hasOperatorName(">>="))));
1444 EXPECT_TRUE(
1445 matches("int i = 42 ^ 23;", binaryOperator(hasOperatorName("^"))));
1446 EXPECT_TRUE(
1447 matches("int i = 42; int j = (i ^= 42);",
1448 binaryOperator(hasOperatorName("^="))));
1449 EXPECT_TRUE(
1450 matches("int i = 42 % 23;", binaryOperator(hasOperatorName("%"))));
1451 EXPECT_TRUE(
1452 matches("int i = 42; int j = (i %= 42);",
1453 binaryOperator(hasOperatorName("%="))));
1454 EXPECT_TRUE(
1455 matches("bool b = 42 &23;", binaryOperator(hasOperatorName("&"))));
1456 EXPECT_TRUE(
1457 matches("bool b = true && false;",
1458 binaryOperator(hasOperatorName("&&"))));
1459 EXPECT_TRUE(
1460 matches("bool b = true; bool c = (b &= false);",
1461 binaryOperator(hasOperatorName("&="))));
1462 EXPECT_TRUE(
1463 matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|"))));
1464 EXPECT_TRUE(
1465 matches("bool b = true || false;",
1466 binaryOperator(hasOperatorName("||"))));
1467 EXPECT_TRUE(
1468 matches("bool b = true; bool c = (b |= false);",
1469 binaryOperator(hasOperatorName("|="))));
1470 EXPECT_TRUE(
1471 matches("int i = 42 *23;", binaryOperator(hasOperatorName("*"))));
1472 EXPECT_TRUE(
1473 matches("int i = 42; int j = (i *= 23);",
1474 binaryOperator(hasOperatorName("*="))));
1475 EXPECT_TRUE(
1476 matches("int i = 42 / 23;", binaryOperator(hasOperatorName("/"))));
1477 EXPECT_TRUE(
1478 matches("int i = 42; int j = (i /= 23);",
1479 binaryOperator(hasOperatorName("/="))));
1480 EXPECT_TRUE(
1481 matches("int i = 42 + 23;", binaryOperator(hasOperatorName("+"))));
1482 EXPECT_TRUE(
1483 matches("int i = 42; int j = (i += 23);",
1484 binaryOperator(hasOperatorName("+="))));
1485 EXPECT_TRUE(
1486 matches("int i = 42 - 23;", binaryOperator(hasOperatorName("-"))));
1487 EXPECT_TRUE(
1488 matches("int i = 42; int j = (i -= 23);",
1489 binaryOperator(hasOperatorName("-="))));
1490 EXPECT_TRUE(
1491 matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };",
1492 binaryOperator(hasOperatorName("->*"))));
1493 EXPECT_TRUE(
1494 matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };",
1495 binaryOperator(hasOperatorName(".*"))));
1496
1497 // Member expressions as operators are not supported in matches.
1498 EXPECT_TRUE(
1499 notMatches("struct A { void x(A *a) { a->x(this); } };",
1500 binaryOperator(hasOperatorName("->"))));
1501
1502 // Initializer assignments are not represented as operator equals.
1503 EXPECT_TRUE(
1504 notMatches("bool b = true;", binaryOperator(hasOperatorName("="))));
1505
1506 // Array indexing is not represented as operator.
1507 EXPECT_TRUE(notMatches("int a[42]; void x() { a[23]; }", unaryOperator()));
1508
1509 // Overloaded operators do not match at all.
1510 EXPECT_TRUE(notMatches(
1511 "struct A { bool operator&&(const A &a) const { return false; } };"
1512 "void x() { A a, b; a && b; }",
1513 binaryOperator()));
1514}
1515
1516TEST(MatchUnaryOperator, HasOperatorName) {
1517 StatementMatcher OperatorNot = unaryOperator(hasOperatorName("!"));
1518
1519 EXPECT_TRUE(matches("void x() { !true; } ", OperatorNot));
1520 EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
1521}
1522
1523TEST(MatchUnaryOperator, HasUnaryOperand) {
1524 StatementMatcher OperatorOnFalse =
1525 unaryOperator(hasUnaryOperand(boolLiteral(equals(false))));
1526
1527 EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse));
1528 EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse));
1529}
1530
1531TEST(Matcher, UnaryOperatorTypes) {
1532 // Integration test that verifies the AST provides all unary operators in
1533 // a way we expect.
1534 EXPECT_TRUE(matches("bool b = !true;", unaryOperator(hasOperatorName("!"))));
1535 EXPECT_TRUE(
1536 matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&"))));
1537 EXPECT_TRUE(matches("int i = ~ 1;", unaryOperator(hasOperatorName("~"))));
1538 EXPECT_TRUE(
1539 matches("bool *p; bool b = *p;", unaryOperator(hasOperatorName("*"))));
1540 EXPECT_TRUE(
1541 matches("int i; int j = +i;", unaryOperator(hasOperatorName("+"))));
1542 EXPECT_TRUE(
1543 matches("int i; int j = -i;", unaryOperator(hasOperatorName("-"))));
1544 EXPECT_TRUE(
1545 matches("int i; int j = ++i;", unaryOperator(hasOperatorName("++"))));
1546 EXPECT_TRUE(
1547 matches("int i; int j = i++;", unaryOperator(hasOperatorName("++"))));
1548 EXPECT_TRUE(
1549 matches("int i; int j = --i;", unaryOperator(hasOperatorName("--"))));
1550 EXPECT_TRUE(
1551 matches("int i; int j = i--;", unaryOperator(hasOperatorName("--"))));
1552
1553 // We don't match conversion operators.
1554 EXPECT_TRUE(notMatches("int i; double d = (double)i;", unaryOperator()));
1555
1556 // Function calls are not represented as operator.
1557 EXPECT_TRUE(notMatches("void f(); void x() { f(); }", unaryOperator()));
1558
1559 // Overloaded operators do not match at all.
1560 // FIXME: We probably want to add that.
1561 EXPECT_TRUE(notMatches(
1562 "struct A { bool operator!() const { return false; } };"
1563 "void x() { A a; !a; }", unaryOperator(hasOperatorName("!"))));
1564}
1565
1566TEST(Matcher, ConditionalOperator) {
1567 StatementMatcher Conditional = conditionalOperator(
1568 hasCondition(boolLiteral(equals(true))),
1569 hasTrueExpression(boolLiteral(equals(false))));
1570
1571 EXPECT_TRUE(matches("void x() { true ? false : true; }", Conditional));
1572 EXPECT_TRUE(notMatches("void x() { false ? false : true; }", Conditional));
1573 EXPECT_TRUE(notMatches("void x() { true ? true : false; }", Conditional));
1574
1575 StatementMatcher ConditionalFalse = conditionalOperator(
1576 hasFalseExpression(boolLiteral(equals(false))));
1577
1578 EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
1579 EXPECT_TRUE(
1580 notMatches("void x() { true ? false : true; }", ConditionalFalse));
1581}
1582
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001583TEST(ArraySubscriptMatchers, ArraySubscripts) {
1584 EXPECT_TRUE(matches("int i[2]; void f() { i[1] = 1; }",
1585 arraySubscriptExpr()));
1586 EXPECT_TRUE(notMatches("int i; void f() { i = 1; }",
1587 arraySubscriptExpr()));
1588}
1589
1590TEST(ArraySubscriptMatchers, ArrayIndex) {
1591 EXPECT_TRUE(matches(
1592 "int i[2]; void f() { i[1] = 1; }",
1593 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
1594 EXPECT_TRUE(matches(
1595 "int i[2]; void f() { 1[i] = 1; }",
1596 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
1597 EXPECT_TRUE(notMatches(
1598 "int i[2]; void f() { i[1] = 1; }",
1599 arraySubscriptExpr(hasIndex(integerLiteral(equals(0))))));
1600}
1601
1602TEST(ArraySubscriptMatchers, MatchesArrayBase) {
1603 EXPECT_TRUE(matches(
1604 "int i[2]; void f() { i[1] = 2; }",
1605 arraySubscriptExpr(hasBase(implicitCast(
1606 hasSourceExpression(declarationReference()))))));
1607}
1608
Manuel Klimek4da21662012-07-06 05:48:52 +00001609TEST(Matcher, HasNameSupportsNamespaces) {
1610 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1611 record(hasName("a::b::C"))));
1612 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1613 record(hasName("::a::b::C"))));
1614 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1615 record(hasName("b::C"))));
1616 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1617 record(hasName("C"))));
1618 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1619 record(hasName("c::b::C"))));
1620 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1621 record(hasName("a::c::C"))));
1622 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1623 record(hasName("a::b::A"))));
1624 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1625 record(hasName("::C"))));
1626 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1627 record(hasName("::b::C"))));
1628 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1629 record(hasName("z::a::b::C"))));
1630 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1631 record(hasName("a+b::C"))));
1632 EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
1633 record(hasName("C"))));
1634}
1635
1636TEST(Matcher, HasNameSupportsOuterClasses) {
1637 EXPECT_TRUE(
1638 matches("class A { class B { class C; }; };", record(hasName("A::B::C"))));
1639 EXPECT_TRUE(
1640 matches("class A { class B { class C; }; };",
1641 record(hasName("::A::B::C"))));
1642 EXPECT_TRUE(
1643 matches("class A { class B { class C; }; };", record(hasName("B::C"))));
1644 EXPECT_TRUE(
1645 matches("class A { class B { class C; }; };", record(hasName("C"))));
1646 EXPECT_TRUE(
1647 notMatches("class A { class B { class C; }; };",
1648 record(hasName("c::B::C"))));
1649 EXPECT_TRUE(
1650 notMatches("class A { class B { class C; }; };",
1651 record(hasName("A::c::C"))));
1652 EXPECT_TRUE(
1653 notMatches("class A { class B { class C; }; };",
1654 record(hasName("A::B::A"))));
1655 EXPECT_TRUE(
1656 notMatches("class A { class B { class C; }; };", record(hasName("::C"))));
1657 EXPECT_TRUE(
1658 notMatches("class A { class B { class C; }; };",
1659 record(hasName("::B::C"))));
1660 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
1661 record(hasName("z::A::B::C"))));
1662 EXPECT_TRUE(
1663 notMatches("class A { class B { class C; }; };",
1664 record(hasName("A+B::C"))));
1665}
1666
1667TEST(Matcher, IsDefinition) {
1668 DeclarationMatcher DefinitionOfClassA =
1669 record(hasName("A"), isDefinition());
1670 EXPECT_TRUE(matches("class A {};", DefinitionOfClassA));
1671 EXPECT_TRUE(notMatches("class A;", DefinitionOfClassA));
1672
1673 DeclarationMatcher DefinitionOfVariableA =
1674 variable(hasName("a"), isDefinition());
1675 EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));
1676 EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));
1677
1678 DeclarationMatcher DefinitionOfMethodA =
1679 method(hasName("a"), isDefinition());
1680 EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));
1681 EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));
1682}
1683
1684TEST(Matcher, OfClass) {
1685 StatementMatcher Constructor = constructorCall(hasDeclaration(method(
1686 ofClass(hasName("X")))));
1687
1688 EXPECT_TRUE(
1689 matches("class X { public: X(); }; void x(int) { X x; }", Constructor));
1690 EXPECT_TRUE(
1691 matches("class X { public: X(); }; void x(int) { X x = X(); }",
1692 Constructor));
1693 EXPECT_TRUE(
1694 notMatches("class Y { public: Y(); }; void x(int) { Y y; }",
1695 Constructor));
1696}
1697
1698TEST(Matcher, VisitsTemplateInstantiations) {
1699 EXPECT_TRUE(matches(
1700 "class A { public: void x(); };"
1701 "template <typename T> class B { public: void y() { T t; t.x(); } };"
1702 "void f() { B<A> b; b.y(); }", call(callee(method(hasName("x"))))));
1703
1704 EXPECT_TRUE(matches(
1705 "class A { public: void x(); };"
1706 "class C {"
1707 " public:"
1708 " template <typename T> class B { public: void y() { T t; t.x(); } };"
1709 "};"
1710 "void f() {"
1711 " C::B<A> b; b.y();"
1712 "}", record(hasName("C"),
1713 hasDescendant(call(callee(method(hasName("x"))))))));
1714}
1715
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001716TEST(Matcher, HandlesNullQualTypes) {
1717 // FIXME: Add a Type matcher so we can replace uses of this
1718 // variable with Type(True())
1719 const TypeMatcher AnyType = anything();
1720
1721 // We don't really care whether this matcher succeeds; we're testing that
1722 // it completes without crashing.
1723 EXPECT_TRUE(matches(
1724 "struct A { };"
1725 "template <typename T>"
1726 "void f(T t) {"
1727 " T local_t(t /* this becomes a null QualType in the AST */);"
1728 "}"
1729 "void g() {"
1730 " f(0);"
1731 "}",
1732 expression(hasType(TypeMatcher(
1733 anyOf(
1734 TypeMatcher(hasDeclaration(anything())),
1735 pointsTo(AnyType),
1736 references(AnyType)
1737 // Other QualType matchers should go here.
1738 ))))));
1739}
1740
Manuel Klimek4da21662012-07-06 05:48:52 +00001741// For testing AST_MATCHER_P().
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001742AST_MATCHER_P(Decl, just, internal::Matcher<Decl>, AMatcher) {
Manuel Klimek4da21662012-07-06 05:48:52 +00001743 // Make sure all special variables are used: node, match_finder,
1744 // bound_nodes_builder, and the parameter named 'AMatcher'.
1745 return AMatcher.matches(Node, Finder, Builder);
1746}
1747
1748TEST(AstMatcherPMacro, Works) {
Manuel Klimek9f174082012-07-24 13:37:29 +00001749 DeclarationMatcher HasClassB = just(has(record(hasName("B")).bind("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001750
1751 EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001752 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001753
1754 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001755 HasClassB, new VerifyIdIsBoundToDecl<Decl>("a")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001756
1757 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001758 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001759}
1760
1761AST_POLYMORPHIC_MATCHER_P(
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001762 polymorphicHas, internal::Matcher<Decl>, AMatcher) {
1763 TOOLING_COMPILE_ASSERT((llvm::is_same<NodeType, Decl>::value) ||
1764 (llvm::is_same<NodeType, Stmt>::value),
Manuel Klimek4da21662012-07-06 05:48:52 +00001765 assert_node_type_is_accessible);
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001766 internal::TypedBaseMatcher<Decl> ChildMatcher(AMatcher);
Manuel Klimek4da21662012-07-06 05:48:52 +00001767 return Finder->matchesChildOf(
1768 Node, ChildMatcher, Builder,
1769 ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
1770 ASTMatchFinder::BK_First);
1771}
1772
1773TEST(AstPolymorphicMatcherPMacro, Works) {
Manuel Klimek9f174082012-07-24 13:37:29 +00001774 DeclarationMatcher HasClassB = polymorphicHas(record(hasName("B")).bind("b"));
Manuel Klimek4da21662012-07-06 05:48:52 +00001775
1776 EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001777 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001778
1779 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001780 HasClassB, new VerifyIdIsBoundToDecl<Decl>("a")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001781
1782 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001783 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001784
1785 StatementMatcher StatementHasClassB =
1786 polymorphicHas(record(hasName("B")));
1787
1788 EXPECT_TRUE(matches("void x() { class B {}; }", StatementHasClassB));
1789}
1790
1791TEST(For, FindsForLoops) {
1792 EXPECT_TRUE(matches("void f() { for(;;); }", forStmt()));
1793 EXPECT_TRUE(matches("void f() { if(true) for(;;); }", forStmt()));
1794}
1795
Daniel Jasper6a124492012-07-12 08:50:38 +00001796TEST(For, ForLoopInternals) {
1797 EXPECT_TRUE(matches("void f(){ int i; for (; i < 3 ; ); }",
1798 forStmt(hasCondition(anything()))));
1799 EXPECT_TRUE(matches("void f() { for (int i = 0; ;); }",
1800 forStmt(hasLoopInit(anything()))));
1801}
1802
1803TEST(For, NegativeForLoopInternals) {
1804 EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }",
1805 forStmt(hasCondition(expression()))));
1806 EXPECT_TRUE(notMatches("void f() {int i; for (; i < 4; ++i) {} }",
1807 forStmt(hasLoopInit(anything()))));
1808}
1809
Manuel Klimek4da21662012-07-06 05:48:52 +00001810TEST(For, ReportsNoFalsePositives) {
1811 EXPECT_TRUE(notMatches("void f() { ; }", forStmt()));
1812 EXPECT_TRUE(notMatches("void f() { if(true); }", forStmt()));
1813}
1814
1815TEST(CompoundStatement, HandlesSimpleCases) {
1816 EXPECT_TRUE(notMatches("void f();", compoundStatement()));
1817 EXPECT_TRUE(matches("void f() {}", compoundStatement()));
1818 EXPECT_TRUE(matches("void f() {{}}", compoundStatement()));
1819}
1820
1821TEST(CompoundStatement, DoesNotMatchEmptyStruct) {
1822 // It's not a compound statement just because there's "{}" in the source
1823 // text. This is an AST search, not grep.
1824 EXPECT_TRUE(notMatches("namespace n { struct S {}; }",
1825 compoundStatement()));
1826 EXPECT_TRUE(matches("namespace n { struct S { void f() {{}} }; }",
1827 compoundStatement()));
1828}
1829
Daniel Jasper6a124492012-07-12 08:50:38 +00001830TEST(HasBody, FindsBodyOfForWhileDoLoops) {
Manuel Klimek4da21662012-07-06 05:48:52 +00001831 EXPECT_TRUE(matches("void f() { for(;;) {} }",
Daniel Jasper6a124492012-07-12 08:50:38 +00001832 forStmt(hasBody(compoundStatement()))));
Manuel Klimek4da21662012-07-06 05:48:52 +00001833 EXPECT_TRUE(notMatches("void f() { for(;;); }",
Daniel Jasper6a124492012-07-12 08:50:38 +00001834 forStmt(hasBody(compoundStatement()))));
1835 EXPECT_TRUE(matches("void f() { while(true) {} }",
1836 whileStmt(hasBody(compoundStatement()))));
1837 EXPECT_TRUE(matches("void f() { do {} while(true); }",
1838 doStmt(hasBody(compoundStatement()))));
Manuel Klimek4da21662012-07-06 05:48:52 +00001839}
1840
1841TEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
1842 // The simplest case: every compound statement is in a function
1843 // definition, and the function body itself must be a compound
1844 // statement.
1845 EXPECT_TRUE(matches("void f() { for (;;); }",
1846 compoundStatement(hasAnySubstatement(forStmt()))));
1847}
1848
1849TEST(HasAnySubstatement, IsNotRecursive) {
1850 // It's really "has any immediate substatement".
1851 EXPECT_TRUE(notMatches("void f() { if (true) for (;;); }",
1852 compoundStatement(hasAnySubstatement(forStmt()))));
1853}
1854
1855TEST(HasAnySubstatement, MatchesInNestedCompoundStatements) {
1856 EXPECT_TRUE(matches("void f() { if (true) { for (;;); } }",
1857 compoundStatement(hasAnySubstatement(forStmt()))));
1858}
1859
1860TEST(HasAnySubstatement, FindsSubstatementBetweenOthers) {
1861 EXPECT_TRUE(matches("void f() { 1; 2; 3; for (;;); 4; 5; 6; }",
1862 compoundStatement(hasAnySubstatement(forStmt()))));
1863}
1864
1865TEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) {
1866 EXPECT_TRUE(matches("void f() { }",
1867 compoundStatement(statementCountIs(0))));
1868 EXPECT_TRUE(notMatches("void f() {}",
1869 compoundStatement(statementCountIs(1))));
1870}
1871
1872TEST(StatementCountIs, AppearsToMatchOnlyOneCount) {
1873 EXPECT_TRUE(matches("void f() { 1; }",
1874 compoundStatement(statementCountIs(1))));
1875 EXPECT_TRUE(notMatches("void f() { 1; }",
1876 compoundStatement(statementCountIs(0))));
1877 EXPECT_TRUE(notMatches("void f() { 1; }",
1878 compoundStatement(statementCountIs(2))));
1879}
1880
1881TEST(StatementCountIs, WorksWithMultipleStatements) {
1882 EXPECT_TRUE(matches("void f() { 1; 2; 3; }",
1883 compoundStatement(statementCountIs(3))));
1884}
1885
1886TEST(StatementCountIs, WorksWithNestedCompoundStatements) {
1887 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1888 compoundStatement(statementCountIs(1))));
1889 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1890 compoundStatement(statementCountIs(2))));
1891 EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
1892 compoundStatement(statementCountIs(3))));
1893 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1894 compoundStatement(statementCountIs(4))));
1895}
1896
1897TEST(Member, WorksInSimplestCase) {
1898 EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
1899 memberExpression(member(hasName("first")))));
1900}
1901
1902TEST(Member, DoesNotMatchTheBaseExpression) {
1903 // Don't pick out the wrong part of the member expression, this should
1904 // be checking the member (name) only.
1905 EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
1906 memberExpression(member(hasName("first")))));
1907}
1908
1909TEST(Member, MatchesInMemberFunctionCall) {
1910 EXPECT_TRUE(matches("void f() {"
1911 " struct { void first() {}; } s;"
1912 " s.first();"
1913 "};",
1914 memberExpression(member(hasName("first")))));
1915}
1916
1917TEST(HasObjectExpression, DoesNotMatchMember) {
1918 EXPECT_TRUE(notMatches(
1919 "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
1920 memberExpression(hasObjectExpression(hasType(record(hasName("X")))))));
1921}
1922
1923TEST(HasObjectExpression, MatchesBaseOfVariable) {
1924 EXPECT_TRUE(matches(
1925 "struct X { int m; }; void f(X x) { x.m; }",
1926 memberExpression(hasObjectExpression(hasType(record(hasName("X")))))));
1927 EXPECT_TRUE(matches(
1928 "struct X { int m; }; void f(X* x) { x->m; }",
1929 memberExpression(hasObjectExpression(
1930 hasType(pointsTo(record(hasName("X"))))))));
1931}
1932
1933TEST(HasObjectExpression,
1934 MatchesObjectExpressionOfImplicitlyFormedMemberExpression) {
1935 EXPECT_TRUE(matches(
1936 "class X {}; struct S { X m; void f() { this->m; } };",
1937 memberExpression(hasObjectExpression(
1938 hasType(pointsTo(record(hasName("S"))))))));
1939 EXPECT_TRUE(matches(
1940 "class X {}; struct S { X m; void f() { m; } };",
1941 memberExpression(hasObjectExpression(
1942 hasType(pointsTo(record(hasName("S"))))))));
1943}
1944
1945TEST(Field, DoesNotMatchNonFieldMembers) {
1946 EXPECT_TRUE(notMatches("class X { void m(); };", field(hasName("m"))));
1947 EXPECT_TRUE(notMatches("class X { class m {}; };", field(hasName("m"))));
1948 EXPECT_TRUE(notMatches("class X { enum { m }; };", field(hasName("m"))));
1949 EXPECT_TRUE(notMatches("class X { enum m {}; };", field(hasName("m"))));
1950}
1951
1952TEST(Field, MatchesField) {
1953 EXPECT_TRUE(matches("class X { int m; };", field(hasName("m"))));
1954}
1955
1956TEST(IsConstQualified, MatchesConstInt) {
1957 EXPECT_TRUE(matches("const int i = 42;",
1958 variable(hasType(isConstQualified()))));
1959}
1960
1961TEST(IsConstQualified, MatchesConstPointer) {
1962 EXPECT_TRUE(matches("int i = 42; int* const p(&i);",
1963 variable(hasType(isConstQualified()))));
1964}
1965
1966TEST(IsConstQualified, MatchesThroughTypedef) {
1967 EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
1968 variable(hasType(isConstQualified()))));
1969 EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p(0);",
1970 variable(hasType(isConstQualified()))));
1971}
1972
1973TEST(IsConstQualified, DoesNotMatchInappropriately) {
1974 EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
1975 variable(hasType(isConstQualified()))));
1976 EXPECT_TRUE(notMatches("int const* p;",
1977 variable(hasType(isConstQualified()))));
1978}
1979
1980TEST(ReinterpretCast, MatchesSimpleCase) {
1981 EXPECT_TRUE(matches("char* p = reinterpret_cast<char*>(&p);",
1982 expression(reinterpretCast())));
1983}
1984
1985TEST(ReinterpretCast, DoesNotMatchOtherCasts) {
1986 EXPECT_TRUE(notMatches("char* p = (char*)(&p);",
1987 expression(reinterpretCast())));
1988 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
1989 expression(reinterpretCast())));
1990 EXPECT_TRUE(notMatches("void* p = static_cast<void*>(&p);",
1991 expression(reinterpretCast())));
1992 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
1993 "B b;"
1994 "D* p = dynamic_cast<D*>(&b);",
1995 expression(reinterpretCast())));
1996}
1997
1998TEST(FunctionalCast, MatchesSimpleCase) {
1999 std::string foo_class = "class Foo { public: Foo(char*); };";
2000 EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",
2001 expression(functionalCast())));
2002}
2003
2004TEST(FunctionalCast, DoesNotMatchOtherCasts) {
2005 std::string FooClass = "class Foo { public: Foo(char*); };";
2006 EXPECT_TRUE(
2007 notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",
2008 expression(functionalCast())));
2009 EXPECT_TRUE(
2010 notMatches(FooClass + "void r() { Foo f = \"hello world\"; }",
2011 expression(functionalCast())));
2012}
2013
2014TEST(DynamicCast, MatchesSimpleCase) {
2015 EXPECT_TRUE(matches("struct B { virtual ~B() {} }; struct D : B {};"
2016 "B b;"
2017 "D* p = dynamic_cast<D*>(&b);",
2018 expression(dynamicCast())));
2019}
2020
2021TEST(StaticCast, MatchesSimpleCase) {
2022 EXPECT_TRUE(matches("void* p(static_cast<void*>(&p));",
2023 expression(staticCast())));
2024}
2025
2026TEST(StaticCast, DoesNotMatchOtherCasts) {
2027 EXPECT_TRUE(notMatches("char* p = (char*)(&p);",
2028 expression(staticCast())));
2029 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
2030 expression(staticCast())));
2031 EXPECT_TRUE(notMatches("void* p = reinterpret_cast<char*>(&p);",
2032 expression(staticCast())));
2033 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
2034 "B b;"
2035 "D* p = dynamic_cast<D*>(&b);",
2036 expression(staticCast())));
2037}
2038
2039TEST(HasDestinationType, MatchesSimpleCase) {
2040 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
2041 expression(
2042 staticCast(hasDestinationType(
2043 pointsTo(TypeMatcher(anything())))))));
2044}
2045
Manuel Klimek715c9562012-07-25 10:02:02 +00002046TEST(HasSourceExpression, MatchesImplicitCasts) {
Manuel Klimek4da21662012-07-06 05:48:52 +00002047 EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
2048 "void r() {string a_string; URL url = a_string; }",
2049 expression(implicitCast(
2050 hasSourceExpression(constructorCall())))));
2051}
2052
Manuel Klimek715c9562012-07-25 10:02:02 +00002053TEST(HasSourceExpression, MatchesExplicitCasts) {
2054 EXPECT_TRUE(matches("float x = static_cast<float>(42);",
2055 expression(explicitCast(
2056 hasSourceExpression(hasDescendant(
2057 expression(integerLiteral())))))));
2058}
2059
Manuel Klimek4da21662012-07-06 05:48:52 +00002060TEST(Statement, DoesNotMatchDeclarations) {
2061 EXPECT_TRUE(notMatches("class X {};", statement()));
2062}
2063
2064TEST(Statement, MatchesCompoundStatments) {
2065 EXPECT_TRUE(matches("void x() {}", statement()));
2066}
2067
2068TEST(DeclarationStatement, DoesNotMatchCompoundStatements) {
2069 EXPECT_TRUE(notMatches("void x() {}", declarationStatement()));
2070}
2071
2072TEST(DeclarationStatement, MatchesVariableDeclarationStatements) {
2073 EXPECT_TRUE(matches("void x() { int a; }", declarationStatement()));
2074}
2075
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002076TEST(InitListExpression, MatchesInitListExpression) {
2077 EXPECT_TRUE(matches("int a[] = { 1, 2 };",
2078 initListExpr(hasType(asString("int [2]")))));
2079 EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };",
2080 initListExpr(hasType(record(hasName("B"))))));
2081}
2082
2083TEST(UsingDeclaration, MatchesUsingDeclarations) {
2084 EXPECT_TRUE(matches("namespace X { int x; } using X::x;",
2085 usingDecl()));
2086}
2087
2088TEST(UsingDeclaration, MatchesShadowUsingDelcarations) {
2089 EXPECT_TRUE(matches("namespace f { int a; } using f::a;",
2090 usingDecl(hasAnyUsingShadowDecl(hasName("a")))));
2091}
2092
2093TEST(UsingDeclaration, MatchesSpecificTarget) {
2094 EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
2095 usingDecl(hasAnyUsingShadowDecl(
2096 hasTargetDecl(function())))));
2097 EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
2098 usingDecl(hasAnyUsingShadowDecl(
2099 hasTargetDecl(function())))));
2100}
2101
2102TEST(UsingDeclaration, ThroughUsingDeclaration) {
2103 EXPECT_TRUE(matches(
2104 "namespace a { void f(); } using a::f; void g() { f(); }",
2105 declarationReference(throughUsingDecl(anything()))));
2106 EXPECT_TRUE(notMatches(
2107 "namespace a { void f(); } using a::f; void g() { a::f(); }",
2108 declarationReference(throughUsingDecl(anything()))));
2109}
2110
Manuel Klimek4da21662012-07-06 05:48:52 +00002111TEST(While, MatchesWhileLoops) {
2112 EXPECT_TRUE(notMatches("void x() {}", whileStmt()));
2113 EXPECT_TRUE(matches("void x() { while(true); }", whileStmt()));
2114 EXPECT_TRUE(notMatches("void x() { do {} while(true); }", whileStmt()));
2115}
2116
2117TEST(Do, MatchesDoLoops) {
2118 EXPECT_TRUE(matches("void x() { do {} while(true); }", doStmt()));
2119 EXPECT_TRUE(matches("void x() { do ; while(false); }", doStmt()));
2120}
2121
2122TEST(Do, DoesNotMatchWhileLoops) {
2123 EXPECT_TRUE(notMatches("void x() { while(true) {} }", doStmt()));
2124}
2125
2126TEST(SwitchCase, MatchesCase) {
2127 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchCase()));
2128 EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchCase()));
2129 EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchCase()));
2130 EXPECT_TRUE(notMatches("void x() { switch(42) {} }", switchCase()));
2131}
2132
2133TEST(HasConditionVariableStatement, DoesNotMatchCondition) {
2134 EXPECT_TRUE(notMatches(
2135 "void x() { if(true) {} }",
2136 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2137 EXPECT_TRUE(notMatches(
2138 "void x() { int x; if((x = 42)) {} }",
2139 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2140}
2141
2142TEST(HasConditionVariableStatement, MatchesConditionVariables) {
2143 EXPECT_TRUE(matches(
2144 "void x() { if(int* a = 0) {} }",
2145 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2146}
2147
2148TEST(ForEach, BindsOneNode) {
2149 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002150 record(hasName("C"), forEach(field(hasName("x")).bind("x"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002151 new VerifyIdIsBoundToDecl<FieldDecl>("x", 1)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002152}
2153
2154TEST(ForEach, BindsMultipleNodes) {
2155 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002156 record(hasName("C"), forEach(field().bind("f"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002157 new VerifyIdIsBoundToDecl<FieldDecl>("f", 3)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002158}
2159
2160TEST(ForEach, BindsRecursiveCombinations) {
2161 EXPECT_TRUE(matchAndVerifyResultTrue(
2162 "class C { class D { int x; int y; }; class E { int y; int z; }; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002163 record(hasName("C"), forEach(record(forEach(field().bind("f"))))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002164 new VerifyIdIsBoundToDecl<FieldDecl>("f", 4)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002165}
2166
2167TEST(ForEachDescendant, BindsOneNode) {
2168 EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002169 record(hasName("C"), forEachDescendant(field(hasName("x")).bind("x"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002170 new VerifyIdIsBoundToDecl<FieldDecl>("x", 1)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002171}
2172
2173TEST(ForEachDescendant, BindsMultipleNodes) {
2174 EXPECT_TRUE(matchAndVerifyResultTrue(
2175 "class C { class D { int x; int y; }; "
2176 " class E { class F { int y; int z; }; }; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002177 record(hasName("C"), forEachDescendant(field().bind("f"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002178 new VerifyIdIsBoundToDecl<FieldDecl>("f", 4)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002179}
2180
2181TEST(ForEachDescendant, BindsRecursiveCombinations) {
2182 EXPECT_TRUE(matchAndVerifyResultTrue(
2183 "class C { class D { "
2184 " class E { class F { class G { int y; int z; }; }; }; }; };",
2185 record(hasName("C"), forEachDescendant(record(
Manuel Klimek9f174082012-07-24 13:37:29 +00002186 forEachDescendant(field().bind("f"))))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002187 new VerifyIdIsBoundToDecl<FieldDecl>("f", 8)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002188}
2189
2190
2191TEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) {
2192 // Make sure that we can both match the class by name (::X) and by the type
2193 // the template was instantiated with (via a field).
2194
2195 EXPECT_TRUE(matches(
2196 "template <typename T> class X {}; class A {}; X<A> x;",
2197 record(hasName("::X"), isTemplateInstantiation())));
2198
2199 EXPECT_TRUE(matches(
2200 "template <typename T> class X { T t; }; class A {}; X<A> x;",
2201 record(isTemplateInstantiation(), hasDescendant(
2202 field(hasType(record(hasName("A"))))))));
2203}
2204
2205TEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) {
2206 EXPECT_TRUE(matches(
2207 "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
2208 function(hasParameter(0, hasType(record(hasName("A")))),
2209 isTemplateInstantiation())));
2210}
2211
2212TEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) {
2213 EXPECT_TRUE(matches(
2214 "template <typename T> class X { T t; }; class A {};"
2215 "template class X<A>;",
2216 record(isTemplateInstantiation(), hasDescendant(
2217 field(hasType(record(hasName("A"))))))));
2218}
2219
2220TEST(IsTemplateInstantiation,
2221 MatchesInstantiationOfPartiallySpecializedClassTemplate) {
2222 EXPECT_TRUE(matches(
2223 "template <typename T> class X {};"
2224 "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
2225 record(hasName("::X"), isTemplateInstantiation())));
2226}
2227
2228TEST(IsTemplateInstantiation,
2229 MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
2230 EXPECT_TRUE(matches(
2231 "class A {};"
2232 "class X {"
2233 " template <typename U> class Y { U u; };"
2234 " Y<A> y;"
2235 "};",
2236 record(hasName("::X::Y"), isTemplateInstantiation())));
2237}
2238
2239TEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) {
2240 // FIXME: Figure out whether this makes sense. It doesn't affect the
2241 // normal use case as long as the uppermost instantiation always is marked
2242 // as template instantiation, but it might be confusing as a predicate.
2243 EXPECT_TRUE(matches(
2244 "class A {};"
2245 "template <typename T> class X {"
2246 " template <typename U> class Y { U u; };"
2247 " Y<T> y;"
2248 "}; X<A> x;",
2249 record(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
2250}
2251
2252TEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) {
2253 EXPECT_TRUE(notMatches(
2254 "template <typename T> class X {}; class A {};"
2255 "template <> class X<A> {}; X<A> x;",
2256 record(hasName("::X"), isTemplateInstantiation())));
2257}
2258
2259TEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) {
2260 EXPECT_TRUE(notMatches(
2261 "class A {}; class Y { A a; };",
2262 record(isTemplateInstantiation())));
2263}
2264
2265} // end namespace ast_matchers
2266} // end namespace clang