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