blob: f76a59696f87b2b510cf809e96cb23d1f8b46edf [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
42TEST(NameableDeclaration, MatchesVariousDecls) {
43 DeclarationMatcher NamedX = nameableDeclaration(hasName("X"));
44 EXPECT_TRUE(matches("typedef int X;", NamedX));
45 EXPECT_TRUE(matches("int X;", NamedX));
46 EXPECT_TRUE(matches("class foo { virtual void X(); };", NamedX));
47 EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", NamedX));
48 EXPECT_TRUE(matches("void foo() { int X; }", NamedX));
49 EXPECT_TRUE(matches("namespace X { }", NamedX));
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +000050 EXPECT_TRUE(matches("enum X { A, B, C };", NamedX));
Manuel Klimek4da21662012-07-06 05:48:52 +000051
52 EXPECT_TRUE(notMatches("#define X 1", NamedX));
53}
54
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +000055TEST(NameableDeclaration, REMatchesVariousDecls) {
56 DeclarationMatcher NamedX = nameableDeclaration(matchesName("::X"));
57 EXPECT_TRUE(matches("typedef int Xa;", NamedX));
58 EXPECT_TRUE(matches("int Xb;", NamedX));
59 EXPECT_TRUE(matches("class foo { virtual void Xc(); };", NamedX));
60 EXPECT_TRUE(matches("void foo() try { } catch(int Xdef) { }", NamedX));
61 EXPECT_TRUE(matches("void foo() { int Xgh; }", NamedX));
62 EXPECT_TRUE(matches("namespace Xij { }", NamedX));
63 EXPECT_TRUE(matches("enum X { A, B, C };", NamedX));
64
65 EXPECT_TRUE(notMatches("#define Xkl 1", NamedX));
66
67 DeclarationMatcher StartsWithNo = nameableDeclaration(matchesName("::no"));
68 EXPECT_TRUE(matches("int no_foo;", StartsWithNo));
69 EXPECT_TRUE(matches("class foo { virtual void nobody(); };", StartsWithNo));
70
71 DeclarationMatcher Abc = nameableDeclaration(matchesName("a.*b.*c"));
72 EXPECT_TRUE(matches("int abc;", Abc));
73 EXPECT_TRUE(matches("int aFOObBARc;", Abc));
74 EXPECT_TRUE(notMatches("int cab;", Abc));
75 EXPECT_TRUE(matches("int cabc;", Abc));
76}
77
Manuel Klimek4da21662012-07-06 05:48:52 +000078TEST(DeclarationMatcher, MatchClass) {
79 DeclarationMatcher ClassMatcher(record());
Manuel Klimeke265c872012-07-10 14:21:30 +000080#if !defined(_MSC_VER)
Manuel Klimek4da21662012-07-06 05:48:52 +000081 EXPECT_FALSE(matches("", ClassMatcher));
Manuel Klimeke265c872012-07-10 14:21:30 +000082#else
83 // Matches class type_info.
84 EXPECT_TRUE(matches("", ClassMatcher));
85#endif
Manuel Klimek4da21662012-07-06 05:48:52 +000086
87 DeclarationMatcher ClassX = record(record(hasName("X")));
88 EXPECT_TRUE(matches("class X;", ClassX));
89 EXPECT_TRUE(matches("class X {};", ClassX));
90 EXPECT_TRUE(matches("template<class T> class X {};", ClassX));
91 EXPECT_TRUE(notMatches("", ClassX));
92}
93
94TEST(DeclarationMatcher, ClassIsDerived) {
95 DeclarationMatcher IsDerivedFromX = record(isDerivedFrom("X"));
96
97 EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsDerivedFromX));
98 EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsDerivedFromX));
99 EXPECT_TRUE(matches("class X {};", IsDerivedFromX));
100 EXPECT_TRUE(matches("class X;", IsDerivedFromX));
101 EXPECT_TRUE(notMatches("class Y;", IsDerivedFromX));
102 EXPECT_TRUE(notMatches("", IsDerivedFromX));
103
104 DeclarationMatcher ZIsDerivedFromX =
105 record(hasName("Z"), isDerivedFrom("X"));
106 EXPECT_TRUE(
107 matches("class X {}; class Y : public X {}; class Z : public Y {};",
108 ZIsDerivedFromX));
109 EXPECT_TRUE(
110 matches("class X {};"
111 "template<class T> class Y : public X {};"
112 "class Z : public Y<int> {};", ZIsDerivedFromX));
113 EXPECT_TRUE(matches("class X {}; template<class T> class Z : public X {};",
114 ZIsDerivedFromX));
115 EXPECT_TRUE(
116 matches("template<class T> class X {}; "
117 "template<class T> class Z : public X<T> {};",
118 ZIsDerivedFromX));
119 EXPECT_TRUE(
120 matches("template<class T, class U=T> class X {}; "
121 "template<class T> class Z : public X<T> {};",
122 ZIsDerivedFromX));
123 EXPECT_TRUE(
124 notMatches("template<class X> class A { class Z : public X {}; };",
125 ZIsDerivedFromX));
126 EXPECT_TRUE(
127 matches("template<class X> class A { public: class Z : public X {}; }; "
128 "class X{}; void y() { A<X>::Z z; }", ZIsDerivedFromX));
129 EXPECT_TRUE(
130 matches("template <class T> class X {}; "
131 "template<class Y> class A { class Z : public X<Y> {}; };",
132 ZIsDerivedFromX));
133 EXPECT_TRUE(
134 notMatches("template<template<class T> class X> class A { "
135 " class Z : public X<int> {}; };", ZIsDerivedFromX));
136 EXPECT_TRUE(
137 matches("template<template<class T> class X> class A { "
138 " public: class Z : public X<int> {}; }; "
139 "template<class T> class X {}; void y() { A<X>::Z z; }",
140 ZIsDerivedFromX));
141 EXPECT_TRUE(
142 notMatches("template<class X> class A { class Z : public X::D {}; };",
143 ZIsDerivedFromX));
144 EXPECT_TRUE(
145 matches("template<class X> class A { public: "
146 " class Z : public X::D {}; }; "
147 "class Y { public: class X {}; typedef X D; }; "
148 "void y() { A<Y>::Z z; }", ZIsDerivedFromX));
149 EXPECT_TRUE(
150 matches("class X {}; typedef X Y; class Z : public Y {};",
151 ZIsDerivedFromX));
152 EXPECT_TRUE(
153 matches("template<class T> class Y { typedef typename T::U X; "
154 " class Z : public X {}; };", ZIsDerivedFromX));
155 EXPECT_TRUE(matches("class X {}; class Z : public ::X {};",
156 ZIsDerivedFromX));
157 EXPECT_TRUE(
158 notMatches("template<class T> class X {}; "
159 "template<class T> class A { class Z : public X<T>::D {}; };",
160 ZIsDerivedFromX));
161 EXPECT_TRUE(
162 matches("template<class T> class X { public: typedef X<T> D; }; "
163 "template<class T> class A { public: "
164 " class Z : public X<T>::D {}; }; void y() { A<int>::Z z; }",
165 ZIsDerivedFromX));
166 EXPECT_TRUE(
167 notMatches("template<class X> class A { class Z : public X::D::E {}; };",
168 ZIsDerivedFromX));
169 EXPECT_TRUE(
170 matches("class X {}; typedef X V; typedef V W; class Z : public W {};",
171 ZIsDerivedFromX));
172 EXPECT_TRUE(
173 matches("class X {}; class Y : public X {}; "
174 "typedef Y V; typedef V W; class Z : public W {};",
175 ZIsDerivedFromX));
176 EXPECT_TRUE(
177 matches("template<class T, class U> class X {}; "
178 "template<class T> class A { class Z : public X<T, int> {}; };",
179 ZIsDerivedFromX));
180 EXPECT_TRUE(
181 notMatches("template<class X> class D { typedef X A; typedef A B; "
182 " typedef B C; class Z : public C {}; };",
183 ZIsDerivedFromX));
184 EXPECT_TRUE(
185 matches("class X {}; typedef X A; typedef A B; "
186 "class Z : public B {};", ZIsDerivedFromX));
187 EXPECT_TRUE(
188 matches("class X {}; typedef X A; typedef A B; typedef B C; "
189 "class Z : public C {};", ZIsDerivedFromX));
190 EXPECT_TRUE(
191 matches("class U {}; typedef U X; typedef X V; "
192 "class Z : public V {};", ZIsDerivedFromX));
193 EXPECT_TRUE(
194 matches("class Base {}; typedef Base X; "
195 "class Z : public Base {};", ZIsDerivedFromX));
196 EXPECT_TRUE(
197 matches("class Base {}; typedef Base Base2; typedef Base2 X; "
198 "class Z : public Base {};", ZIsDerivedFromX));
199 EXPECT_TRUE(
200 notMatches("class Base {}; class Base2 {}; typedef Base2 X; "
201 "class Z : public Base {};", ZIsDerivedFromX));
202 EXPECT_TRUE(
203 matches("class A {}; typedef A X; typedef A Y; "
204 "class Z : public Y {};", ZIsDerivedFromX));
205 EXPECT_TRUE(
206 notMatches("template <typename T> class Z;"
207 "template <> class Z<void> {};"
208 "template <typename T> class Z : public Z<void> {};",
209 IsDerivedFromX));
210 EXPECT_TRUE(
211 matches("template <typename T> class X;"
212 "template <> class X<void> {};"
213 "template <typename T> class X : public X<void> {};",
214 IsDerivedFromX));
215 EXPECT_TRUE(matches(
216 "class X {};"
217 "template <typename T> class Z;"
218 "template <> class Z<void> {};"
219 "template <typename T> class Z : public Z<void>, public X {};",
220 ZIsDerivedFromX));
221
222 // FIXME: Once we have better matchers for template type matching,
223 // get rid of the Variable(...) matching and match the right template
224 // declarations directly.
225 const char *RecursiveTemplateOneParameter =
226 "class Base1 {}; class Base2 {};"
227 "template <typename T> class Z;"
228 "template <> class Z<void> : public Base1 {};"
229 "template <> class Z<int> : public Base2 {};"
230 "template <> class Z<float> : public Z<void> {};"
231 "template <> class Z<double> : public Z<int> {};"
232 "template <typename T> class Z : public Z<float>, public Z<double> {};"
233 "void f() { Z<float> z_float; Z<double> z_double; Z<char> z_char; }";
234 EXPECT_TRUE(matches(
235 RecursiveTemplateOneParameter,
236 variable(hasName("z_float"),
237 hasInitializer(hasType(record(isDerivedFrom("Base1")))))));
238 EXPECT_TRUE(notMatches(
239 RecursiveTemplateOneParameter,
240 variable(
241 hasName("z_float"),
242 hasInitializer(hasType(record(isDerivedFrom("Base2")))))));
243 EXPECT_TRUE(matches(
244 RecursiveTemplateOneParameter,
245 variable(
246 hasName("z_char"),
247 hasInitializer(hasType(record(isDerivedFrom("Base1"),
Daniel Jasper20b802d2012-07-17 07:39:27 +0000248 isDerivedFrom("Base2")))))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000249
250 const char *RecursiveTemplateTwoParameters =
251 "class Base1 {}; class Base2 {};"
252 "template <typename T1, typename T2> class Z;"
253 "template <typename T> class Z<void, T> : public Base1 {};"
254 "template <typename T> class Z<int, T> : public Base2 {};"
255 "template <typename T> class Z<float, T> : public Z<void, T> {};"
256 "template <typename T> class Z<double, T> : public Z<int, T> {};"
257 "template <typename T1, typename T2> class Z : "
258 " public Z<float, T2>, public Z<double, T2> {};"
259 "void f() { Z<float, void> z_float; Z<double, void> z_double; "
260 " Z<char, void> z_char; }";
261 EXPECT_TRUE(matches(
262 RecursiveTemplateTwoParameters,
263 variable(
264 hasName("z_float"),
265 hasInitializer(hasType(record(isDerivedFrom("Base1")))))));
266 EXPECT_TRUE(notMatches(
267 RecursiveTemplateTwoParameters,
268 variable(
269 hasName("z_float"),
270 hasInitializer(hasType(record(isDerivedFrom("Base2")))))));
271 EXPECT_TRUE(matches(
272 RecursiveTemplateTwoParameters,
273 variable(
274 hasName("z_char"),
275 hasInitializer(hasType(record(isDerivedFrom("Base1"),
Daniel Jasper20b802d2012-07-17 07:39:27 +0000276 isDerivedFrom("Base2")))))));
277 EXPECT_TRUE(matches(
278 "namespace ns { class X {}; class Y : public X {}; }",
279 record(isDerivedFrom("::ns::X"))));
280 EXPECT_TRUE(notMatches(
281 "class X {}; class Y : public X {};",
282 record(isDerivedFrom("::ns::X"))));
283
284 EXPECT_TRUE(matches(
285 "class X {}; class Y : public X {};",
Manuel Klimek9f174082012-07-24 13:37:29 +0000286 record(isDerivedFrom(record(hasName("X")).bind("test")))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000287}
288
Daniel Jasper6a124492012-07-12 08:50:38 +0000289TEST(AllOf, AllOverloadsWork) {
290 const char Program[] =
291 "struct T { }; int f(int, T*); void g(int x) { T t; f(x, &t); }";
292 EXPECT_TRUE(matches(Program,
293 call(allOf(callee(function(hasName("f"))),
294 hasArgument(0, declarationReference(to(variable())))))));
295 EXPECT_TRUE(matches(Program,
296 call(allOf(callee(function(hasName("f"))),
297 hasArgument(0, declarationReference(to(variable()))),
298 hasArgument(1, hasType(pointsTo(record(hasName("T")))))))));
299}
300
Manuel Klimek4da21662012-07-06 05:48:52 +0000301TEST(DeclarationMatcher, MatchAnyOf) {
302 DeclarationMatcher YOrZDerivedFromX =
303 record(anyOf(hasName("Y"), allOf(isDerivedFrom("X"), hasName("Z"))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000304 EXPECT_TRUE(
305 matches("class X {}; class Z : public X {};", YOrZDerivedFromX));
306 EXPECT_TRUE(matches("class Y {};", YOrZDerivedFromX));
307 EXPECT_TRUE(
308 notMatches("class X {}; class W : public X {};", YOrZDerivedFromX));
309 EXPECT_TRUE(notMatches("class Z {};", YOrZDerivedFromX));
310
Daniel Jasperff2fcb82012-07-15 19:57:12 +0000311 DeclarationMatcher XOrYOrZOrU =
312 record(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U")));
313 EXPECT_TRUE(matches("class X {};", XOrYOrZOrU));
314 EXPECT_TRUE(notMatches("class V {};", XOrYOrZOrU));
315
Manuel Klimek4da21662012-07-06 05:48:52 +0000316 DeclarationMatcher XOrYOrZOrUOrV =
317 record(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U"),
Daniel Jasperff2fcb82012-07-15 19:57:12 +0000318 hasName("V")));
Manuel Klimek4da21662012-07-06 05:48:52 +0000319 EXPECT_TRUE(matches("class X {};", XOrYOrZOrUOrV));
320 EXPECT_TRUE(matches("class Y {};", XOrYOrZOrUOrV));
321 EXPECT_TRUE(matches("class Z {};", XOrYOrZOrUOrV));
322 EXPECT_TRUE(matches("class U {};", XOrYOrZOrUOrV));
323 EXPECT_TRUE(matches("class V {};", XOrYOrZOrUOrV));
324 EXPECT_TRUE(notMatches("class A {};", XOrYOrZOrUOrV));
325}
326
327TEST(DeclarationMatcher, MatchHas) {
328 DeclarationMatcher HasClassX = record(has(record(hasName("X"))));
329
330 EXPECT_TRUE(matches("class Y { class X {}; };", HasClassX));
331 EXPECT_TRUE(matches("class X {};", HasClassX));
332
333 DeclarationMatcher YHasClassX =
334 record(hasName("Y"), has(record(hasName("X"))));
335 EXPECT_TRUE(matches("class Y { class X {}; };", YHasClassX));
336 EXPECT_TRUE(notMatches("class X {};", YHasClassX));
337 EXPECT_TRUE(
338 notMatches("class Y { class Z { class X {}; }; };", YHasClassX));
339}
340
341TEST(DeclarationMatcher, MatchHasRecursiveAllOf) {
342 DeclarationMatcher Recursive =
343 record(
344 has(record(
345 has(record(hasName("X"))),
346 has(record(hasName("Y"))),
347 hasName("Z"))),
348 has(record(
349 has(record(hasName("A"))),
350 has(record(hasName("B"))),
351 hasName("C"))),
352 hasName("F"));
353
354 EXPECT_TRUE(matches(
355 "class F {"
356 " class Z {"
357 " class X {};"
358 " class Y {};"
359 " };"
360 " class C {"
361 " class A {};"
362 " class B {};"
363 " };"
364 "};", Recursive));
365
366 EXPECT_TRUE(matches(
367 "class F {"
368 " class Z {"
369 " class A {};"
370 " class X {};"
371 " class Y {};"
372 " };"
373 " class C {"
374 " class X {};"
375 " class A {};"
376 " class B {};"
377 " };"
378 "};", Recursive));
379
380 EXPECT_TRUE(matches(
381 "class O1 {"
382 " class O2 {"
383 " class F {"
384 " class Z {"
385 " class A {};"
386 " class X {};"
387 " class Y {};"
388 " };"
389 " class C {"
390 " class X {};"
391 " class A {};"
392 " class B {};"
393 " };"
394 " };"
395 " };"
396 "};", Recursive));
397}
398
399TEST(DeclarationMatcher, MatchHasRecursiveAnyOf) {
400 DeclarationMatcher Recursive =
401 record(
402 anyOf(
403 has(record(
404 anyOf(
405 has(record(
406 hasName("X"))),
407 has(record(
408 hasName("Y"))),
409 hasName("Z")))),
410 has(record(
411 anyOf(
412 hasName("C"),
413 has(record(
414 hasName("A"))),
415 has(record(
416 hasName("B")))))),
417 hasName("F")));
418
419 EXPECT_TRUE(matches("class F {};", Recursive));
420 EXPECT_TRUE(matches("class Z {};", Recursive));
421 EXPECT_TRUE(matches("class C {};", Recursive));
422 EXPECT_TRUE(matches("class M { class N { class X {}; }; };", Recursive));
423 EXPECT_TRUE(matches("class M { class N { class B {}; }; };", Recursive));
424 EXPECT_TRUE(
425 matches("class O1 { class O2 {"
426 " class M { class N { class B {}; }; }; "
427 "}; };", Recursive));
428}
429
430TEST(DeclarationMatcher, MatchNot) {
431 DeclarationMatcher NotClassX =
432 record(
433 isDerivedFrom("Y"),
434 unless(hasName("Y")),
435 unless(hasName("X")));
436 EXPECT_TRUE(notMatches("", NotClassX));
437 EXPECT_TRUE(notMatches("class Y {};", NotClassX));
438 EXPECT_TRUE(matches("class Y {}; class Z : public Y {};", NotClassX));
439 EXPECT_TRUE(notMatches("class Y {}; class X : public Y {};", NotClassX));
440 EXPECT_TRUE(
441 notMatches("class Y {}; class Z {}; class X : public Y {};",
442 NotClassX));
443
444 DeclarationMatcher ClassXHasNotClassY =
445 record(
446 hasName("X"),
447 has(record(hasName("Z"))),
448 unless(
449 has(record(hasName("Y")))));
450 EXPECT_TRUE(matches("class X { class Z {}; };", ClassXHasNotClassY));
451 EXPECT_TRUE(notMatches("class X { class Y {}; class Z {}; };",
452 ClassXHasNotClassY));
453}
454
455TEST(DeclarationMatcher, HasDescendant) {
456 DeclarationMatcher ZDescendantClassX =
457 record(
458 hasDescendant(record(hasName("X"))),
459 hasName("Z"));
460 EXPECT_TRUE(matches("class Z { class X {}; };", ZDescendantClassX));
461 EXPECT_TRUE(
462 matches("class Z { class Y { class X {}; }; };", ZDescendantClassX));
463 EXPECT_TRUE(
464 matches("class Z { class A { class Y { class X {}; }; }; };",
465 ZDescendantClassX));
466 EXPECT_TRUE(
467 matches("class Z { class A { class B { class Y { class X {}; }; }; }; };",
468 ZDescendantClassX));
469 EXPECT_TRUE(notMatches("class Z {};", ZDescendantClassX));
470
471 DeclarationMatcher ZDescendantClassXHasClassY =
472 record(
473 hasDescendant(record(has(record(hasName("Y"))),
474 hasName("X"))),
475 hasName("Z"));
476 EXPECT_TRUE(matches("class Z { class X { class Y {}; }; };",
477 ZDescendantClassXHasClassY));
478 EXPECT_TRUE(
479 matches("class Z { class A { class B { class X { class Y {}; }; }; }; };",
480 ZDescendantClassXHasClassY));
481 EXPECT_TRUE(notMatches(
482 "class Z {"
483 " class A {"
484 " class B {"
485 " class X {"
486 " class C {"
487 " class Y {};"
488 " };"
489 " };"
490 " }; "
491 " };"
492 "};", ZDescendantClassXHasClassY));
493
494 DeclarationMatcher ZDescendantClassXDescendantClassY =
495 record(
496 hasDescendant(record(hasDescendant(record(hasName("Y"))),
497 hasName("X"))),
498 hasName("Z"));
499 EXPECT_TRUE(
500 matches("class Z { class A { class X { class B { class Y {}; }; }; }; };",
501 ZDescendantClassXDescendantClassY));
502 EXPECT_TRUE(matches(
503 "class Z {"
504 " class A {"
505 " class X {"
506 " class B {"
507 " class Y {};"
508 " };"
509 " class Y {};"
510 " };"
511 " };"
512 "};", ZDescendantClassXDescendantClassY));
513}
514
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000515TEST(Enum, DoesNotMatchClasses) {
516 EXPECT_TRUE(notMatches("class X {};", enumDecl(hasName("X"))));
517}
518
519TEST(Enum, MatchesEnums) {
520 EXPECT_TRUE(matches("enum X {};", enumDecl(hasName("X"))));
521}
522
523TEST(EnumConstant, Matches) {
524 DeclarationMatcher Matcher = enumConstant(hasName("A"));
525 EXPECT_TRUE(matches("enum X{ A };", Matcher));
526 EXPECT_TRUE(notMatches("enum X{ B };", Matcher));
527 EXPECT_TRUE(notMatches("enum X {};", Matcher));
528}
529
Manuel Klimek4da21662012-07-06 05:48:52 +0000530TEST(StatementMatcher, Has) {
531 StatementMatcher HasVariableI =
532 expression(
533 hasType(pointsTo(record(hasName("X")))),
534 has(declarationReference(to(variable(hasName("i"))))));
535
536 EXPECT_TRUE(matches(
537 "class X; X *x(int); void c() { int i; x(i); }", HasVariableI));
538 EXPECT_TRUE(notMatches(
539 "class X; X *x(int); void c() { int i; x(42); }", HasVariableI));
540}
541
542TEST(StatementMatcher, HasDescendant) {
543 StatementMatcher HasDescendantVariableI =
544 expression(
545 hasType(pointsTo(record(hasName("X")))),
546 hasDescendant(declarationReference(to(variable(hasName("i"))))));
547
548 EXPECT_TRUE(matches(
549 "class X; X *x(bool); bool b(int); void c() { int i; x(b(i)); }",
550 HasDescendantVariableI));
551 EXPECT_TRUE(notMatches(
552 "class X; X *x(bool); bool b(int); void c() { int i; x(b(42)); }",
553 HasDescendantVariableI));
554}
555
556TEST(TypeMatcher, MatchesClassType) {
557 TypeMatcher TypeA = hasDeclaration(record(hasName("A")));
558
559 EXPECT_TRUE(matches("class A { public: A *a; };", TypeA));
560 EXPECT_TRUE(notMatches("class A {};", TypeA));
561
562 TypeMatcher TypeDerivedFromA = hasDeclaration(record(isDerivedFrom("A")));
563
564 EXPECT_TRUE(matches("class A {}; class B : public A { public: B *b; };",
565 TypeDerivedFromA));
566 EXPECT_TRUE(notMatches("class A {};", TypeA));
567
568 TypeMatcher TypeAHasClassB = hasDeclaration(
569 record(hasName("A"), has(record(hasName("B")))));
570
571 EXPECT_TRUE(
572 matches("class A { public: A *a; class B {}; };", TypeAHasClassB));
573}
574
575// Returns from Run whether 'bound_nodes' contain a Decl bound to 'Id', which
576// can be dynamically casted to T.
577// Optionally checks that the check succeeded a specific number of times.
578template <typename T>
579class VerifyIdIsBoundToDecl : public BoundNodesCallback {
580public:
581 // Create an object that checks that a node of type 'T' was bound to 'Id'.
582 // Does not check for a certain number of matches.
583 explicit VerifyIdIsBoundToDecl(const std::string& Id)
584 : Id(Id), ExpectedCount(-1), Count(0) {}
585
586 // Create an object that checks that a node of type 'T' was bound to 'Id'.
587 // Checks that there were exactly 'ExpectedCount' matches.
588 explicit VerifyIdIsBoundToDecl(const std::string& Id, int ExpectedCount)
589 : Id(Id), ExpectedCount(ExpectedCount), Count(0) {}
590
591 ~VerifyIdIsBoundToDecl() {
592 if (ExpectedCount != -1) {
593 EXPECT_EQ(ExpectedCount, Count);
594 }
595 }
596
597 virtual bool run(const BoundNodes *Nodes) {
598 if (Nodes->getDeclAs<T>(Id) != NULL) {
599 ++Count;
600 return true;
601 }
602 return false;
603 }
604
605private:
606 const std::string Id;
607 const int ExpectedCount;
608 int Count;
609};
610template <typename T>
611class VerifyIdIsBoundToStmt : public BoundNodesCallback {
612public:
613 explicit VerifyIdIsBoundToStmt(const std::string &Id) : Id(Id) {}
614 virtual bool run(const BoundNodes *Nodes) {
615 const T *Node = Nodes->getStmtAs<T>(Id);
616 return Node != NULL;
617 }
618private:
619 const std::string Id;
620};
621
622TEST(Matcher, BindMatchedNodes) {
Manuel Klimek9f174082012-07-24 13:37:29 +0000623 DeclarationMatcher ClassX = has(record(hasName("::X")).bind("x"));
Manuel Klimek4da21662012-07-06 05:48:52 +0000624
625 EXPECT_TRUE(matchAndVerifyResultTrue("class X {};",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000626 ClassX, new VerifyIdIsBoundToDecl<CXXRecordDecl>("x")));
Manuel Klimek4da21662012-07-06 05:48:52 +0000627
628 EXPECT_TRUE(matchAndVerifyResultFalse("class X {};",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000629 ClassX, new VerifyIdIsBoundToDecl<CXXRecordDecl>("other-id")));
Manuel Klimek4da21662012-07-06 05:48:52 +0000630
631 TypeMatcher TypeAHasClassB = hasDeclaration(
Manuel Klimek9f174082012-07-24 13:37:29 +0000632 record(hasName("A"), has(record(hasName("B")).bind("b"))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000633
634 EXPECT_TRUE(matchAndVerifyResultTrue("class A { public: A *a; class B {}; };",
635 TypeAHasClassB,
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000636 new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +0000637
Manuel Klimek9f174082012-07-24 13:37:29 +0000638 StatementMatcher MethodX = call(callee(method(hasName("x")))).bind("x");
Manuel Klimek4da21662012-07-06 05:48:52 +0000639
640 EXPECT_TRUE(matchAndVerifyResultTrue("class A { void x() { x(); } };",
641 MethodX,
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000642 new VerifyIdIsBoundToStmt<CXXMemberCallExpr>("x")));
643}
644
645TEST(Matcher, BindTheSameNameInAlternatives) {
646 StatementMatcher matcher = anyOf(
647 binaryOperator(hasOperatorName("+"),
Manuel Klimek9f174082012-07-24 13:37:29 +0000648 hasLHS(expression().bind("x")),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000649 hasRHS(integerLiteral(equals(0)))),
650 binaryOperator(hasOperatorName("+"),
651 hasLHS(integerLiteral(equals(0))),
Manuel Klimek9f174082012-07-24 13:37:29 +0000652 hasRHS(expression().bind("x"))));
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000653
654 EXPECT_TRUE(matchAndVerifyResultTrue(
655 // The first branch of the matcher binds x to 0 but then fails.
656 // The second branch binds x to f() and succeeds.
657 "int f() { return 0 + f(); }",
658 matcher,
659 new VerifyIdIsBoundToStmt<CallExpr>("x")));
Manuel Klimek4da21662012-07-06 05:48:52 +0000660}
661
662TEST(HasType, TakesQualTypeMatcherAndMatchesExpr) {
663 TypeMatcher ClassX = hasDeclaration(record(hasName("X")));
664 EXPECT_TRUE(
665 matches("class X {}; void y(X &x) { x; }", expression(hasType(ClassX))));
666 EXPECT_TRUE(
667 notMatches("class X {}; void y(X *x) { x; }",
668 expression(hasType(ClassX))));
669 EXPECT_TRUE(
670 matches("class X {}; void y(X *x) { x; }",
671 expression(hasType(pointsTo(ClassX)))));
672}
673
674TEST(HasType, TakesQualTypeMatcherAndMatchesValueDecl) {
675 TypeMatcher ClassX = hasDeclaration(record(hasName("X")));
676 EXPECT_TRUE(
677 matches("class X {}; void y() { X x; }", variable(hasType(ClassX))));
678 EXPECT_TRUE(
679 notMatches("class X {}; void y() { X *x; }", variable(hasType(ClassX))));
680 EXPECT_TRUE(
681 matches("class X {}; void y() { X *x; }",
682 variable(hasType(pointsTo(ClassX)))));
683}
684
685TEST(HasType, TakesDeclMatcherAndMatchesExpr) {
686 DeclarationMatcher ClassX = record(hasName("X"));
687 EXPECT_TRUE(
688 matches("class X {}; void y(X &x) { x; }", expression(hasType(ClassX))));
689 EXPECT_TRUE(
690 notMatches("class X {}; void y(X *x) { x; }",
691 expression(hasType(ClassX))));
692}
693
694TEST(HasType, TakesDeclMatcherAndMatchesValueDecl) {
695 DeclarationMatcher ClassX = record(hasName("X"));
696 EXPECT_TRUE(
697 matches("class X {}; void y() { X x; }", variable(hasType(ClassX))));
698 EXPECT_TRUE(
699 notMatches("class X {}; void y() { X *x; }", variable(hasType(ClassX))));
700}
701
702TEST(Matcher, Call) {
703 // FIXME: Do we want to overload Call() to directly take
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000704 // Matcher<Decl>, too?
Manuel Klimek4da21662012-07-06 05:48:52 +0000705 StatementMatcher MethodX = call(hasDeclaration(method(hasName("x"))));
706
707 EXPECT_TRUE(matches("class Y { void x() { x(); } };", MethodX));
708 EXPECT_TRUE(notMatches("class Y { void x() {} };", MethodX));
709
Manuel Klimek9f174082012-07-24 13:37:29 +0000710 StatementMatcher MethodOnY = memberCall(on(hasType(record(hasName("Y")))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000711
712 EXPECT_TRUE(
713 matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
714 MethodOnY));
715 EXPECT_TRUE(
716 matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
717 MethodOnY));
718 EXPECT_TRUE(
719 notMatches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
720 MethodOnY));
721 EXPECT_TRUE(
722 notMatches("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
728 StatementMatcher MethodOnYPointer =
Manuel Klimek9f174082012-07-24 13:37:29 +0000729 memberCall(on(hasType(pointsTo(record(hasName("Y"))))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000730
731 EXPECT_TRUE(
732 matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
733 MethodOnYPointer));
734 EXPECT_TRUE(
735 matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
736 MethodOnYPointer));
737 EXPECT_TRUE(
738 matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
739 MethodOnYPointer));
740 EXPECT_TRUE(
741 notMatches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
742 MethodOnYPointer));
743 EXPECT_TRUE(
744 notMatches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
745 MethodOnYPointer));
746}
747
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000748TEST(HasType, MatchesAsString) {
749 EXPECT_TRUE(
750 matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }",
Manuel Klimek9f174082012-07-24 13:37:29 +0000751 memberCall(on(hasType(asString("class Y *"))))));
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000752 EXPECT_TRUE(matches("class X { void x(int x) {} };",
753 method(hasParameter(0, hasType(asString("int"))))));
754 EXPECT_TRUE(matches("namespace ns { struct A {}; } struct B { ns::A a; };",
755 field(hasType(asString("ns::A")))));
756 EXPECT_TRUE(matches("namespace { struct A {}; } struct B { A a; };",
757 field(hasType(asString("struct <anonymous>::A")))));
758}
759
Manuel Klimek4da21662012-07-06 05:48:52 +0000760TEST(Matcher, OverloadedOperatorCall) {
761 StatementMatcher OpCall = overloadedOperatorCall();
762 // Unary operator
763 EXPECT_TRUE(matches("class Y { }; "
764 "bool operator!(Y x) { return false; }; "
765 "Y y; bool c = !y;", OpCall));
766 // No match -- special operators like "new", "delete"
767 // FIXME: operator new takes size_t, for which we need stddef.h, for which
768 // we need to figure out include paths in the test.
769 // EXPECT_TRUE(NotMatches("#include <stddef.h>\n"
770 // "class Y { }; "
771 // "void *operator new(size_t size) { return 0; } "
772 // "Y *y = new Y;", OpCall));
773 EXPECT_TRUE(notMatches("class Y { }; "
774 "void operator delete(void *p) { } "
775 "void a() {Y *y = new Y; delete y;}", OpCall));
776 // Binary operator
777 EXPECT_TRUE(matches("class Y { }; "
778 "bool operator&&(Y x, Y y) { return true; }; "
779 "Y a; Y b; bool c = a && b;",
780 OpCall));
781 // No match -- normal operator, not an overloaded one.
782 EXPECT_TRUE(notMatches("bool x = true, y = true; bool t = x && y;", OpCall));
783 EXPECT_TRUE(notMatches("int t = 5 << 2;", OpCall));
784}
785
786TEST(Matcher, HasOperatorNameForOverloadedOperatorCall) {
787 StatementMatcher OpCallAndAnd =
788 overloadedOperatorCall(hasOverloadedOperatorName("&&"));
789 EXPECT_TRUE(matches("class Y { }; "
790 "bool operator&&(Y x, Y y) { return true; }; "
791 "Y a; Y b; bool c = a && b;", OpCallAndAnd));
792 StatementMatcher OpCallLessLess =
793 overloadedOperatorCall(hasOverloadedOperatorName("<<"));
794 EXPECT_TRUE(notMatches("class Y { }; "
795 "bool operator&&(Y x, Y y) { return true; }; "
796 "Y a; Y b; bool c = a && b;",
797 OpCallLessLess));
798}
799
800TEST(Matcher, ThisPointerType) {
Manuel Klimek9f174082012-07-24 13:37:29 +0000801 StatementMatcher MethodOnY =
802 memberCall(thisPointerType(record(hasName("Y"))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000803
804 EXPECT_TRUE(
805 matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
806 MethodOnY));
807 EXPECT_TRUE(
808 matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
809 MethodOnY));
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
820 EXPECT_TRUE(matches(
821 "class Y {"
822 " public: virtual void x();"
823 "};"
824 "class X : public Y {"
825 " public: virtual void x();"
826 "};"
827 "void z() { X *x; x->Y::x(); }", MethodOnY));
828}
829
830TEST(Matcher, VariableUsage) {
831 StatementMatcher Reference =
832 declarationReference(to(
833 variable(hasInitializer(
Manuel Klimek9f174082012-07-24 13:37:29 +0000834 memberCall(thisPointerType(record(hasName("Y"))))))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000835
836 EXPECT_TRUE(matches(
837 "class Y {"
838 " public:"
839 " bool x() const;"
840 "};"
841 "void z(const Y &y) {"
842 " bool b = y.x();"
843 " if (b) {}"
844 "}", Reference));
845
846 EXPECT_TRUE(notMatches(
847 "class Y {"
848 " public:"
849 " bool x() const;"
850 "};"
851 "void z(const Y &y) {"
852 " bool b = y.x();"
853 "}", Reference));
854}
855
856TEST(Matcher, CalledVariable) {
857 StatementMatcher CallOnVariableY = expression(
Manuel Klimek9f174082012-07-24 13:37:29 +0000858 memberCall(on(declarationReference(to(variable(hasName("y")))))));
Manuel Klimek4da21662012-07-06 05:48:52 +0000859
860 EXPECT_TRUE(matches(
861 "class Y { public: void x() { Y y; y.x(); } };", CallOnVariableY));
862 EXPECT_TRUE(matches(
863 "class Y { public: void x() const { Y y; y.x(); } };", CallOnVariableY));
864 EXPECT_TRUE(matches(
865 "class Y { public: void x(); };"
866 "class X : public Y { void z() { X y; y.x(); } };", CallOnVariableY));
867 EXPECT_TRUE(matches(
868 "class Y { public: void x(); };"
869 "class X : public Y { void z() { X *y; y->x(); } };", CallOnVariableY));
870 EXPECT_TRUE(notMatches(
871 "class Y { public: void x(); };"
872 "class X : public Y { void z() { unsigned long y; ((X*)y)->x(); } };",
873 CallOnVariableY));
874}
875
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000876TEST(UnaryExprOrTypeTraitExpr, MatchesSizeOfAndAlignOf) {
877 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }",
878 unaryExprOrTypeTraitExpr()));
879 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }",
880 alignOfExpr(anything())));
881 // FIXME: Uncomment once alignof is enabled.
882 // EXPECT_TRUE(matches("void x() { int a = alignof(a); }",
883 // unaryExprOrTypeTraitExpr()));
884 // EXPECT_TRUE(notMatches("void x() { int a = alignof(a); }",
885 // sizeOfExpr()));
886}
887
888TEST(UnaryExpressionOrTypeTraitExpression, MatchesCorrectType) {
889 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }", sizeOfExpr(
890 hasArgumentOfType(asString("int")))));
891 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
892 hasArgumentOfType(asString("float")))));
893 EXPECT_TRUE(matches(
894 "struct A {}; void x() { A a; int b = sizeof(a); }",
895 sizeOfExpr(hasArgumentOfType(hasDeclaration(record(hasName("A")))))));
896 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
897 hasArgumentOfType(hasDeclaration(record(hasName("string")))))));
898}
899
Manuel Klimek4da21662012-07-06 05:48:52 +0000900TEST(MemberExpression, DoesNotMatchClasses) {
901 EXPECT_TRUE(notMatches("class Y { void x() {} };", memberExpression()));
902}
903
904TEST(MemberExpression, MatchesMemberFunctionCall) {
905 EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpression()));
906}
907
908TEST(MemberExpression, MatchesVariable) {
909 EXPECT_TRUE(
910 matches("class Y { void x() { this->y; } int y; };", memberExpression()));
911 EXPECT_TRUE(
912 matches("class Y { void x() { y; } int y; };", memberExpression()));
913 EXPECT_TRUE(
914 matches("class Y { void x() { Y y; y.y; } int y; };",
915 memberExpression()));
916}
917
918TEST(MemberExpression, MatchesStaticVariable) {
919 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
920 memberExpression()));
921 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
922 memberExpression()));
923 EXPECT_TRUE(notMatches("class Y { void x() { Y::y; } static int y; };",
924 memberExpression()));
925}
926
Daniel Jasper6a124492012-07-12 08:50:38 +0000927TEST(IsInteger, MatchesIntegers) {
928 EXPECT_TRUE(matches("int i = 0;", variable(hasType(isInteger()))));
929 EXPECT_TRUE(matches("long long i = 0; void f(long long) { }; void g() {f(i);}",
930 call(hasArgument(0, declarationReference(
931 to(variable(hasType(isInteger()))))))));
932}
933
934TEST(IsInteger, ReportsNoFalsePositives) {
935 EXPECT_TRUE(notMatches("int *i;", variable(hasType(isInteger()))));
936 EXPECT_TRUE(notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}",
937 call(hasArgument(0, declarationReference(
938 to(variable(hasType(isInteger()))))))));
939}
940
Manuel Klimek4da21662012-07-06 05:48:52 +0000941TEST(IsArrow, MatchesMemberVariablesViaArrow) {
942 EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };",
943 memberExpression(isArrow())));
944 EXPECT_TRUE(matches("class Y { void x() { y; } int y; };",
945 memberExpression(isArrow())));
946 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };",
947 memberExpression(isArrow())));
948}
949
950TEST(IsArrow, MatchesStaticMemberVariablesViaArrow) {
951 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
952 memberExpression(isArrow())));
953 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
954 memberExpression(isArrow())));
955 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } static int y; };",
956 memberExpression(isArrow())));
957}
958
959TEST(IsArrow, MatchesMemberCallsViaArrow) {
960 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
961 memberExpression(isArrow())));
962 EXPECT_TRUE(matches("class Y { void x() { x(); } };",
963 memberExpression(isArrow())));
964 EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",
965 memberExpression(isArrow())));
966}
967
968TEST(Callee, MatchesDeclarations) {
969 StatementMatcher CallMethodX = call(callee(method(hasName("x"))));
970
971 EXPECT_TRUE(matches("class Y { void x() { x(); } };", CallMethodX));
972 EXPECT_TRUE(notMatches("class Y { void x() {} };", CallMethodX));
973}
974
975TEST(Callee, MatchesMemberExpressions) {
976 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
977 call(callee(memberExpression()))));
978 EXPECT_TRUE(
979 notMatches("class Y { void x() { this->x(); } };", call(callee(call()))));
980}
981
982TEST(Function, MatchesFunctionDeclarations) {
983 StatementMatcher CallFunctionF = call(callee(function(hasName("f"))));
984
985 EXPECT_TRUE(matches("void f() { f(); }", CallFunctionF));
986 EXPECT_TRUE(notMatches("void f() { }", CallFunctionF));
987
Manuel Klimeke265c872012-07-10 14:21:30 +0000988#if !defined(_MSC_VER)
989 // FIXME: Make this work for MSVC.
Manuel Klimek4da21662012-07-06 05:48:52 +0000990 // Dependent contexts, but a non-dependent call.
991 EXPECT_TRUE(matches("void f(); template <int N> void g() { f(); }",
992 CallFunctionF));
993 EXPECT_TRUE(
994 matches("void f(); template <int N> struct S { void g() { f(); } };",
995 CallFunctionF));
Manuel Klimeke265c872012-07-10 14:21:30 +0000996#endif
Manuel Klimek4da21662012-07-06 05:48:52 +0000997
998 // Depedent calls don't match.
999 EXPECT_TRUE(
1000 notMatches("void f(int); template <typename T> void g(T t) { f(t); }",
1001 CallFunctionF));
1002 EXPECT_TRUE(
1003 notMatches("void f(int);"
1004 "template <typename T> struct S { void g(T t) { f(t); } };",
1005 CallFunctionF));
1006}
1007
1008TEST(Matcher, Argument) {
1009 StatementMatcher CallArgumentY = expression(call(
1010 hasArgument(0, declarationReference(to(variable(hasName("y")))))));
1011
1012 EXPECT_TRUE(matches("void x(int) { int y; x(y); }", CallArgumentY));
1013 EXPECT_TRUE(
1014 matches("class X { void x(int) { int y; x(y); } };", CallArgumentY));
1015 EXPECT_TRUE(notMatches("void x(int) { int z; x(z); }", CallArgumentY));
1016
1017 StatementMatcher WrongIndex = expression(call(
1018 hasArgument(42, declarationReference(to(variable(hasName("y")))))));
1019 EXPECT_TRUE(notMatches("void x(int) { int y; x(y); }", WrongIndex));
1020}
1021
1022TEST(Matcher, AnyArgument) {
1023 StatementMatcher CallArgumentY = expression(call(
1024 hasAnyArgument(declarationReference(to(variable(hasName("y")))))));
1025 EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
1026 EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
1027 EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
1028}
1029
1030TEST(Matcher, ArgumentCount) {
1031 StatementMatcher Call1Arg = expression(call(argumentCountIs(1)));
1032
1033 EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg));
1034 EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg));
1035 EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg));
1036}
1037
1038TEST(Matcher, References) {
1039 DeclarationMatcher ReferenceClassX = variable(
1040 hasType(references(record(hasName("X")))));
1041 EXPECT_TRUE(matches("class X {}; void y(X y) { X &x = y; }",
1042 ReferenceClassX));
1043 EXPECT_TRUE(
1044 matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
1045 EXPECT_TRUE(
1046 notMatches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
1047 EXPECT_TRUE(
1048 notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
1049}
1050
1051TEST(HasParameter, CallsInnerMatcher) {
1052 EXPECT_TRUE(matches("class X { void x(int) {} };",
1053 method(hasParameter(0, variable()))));
1054 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
1055 method(hasParameter(0, hasName("x")))));
1056}
1057
1058TEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) {
1059 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
1060 method(hasParameter(42, variable()))));
1061}
1062
1063TEST(HasType, MatchesParameterVariableTypesStrictly) {
1064 EXPECT_TRUE(matches("class X { void x(X x) {} };",
1065 method(hasParameter(0, hasType(record(hasName("X")))))));
1066 EXPECT_TRUE(notMatches("class X { void x(const X &x) {} };",
1067 method(hasParameter(0, hasType(record(hasName("X")))))));
1068 EXPECT_TRUE(matches("class X { void x(const X *x) {} };",
1069 method(hasParameter(0, hasType(pointsTo(record(hasName("X"))))))));
1070 EXPECT_TRUE(matches("class X { void x(const X &x) {} };",
1071 method(hasParameter(0, hasType(references(record(hasName("X"))))))));
1072}
1073
1074TEST(HasAnyParameter, MatchesIndependentlyOfPosition) {
1075 EXPECT_TRUE(matches("class Y {}; class X { void x(X x, Y y) {} };",
1076 method(hasAnyParameter(hasType(record(hasName("X")))))));
1077 EXPECT_TRUE(matches("class Y {}; class X { void x(Y y, X x) {} };",
1078 method(hasAnyParameter(hasType(record(hasName("X")))))));
1079}
1080
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001081TEST(Returns, MatchesReturnTypes) {
1082 EXPECT_TRUE(matches("class Y { int f() { return 1; } };",
1083 function(returns(asString("int")))));
1084 EXPECT_TRUE(notMatches("class Y { int f() { return 1; } };",
1085 function(returns(asString("float")))));
1086 EXPECT_TRUE(matches("class Y { Y getMe() { return *this; } };",
1087 function(returns(hasDeclaration(record(hasName("Y")))))));
1088}
1089
Manuel Klimek4da21662012-07-06 05:48:52 +00001090TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
1091 EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
1092 method(hasAnyParameter(hasType(record(hasName("X")))))));
1093}
1094
1095TEST(HasAnyParameter, DoesNotMatchThisPointer) {
1096 EXPECT_TRUE(notMatches("class Y {}; class X { void x() {} };",
1097 method(hasAnyParameter(hasType(pointsTo(record(hasName("X"))))))));
1098}
1099
1100TEST(HasName, MatchesParameterVariableDeclartions) {
1101 EXPECT_TRUE(matches("class Y {}; class X { void x(int x) {} };",
1102 method(hasAnyParameter(hasName("x")))));
1103 EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
1104 method(hasAnyParameter(hasName("x")))));
1105}
1106
1107TEST(Matcher, ConstructorCall) {
1108 StatementMatcher Constructor = expression(constructorCall());
1109
1110 EXPECT_TRUE(
1111 matches("class X { public: X(); }; void x() { X x; }", Constructor));
1112 EXPECT_TRUE(
1113 matches("class X { public: X(); }; void x() { X x = X(); }",
1114 Constructor));
1115 EXPECT_TRUE(
1116 matches("class X { public: X(int); }; void x() { X x = 0; }",
1117 Constructor));
1118 EXPECT_TRUE(matches("class X {}; void x(int) { X x; }", Constructor));
1119}
1120
1121TEST(Matcher, ConstructorArgument) {
1122 StatementMatcher Constructor = expression(constructorCall(
1123 hasArgument(0, declarationReference(to(variable(hasName("y")))))));
1124
1125 EXPECT_TRUE(
1126 matches("class X { public: X(int); }; void x() { int y; X x(y); }",
1127 Constructor));
1128 EXPECT_TRUE(
1129 matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
1130 Constructor));
1131 EXPECT_TRUE(
1132 matches("class X { public: X(int); }; void x() { int y; X x = y; }",
1133 Constructor));
1134 EXPECT_TRUE(
1135 notMatches("class X { public: X(int); }; void x() { int z; X x(z); }",
1136 Constructor));
1137
1138 StatementMatcher WrongIndex = expression(constructorCall(
1139 hasArgument(42, declarationReference(to(variable(hasName("y")))))));
1140 EXPECT_TRUE(
1141 notMatches("class X { public: X(int); }; void x() { int y; X x(y); }",
1142 WrongIndex));
1143}
1144
1145TEST(Matcher, ConstructorArgumentCount) {
1146 StatementMatcher Constructor1Arg =
1147 expression(constructorCall(argumentCountIs(1)));
1148
1149 EXPECT_TRUE(
1150 matches("class X { public: X(int); }; void x() { X x(0); }",
1151 Constructor1Arg));
1152 EXPECT_TRUE(
1153 matches("class X { public: X(int); }; void x() { X x = X(0); }",
1154 Constructor1Arg));
1155 EXPECT_TRUE(
1156 matches("class X { public: X(int); }; void x() { X x = 0; }",
1157 Constructor1Arg));
1158 EXPECT_TRUE(
1159 notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
1160 Constructor1Arg));
1161}
1162
1163TEST(Matcher, BindTemporaryExpression) {
1164 StatementMatcher TempExpression = expression(bindTemporaryExpression());
1165
1166 std::string ClassString = "class string { public: string(); ~string(); }; ";
1167
1168 EXPECT_TRUE(
1169 matches(ClassString +
1170 "string GetStringByValue();"
1171 "void FunctionTakesString(string s);"
1172 "void run() { FunctionTakesString(GetStringByValue()); }",
1173 TempExpression));
1174
1175 EXPECT_TRUE(
1176 notMatches(ClassString +
1177 "string* GetStringPointer(); "
1178 "void FunctionTakesStringPtr(string* s);"
1179 "void run() {"
1180 " string* s = GetStringPointer();"
1181 " FunctionTakesStringPtr(GetStringPointer());"
1182 " FunctionTakesStringPtr(s);"
1183 "}",
1184 TempExpression));
1185
1186 EXPECT_TRUE(
1187 notMatches("class no_dtor {};"
1188 "no_dtor GetObjByValue();"
1189 "void ConsumeObj(no_dtor param);"
1190 "void run() { ConsumeObj(GetObjByValue()); }",
1191 TempExpression));
1192}
1193
1194TEST(ConstructorDeclaration, SimpleCase) {
1195 EXPECT_TRUE(matches("class Foo { Foo(int i); };",
1196 constructor(ofClass(hasName("Foo")))));
1197 EXPECT_TRUE(notMatches("class Foo { Foo(int i); };",
1198 constructor(ofClass(hasName("Bar")))));
1199}
1200
1201TEST(ConstructorDeclaration, IsImplicit) {
1202 // This one doesn't match because the constructor is not added by the
1203 // compiler (it is not needed).
1204 EXPECT_TRUE(notMatches("class Foo { };",
1205 constructor(isImplicit())));
1206 // The compiler added the implicit default constructor.
1207 EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
1208 constructor(isImplicit())));
1209 EXPECT_TRUE(matches("class Foo { Foo(){} };",
1210 constructor(unless(isImplicit()))));
1211}
1212
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001213TEST(DestructorDeclaration, MatchesVirtualDestructor) {
1214 EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };",
1215 destructor(ofClass(hasName("Foo")))));
1216}
1217
1218TEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) {
1219 EXPECT_TRUE(notMatches("class Foo {};", destructor(ofClass(hasName("Foo")))));
1220}
1221
Manuel Klimek4da21662012-07-06 05:48:52 +00001222TEST(HasAnyConstructorInitializer, SimpleCase) {
1223 EXPECT_TRUE(notMatches(
1224 "class Foo { Foo() { } };",
1225 constructor(hasAnyConstructorInitializer(anything()))));
1226 EXPECT_TRUE(matches(
1227 "class Foo {"
1228 " Foo() : foo_() { }"
1229 " int foo_;"
1230 "};",
1231 constructor(hasAnyConstructorInitializer(anything()))));
1232}
1233
1234TEST(HasAnyConstructorInitializer, ForField) {
1235 static const char Code[] =
1236 "class Baz { };"
1237 "class Foo {"
1238 " Foo() : foo_() { }"
1239 " Baz foo_;"
1240 " Baz bar_;"
1241 "};";
1242 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1243 forField(hasType(record(hasName("Baz"))))))));
1244 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1245 forField(hasName("foo_"))))));
1246 EXPECT_TRUE(notMatches(Code, constructor(hasAnyConstructorInitializer(
1247 forField(hasType(record(hasName("Bar"))))))));
1248}
1249
1250TEST(HasAnyConstructorInitializer, WithInitializer) {
1251 static const char Code[] =
1252 "class Foo {"
1253 " Foo() : foo_(0) { }"
1254 " int foo_;"
1255 "};";
1256 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1257 withInitializer(integerLiteral(equals(0)))))));
1258 EXPECT_TRUE(notMatches(Code, constructor(hasAnyConstructorInitializer(
1259 withInitializer(integerLiteral(equals(1)))))));
1260}
1261
1262TEST(HasAnyConstructorInitializer, IsWritten) {
1263 static const char Code[] =
1264 "struct Bar { Bar(){} };"
1265 "class Foo {"
1266 " Foo() : foo_() { }"
1267 " Bar foo_;"
1268 " Bar bar_;"
1269 "};";
1270 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1271 allOf(forField(hasName("foo_")), isWritten())))));
1272 EXPECT_TRUE(notMatches(Code, constructor(hasAnyConstructorInitializer(
1273 allOf(forField(hasName("bar_")), isWritten())))));
1274 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1275 allOf(forField(hasName("bar_")), unless(isWritten()))))));
1276}
1277
1278TEST(Matcher, NewExpression) {
1279 StatementMatcher New = expression(newExpression());
1280
1281 EXPECT_TRUE(matches("class X { public: X(); }; void x() { new X; }", New));
1282 EXPECT_TRUE(
1283 matches("class X { public: X(); }; void x() { new X(); }", New));
1284 EXPECT_TRUE(
1285 matches("class X { public: X(int); }; void x() { new X(0); }", New));
1286 EXPECT_TRUE(matches("class X {}; void x(int) { new X; }", New));
1287}
1288
1289TEST(Matcher, NewExpressionArgument) {
1290 StatementMatcher New = expression(constructorCall(
1291 hasArgument(
1292 0, declarationReference(to(variable(hasName("y")))))));
1293
1294 EXPECT_TRUE(
1295 matches("class X { public: X(int); }; void x() { int y; new X(y); }",
1296 New));
1297 EXPECT_TRUE(
1298 matches("class X { public: X(int); }; void x() { int y; new X(y); }",
1299 New));
1300 EXPECT_TRUE(
1301 notMatches("class X { public: X(int); }; void x() { int z; new X(z); }",
1302 New));
1303
1304 StatementMatcher WrongIndex = expression(constructorCall(
1305 hasArgument(
1306 42, declarationReference(to(variable(hasName("y")))))));
1307 EXPECT_TRUE(
1308 notMatches("class X { public: X(int); }; void x() { int y; new X(y); }",
1309 WrongIndex));
1310}
1311
1312TEST(Matcher, NewExpressionArgumentCount) {
1313 StatementMatcher New = constructorCall(argumentCountIs(1));
1314
1315 EXPECT_TRUE(
1316 matches("class X { public: X(int); }; void x() { new X(0); }", New));
1317 EXPECT_TRUE(
1318 notMatches("class X { public: X(int, int); }; void x() { new X(0, 0); }",
1319 New));
1320}
1321
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001322TEST(Matcher, DeleteExpression) {
1323 EXPECT_TRUE(matches("struct A {}; void f(A* a) { delete a; }",
1324 deleteExpression()));
1325}
1326
Manuel Klimek4da21662012-07-06 05:48:52 +00001327TEST(Matcher, DefaultArgument) {
1328 StatementMatcher Arg = defaultArgument();
1329
1330 EXPECT_TRUE(matches("void x(int, int = 0) { int y; x(y); }", Arg));
1331 EXPECT_TRUE(
1332 matches("class X { void x(int, int = 0) { int y; x(y); } };", Arg));
1333 EXPECT_TRUE(notMatches("void x(int, int = 0) { int y; x(y, 0); }", Arg));
1334}
1335
1336TEST(Matcher, StringLiterals) {
1337 StatementMatcher Literal = expression(stringLiteral());
1338 EXPECT_TRUE(matches("const char *s = \"string\";", Literal));
1339 // wide string
1340 EXPECT_TRUE(matches("const wchar_t *s = L\"string\";", Literal));
1341 // with escaped characters
1342 EXPECT_TRUE(matches("const char *s = \"\x05five\";", Literal));
1343 // no matching -- though the data type is the same, there is no string literal
1344 EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));
1345}
1346
1347TEST(Matcher, CharacterLiterals) {
1348 StatementMatcher CharLiteral = expression(characterLiteral());
1349 EXPECT_TRUE(matches("const char c = 'c';", CharLiteral));
1350 // wide character
1351 EXPECT_TRUE(matches("const char c = L'c';", CharLiteral));
1352 // wide character, Hex encoded, NOT MATCHED!
1353 EXPECT_TRUE(notMatches("const wchar_t c = 0x2126;", CharLiteral));
1354 EXPECT_TRUE(notMatches("const char c = 0x1;", CharLiteral));
1355}
1356
1357TEST(Matcher, IntegerLiterals) {
1358 StatementMatcher HasIntLiteral = expression(integerLiteral());
1359 EXPECT_TRUE(matches("int i = 10;", HasIntLiteral));
1360 EXPECT_TRUE(matches("int i = 0x1AB;", HasIntLiteral));
1361 EXPECT_TRUE(matches("int i = 10L;", HasIntLiteral));
1362 EXPECT_TRUE(matches("int i = 10U;", HasIntLiteral));
1363
1364 // Non-matching cases (character literals, float and double)
1365 EXPECT_TRUE(notMatches("int i = L'a';",
1366 HasIntLiteral)); // this is actually a character
1367 // literal cast to int
1368 EXPECT_TRUE(notMatches("int i = 'a';", HasIntLiteral));
1369 EXPECT_TRUE(notMatches("int i = 1e10;", HasIntLiteral));
1370 EXPECT_TRUE(notMatches("int i = 10.0;", HasIntLiteral));
1371}
1372
1373TEST(Matcher, Conditions) {
1374 StatementMatcher Condition = ifStmt(hasCondition(boolLiteral(equals(true))));
1375
1376 EXPECT_TRUE(matches("void x() { if (true) {} }", Condition));
1377 EXPECT_TRUE(notMatches("void x() { if (false) {} }", Condition));
1378 EXPECT_TRUE(notMatches("void x() { bool a = true; if (a) {} }", Condition));
1379 EXPECT_TRUE(notMatches("void x() { if (true || false) {} }", Condition));
1380 EXPECT_TRUE(notMatches("void x() { if (1) {} }", Condition));
1381}
1382
1383TEST(MatchBinaryOperator, HasOperatorName) {
1384 StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
1385
1386 EXPECT_TRUE(matches("void x() { true || false; }", OperatorOr));
1387 EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
1388}
1389
1390TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
1391 StatementMatcher OperatorTrueFalse =
1392 binaryOperator(hasLHS(boolLiteral(equals(true))),
1393 hasRHS(boolLiteral(equals(false))));
1394
1395 EXPECT_TRUE(matches("void x() { true || false; }", OperatorTrueFalse));
1396 EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse));
1397 EXPECT_TRUE(notMatches("void x() { false || true; }", OperatorTrueFalse));
1398}
1399
1400TEST(MatchBinaryOperator, HasEitherOperand) {
1401 StatementMatcher HasOperand =
1402 binaryOperator(hasEitherOperand(boolLiteral(equals(false))));
1403
1404 EXPECT_TRUE(matches("void x() { true || false; }", HasOperand));
1405 EXPECT_TRUE(matches("void x() { false && true; }", HasOperand));
1406 EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand));
1407}
1408
1409TEST(Matcher, BinaryOperatorTypes) {
1410 // Integration test that verifies the AST provides all binary operators in
1411 // a way we expect.
1412 // FIXME: Operator ','
1413 EXPECT_TRUE(
1414 matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(","))));
1415 EXPECT_TRUE(
1416 matches("bool b; bool c = (b = true);",
1417 binaryOperator(hasOperatorName("="))));
1418 EXPECT_TRUE(
1419 matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!="))));
1420 EXPECT_TRUE(
1421 matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("=="))));
1422 EXPECT_TRUE(matches("bool b = 1 < 2;", binaryOperator(hasOperatorName("<"))));
1423 EXPECT_TRUE(
1424 matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<="))));
1425 EXPECT_TRUE(
1426 matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<"))));
1427 EXPECT_TRUE(
1428 matches("int i = 1; int j = (i <<= 2);",
1429 binaryOperator(hasOperatorName("<<="))));
1430 EXPECT_TRUE(matches("bool b = 1 > 2;", binaryOperator(hasOperatorName(">"))));
1431 EXPECT_TRUE(
1432 matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">="))));
1433 EXPECT_TRUE(
1434 matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>"))));
1435 EXPECT_TRUE(
1436 matches("int i = 1; int j = (i >>= 2);",
1437 binaryOperator(hasOperatorName(">>="))));
1438 EXPECT_TRUE(
1439 matches("int i = 42 ^ 23;", binaryOperator(hasOperatorName("^"))));
1440 EXPECT_TRUE(
1441 matches("int i = 42; int j = (i ^= 42);",
1442 binaryOperator(hasOperatorName("^="))));
1443 EXPECT_TRUE(
1444 matches("int i = 42 % 23;", binaryOperator(hasOperatorName("%"))));
1445 EXPECT_TRUE(
1446 matches("int i = 42; int j = (i %= 42);",
1447 binaryOperator(hasOperatorName("%="))));
1448 EXPECT_TRUE(
1449 matches("bool b = 42 &23;", binaryOperator(hasOperatorName("&"))));
1450 EXPECT_TRUE(
1451 matches("bool b = true && false;",
1452 binaryOperator(hasOperatorName("&&"))));
1453 EXPECT_TRUE(
1454 matches("bool b = true; bool c = (b &= false);",
1455 binaryOperator(hasOperatorName("&="))));
1456 EXPECT_TRUE(
1457 matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|"))));
1458 EXPECT_TRUE(
1459 matches("bool b = true || false;",
1460 binaryOperator(hasOperatorName("||"))));
1461 EXPECT_TRUE(
1462 matches("bool b = true; bool c = (b |= false);",
1463 binaryOperator(hasOperatorName("|="))));
1464 EXPECT_TRUE(
1465 matches("int i = 42 *23;", binaryOperator(hasOperatorName("*"))));
1466 EXPECT_TRUE(
1467 matches("int i = 42; int j = (i *= 23);",
1468 binaryOperator(hasOperatorName("*="))));
1469 EXPECT_TRUE(
1470 matches("int i = 42 / 23;", binaryOperator(hasOperatorName("/"))));
1471 EXPECT_TRUE(
1472 matches("int i = 42; int j = (i /= 23);",
1473 binaryOperator(hasOperatorName("/="))));
1474 EXPECT_TRUE(
1475 matches("int i = 42 + 23;", binaryOperator(hasOperatorName("+"))));
1476 EXPECT_TRUE(
1477 matches("int i = 42; int j = (i += 23);",
1478 binaryOperator(hasOperatorName("+="))));
1479 EXPECT_TRUE(
1480 matches("int i = 42 - 23;", binaryOperator(hasOperatorName("-"))));
1481 EXPECT_TRUE(
1482 matches("int i = 42; int j = (i -= 23);",
1483 binaryOperator(hasOperatorName("-="))));
1484 EXPECT_TRUE(
1485 matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };",
1486 binaryOperator(hasOperatorName("->*"))));
1487 EXPECT_TRUE(
1488 matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };",
1489 binaryOperator(hasOperatorName(".*"))));
1490
1491 // Member expressions as operators are not supported in matches.
1492 EXPECT_TRUE(
1493 notMatches("struct A { void x(A *a) { a->x(this); } };",
1494 binaryOperator(hasOperatorName("->"))));
1495
1496 // Initializer assignments are not represented as operator equals.
1497 EXPECT_TRUE(
1498 notMatches("bool b = true;", binaryOperator(hasOperatorName("="))));
1499
1500 // Array indexing is not represented as operator.
1501 EXPECT_TRUE(notMatches("int a[42]; void x() { a[23]; }", unaryOperator()));
1502
1503 // Overloaded operators do not match at all.
1504 EXPECT_TRUE(notMatches(
1505 "struct A { bool operator&&(const A &a) const { return false; } };"
1506 "void x() { A a, b; a && b; }",
1507 binaryOperator()));
1508}
1509
1510TEST(MatchUnaryOperator, HasOperatorName) {
1511 StatementMatcher OperatorNot = unaryOperator(hasOperatorName("!"));
1512
1513 EXPECT_TRUE(matches("void x() { !true; } ", OperatorNot));
1514 EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
1515}
1516
1517TEST(MatchUnaryOperator, HasUnaryOperand) {
1518 StatementMatcher OperatorOnFalse =
1519 unaryOperator(hasUnaryOperand(boolLiteral(equals(false))));
1520
1521 EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse));
1522 EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse));
1523}
1524
1525TEST(Matcher, UnaryOperatorTypes) {
1526 // Integration test that verifies the AST provides all unary operators in
1527 // a way we expect.
1528 EXPECT_TRUE(matches("bool b = !true;", unaryOperator(hasOperatorName("!"))));
1529 EXPECT_TRUE(
1530 matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&"))));
1531 EXPECT_TRUE(matches("int i = ~ 1;", unaryOperator(hasOperatorName("~"))));
1532 EXPECT_TRUE(
1533 matches("bool *p; bool b = *p;", unaryOperator(hasOperatorName("*"))));
1534 EXPECT_TRUE(
1535 matches("int i; int j = +i;", unaryOperator(hasOperatorName("+"))));
1536 EXPECT_TRUE(
1537 matches("int i; int j = -i;", unaryOperator(hasOperatorName("-"))));
1538 EXPECT_TRUE(
1539 matches("int i; int j = ++i;", 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
1547 // We don't match conversion operators.
1548 EXPECT_TRUE(notMatches("int i; double d = (double)i;", unaryOperator()));
1549
1550 // Function calls are not represented as operator.
1551 EXPECT_TRUE(notMatches("void f(); void x() { f(); }", unaryOperator()));
1552
1553 // Overloaded operators do not match at all.
1554 // FIXME: We probably want to add that.
1555 EXPECT_TRUE(notMatches(
1556 "struct A { bool operator!() const { return false; } };"
1557 "void x() { A a; !a; }", unaryOperator(hasOperatorName("!"))));
1558}
1559
1560TEST(Matcher, ConditionalOperator) {
1561 StatementMatcher Conditional = conditionalOperator(
1562 hasCondition(boolLiteral(equals(true))),
1563 hasTrueExpression(boolLiteral(equals(false))));
1564
1565 EXPECT_TRUE(matches("void x() { true ? false : true; }", Conditional));
1566 EXPECT_TRUE(notMatches("void x() { false ? false : true; }", Conditional));
1567 EXPECT_TRUE(notMatches("void x() { true ? true : false; }", Conditional));
1568
1569 StatementMatcher ConditionalFalse = conditionalOperator(
1570 hasFalseExpression(boolLiteral(equals(false))));
1571
1572 EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
1573 EXPECT_TRUE(
1574 notMatches("void x() { true ? false : true; }", ConditionalFalse));
1575}
1576
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001577TEST(ArraySubscriptMatchers, ArraySubscripts) {
1578 EXPECT_TRUE(matches("int i[2]; void f() { i[1] = 1; }",
1579 arraySubscriptExpr()));
1580 EXPECT_TRUE(notMatches("int i; void f() { i = 1; }",
1581 arraySubscriptExpr()));
1582}
1583
1584TEST(ArraySubscriptMatchers, ArrayIndex) {
1585 EXPECT_TRUE(matches(
1586 "int i[2]; void f() { i[1] = 1; }",
1587 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
1588 EXPECT_TRUE(matches(
1589 "int i[2]; void f() { 1[i] = 1; }",
1590 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
1591 EXPECT_TRUE(notMatches(
1592 "int i[2]; void f() { i[1] = 1; }",
1593 arraySubscriptExpr(hasIndex(integerLiteral(equals(0))))));
1594}
1595
1596TEST(ArraySubscriptMatchers, MatchesArrayBase) {
1597 EXPECT_TRUE(matches(
1598 "int i[2]; void f() { i[1] = 2; }",
1599 arraySubscriptExpr(hasBase(implicitCast(
1600 hasSourceExpression(declarationReference()))))));
1601}
1602
Manuel Klimek4da21662012-07-06 05:48:52 +00001603TEST(Matcher, HasNameSupportsNamespaces) {
1604 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1605 record(hasName("a::b::C"))));
1606 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1607 record(hasName("::a::b::C"))));
1608 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1609 record(hasName("b::C"))));
1610 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1611 record(hasName("C"))));
1612 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1613 record(hasName("c::b::C"))));
1614 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1615 record(hasName("a::c::C"))));
1616 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1617 record(hasName("a::b::A"))));
1618 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1619 record(hasName("::C"))));
1620 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1621 record(hasName("::b::C"))));
1622 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1623 record(hasName("z::a::b::C"))));
1624 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1625 record(hasName("a+b::C"))));
1626 EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
1627 record(hasName("C"))));
1628}
1629
1630TEST(Matcher, HasNameSupportsOuterClasses) {
1631 EXPECT_TRUE(
1632 matches("class A { class B { class C; }; };", record(hasName("A::B::C"))));
1633 EXPECT_TRUE(
1634 matches("class A { class B { class C; }; };",
1635 record(hasName("::A::B::C"))));
1636 EXPECT_TRUE(
1637 matches("class A { class B { class C; }; };", record(hasName("B::C"))));
1638 EXPECT_TRUE(
1639 matches("class A { class B { class C; }; };", record(hasName("C"))));
1640 EXPECT_TRUE(
1641 notMatches("class A { class B { class C; }; };",
1642 record(hasName("c::B::C"))));
1643 EXPECT_TRUE(
1644 notMatches("class A { class B { class C; }; };",
1645 record(hasName("A::c::C"))));
1646 EXPECT_TRUE(
1647 notMatches("class A { class B { class C; }; };",
1648 record(hasName("A::B::A"))));
1649 EXPECT_TRUE(
1650 notMatches("class A { class B { class C; }; };", record(hasName("::C"))));
1651 EXPECT_TRUE(
1652 notMatches("class A { class B { class C; }; };",
1653 record(hasName("::B::C"))));
1654 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
1655 record(hasName("z::A::B::C"))));
1656 EXPECT_TRUE(
1657 notMatches("class A { class B { class C; }; };",
1658 record(hasName("A+B::C"))));
1659}
1660
1661TEST(Matcher, IsDefinition) {
1662 DeclarationMatcher DefinitionOfClassA =
1663 record(hasName("A"), isDefinition());
1664 EXPECT_TRUE(matches("class A {};", DefinitionOfClassA));
1665 EXPECT_TRUE(notMatches("class A;", DefinitionOfClassA));
1666
1667 DeclarationMatcher DefinitionOfVariableA =
1668 variable(hasName("a"), isDefinition());
1669 EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));
1670 EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));
1671
1672 DeclarationMatcher DefinitionOfMethodA =
1673 method(hasName("a"), isDefinition());
1674 EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));
1675 EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));
1676}
1677
1678TEST(Matcher, OfClass) {
1679 StatementMatcher Constructor = constructorCall(hasDeclaration(method(
1680 ofClass(hasName("X")))));
1681
1682 EXPECT_TRUE(
1683 matches("class X { public: X(); }; void x(int) { X x; }", Constructor));
1684 EXPECT_TRUE(
1685 matches("class X { public: X(); }; void x(int) { X x = X(); }",
1686 Constructor));
1687 EXPECT_TRUE(
1688 notMatches("class Y { public: Y(); }; void x(int) { Y y; }",
1689 Constructor));
1690}
1691
1692TEST(Matcher, VisitsTemplateInstantiations) {
1693 EXPECT_TRUE(matches(
1694 "class A { public: void x(); };"
1695 "template <typename T> class B { public: void y() { T t; t.x(); } };"
1696 "void f() { B<A> b; b.y(); }", call(callee(method(hasName("x"))))));
1697
1698 EXPECT_TRUE(matches(
1699 "class A { public: void x(); };"
1700 "class C {"
1701 " public:"
1702 " template <typename T> class B { public: void y() { T t; t.x(); } };"
1703 "};"
1704 "void f() {"
1705 " C::B<A> b; b.y();"
1706 "}", record(hasName("C"),
1707 hasDescendant(call(callee(method(hasName("x"))))))));
1708}
1709
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001710TEST(Matcher, HandlesNullQualTypes) {
1711 // FIXME: Add a Type matcher so we can replace uses of this
1712 // variable with Type(True())
1713 const TypeMatcher AnyType = anything();
1714
1715 // We don't really care whether this matcher succeeds; we're testing that
1716 // it completes without crashing.
1717 EXPECT_TRUE(matches(
1718 "struct A { };"
1719 "template <typename T>"
1720 "void f(T t) {"
1721 " T local_t(t /* this becomes a null QualType in the AST */);"
1722 "}"
1723 "void g() {"
1724 " f(0);"
1725 "}",
1726 expression(hasType(TypeMatcher(
1727 anyOf(
1728 TypeMatcher(hasDeclaration(anything())),
1729 pointsTo(AnyType),
1730 references(AnyType)
1731 // Other QualType matchers should go here.
1732 ))))));
1733}
1734
Manuel Klimek4da21662012-07-06 05:48:52 +00001735// For testing AST_MATCHER_P().
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001736AST_MATCHER_P(Decl, just, internal::Matcher<Decl>, AMatcher) {
Manuel Klimek4da21662012-07-06 05:48:52 +00001737 // Make sure all special variables are used: node, match_finder,
1738 // bound_nodes_builder, and the parameter named 'AMatcher'.
1739 return AMatcher.matches(Node, Finder, Builder);
1740}
1741
1742TEST(AstMatcherPMacro, Works) {
Manuel Klimek9f174082012-07-24 13:37:29 +00001743 DeclarationMatcher HasClassB = just(has(record(hasName("B")).bind("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001744
1745 EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001746 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001747
1748 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001749 HasClassB, new VerifyIdIsBoundToDecl<Decl>("a")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001750
1751 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001752 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001753}
1754
1755AST_POLYMORPHIC_MATCHER_P(
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001756 polymorphicHas, internal::Matcher<Decl>, AMatcher) {
1757 TOOLING_COMPILE_ASSERT((llvm::is_same<NodeType, Decl>::value) ||
1758 (llvm::is_same<NodeType, Stmt>::value),
Manuel Klimek4da21662012-07-06 05:48:52 +00001759 assert_node_type_is_accessible);
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001760 internal::TypedBaseMatcher<Decl> ChildMatcher(AMatcher);
Manuel Klimek4da21662012-07-06 05:48:52 +00001761 return Finder->matchesChildOf(
1762 Node, ChildMatcher, Builder,
1763 ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
1764 ASTMatchFinder::BK_First);
1765}
1766
1767TEST(AstPolymorphicMatcherPMacro, Works) {
Manuel Klimek9f174082012-07-24 13:37:29 +00001768 DeclarationMatcher HasClassB = polymorphicHas(record(hasName("B")).bind("b"));
Manuel Klimek4da21662012-07-06 05:48:52 +00001769
1770 EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001771 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001772
1773 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001774 HasClassB, new VerifyIdIsBoundToDecl<Decl>("a")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001775
1776 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001777 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001778
1779 StatementMatcher StatementHasClassB =
1780 polymorphicHas(record(hasName("B")));
1781
1782 EXPECT_TRUE(matches("void x() { class B {}; }", StatementHasClassB));
1783}
1784
1785TEST(For, FindsForLoops) {
1786 EXPECT_TRUE(matches("void f() { for(;;); }", forStmt()));
1787 EXPECT_TRUE(matches("void f() { if(true) for(;;); }", forStmt()));
1788}
1789
Daniel Jasper6a124492012-07-12 08:50:38 +00001790TEST(For, ForLoopInternals) {
1791 EXPECT_TRUE(matches("void f(){ int i; for (; i < 3 ; ); }",
1792 forStmt(hasCondition(anything()))));
1793 EXPECT_TRUE(matches("void f() { for (int i = 0; ;); }",
1794 forStmt(hasLoopInit(anything()))));
1795}
1796
1797TEST(For, NegativeForLoopInternals) {
1798 EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }",
1799 forStmt(hasCondition(expression()))));
1800 EXPECT_TRUE(notMatches("void f() {int i; for (; i < 4; ++i) {} }",
1801 forStmt(hasLoopInit(anything()))));
1802}
1803
Manuel Klimek4da21662012-07-06 05:48:52 +00001804TEST(For, ReportsNoFalsePositives) {
1805 EXPECT_TRUE(notMatches("void f() { ; }", forStmt()));
1806 EXPECT_TRUE(notMatches("void f() { if(true); }", forStmt()));
1807}
1808
1809TEST(CompoundStatement, HandlesSimpleCases) {
1810 EXPECT_TRUE(notMatches("void f();", compoundStatement()));
1811 EXPECT_TRUE(matches("void f() {}", compoundStatement()));
1812 EXPECT_TRUE(matches("void f() {{}}", compoundStatement()));
1813}
1814
1815TEST(CompoundStatement, DoesNotMatchEmptyStruct) {
1816 // It's not a compound statement just because there's "{}" in the source
1817 // text. This is an AST search, not grep.
1818 EXPECT_TRUE(notMatches("namespace n { struct S {}; }",
1819 compoundStatement()));
1820 EXPECT_TRUE(matches("namespace n { struct S { void f() {{}} }; }",
1821 compoundStatement()));
1822}
1823
Daniel Jasper6a124492012-07-12 08:50:38 +00001824TEST(HasBody, FindsBodyOfForWhileDoLoops) {
Manuel Klimek4da21662012-07-06 05:48:52 +00001825 EXPECT_TRUE(matches("void f() { for(;;) {} }",
Daniel Jasper6a124492012-07-12 08:50:38 +00001826 forStmt(hasBody(compoundStatement()))));
Manuel Klimek4da21662012-07-06 05:48:52 +00001827 EXPECT_TRUE(notMatches("void f() { for(;;); }",
Daniel Jasper6a124492012-07-12 08:50:38 +00001828 forStmt(hasBody(compoundStatement()))));
1829 EXPECT_TRUE(matches("void f() { while(true) {} }",
1830 whileStmt(hasBody(compoundStatement()))));
1831 EXPECT_TRUE(matches("void f() { do {} while(true); }",
1832 doStmt(hasBody(compoundStatement()))));
Manuel Klimek4da21662012-07-06 05:48:52 +00001833}
1834
1835TEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
1836 // The simplest case: every compound statement is in a function
1837 // definition, and the function body itself must be a compound
1838 // statement.
1839 EXPECT_TRUE(matches("void f() { for (;;); }",
1840 compoundStatement(hasAnySubstatement(forStmt()))));
1841}
1842
1843TEST(HasAnySubstatement, IsNotRecursive) {
1844 // It's really "has any immediate substatement".
1845 EXPECT_TRUE(notMatches("void f() { if (true) for (;;); }",
1846 compoundStatement(hasAnySubstatement(forStmt()))));
1847}
1848
1849TEST(HasAnySubstatement, MatchesInNestedCompoundStatements) {
1850 EXPECT_TRUE(matches("void f() { if (true) { for (;;); } }",
1851 compoundStatement(hasAnySubstatement(forStmt()))));
1852}
1853
1854TEST(HasAnySubstatement, FindsSubstatementBetweenOthers) {
1855 EXPECT_TRUE(matches("void f() { 1; 2; 3; for (;;); 4; 5; 6; }",
1856 compoundStatement(hasAnySubstatement(forStmt()))));
1857}
1858
1859TEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) {
1860 EXPECT_TRUE(matches("void f() { }",
1861 compoundStatement(statementCountIs(0))));
1862 EXPECT_TRUE(notMatches("void f() {}",
1863 compoundStatement(statementCountIs(1))));
1864}
1865
1866TEST(StatementCountIs, AppearsToMatchOnlyOneCount) {
1867 EXPECT_TRUE(matches("void f() { 1; }",
1868 compoundStatement(statementCountIs(1))));
1869 EXPECT_TRUE(notMatches("void f() { 1; }",
1870 compoundStatement(statementCountIs(0))));
1871 EXPECT_TRUE(notMatches("void f() { 1; }",
1872 compoundStatement(statementCountIs(2))));
1873}
1874
1875TEST(StatementCountIs, WorksWithMultipleStatements) {
1876 EXPECT_TRUE(matches("void f() { 1; 2; 3; }",
1877 compoundStatement(statementCountIs(3))));
1878}
1879
1880TEST(StatementCountIs, WorksWithNestedCompoundStatements) {
1881 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1882 compoundStatement(statementCountIs(1))));
1883 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1884 compoundStatement(statementCountIs(2))));
1885 EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
1886 compoundStatement(statementCountIs(3))));
1887 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1888 compoundStatement(statementCountIs(4))));
1889}
1890
1891TEST(Member, WorksInSimplestCase) {
1892 EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
1893 memberExpression(member(hasName("first")))));
1894}
1895
1896TEST(Member, DoesNotMatchTheBaseExpression) {
1897 // Don't pick out the wrong part of the member expression, this should
1898 // be checking the member (name) only.
1899 EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
1900 memberExpression(member(hasName("first")))));
1901}
1902
1903TEST(Member, MatchesInMemberFunctionCall) {
1904 EXPECT_TRUE(matches("void f() {"
1905 " struct { void first() {}; } s;"
1906 " s.first();"
1907 "};",
1908 memberExpression(member(hasName("first")))));
1909}
1910
1911TEST(HasObjectExpression, DoesNotMatchMember) {
1912 EXPECT_TRUE(notMatches(
1913 "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
1914 memberExpression(hasObjectExpression(hasType(record(hasName("X")))))));
1915}
1916
1917TEST(HasObjectExpression, MatchesBaseOfVariable) {
1918 EXPECT_TRUE(matches(
1919 "struct X { int m; }; void f(X x) { x.m; }",
1920 memberExpression(hasObjectExpression(hasType(record(hasName("X")))))));
1921 EXPECT_TRUE(matches(
1922 "struct X { int m; }; void f(X* x) { x->m; }",
1923 memberExpression(hasObjectExpression(
1924 hasType(pointsTo(record(hasName("X"))))))));
1925}
1926
1927TEST(HasObjectExpression,
1928 MatchesObjectExpressionOfImplicitlyFormedMemberExpression) {
1929 EXPECT_TRUE(matches(
1930 "class X {}; struct S { X m; void f() { this->m; } };",
1931 memberExpression(hasObjectExpression(
1932 hasType(pointsTo(record(hasName("S"))))))));
1933 EXPECT_TRUE(matches(
1934 "class X {}; struct S { X m; void f() { m; } };",
1935 memberExpression(hasObjectExpression(
1936 hasType(pointsTo(record(hasName("S"))))))));
1937}
1938
1939TEST(Field, DoesNotMatchNonFieldMembers) {
1940 EXPECT_TRUE(notMatches("class X { void m(); };", field(hasName("m"))));
1941 EXPECT_TRUE(notMatches("class X { class m {}; };", field(hasName("m"))));
1942 EXPECT_TRUE(notMatches("class X { enum { m }; };", field(hasName("m"))));
1943 EXPECT_TRUE(notMatches("class X { enum m {}; };", field(hasName("m"))));
1944}
1945
1946TEST(Field, MatchesField) {
1947 EXPECT_TRUE(matches("class X { int m; };", field(hasName("m"))));
1948}
1949
1950TEST(IsConstQualified, MatchesConstInt) {
1951 EXPECT_TRUE(matches("const int i = 42;",
1952 variable(hasType(isConstQualified()))));
1953}
1954
1955TEST(IsConstQualified, MatchesConstPointer) {
1956 EXPECT_TRUE(matches("int i = 42; int* const p(&i);",
1957 variable(hasType(isConstQualified()))));
1958}
1959
1960TEST(IsConstQualified, MatchesThroughTypedef) {
1961 EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
1962 variable(hasType(isConstQualified()))));
1963 EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p(0);",
1964 variable(hasType(isConstQualified()))));
1965}
1966
1967TEST(IsConstQualified, DoesNotMatchInappropriately) {
1968 EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
1969 variable(hasType(isConstQualified()))));
1970 EXPECT_TRUE(notMatches("int const* p;",
1971 variable(hasType(isConstQualified()))));
1972}
1973
1974TEST(ReinterpretCast, MatchesSimpleCase) {
1975 EXPECT_TRUE(matches("char* p = reinterpret_cast<char*>(&p);",
1976 expression(reinterpretCast())));
1977}
1978
1979TEST(ReinterpretCast, DoesNotMatchOtherCasts) {
1980 EXPECT_TRUE(notMatches("char* p = (char*)(&p);",
1981 expression(reinterpretCast())));
1982 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
1983 expression(reinterpretCast())));
1984 EXPECT_TRUE(notMatches("void* p = static_cast<void*>(&p);",
1985 expression(reinterpretCast())));
1986 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
1987 "B b;"
1988 "D* p = dynamic_cast<D*>(&b);",
1989 expression(reinterpretCast())));
1990}
1991
1992TEST(FunctionalCast, MatchesSimpleCase) {
1993 std::string foo_class = "class Foo { public: Foo(char*); };";
1994 EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",
1995 expression(functionalCast())));
1996}
1997
1998TEST(FunctionalCast, DoesNotMatchOtherCasts) {
1999 std::string FooClass = "class Foo { public: Foo(char*); };";
2000 EXPECT_TRUE(
2001 notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",
2002 expression(functionalCast())));
2003 EXPECT_TRUE(
2004 notMatches(FooClass + "void r() { Foo f = \"hello world\"; }",
2005 expression(functionalCast())));
2006}
2007
2008TEST(DynamicCast, MatchesSimpleCase) {
2009 EXPECT_TRUE(matches("struct B { virtual ~B() {} }; struct D : B {};"
2010 "B b;"
2011 "D* p = dynamic_cast<D*>(&b);",
2012 expression(dynamicCast())));
2013}
2014
2015TEST(StaticCast, MatchesSimpleCase) {
2016 EXPECT_TRUE(matches("void* p(static_cast<void*>(&p));",
2017 expression(staticCast())));
2018}
2019
2020TEST(StaticCast, DoesNotMatchOtherCasts) {
2021 EXPECT_TRUE(notMatches("char* p = (char*)(&p);",
2022 expression(staticCast())));
2023 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
2024 expression(staticCast())));
2025 EXPECT_TRUE(notMatches("void* p = reinterpret_cast<char*>(&p);",
2026 expression(staticCast())));
2027 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
2028 "B b;"
2029 "D* p = dynamic_cast<D*>(&b);",
2030 expression(staticCast())));
2031}
2032
2033TEST(HasDestinationType, MatchesSimpleCase) {
2034 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
2035 expression(
2036 staticCast(hasDestinationType(
2037 pointsTo(TypeMatcher(anything())))))));
2038}
2039
2040TEST(HasSourceExpression, MatchesSimpleCase) {
2041 EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
2042 "void r() {string a_string; URL url = a_string; }",
2043 expression(implicitCast(
2044 hasSourceExpression(constructorCall())))));
2045}
2046
2047TEST(Statement, DoesNotMatchDeclarations) {
2048 EXPECT_TRUE(notMatches("class X {};", statement()));
2049}
2050
2051TEST(Statement, MatchesCompoundStatments) {
2052 EXPECT_TRUE(matches("void x() {}", statement()));
2053}
2054
2055TEST(DeclarationStatement, DoesNotMatchCompoundStatements) {
2056 EXPECT_TRUE(notMatches("void x() {}", declarationStatement()));
2057}
2058
2059TEST(DeclarationStatement, MatchesVariableDeclarationStatements) {
2060 EXPECT_TRUE(matches("void x() { int a; }", declarationStatement()));
2061}
2062
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002063TEST(InitListExpression, MatchesInitListExpression) {
2064 EXPECT_TRUE(matches("int a[] = { 1, 2 };",
2065 initListExpr(hasType(asString("int [2]")))));
2066 EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };",
2067 initListExpr(hasType(record(hasName("B"))))));
2068}
2069
2070TEST(UsingDeclaration, MatchesUsingDeclarations) {
2071 EXPECT_TRUE(matches("namespace X { int x; } using X::x;",
2072 usingDecl()));
2073}
2074
2075TEST(UsingDeclaration, MatchesShadowUsingDelcarations) {
2076 EXPECT_TRUE(matches("namespace f { int a; } using f::a;",
2077 usingDecl(hasAnyUsingShadowDecl(hasName("a")))));
2078}
2079
2080TEST(UsingDeclaration, MatchesSpecificTarget) {
2081 EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
2082 usingDecl(hasAnyUsingShadowDecl(
2083 hasTargetDecl(function())))));
2084 EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
2085 usingDecl(hasAnyUsingShadowDecl(
2086 hasTargetDecl(function())))));
2087}
2088
2089TEST(UsingDeclaration, ThroughUsingDeclaration) {
2090 EXPECT_TRUE(matches(
2091 "namespace a { void f(); } using a::f; void g() { f(); }",
2092 declarationReference(throughUsingDecl(anything()))));
2093 EXPECT_TRUE(notMatches(
2094 "namespace a { void f(); } using a::f; void g() { a::f(); }",
2095 declarationReference(throughUsingDecl(anything()))));
2096}
2097
Manuel Klimek4da21662012-07-06 05:48:52 +00002098TEST(While, MatchesWhileLoops) {
2099 EXPECT_TRUE(notMatches("void x() {}", whileStmt()));
2100 EXPECT_TRUE(matches("void x() { while(true); }", whileStmt()));
2101 EXPECT_TRUE(notMatches("void x() { do {} while(true); }", whileStmt()));
2102}
2103
2104TEST(Do, MatchesDoLoops) {
2105 EXPECT_TRUE(matches("void x() { do {} while(true); }", doStmt()));
2106 EXPECT_TRUE(matches("void x() { do ; while(false); }", doStmt()));
2107}
2108
2109TEST(Do, DoesNotMatchWhileLoops) {
2110 EXPECT_TRUE(notMatches("void x() { while(true) {} }", doStmt()));
2111}
2112
2113TEST(SwitchCase, MatchesCase) {
2114 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchCase()));
2115 EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchCase()));
2116 EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchCase()));
2117 EXPECT_TRUE(notMatches("void x() { switch(42) {} }", switchCase()));
2118}
2119
2120TEST(HasConditionVariableStatement, DoesNotMatchCondition) {
2121 EXPECT_TRUE(notMatches(
2122 "void x() { if(true) {} }",
2123 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2124 EXPECT_TRUE(notMatches(
2125 "void x() { int x; if((x = 42)) {} }",
2126 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2127}
2128
2129TEST(HasConditionVariableStatement, MatchesConditionVariables) {
2130 EXPECT_TRUE(matches(
2131 "void x() { if(int* a = 0) {} }",
2132 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2133}
2134
2135TEST(ForEach, BindsOneNode) {
2136 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002137 record(hasName("C"), forEach(field(hasName("x")).bind("x"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002138 new VerifyIdIsBoundToDecl<FieldDecl>("x", 1)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002139}
2140
2141TEST(ForEach, BindsMultipleNodes) {
2142 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002143 record(hasName("C"), forEach(field().bind("f"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002144 new VerifyIdIsBoundToDecl<FieldDecl>("f", 3)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002145}
2146
2147TEST(ForEach, BindsRecursiveCombinations) {
2148 EXPECT_TRUE(matchAndVerifyResultTrue(
2149 "class C { class D { int x; int y; }; class E { int y; int z; }; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002150 record(hasName("C"), forEach(record(forEach(field().bind("f"))))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002151 new VerifyIdIsBoundToDecl<FieldDecl>("f", 4)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002152}
2153
2154TEST(ForEachDescendant, BindsOneNode) {
2155 EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002156 record(hasName("C"), forEachDescendant(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(ForEachDescendant, BindsMultipleNodes) {
2161 EXPECT_TRUE(matchAndVerifyResultTrue(
2162 "class C { class D { int x; int y; }; "
2163 " class E { class F { int y; int z; }; }; };",
Manuel Klimek9f174082012-07-24 13:37:29 +00002164 record(hasName("C"), forEachDescendant(field().bind("f"))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002165 new VerifyIdIsBoundToDecl<FieldDecl>("f", 4)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002166}
2167
2168TEST(ForEachDescendant, BindsRecursiveCombinations) {
2169 EXPECT_TRUE(matchAndVerifyResultTrue(
2170 "class C { class D { "
2171 " class E { class F { class G { int y; int z; }; }; }; }; };",
2172 record(hasName("C"), forEachDescendant(record(
Manuel Klimek9f174082012-07-24 13:37:29 +00002173 forEachDescendant(field().bind("f"))))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002174 new VerifyIdIsBoundToDecl<FieldDecl>("f", 8)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002175}
2176
2177
2178TEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) {
2179 // Make sure that we can both match the class by name (::X) and by the type
2180 // the template was instantiated with (via a field).
2181
2182 EXPECT_TRUE(matches(
2183 "template <typename T> class X {}; class A {}; X<A> x;",
2184 record(hasName("::X"), isTemplateInstantiation())));
2185
2186 EXPECT_TRUE(matches(
2187 "template <typename T> class X { T t; }; class A {}; X<A> x;",
2188 record(isTemplateInstantiation(), hasDescendant(
2189 field(hasType(record(hasName("A"))))))));
2190}
2191
2192TEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) {
2193 EXPECT_TRUE(matches(
2194 "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
2195 function(hasParameter(0, hasType(record(hasName("A")))),
2196 isTemplateInstantiation())));
2197}
2198
2199TEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) {
2200 EXPECT_TRUE(matches(
2201 "template <typename T> class X { T t; }; class A {};"
2202 "template class X<A>;",
2203 record(isTemplateInstantiation(), hasDescendant(
2204 field(hasType(record(hasName("A"))))))));
2205}
2206
2207TEST(IsTemplateInstantiation,
2208 MatchesInstantiationOfPartiallySpecializedClassTemplate) {
2209 EXPECT_TRUE(matches(
2210 "template <typename T> class X {};"
2211 "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
2212 record(hasName("::X"), isTemplateInstantiation())));
2213}
2214
2215TEST(IsTemplateInstantiation,
2216 MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
2217 EXPECT_TRUE(matches(
2218 "class A {};"
2219 "class X {"
2220 " template <typename U> class Y { U u; };"
2221 " Y<A> y;"
2222 "};",
2223 record(hasName("::X::Y"), isTemplateInstantiation())));
2224}
2225
2226TEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) {
2227 // FIXME: Figure out whether this makes sense. It doesn't affect the
2228 // normal use case as long as the uppermost instantiation always is marked
2229 // as template instantiation, but it might be confusing as a predicate.
2230 EXPECT_TRUE(matches(
2231 "class A {};"
2232 "template <typename T> class X {"
2233 " template <typename U> class Y { U u; };"
2234 " Y<T> y;"
2235 "}; X<A> x;",
2236 record(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
2237}
2238
2239TEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) {
2240 EXPECT_TRUE(notMatches(
2241 "template <typename T> class X {}; class A {};"
2242 "template <> class X<A> {}; X<A> x;",
2243 record(hasName("::X"), isTemplateInstantiation())));
2244}
2245
2246TEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) {
2247 EXPECT_TRUE(notMatches(
2248 "class A {}; class Y { A a; };",
2249 record(isTemplateInstantiation())));
2250}
2251
2252} // end namespace ast_matchers
2253} // end namespace clang