blob: 8768baf18694d96f6526e59dd739cc74b52184c5 [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
Manuel Klimek4da21662012-07-06 05:48:52 +00001102TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
1103 EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
1104 method(hasAnyParameter(hasType(record(hasName("X")))))));
1105}
1106
1107TEST(HasAnyParameter, DoesNotMatchThisPointer) {
1108 EXPECT_TRUE(notMatches("class Y {}; class X { void x() {} };",
1109 method(hasAnyParameter(hasType(pointsTo(record(hasName("X"))))))));
1110}
1111
1112TEST(HasName, MatchesParameterVariableDeclartions) {
1113 EXPECT_TRUE(matches("class Y {}; class X { void x(int x) {} };",
1114 method(hasAnyParameter(hasName("x")))));
1115 EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
1116 method(hasAnyParameter(hasName("x")))));
1117}
1118
1119TEST(Matcher, ConstructorCall) {
1120 StatementMatcher Constructor = expression(constructorCall());
1121
1122 EXPECT_TRUE(
1123 matches("class X { public: X(); }; void x() { X x; }", Constructor));
1124 EXPECT_TRUE(
1125 matches("class X { public: X(); }; void x() { X x = X(); }",
1126 Constructor));
1127 EXPECT_TRUE(
1128 matches("class X { public: X(int); }; void x() { X x = 0; }",
1129 Constructor));
1130 EXPECT_TRUE(matches("class X {}; void x(int) { X x; }", Constructor));
1131}
1132
1133TEST(Matcher, ConstructorArgument) {
1134 StatementMatcher Constructor = expression(constructorCall(
1135 hasArgument(0, declarationReference(to(variable(hasName("y")))))));
1136
1137 EXPECT_TRUE(
1138 matches("class X { public: X(int); }; void x() { int y; X x(y); }",
1139 Constructor));
1140 EXPECT_TRUE(
1141 matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
1142 Constructor));
1143 EXPECT_TRUE(
1144 matches("class X { public: X(int); }; void x() { int y; X x = y; }",
1145 Constructor));
1146 EXPECT_TRUE(
1147 notMatches("class X { public: X(int); }; void x() { int z; X x(z); }",
1148 Constructor));
1149
1150 StatementMatcher WrongIndex = expression(constructorCall(
1151 hasArgument(42, declarationReference(to(variable(hasName("y")))))));
1152 EXPECT_TRUE(
1153 notMatches("class X { public: X(int); }; void x() { int y; X x(y); }",
1154 WrongIndex));
1155}
1156
1157TEST(Matcher, ConstructorArgumentCount) {
1158 StatementMatcher Constructor1Arg =
1159 expression(constructorCall(argumentCountIs(1)));
1160
1161 EXPECT_TRUE(
1162 matches("class X { public: X(int); }; void x() { X x(0); }",
1163 Constructor1Arg));
1164 EXPECT_TRUE(
1165 matches("class X { public: X(int); }; void x() { X x = X(0); }",
1166 Constructor1Arg));
1167 EXPECT_TRUE(
1168 matches("class X { public: X(int); }; void x() { X x = 0; }",
1169 Constructor1Arg));
1170 EXPECT_TRUE(
1171 notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
1172 Constructor1Arg));
1173}
1174
1175TEST(Matcher, BindTemporaryExpression) {
1176 StatementMatcher TempExpression = expression(bindTemporaryExpression());
1177
1178 std::string ClassString = "class string { public: string(); ~string(); }; ";
1179
1180 EXPECT_TRUE(
1181 matches(ClassString +
1182 "string GetStringByValue();"
1183 "void FunctionTakesString(string s);"
1184 "void run() { FunctionTakesString(GetStringByValue()); }",
1185 TempExpression));
1186
1187 EXPECT_TRUE(
1188 notMatches(ClassString +
1189 "string* GetStringPointer(); "
1190 "void FunctionTakesStringPtr(string* s);"
1191 "void run() {"
1192 " string* s = GetStringPointer();"
1193 " FunctionTakesStringPtr(GetStringPointer());"
1194 " FunctionTakesStringPtr(s);"
1195 "}",
1196 TempExpression));
1197
1198 EXPECT_TRUE(
1199 notMatches("class no_dtor {};"
1200 "no_dtor GetObjByValue();"
1201 "void ConsumeObj(no_dtor param);"
1202 "void run() { ConsumeObj(GetObjByValue()); }",
1203 TempExpression));
1204}
1205
1206TEST(ConstructorDeclaration, SimpleCase) {
1207 EXPECT_TRUE(matches("class Foo { Foo(int i); };",
1208 constructor(ofClass(hasName("Foo")))));
1209 EXPECT_TRUE(notMatches("class Foo { Foo(int i); };",
1210 constructor(ofClass(hasName("Bar")))));
1211}
1212
1213TEST(ConstructorDeclaration, IsImplicit) {
1214 // This one doesn't match because the constructor is not added by the
1215 // compiler (it is not needed).
1216 EXPECT_TRUE(notMatches("class Foo { };",
1217 constructor(isImplicit())));
1218 // The compiler added the implicit default constructor.
1219 EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
1220 constructor(isImplicit())));
1221 EXPECT_TRUE(matches("class Foo { Foo(){} };",
1222 constructor(unless(isImplicit()))));
1223}
1224
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001225TEST(DestructorDeclaration, MatchesVirtualDestructor) {
1226 EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };",
1227 destructor(ofClass(hasName("Foo")))));
1228}
1229
1230TEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) {
1231 EXPECT_TRUE(notMatches("class Foo {};", destructor(ofClass(hasName("Foo")))));
1232}
1233
Manuel Klimek4da21662012-07-06 05:48:52 +00001234TEST(HasAnyConstructorInitializer, SimpleCase) {
1235 EXPECT_TRUE(notMatches(
1236 "class Foo { Foo() { } };",
1237 constructor(hasAnyConstructorInitializer(anything()))));
1238 EXPECT_TRUE(matches(
1239 "class Foo {"
1240 " Foo() : foo_() { }"
1241 " int foo_;"
1242 "};",
1243 constructor(hasAnyConstructorInitializer(anything()))));
1244}
1245
1246TEST(HasAnyConstructorInitializer, ForField) {
1247 static const char Code[] =
1248 "class Baz { };"
1249 "class Foo {"
1250 " Foo() : foo_() { }"
1251 " Baz foo_;"
1252 " Baz bar_;"
1253 "};";
1254 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1255 forField(hasType(record(hasName("Baz"))))))));
1256 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1257 forField(hasName("foo_"))))));
1258 EXPECT_TRUE(notMatches(Code, constructor(hasAnyConstructorInitializer(
1259 forField(hasType(record(hasName("Bar"))))))));
1260}
1261
1262TEST(HasAnyConstructorInitializer, WithInitializer) {
1263 static const char Code[] =
1264 "class Foo {"
1265 " Foo() : foo_(0) { }"
1266 " int foo_;"
1267 "};";
1268 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1269 withInitializer(integerLiteral(equals(0)))))));
1270 EXPECT_TRUE(notMatches(Code, constructor(hasAnyConstructorInitializer(
1271 withInitializer(integerLiteral(equals(1)))))));
1272}
1273
1274TEST(HasAnyConstructorInitializer, IsWritten) {
1275 static const char Code[] =
1276 "struct Bar { Bar(){} };"
1277 "class Foo {"
1278 " Foo() : foo_() { }"
1279 " Bar foo_;"
1280 " Bar bar_;"
1281 "};";
1282 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1283 allOf(forField(hasName("foo_")), isWritten())))));
1284 EXPECT_TRUE(notMatches(Code, constructor(hasAnyConstructorInitializer(
1285 allOf(forField(hasName("bar_")), isWritten())))));
1286 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1287 allOf(forField(hasName("bar_")), unless(isWritten()))))));
1288}
1289
1290TEST(Matcher, NewExpression) {
1291 StatementMatcher New = expression(newExpression());
1292
1293 EXPECT_TRUE(matches("class X { public: X(); }; void x() { new X; }", New));
1294 EXPECT_TRUE(
1295 matches("class X { public: X(); }; void x() { new X(); }", New));
1296 EXPECT_TRUE(
1297 matches("class X { public: X(int); }; void x() { new X(0); }", New));
1298 EXPECT_TRUE(matches("class X {}; void x(int) { new X; }", New));
1299}
1300
1301TEST(Matcher, NewExpressionArgument) {
1302 StatementMatcher New = expression(constructorCall(
1303 hasArgument(
1304 0, declarationReference(to(variable(hasName("y")))))));
1305
1306 EXPECT_TRUE(
1307 matches("class X { public: X(int); }; void x() { int y; new X(y); }",
1308 New));
1309 EXPECT_TRUE(
1310 matches("class X { public: X(int); }; void x() { int y; new X(y); }",
1311 New));
1312 EXPECT_TRUE(
1313 notMatches("class X { public: X(int); }; void x() { int z; new X(z); }",
1314 New));
1315
1316 StatementMatcher WrongIndex = expression(constructorCall(
1317 hasArgument(
1318 42, declarationReference(to(variable(hasName("y")))))));
1319 EXPECT_TRUE(
1320 notMatches("class X { public: X(int); }; void x() { int y; new X(y); }",
1321 WrongIndex));
1322}
1323
1324TEST(Matcher, NewExpressionArgumentCount) {
1325 StatementMatcher New = constructorCall(argumentCountIs(1));
1326
1327 EXPECT_TRUE(
1328 matches("class X { public: X(int); }; void x() { new X(0); }", New));
1329 EXPECT_TRUE(
1330 notMatches("class X { public: X(int, int); }; void x() { new X(0, 0); }",
1331 New));
1332}
1333
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001334TEST(Matcher, DeleteExpression) {
1335 EXPECT_TRUE(matches("struct A {}; void f(A* a) { delete a; }",
1336 deleteExpression()));
1337}
1338
Manuel Klimek4da21662012-07-06 05:48:52 +00001339TEST(Matcher, DefaultArgument) {
1340 StatementMatcher Arg = defaultArgument();
1341
1342 EXPECT_TRUE(matches("void x(int, int = 0) { int y; x(y); }", Arg));
1343 EXPECT_TRUE(
1344 matches("class X { void x(int, int = 0) { int y; x(y); } };", Arg));
1345 EXPECT_TRUE(notMatches("void x(int, int = 0) { int y; x(y, 0); }", Arg));
1346}
1347
1348TEST(Matcher, StringLiterals) {
1349 StatementMatcher Literal = expression(stringLiteral());
1350 EXPECT_TRUE(matches("const char *s = \"string\";", Literal));
1351 // wide string
1352 EXPECT_TRUE(matches("const wchar_t *s = L\"string\";", Literal));
1353 // with escaped characters
1354 EXPECT_TRUE(matches("const char *s = \"\x05five\";", Literal));
1355 // no matching -- though the data type is the same, there is no string literal
1356 EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));
1357}
1358
1359TEST(Matcher, CharacterLiterals) {
1360 StatementMatcher CharLiteral = expression(characterLiteral());
1361 EXPECT_TRUE(matches("const char c = 'c';", CharLiteral));
1362 // wide character
1363 EXPECT_TRUE(matches("const char c = L'c';", CharLiteral));
1364 // wide character, Hex encoded, NOT MATCHED!
1365 EXPECT_TRUE(notMatches("const wchar_t c = 0x2126;", CharLiteral));
1366 EXPECT_TRUE(notMatches("const char c = 0x1;", CharLiteral));
1367}
1368
1369TEST(Matcher, IntegerLiterals) {
1370 StatementMatcher HasIntLiteral = expression(integerLiteral());
1371 EXPECT_TRUE(matches("int i = 10;", HasIntLiteral));
1372 EXPECT_TRUE(matches("int i = 0x1AB;", HasIntLiteral));
1373 EXPECT_TRUE(matches("int i = 10L;", HasIntLiteral));
1374 EXPECT_TRUE(matches("int i = 10U;", HasIntLiteral));
1375
1376 // Non-matching cases (character literals, float and double)
1377 EXPECT_TRUE(notMatches("int i = L'a';",
1378 HasIntLiteral)); // this is actually a character
1379 // literal cast to int
1380 EXPECT_TRUE(notMatches("int i = 'a';", HasIntLiteral));
1381 EXPECT_TRUE(notMatches("int i = 1e10;", HasIntLiteral));
1382 EXPECT_TRUE(notMatches("int i = 10.0;", HasIntLiteral));
1383}
1384
1385TEST(Matcher, Conditions) {
1386 StatementMatcher Condition = ifStmt(hasCondition(boolLiteral(equals(true))));
1387
1388 EXPECT_TRUE(matches("void x() { if (true) {} }", Condition));
1389 EXPECT_TRUE(notMatches("void x() { if (false) {} }", Condition));
1390 EXPECT_TRUE(notMatches("void x() { bool a = true; if (a) {} }", Condition));
1391 EXPECT_TRUE(notMatches("void x() { if (true || false) {} }", Condition));
1392 EXPECT_TRUE(notMatches("void x() { if (1) {} }", Condition));
1393}
1394
1395TEST(MatchBinaryOperator, HasOperatorName) {
1396 StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
1397
1398 EXPECT_TRUE(matches("void x() { true || false; }", OperatorOr));
1399 EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
1400}
1401
1402TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
1403 StatementMatcher OperatorTrueFalse =
1404 binaryOperator(hasLHS(boolLiteral(equals(true))),
1405 hasRHS(boolLiteral(equals(false))));
1406
1407 EXPECT_TRUE(matches("void x() { true || false; }", OperatorTrueFalse));
1408 EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse));
1409 EXPECT_TRUE(notMatches("void x() { false || true; }", OperatorTrueFalse));
1410}
1411
1412TEST(MatchBinaryOperator, HasEitherOperand) {
1413 StatementMatcher HasOperand =
1414 binaryOperator(hasEitherOperand(boolLiteral(equals(false))));
1415
1416 EXPECT_TRUE(matches("void x() { true || false; }", HasOperand));
1417 EXPECT_TRUE(matches("void x() { false && true; }", HasOperand));
1418 EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand));
1419}
1420
1421TEST(Matcher, BinaryOperatorTypes) {
1422 // Integration test that verifies the AST provides all binary operators in
1423 // a way we expect.
1424 // FIXME: Operator ','
1425 EXPECT_TRUE(
1426 matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(","))));
1427 EXPECT_TRUE(
1428 matches("bool b; bool c = (b = true);",
1429 binaryOperator(hasOperatorName("="))));
1430 EXPECT_TRUE(
1431 matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!="))));
1432 EXPECT_TRUE(
1433 matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("=="))));
1434 EXPECT_TRUE(matches("bool b = 1 < 2;", binaryOperator(hasOperatorName("<"))));
1435 EXPECT_TRUE(
1436 matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<="))));
1437 EXPECT_TRUE(
1438 matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<"))));
1439 EXPECT_TRUE(
1440 matches("int i = 1; int j = (i <<= 2);",
1441 binaryOperator(hasOperatorName("<<="))));
1442 EXPECT_TRUE(matches("bool b = 1 > 2;", binaryOperator(hasOperatorName(">"))));
1443 EXPECT_TRUE(
1444 matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">="))));
1445 EXPECT_TRUE(
1446 matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>"))));
1447 EXPECT_TRUE(
1448 matches("int i = 1; int j = (i >>= 2);",
1449 binaryOperator(hasOperatorName(">>="))));
1450 EXPECT_TRUE(
1451 matches("int i = 42 ^ 23;", binaryOperator(hasOperatorName("^"))));
1452 EXPECT_TRUE(
1453 matches("int i = 42; int j = (i ^= 42);",
1454 binaryOperator(hasOperatorName("^="))));
1455 EXPECT_TRUE(
1456 matches("int i = 42 % 23;", binaryOperator(hasOperatorName("%"))));
1457 EXPECT_TRUE(
1458 matches("int i = 42; int j = (i %= 42);",
1459 binaryOperator(hasOperatorName("%="))));
1460 EXPECT_TRUE(
1461 matches("bool b = 42 &23;", binaryOperator(hasOperatorName("&"))));
1462 EXPECT_TRUE(
1463 matches("bool b = true && false;",
1464 binaryOperator(hasOperatorName("&&"))));
1465 EXPECT_TRUE(
1466 matches("bool b = true; bool c = (b &= false);",
1467 binaryOperator(hasOperatorName("&="))));
1468 EXPECT_TRUE(
1469 matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|"))));
1470 EXPECT_TRUE(
1471 matches("bool b = true || false;",
1472 binaryOperator(hasOperatorName("||"))));
1473 EXPECT_TRUE(
1474 matches("bool b = true; bool c = (b |= false);",
1475 binaryOperator(hasOperatorName("|="))));
1476 EXPECT_TRUE(
1477 matches("int i = 42 *23;", binaryOperator(hasOperatorName("*"))));
1478 EXPECT_TRUE(
1479 matches("int i = 42; int j = (i *= 23);",
1480 binaryOperator(hasOperatorName("*="))));
1481 EXPECT_TRUE(
1482 matches("int i = 42 / 23;", binaryOperator(hasOperatorName("/"))));
1483 EXPECT_TRUE(
1484 matches("int i = 42; int j = (i /= 23);",
1485 binaryOperator(hasOperatorName("/="))));
1486 EXPECT_TRUE(
1487 matches("int i = 42 + 23;", binaryOperator(hasOperatorName("+"))));
1488 EXPECT_TRUE(
1489 matches("int i = 42; int j = (i += 23);",
1490 binaryOperator(hasOperatorName("+="))));
1491 EXPECT_TRUE(
1492 matches("int i = 42 - 23;", binaryOperator(hasOperatorName("-"))));
1493 EXPECT_TRUE(
1494 matches("int i = 42; int j = (i -= 23);",
1495 binaryOperator(hasOperatorName("-="))));
1496 EXPECT_TRUE(
1497 matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };",
1498 binaryOperator(hasOperatorName("->*"))));
1499 EXPECT_TRUE(
1500 matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };",
1501 binaryOperator(hasOperatorName(".*"))));
1502
1503 // Member expressions as operators are not supported in matches.
1504 EXPECT_TRUE(
1505 notMatches("struct A { void x(A *a) { a->x(this); } };",
1506 binaryOperator(hasOperatorName("->"))));
1507
1508 // Initializer assignments are not represented as operator equals.
1509 EXPECT_TRUE(
1510 notMatches("bool b = true;", binaryOperator(hasOperatorName("="))));
1511
1512 // Array indexing is not represented as operator.
1513 EXPECT_TRUE(notMatches("int a[42]; void x() { a[23]; }", unaryOperator()));
1514
1515 // Overloaded operators do not match at all.
1516 EXPECT_TRUE(notMatches(
1517 "struct A { bool operator&&(const A &a) const { return false; } };"
1518 "void x() { A a, b; a && b; }",
1519 binaryOperator()));
1520}
1521
1522TEST(MatchUnaryOperator, HasOperatorName) {
1523 StatementMatcher OperatorNot = unaryOperator(hasOperatorName("!"));
1524
1525 EXPECT_TRUE(matches("void x() { !true; } ", OperatorNot));
1526 EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
1527}
1528
1529TEST(MatchUnaryOperator, HasUnaryOperand) {
1530 StatementMatcher OperatorOnFalse =
1531 unaryOperator(hasUnaryOperand(boolLiteral(equals(false))));
1532
1533 EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse));
1534 EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse));
1535}
1536
1537TEST(Matcher, UnaryOperatorTypes) {
1538 // Integration test that verifies the AST provides all unary operators in
1539 // a way we expect.
1540 EXPECT_TRUE(matches("bool b = !true;", unaryOperator(hasOperatorName("!"))));
1541 EXPECT_TRUE(
1542 matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&"))));
1543 EXPECT_TRUE(matches("int i = ~ 1;", unaryOperator(hasOperatorName("~"))));
1544 EXPECT_TRUE(
1545 matches("bool *p; bool b = *p;", 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 EXPECT_TRUE(
1553 matches("int i; int j = i++;", unaryOperator(hasOperatorName("++"))));
1554 EXPECT_TRUE(
1555 matches("int i; int j = --i;", unaryOperator(hasOperatorName("--"))));
1556 EXPECT_TRUE(
1557 matches("int i; int j = i--;", unaryOperator(hasOperatorName("--"))));
1558
1559 // We don't match conversion operators.
1560 EXPECT_TRUE(notMatches("int i; double d = (double)i;", unaryOperator()));
1561
1562 // Function calls are not represented as operator.
1563 EXPECT_TRUE(notMatches("void f(); void x() { f(); }", unaryOperator()));
1564
1565 // Overloaded operators do not match at all.
1566 // FIXME: We probably want to add that.
1567 EXPECT_TRUE(notMatches(
1568 "struct A { bool operator!() const { return false; } };"
1569 "void x() { A a; !a; }", unaryOperator(hasOperatorName("!"))));
1570}
1571
1572TEST(Matcher, ConditionalOperator) {
1573 StatementMatcher Conditional = conditionalOperator(
1574 hasCondition(boolLiteral(equals(true))),
1575 hasTrueExpression(boolLiteral(equals(false))));
1576
1577 EXPECT_TRUE(matches("void x() { true ? false : true; }", Conditional));
1578 EXPECT_TRUE(notMatches("void x() { false ? false : true; }", Conditional));
1579 EXPECT_TRUE(notMatches("void x() { true ? true : false; }", Conditional));
1580
1581 StatementMatcher ConditionalFalse = conditionalOperator(
1582 hasFalseExpression(boolLiteral(equals(false))));
1583
1584 EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
1585 EXPECT_TRUE(
1586 notMatches("void x() { true ? false : true; }", ConditionalFalse));
1587}
1588
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001589TEST(ArraySubscriptMatchers, ArraySubscripts) {
1590 EXPECT_TRUE(matches("int i[2]; void f() { i[1] = 1; }",
1591 arraySubscriptExpr()));
1592 EXPECT_TRUE(notMatches("int i; void f() { i = 1; }",
1593 arraySubscriptExpr()));
1594}
1595
1596TEST(ArraySubscriptMatchers, ArrayIndex) {
1597 EXPECT_TRUE(matches(
1598 "int i[2]; void f() { i[1] = 1; }",
1599 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
1600 EXPECT_TRUE(matches(
1601 "int i[2]; void f() { 1[i] = 1; }",
1602 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
1603 EXPECT_TRUE(notMatches(
1604 "int i[2]; void f() { i[1] = 1; }",
1605 arraySubscriptExpr(hasIndex(integerLiteral(equals(0))))));
1606}
1607
1608TEST(ArraySubscriptMatchers, MatchesArrayBase) {
1609 EXPECT_TRUE(matches(
1610 "int i[2]; void f() { i[1] = 2; }",
1611 arraySubscriptExpr(hasBase(implicitCast(
1612 hasSourceExpression(declarationReference()))))));
1613}
1614
Manuel Klimek4da21662012-07-06 05:48:52 +00001615TEST(Matcher, HasNameSupportsNamespaces) {
1616 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1617 record(hasName("a::b::C"))));
1618 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1619 record(hasName("::a::b::C"))));
1620 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1621 record(hasName("b::C"))));
1622 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1623 record(hasName("C"))));
1624 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1625 record(hasName("c::b::C"))));
1626 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1627 record(hasName("a::c::C"))));
1628 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1629 record(hasName("a::b::A"))));
1630 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1631 record(hasName("::C"))));
1632 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1633 record(hasName("::b::C"))));
1634 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1635 record(hasName("z::a::b::C"))));
1636 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1637 record(hasName("a+b::C"))));
1638 EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
1639 record(hasName("C"))));
1640}
1641
1642TEST(Matcher, HasNameSupportsOuterClasses) {
1643 EXPECT_TRUE(
1644 matches("class A { class B { class C; }; };", record(hasName("A::B::C"))));
1645 EXPECT_TRUE(
1646 matches("class A { class B { class C; }; };",
1647 record(hasName("::A::B::C"))));
1648 EXPECT_TRUE(
1649 matches("class A { class B { class C; }; };", record(hasName("B::C"))));
1650 EXPECT_TRUE(
1651 matches("class A { class B { class C; }; };", record(hasName("C"))));
1652 EXPECT_TRUE(
1653 notMatches("class A { class B { class C; }; };",
1654 record(hasName("c::B::C"))));
1655 EXPECT_TRUE(
1656 notMatches("class A { class B { class C; }; };",
1657 record(hasName("A::c::C"))));
1658 EXPECT_TRUE(
1659 notMatches("class A { class B { class C; }; };",
1660 record(hasName("A::B::A"))));
1661 EXPECT_TRUE(
1662 notMatches("class A { class B { class C; }; };", record(hasName("::C"))));
1663 EXPECT_TRUE(
1664 notMatches("class A { class B { class C; }; };",
1665 record(hasName("::B::C"))));
1666 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
1667 record(hasName("z::A::B::C"))));
1668 EXPECT_TRUE(
1669 notMatches("class A { class B { class C; }; };",
1670 record(hasName("A+B::C"))));
1671}
1672
1673TEST(Matcher, IsDefinition) {
1674 DeclarationMatcher DefinitionOfClassA =
1675 record(hasName("A"), isDefinition());
1676 EXPECT_TRUE(matches("class A {};", DefinitionOfClassA));
1677 EXPECT_TRUE(notMatches("class A;", DefinitionOfClassA));
1678
1679 DeclarationMatcher DefinitionOfVariableA =
1680 variable(hasName("a"), isDefinition());
1681 EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));
1682 EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));
1683
1684 DeclarationMatcher DefinitionOfMethodA =
1685 method(hasName("a"), isDefinition());
1686 EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));
1687 EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));
1688}
1689
1690TEST(Matcher, OfClass) {
1691 StatementMatcher Constructor = constructorCall(hasDeclaration(method(
1692 ofClass(hasName("X")))));
1693
1694 EXPECT_TRUE(
1695 matches("class X { public: X(); }; void x(int) { X x; }", Constructor));
1696 EXPECT_TRUE(
1697 matches("class X { public: X(); }; void x(int) { X x = X(); }",
1698 Constructor));
1699 EXPECT_TRUE(
1700 notMatches("class Y { public: Y(); }; void x(int) { Y y; }",
1701 Constructor));
1702}
1703
1704TEST(Matcher, VisitsTemplateInstantiations) {
1705 EXPECT_TRUE(matches(
1706 "class A { public: void x(); };"
1707 "template <typename T> class B { public: void y() { T t; t.x(); } };"
1708 "void f() { B<A> b; b.y(); }", call(callee(method(hasName("x"))))));
1709
1710 EXPECT_TRUE(matches(
1711 "class A { public: void x(); };"
1712 "class C {"
1713 " public:"
1714 " template <typename T> class B { public: void y() { T t; t.x(); } };"
1715 "};"
1716 "void f() {"
1717 " C::B<A> b; b.y();"
1718 "}", record(hasName("C"),
1719 hasDescendant(call(callee(method(hasName("x"))))))));
1720}
1721
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001722TEST(Matcher, HandlesNullQualTypes) {
1723 // FIXME: Add a Type matcher so we can replace uses of this
1724 // variable with Type(True())
1725 const TypeMatcher AnyType = anything();
1726
1727 // We don't really care whether this matcher succeeds; we're testing that
1728 // it completes without crashing.
1729 EXPECT_TRUE(matches(
1730 "struct A { };"
1731 "template <typename T>"
1732 "void f(T t) {"
1733 " T local_t(t /* this becomes a null QualType in the AST */);"
1734 "}"
1735 "void g() {"
1736 " f(0);"
1737 "}",
1738 expression(hasType(TypeMatcher(
1739 anyOf(
1740 TypeMatcher(hasDeclaration(anything())),
1741 pointsTo(AnyType),
1742 references(AnyType)
1743 // Other QualType matchers should go here.
1744 ))))));
1745}
1746
Manuel Klimek4da21662012-07-06 05:48:52 +00001747// For testing AST_MATCHER_P().
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001748AST_MATCHER_P(Decl, just, internal::Matcher<Decl>, AMatcher) {
Manuel Klimek4da21662012-07-06 05:48:52 +00001749 // Make sure all special variables are used: node, match_finder,
1750 // bound_nodes_builder, and the parameter named 'AMatcher'.
1751 return AMatcher.matches(Node, Finder, Builder);
1752}
1753
1754TEST(AstMatcherPMacro, Works) {
Manuel Klimek9f174082012-07-24 13:37:29 +00001755 DeclarationMatcher HasClassB = just(has(record(hasName("B")).bind("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001756
1757 EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001758 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001759
1760 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001761 HasClassB, new VerifyIdIsBoundToDecl<Decl>("a")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001762
1763 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001764 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001765}
1766
1767AST_POLYMORPHIC_MATCHER_P(
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001768 polymorphicHas, internal::Matcher<Decl>, AMatcher) {
1769 TOOLING_COMPILE_ASSERT((llvm::is_same<NodeType, Decl>::value) ||
1770 (llvm::is_same<NodeType, Stmt>::value),
Manuel Klimek4da21662012-07-06 05:48:52 +00001771 assert_node_type_is_accessible);
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001772 internal::TypedBaseMatcher<Decl> ChildMatcher(AMatcher);
Manuel Klimek4da21662012-07-06 05:48:52 +00001773 return Finder->matchesChildOf(
1774 Node, ChildMatcher, Builder,
1775 ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
1776 ASTMatchFinder::BK_First);
1777}
1778
1779TEST(AstPolymorphicMatcherPMacro, Works) {
Manuel Klimek9f174082012-07-24 13:37:29 +00001780 DeclarationMatcher HasClassB = polymorphicHas(record(hasName("B")).bind("b"));
Manuel Klimek4da21662012-07-06 05:48:52 +00001781
1782 EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001783 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001784
1785 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001786 HasClassB, new VerifyIdIsBoundToDecl<Decl>("a")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001787
1788 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001789 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001790
1791 StatementMatcher StatementHasClassB =
1792 polymorphicHas(record(hasName("B")));
1793
1794 EXPECT_TRUE(matches("void x() { class B {}; }", StatementHasClassB));
1795}
1796
1797TEST(For, FindsForLoops) {
1798 EXPECT_TRUE(matches("void f() { for(;;); }", forStmt()));
1799 EXPECT_TRUE(matches("void f() { if(true) for(;;); }", forStmt()));
1800}
1801
Daniel Jasper6a124492012-07-12 08:50:38 +00001802TEST(For, ForLoopInternals) {
1803 EXPECT_TRUE(matches("void f(){ int i; for (; i < 3 ; ); }",
1804 forStmt(hasCondition(anything()))));
1805 EXPECT_TRUE(matches("void f() { for (int i = 0; ;); }",
1806 forStmt(hasLoopInit(anything()))));
1807}
1808
1809TEST(For, NegativeForLoopInternals) {
1810 EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }",
1811 forStmt(hasCondition(expression()))));
1812 EXPECT_TRUE(notMatches("void f() {int i; for (; i < 4; ++i) {} }",
1813 forStmt(hasLoopInit(anything()))));
1814}
1815
Manuel Klimek4da21662012-07-06 05:48:52 +00001816TEST(For, ReportsNoFalsePositives) {
1817 EXPECT_TRUE(notMatches("void f() { ; }", forStmt()));
1818 EXPECT_TRUE(notMatches("void f() { if(true); }", forStmt()));
1819}
1820
1821TEST(CompoundStatement, HandlesSimpleCases) {
1822 EXPECT_TRUE(notMatches("void f();", compoundStatement()));
1823 EXPECT_TRUE(matches("void f() {}", compoundStatement()));
1824 EXPECT_TRUE(matches("void f() {{}}", compoundStatement()));
1825}
1826
1827TEST(CompoundStatement, DoesNotMatchEmptyStruct) {
1828 // It's not a compound statement just because there's "{}" in the source
1829 // text. This is an AST search, not grep.
1830 EXPECT_TRUE(notMatches("namespace n { struct S {}; }",
1831 compoundStatement()));
1832 EXPECT_TRUE(matches("namespace n { struct S { void f() {{}} }; }",
1833 compoundStatement()));
1834}
1835
Daniel Jasper6a124492012-07-12 08:50:38 +00001836TEST(HasBody, FindsBodyOfForWhileDoLoops) {
Manuel Klimek4da21662012-07-06 05:48:52 +00001837 EXPECT_TRUE(matches("void f() { for(;;) {} }",
Daniel Jasper6a124492012-07-12 08:50:38 +00001838 forStmt(hasBody(compoundStatement()))));
Manuel Klimek4da21662012-07-06 05:48:52 +00001839 EXPECT_TRUE(notMatches("void f() { for(;;); }",
Daniel Jasper6a124492012-07-12 08:50:38 +00001840 forStmt(hasBody(compoundStatement()))));
1841 EXPECT_TRUE(matches("void f() { while(true) {} }",
1842 whileStmt(hasBody(compoundStatement()))));
1843 EXPECT_TRUE(matches("void f() { do {} while(true); }",
1844 doStmt(hasBody(compoundStatement()))));
Manuel Klimek4da21662012-07-06 05:48:52 +00001845}
1846
1847TEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
1848 // The simplest case: every compound statement is in a function
1849 // definition, and the function body itself must be a compound
1850 // statement.
1851 EXPECT_TRUE(matches("void f() { for (;;); }",
1852 compoundStatement(hasAnySubstatement(forStmt()))));
1853}
1854
1855TEST(HasAnySubstatement, IsNotRecursive) {
1856 // It's really "has any immediate substatement".
1857 EXPECT_TRUE(notMatches("void f() { if (true) for (;;); }",
1858 compoundStatement(hasAnySubstatement(forStmt()))));
1859}
1860
1861TEST(HasAnySubstatement, MatchesInNestedCompoundStatements) {
1862 EXPECT_TRUE(matches("void f() { if (true) { for (;;); } }",
1863 compoundStatement(hasAnySubstatement(forStmt()))));
1864}
1865
1866TEST(HasAnySubstatement, FindsSubstatementBetweenOthers) {
1867 EXPECT_TRUE(matches("void f() { 1; 2; 3; for (;;); 4; 5; 6; }",
1868 compoundStatement(hasAnySubstatement(forStmt()))));
1869}
1870
1871TEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) {
1872 EXPECT_TRUE(matches("void f() { }",
1873 compoundStatement(statementCountIs(0))));
1874 EXPECT_TRUE(notMatches("void f() {}",
1875 compoundStatement(statementCountIs(1))));
1876}
1877
1878TEST(StatementCountIs, AppearsToMatchOnlyOneCount) {
1879 EXPECT_TRUE(matches("void f() { 1; }",
1880 compoundStatement(statementCountIs(1))));
1881 EXPECT_TRUE(notMatches("void f() { 1; }",
1882 compoundStatement(statementCountIs(0))));
1883 EXPECT_TRUE(notMatches("void f() { 1; }",
1884 compoundStatement(statementCountIs(2))));
1885}
1886
1887TEST(StatementCountIs, WorksWithMultipleStatements) {
1888 EXPECT_TRUE(matches("void f() { 1; 2; 3; }",
1889 compoundStatement(statementCountIs(3))));
1890}
1891
1892TEST(StatementCountIs, WorksWithNestedCompoundStatements) {
1893 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1894 compoundStatement(statementCountIs(1))));
1895 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1896 compoundStatement(statementCountIs(2))));
1897 EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
1898 compoundStatement(statementCountIs(3))));
1899 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1900 compoundStatement(statementCountIs(4))));
1901}
1902
1903TEST(Member, WorksInSimplestCase) {
1904 EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
1905 memberExpression(member(hasName("first")))));
1906}
1907
1908TEST(Member, DoesNotMatchTheBaseExpression) {
1909 // Don't pick out the wrong part of the member expression, this should
1910 // be checking the member (name) only.
1911 EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
1912 memberExpression(member(hasName("first")))));
1913}
1914
1915TEST(Member, MatchesInMemberFunctionCall) {
1916 EXPECT_TRUE(matches("void f() {"
1917 " struct { void first() {}; } s;"
1918 " s.first();"
1919 "};",
1920 memberExpression(member(hasName("first")))));
1921}
1922
1923TEST(HasObjectExpression, DoesNotMatchMember) {
1924 EXPECT_TRUE(notMatches(
1925 "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
1926 memberExpression(hasObjectExpression(hasType(record(hasName("X")))))));
1927}
1928
1929TEST(HasObjectExpression, MatchesBaseOfVariable) {
1930 EXPECT_TRUE(matches(
1931 "struct X { int m; }; void f(X x) { x.m; }",
1932 memberExpression(hasObjectExpression(hasType(record(hasName("X")))))));
1933 EXPECT_TRUE(matches(
1934 "struct X { int m; }; void f(X* x) { x->m; }",
1935 memberExpression(hasObjectExpression(
1936 hasType(pointsTo(record(hasName("X"))))))));
1937}
1938
1939TEST(HasObjectExpression,
1940 MatchesObjectExpressionOfImplicitlyFormedMemberExpression) {
1941 EXPECT_TRUE(matches(
1942 "class X {}; struct S { X m; void f() { this->m; } };",
1943 memberExpression(hasObjectExpression(
1944 hasType(pointsTo(record(hasName("S"))))))));
1945 EXPECT_TRUE(matches(
1946 "class X {}; struct S { X m; void f() { m; } };",
1947 memberExpression(hasObjectExpression(
1948 hasType(pointsTo(record(hasName("S"))))))));
1949}
1950
1951TEST(Field, DoesNotMatchNonFieldMembers) {
1952 EXPECT_TRUE(notMatches("class X { void m(); };", field(hasName("m"))));
1953 EXPECT_TRUE(notMatches("class X { class m {}; };", field(hasName("m"))));
1954 EXPECT_TRUE(notMatches("class X { enum { m }; };", field(hasName("m"))));
1955 EXPECT_TRUE(notMatches("class X { enum m {}; };", field(hasName("m"))));
1956}
1957
1958TEST(Field, MatchesField) {
1959 EXPECT_TRUE(matches("class X { int m; };", field(hasName("m"))));
1960}
1961
1962TEST(IsConstQualified, MatchesConstInt) {
1963 EXPECT_TRUE(matches("const int i = 42;",
1964 variable(hasType(isConstQualified()))));
1965}
1966
1967TEST(IsConstQualified, MatchesConstPointer) {
1968 EXPECT_TRUE(matches("int i = 42; int* const p(&i);",
1969 variable(hasType(isConstQualified()))));
1970}
1971
1972TEST(IsConstQualified, MatchesThroughTypedef) {
1973 EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
1974 variable(hasType(isConstQualified()))));
1975 EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p(0);",
1976 variable(hasType(isConstQualified()))));
1977}
1978
1979TEST(IsConstQualified, DoesNotMatchInappropriately) {
1980 EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
1981 variable(hasType(isConstQualified()))));
1982 EXPECT_TRUE(notMatches("int const* p;",
1983 variable(hasType(isConstQualified()))));
1984}
1985
1986TEST(ReinterpretCast, MatchesSimpleCase) {
1987 EXPECT_TRUE(matches("char* p = reinterpret_cast<char*>(&p);",
1988 expression(reinterpretCast())));
1989}
1990
1991TEST(ReinterpretCast, DoesNotMatchOtherCasts) {
1992 EXPECT_TRUE(notMatches("char* p = (char*)(&p);",
1993 expression(reinterpretCast())));
1994 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
1995 expression(reinterpretCast())));
1996 EXPECT_TRUE(notMatches("void* p = static_cast<void*>(&p);",
1997 expression(reinterpretCast())));
1998 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
1999 "B b;"
2000 "D* p = dynamic_cast<D*>(&b);",
2001 expression(reinterpretCast())));
2002}
2003
2004TEST(FunctionalCast, MatchesSimpleCase) {
2005 std::string foo_class = "class Foo { public: Foo(char*); };";
2006 EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",
2007 expression(functionalCast())));
2008}
2009
2010TEST(FunctionalCast, DoesNotMatchOtherCasts) {
2011 std::string FooClass = "class Foo { public: Foo(char*); };";
2012 EXPECT_TRUE(
2013 notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",
2014 expression(functionalCast())));
2015 EXPECT_TRUE(
2016 notMatches(FooClass + "void r() { Foo f = \"hello world\"; }",
2017 expression(functionalCast())));
2018}
2019
2020TEST(DynamicCast, MatchesSimpleCase) {
2021 EXPECT_TRUE(matches("struct B { virtual ~B() {} }; struct D : B {};"
2022 "B b;"
2023 "D* p = dynamic_cast<D*>(&b);",
2024 expression(dynamicCast())));
2025}
2026
2027TEST(StaticCast, MatchesSimpleCase) {
2028 EXPECT_TRUE(matches("void* p(static_cast<void*>(&p));",
2029 expression(staticCast())));
2030}
2031
2032TEST(StaticCast, DoesNotMatchOtherCasts) {
2033 EXPECT_TRUE(notMatches("char* p = (char*)(&p);",
2034 expression(staticCast())));
2035 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
2036 expression(staticCast())));
2037 EXPECT_TRUE(notMatches("void* p = reinterpret_cast<char*>(&p);",
2038 expression(staticCast())));
2039 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
2040 "B b;"
2041 "D* p = dynamic_cast<D*>(&b);",
2042 expression(staticCast())));
2043}
2044
2045TEST(HasDestinationType, MatchesSimpleCase) {
2046 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
2047 expression(
2048 staticCast(hasDestinationType(
2049 pointsTo(TypeMatcher(anything())))))));
2050}
2051
Manuel Klimek715c9562012-07-25 10:02:02 +00002052TEST(HasSourceExpression, MatchesImplicitCasts) {
Manuel Klimek4da21662012-07-06 05:48:52 +00002053 EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
2054 "void r() {string a_string; URL url = a_string; }",
2055 expression(implicitCast(
2056 hasSourceExpression(constructorCall())))));
2057}
2058
Manuel Klimek715c9562012-07-25 10:02:02 +00002059TEST(HasSourceExpression, MatchesExplicitCasts) {
2060 EXPECT_TRUE(matches("float x = static_cast<float>(42);",
2061 expression(explicitCast(
2062 hasSourceExpression(hasDescendant(
2063 expression(integerLiteral())))))));
2064}
2065
Manuel Klimek4da21662012-07-06 05:48:52 +00002066TEST(Statement, DoesNotMatchDeclarations) {
2067 EXPECT_TRUE(notMatches("class X {};", statement()));
2068}
2069
2070TEST(Statement, MatchesCompoundStatments) {
2071 EXPECT_TRUE(matches("void x() {}", statement()));
2072}
2073
2074TEST(DeclarationStatement, DoesNotMatchCompoundStatements) {
2075 EXPECT_TRUE(notMatches("void x() {}", declarationStatement()));
2076}
2077
2078TEST(DeclarationStatement, MatchesVariableDeclarationStatements) {
2079 EXPECT_TRUE(matches("void x() { int a; }", declarationStatement()));
2080}
2081
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002082TEST(InitListExpression, MatchesInitListExpression) {
2083 EXPECT_TRUE(matches("int a[] = { 1, 2 };",
2084 initListExpr(hasType(asString("int [2]")))));
2085 EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };",
2086 initListExpr(hasType(record(hasName("B"))))));
2087}
2088
2089TEST(UsingDeclaration, MatchesUsingDeclarations) {
2090 EXPECT_TRUE(matches("namespace X { int x; } using X::x;",
2091 usingDecl()));
2092}
2093
2094TEST(UsingDeclaration, MatchesShadowUsingDelcarations) {
2095 EXPECT_TRUE(matches("namespace f { int a; } using f::a;",
2096 usingDecl(hasAnyUsingShadowDecl(hasName("a")))));
2097}
2098
2099TEST(UsingDeclaration, MatchesSpecificTarget) {
2100 EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
2101 usingDecl(hasAnyUsingShadowDecl(
2102 hasTargetDecl(function())))));
2103 EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
2104 usingDecl(hasAnyUsingShadowDecl(
2105 hasTargetDecl(function())))));
2106}
2107
2108TEST(UsingDeclaration, ThroughUsingDeclaration) {
2109 EXPECT_TRUE(matches(
2110 "namespace a { void f(); } using a::f; void g() { f(); }",
2111 declarationReference(throughUsingDecl(anything()))));
2112 EXPECT_TRUE(notMatches(
2113 "namespace a { void f(); } using a::f; void g() { a::f(); }",
2114 declarationReference(throughUsingDecl(anything()))));
2115}
2116
Manuel Klimek4da21662012-07-06 05:48:52 +00002117TEST(While, MatchesWhileLoops) {
2118 EXPECT_TRUE(notMatches("void x() {}", whileStmt()));
2119 EXPECT_TRUE(matches("void x() { while(true); }", whileStmt()));
2120 EXPECT_TRUE(notMatches("void x() { do {} while(true); }", whileStmt()));
2121}
2122
2123TEST(Do, MatchesDoLoops) {
2124 EXPECT_TRUE(matches("void x() { do {} while(true); }", doStmt()));
2125 EXPECT_TRUE(matches("void x() { do ; while(false); }", doStmt()));
2126}
2127
2128TEST(Do, DoesNotMatchWhileLoops) {
2129 EXPECT_TRUE(notMatches("void x() { while(true) {} }", doStmt()));
2130}
2131
2132TEST(SwitchCase, MatchesCase) {
2133 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchCase()));
2134 EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchCase()));
2135 EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchCase()));
2136 EXPECT_TRUE(notMatches("void x() { switch(42) {} }", switchCase()));
2137}
2138
2139TEST(HasConditionVariableStatement, DoesNotMatchCondition) {
2140 EXPECT_TRUE(notMatches(
2141 "void x() { if(true) {} }",
2142 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2143 EXPECT_TRUE(notMatches(
2144 "void x() { int x; if((x = 42)) {} }",
2145 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2146}
2147
2148TEST(HasConditionVariableStatement, MatchesConditionVariables) {
2149 EXPECT_TRUE(matches(
2150 "void x() { if(int* a = 0) {} }",
2151 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2152}
2153
2154TEST(ForEach, BindsOneNode) {
2155 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002156 record(hasName("C"), forEach(field(hasName("x")).bind("x"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002157 new VerifyIdIsBoundToDecl<FieldDecl>("x", 1)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002158}
2159
2160TEST(ForEach, BindsMultipleNodes) {
2161 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002162 record(hasName("C"), forEach(field().bind("f"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002163 new VerifyIdIsBoundToDecl<FieldDecl>("f", 3)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002164}
2165
2166TEST(ForEach, BindsRecursiveCombinations) {
2167 EXPECT_TRUE(matchAndVerifyResultTrue(
2168 "class C { class D { int x; int y; }; class E { int y; int z; }; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002169 record(hasName("C"), forEach(record(forEach(field().bind("f"))))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002170 new VerifyIdIsBoundToDecl<FieldDecl>("f", 4)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002171}
2172
2173TEST(ForEachDescendant, BindsOneNode) {
2174 EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002175 record(hasName("C"), forEachDescendant(field(hasName("x")).bind("x"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002176 new VerifyIdIsBoundToDecl<FieldDecl>("x", 1)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002177}
2178
2179TEST(ForEachDescendant, BindsMultipleNodes) {
2180 EXPECT_TRUE(matchAndVerifyResultTrue(
2181 "class C { class D { int x; int y; }; "
2182 " class E { class F { int y; int z; }; }; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002183 record(hasName("C"), forEachDescendant(field().bind("f"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002184 new VerifyIdIsBoundToDecl<FieldDecl>("f", 4)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002185}
2186
2187TEST(ForEachDescendant, BindsRecursiveCombinations) {
2188 EXPECT_TRUE(matchAndVerifyResultTrue(
2189 "class C { class D { "
2190 " class E { class F { class G { int y; int z; }; }; }; }; };",
2191 record(hasName("C"), forEachDescendant(record(
Manuel Klimek9f174082012-07-24 13:37:29 +00002192 forEachDescendant(field().bind("f"))))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002193 new VerifyIdIsBoundToDecl<FieldDecl>("f", 8)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002194}
2195
2196
2197TEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) {
2198 // Make sure that we can both match the class by name (::X) and by the type
2199 // the template was instantiated with (via a field).
2200
2201 EXPECT_TRUE(matches(
2202 "template <typename T> class X {}; class A {}; X<A> x;",
2203 record(hasName("::X"), isTemplateInstantiation())));
2204
2205 EXPECT_TRUE(matches(
2206 "template <typename T> class X { T t; }; class A {}; X<A> x;",
2207 record(isTemplateInstantiation(), hasDescendant(
2208 field(hasType(record(hasName("A"))))))));
2209}
2210
2211TEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) {
2212 EXPECT_TRUE(matches(
2213 "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
2214 function(hasParameter(0, hasType(record(hasName("A")))),
2215 isTemplateInstantiation())));
2216}
2217
2218TEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) {
2219 EXPECT_TRUE(matches(
2220 "template <typename T> class X { T t; }; class A {};"
2221 "template class X<A>;",
2222 record(isTemplateInstantiation(), hasDescendant(
2223 field(hasType(record(hasName("A"))))))));
2224}
2225
2226TEST(IsTemplateInstantiation,
2227 MatchesInstantiationOfPartiallySpecializedClassTemplate) {
2228 EXPECT_TRUE(matches(
2229 "template <typename T> class X {};"
2230 "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
2231 record(hasName("::X"), isTemplateInstantiation())));
2232}
2233
2234TEST(IsTemplateInstantiation,
2235 MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
2236 EXPECT_TRUE(matches(
2237 "class A {};"
2238 "class X {"
2239 " template <typename U> class Y { U u; };"
2240 " Y<A> y;"
2241 "};",
2242 record(hasName("::X::Y"), isTemplateInstantiation())));
2243}
2244
2245TEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) {
2246 // FIXME: Figure out whether this makes sense. It doesn't affect the
2247 // normal use case as long as the uppermost instantiation always is marked
2248 // as template instantiation, but it might be confusing as a predicate.
2249 EXPECT_TRUE(matches(
2250 "class A {};"
2251 "template <typename T> class X {"
2252 " template <typename U> class Y { U u; };"
2253 " Y<T> y;"
2254 "}; X<A> x;",
2255 record(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
2256}
2257
2258TEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) {
2259 EXPECT_TRUE(notMatches(
2260 "template <typename T> class X {}; class A {};"
2261 "template <> class X<A> {}; X<A> x;",
2262 record(hasName("::X"), isTemplateInstantiation())));
2263}
2264
2265TEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) {
2266 EXPECT_TRUE(notMatches(
2267 "class A {}; class Y { A a; };",
2268 record(isTemplateInstantiation())));
2269}
2270
2271} // end namespace ast_matchers
2272} // end namespace clang