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