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