blob: 6024f0ccda80b3dc3df7161d17c3da2cc436892e [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"))));
294
295 EXPECT_TRUE(
296 matches("class X {}; class Z : public X {};", YOrZDerivedFromX));
297 EXPECT_TRUE(matches("class Y {};", YOrZDerivedFromX));
298 EXPECT_TRUE(
299 notMatches("class X {}; class W : public X {};", YOrZDerivedFromX));
300 EXPECT_TRUE(notMatches("class Z {};", YOrZDerivedFromX));
301
302 DeclarationMatcher XOrYOrZOrUOrV =
303 record(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U"),
304 hasName("V")));
305
306 EXPECT_TRUE(matches("class X {};", XOrYOrZOrUOrV));
307 EXPECT_TRUE(matches("class Y {};", XOrYOrZOrUOrV));
308 EXPECT_TRUE(matches("class Z {};", XOrYOrZOrUOrV));
309 EXPECT_TRUE(matches("class U {};", XOrYOrZOrUOrV));
310 EXPECT_TRUE(matches("class V {};", XOrYOrZOrUOrV));
311 EXPECT_TRUE(notMatches("class A {};", XOrYOrZOrUOrV));
312}
313
314TEST(DeclarationMatcher, MatchHas) {
315 DeclarationMatcher HasClassX = record(has(record(hasName("X"))));
316
317 EXPECT_TRUE(matches("class Y { class X {}; };", HasClassX));
318 EXPECT_TRUE(matches("class X {};", HasClassX));
319
320 DeclarationMatcher YHasClassX =
321 record(hasName("Y"), has(record(hasName("X"))));
322 EXPECT_TRUE(matches("class Y { class X {}; };", YHasClassX));
323 EXPECT_TRUE(notMatches("class X {};", YHasClassX));
324 EXPECT_TRUE(
325 notMatches("class Y { class Z { class X {}; }; };", YHasClassX));
326}
327
328TEST(DeclarationMatcher, MatchHasRecursiveAllOf) {
329 DeclarationMatcher Recursive =
330 record(
331 has(record(
332 has(record(hasName("X"))),
333 has(record(hasName("Y"))),
334 hasName("Z"))),
335 has(record(
336 has(record(hasName("A"))),
337 has(record(hasName("B"))),
338 hasName("C"))),
339 hasName("F"));
340
341 EXPECT_TRUE(matches(
342 "class F {"
343 " class Z {"
344 " class X {};"
345 " class Y {};"
346 " };"
347 " class C {"
348 " class A {};"
349 " class B {};"
350 " };"
351 "};", Recursive));
352
353 EXPECT_TRUE(matches(
354 "class F {"
355 " class Z {"
356 " class A {};"
357 " class X {};"
358 " class Y {};"
359 " };"
360 " class C {"
361 " class X {};"
362 " class A {};"
363 " class B {};"
364 " };"
365 "};", Recursive));
366
367 EXPECT_TRUE(matches(
368 "class O1 {"
369 " class O2 {"
370 " class F {"
371 " class Z {"
372 " class A {};"
373 " class X {};"
374 " class Y {};"
375 " };"
376 " class C {"
377 " class X {};"
378 " class A {};"
379 " class B {};"
380 " };"
381 " };"
382 " };"
383 "};", Recursive));
384}
385
386TEST(DeclarationMatcher, MatchHasRecursiveAnyOf) {
387 DeclarationMatcher Recursive =
388 record(
389 anyOf(
390 has(record(
391 anyOf(
392 has(record(
393 hasName("X"))),
394 has(record(
395 hasName("Y"))),
396 hasName("Z")))),
397 has(record(
398 anyOf(
399 hasName("C"),
400 has(record(
401 hasName("A"))),
402 has(record(
403 hasName("B")))))),
404 hasName("F")));
405
406 EXPECT_TRUE(matches("class F {};", Recursive));
407 EXPECT_TRUE(matches("class Z {};", Recursive));
408 EXPECT_TRUE(matches("class C {};", Recursive));
409 EXPECT_TRUE(matches("class M { class N { class X {}; }; };", Recursive));
410 EXPECT_TRUE(matches("class M { class N { class B {}; }; };", Recursive));
411 EXPECT_TRUE(
412 matches("class O1 { class O2 {"
413 " class M { class N { class B {}; }; }; "
414 "}; };", Recursive));
415}
416
417TEST(DeclarationMatcher, MatchNot) {
418 DeclarationMatcher NotClassX =
419 record(
420 isDerivedFrom("Y"),
421 unless(hasName("Y")),
422 unless(hasName("X")));
423 EXPECT_TRUE(notMatches("", NotClassX));
424 EXPECT_TRUE(notMatches("class Y {};", NotClassX));
425 EXPECT_TRUE(matches("class Y {}; class Z : public Y {};", NotClassX));
426 EXPECT_TRUE(notMatches("class Y {}; class X : public Y {};", NotClassX));
427 EXPECT_TRUE(
428 notMatches("class Y {}; class Z {}; class X : public Y {};",
429 NotClassX));
430
431 DeclarationMatcher ClassXHasNotClassY =
432 record(
433 hasName("X"),
434 has(record(hasName("Z"))),
435 unless(
436 has(record(hasName("Y")))));
437 EXPECT_TRUE(matches("class X { class Z {}; };", ClassXHasNotClassY));
438 EXPECT_TRUE(notMatches("class X { class Y {}; class Z {}; };",
439 ClassXHasNotClassY));
440}
441
442TEST(DeclarationMatcher, HasDescendant) {
443 DeclarationMatcher ZDescendantClassX =
444 record(
445 hasDescendant(record(hasName("X"))),
446 hasName("Z"));
447 EXPECT_TRUE(matches("class Z { class X {}; };", ZDescendantClassX));
448 EXPECT_TRUE(
449 matches("class Z { class Y { class X {}; }; };", ZDescendantClassX));
450 EXPECT_TRUE(
451 matches("class Z { class A { class Y { class X {}; }; }; };",
452 ZDescendantClassX));
453 EXPECT_TRUE(
454 matches("class Z { class A { class B { class Y { class X {}; }; }; }; };",
455 ZDescendantClassX));
456 EXPECT_TRUE(notMatches("class Z {};", ZDescendantClassX));
457
458 DeclarationMatcher ZDescendantClassXHasClassY =
459 record(
460 hasDescendant(record(has(record(hasName("Y"))),
461 hasName("X"))),
462 hasName("Z"));
463 EXPECT_TRUE(matches("class Z { class X { class Y {}; }; };",
464 ZDescendantClassXHasClassY));
465 EXPECT_TRUE(
466 matches("class Z { class A { class B { class X { class Y {}; }; }; }; };",
467 ZDescendantClassXHasClassY));
468 EXPECT_TRUE(notMatches(
469 "class Z {"
470 " class A {"
471 " class B {"
472 " class X {"
473 " class C {"
474 " class Y {};"
475 " };"
476 " };"
477 " }; "
478 " };"
479 "};", ZDescendantClassXHasClassY));
480
481 DeclarationMatcher ZDescendantClassXDescendantClassY =
482 record(
483 hasDescendant(record(hasDescendant(record(hasName("Y"))),
484 hasName("X"))),
485 hasName("Z"));
486 EXPECT_TRUE(
487 matches("class Z { class A { class X { class B { class Y {}; }; }; }; };",
488 ZDescendantClassXDescendantClassY));
489 EXPECT_TRUE(matches(
490 "class Z {"
491 " class A {"
492 " class X {"
493 " class B {"
494 " class Y {};"
495 " };"
496 " class Y {};"
497 " };"
498 " };"
499 "};", ZDescendantClassXDescendantClassY));
500}
501
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000502TEST(Enum, DoesNotMatchClasses) {
503 EXPECT_TRUE(notMatches("class X {};", enumDecl(hasName("X"))));
504}
505
506TEST(Enum, MatchesEnums) {
507 EXPECT_TRUE(matches("enum X {};", enumDecl(hasName("X"))));
508}
509
510TEST(EnumConstant, Matches) {
511 DeclarationMatcher Matcher = enumConstant(hasName("A"));
512 EXPECT_TRUE(matches("enum X{ A };", Matcher));
513 EXPECT_TRUE(notMatches("enum X{ B };", Matcher));
514 EXPECT_TRUE(notMatches("enum X {};", Matcher));
515}
516
Manuel Klimek4da21662012-07-06 05:48:52 +0000517TEST(StatementMatcher, Has) {
518 StatementMatcher HasVariableI =
519 expression(
520 hasType(pointsTo(record(hasName("X")))),
521 has(declarationReference(to(variable(hasName("i"))))));
522
523 EXPECT_TRUE(matches(
524 "class X; X *x(int); void c() { int i; x(i); }", HasVariableI));
525 EXPECT_TRUE(notMatches(
526 "class X; X *x(int); void c() { int i; x(42); }", HasVariableI));
527}
528
529TEST(StatementMatcher, HasDescendant) {
530 StatementMatcher HasDescendantVariableI =
531 expression(
532 hasType(pointsTo(record(hasName("X")))),
533 hasDescendant(declarationReference(to(variable(hasName("i"))))));
534
535 EXPECT_TRUE(matches(
536 "class X; X *x(bool); bool b(int); void c() { int i; x(b(i)); }",
537 HasDescendantVariableI));
538 EXPECT_TRUE(notMatches(
539 "class X; X *x(bool); bool b(int); void c() { int i; x(b(42)); }",
540 HasDescendantVariableI));
541}
542
543TEST(TypeMatcher, MatchesClassType) {
544 TypeMatcher TypeA = hasDeclaration(record(hasName("A")));
545
546 EXPECT_TRUE(matches("class A { public: A *a; };", TypeA));
547 EXPECT_TRUE(notMatches("class A {};", TypeA));
548
549 TypeMatcher TypeDerivedFromA = hasDeclaration(record(isDerivedFrom("A")));
550
551 EXPECT_TRUE(matches("class A {}; class B : public A { public: B *b; };",
552 TypeDerivedFromA));
553 EXPECT_TRUE(notMatches("class A {};", TypeA));
554
555 TypeMatcher TypeAHasClassB = hasDeclaration(
556 record(hasName("A"), has(record(hasName("B")))));
557
558 EXPECT_TRUE(
559 matches("class A { public: A *a; class B {}; };", TypeAHasClassB));
560}
561
562// Returns from Run whether 'bound_nodes' contain a Decl bound to 'Id', which
563// can be dynamically casted to T.
564// Optionally checks that the check succeeded a specific number of times.
565template <typename T>
566class VerifyIdIsBoundToDecl : public BoundNodesCallback {
567public:
568 // Create an object that checks that a node of type 'T' was bound to 'Id'.
569 // Does not check for a certain number of matches.
570 explicit VerifyIdIsBoundToDecl(const std::string& Id)
571 : Id(Id), ExpectedCount(-1), Count(0) {}
572
573 // Create an object that checks that a node of type 'T' was bound to 'Id'.
574 // Checks that there were exactly 'ExpectedCount' matches.
575 explicit VerifyIdIsBoundToDecl(const std::string& Id, int ExpectedCount)
576 : Id(Id), ExpectedCount(ExpectedCount), Count(0) {}
577
578 ~VerifyIdIsBoundToDecl() {
579 if (ExpectedCount != -1) {
580 EXPECT_EQ(ExpectedCount, Count);
581 }
582 }
583
584 virtual bool run(const BoundNodes *Nodes) {
585 if (Nodes->getDeclAs<T>(Id) != NULL) {
586 ++Count;
587 return true;
588 }
589 return false;
590 }
591
592private:
593 const std::string Id;
594 const int ExpectedCount;
595 int Count;
596};
597template <typename T>
598class VerifyIdIsBoundToStmt : public BoundNodesCallback {
599public:
600 explicit VerifyIdIsBoundToStmt(const std::string &Id) : Id(Id) {}
601 virtual bool run(const BoundNodes *Nodes) {
602 const T *Node = Nodes->getStmtAs<T>(Id);
603 return Node != NULL;
604 }
605private:
606 const std::string Id;
607};
608
609TEST(Matcher, BindMatchedNodes) {
610 DeclarationMatcher ClassX = has(id("x", record(hasName("X"))));
611
612 EXPECT_TRUE(matchAndVerifyResultTrue("class X {};",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000613 ClassX, new VerifyIdIsBoundToDecl<CXXRecordDecl>("x")));
Manuel Klimek4da21662012-07-06 05:48:52 +0000614
615 EXPECT_TRUE(matchAndVerifyResultFalse("class X {};",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000616 ClassX, new VerifyIdIsBoundToDecl<CXXRecordDecl>("other-id")));
Manuel Klimek4da21662012-07-06 05:48:52 +0000617
618 TypeMatcher TypeAHasClassB = hasDeclaration(
619 record(hasName("A"), has(id("b", record(hasName("B"))))));
620
621 EXPECT_TRUE(matchAndVerifyResultTrue("class A { public: A *a; class B {}; };",
622 TypeAHasClassB,
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000623 new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +0000624
625 StatementMatcher MethodX = id("x", call(callee(method(hasName("x")))));
626
627 EXPECT_TRUE(matchAndVerifyResultTrue("class A { void x() { x(); } };",
628 MethodX,
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000629 new VerifyIdIsBoundToStmt<CXXMemberCallExpr>("x")));
630}
631
632TEST(Matcher, BindTheSameNameInAlternatives) {
633 StatementMatcher matcher = anyOf(
634 binaryOperator(hasOperatorName("+"),
635 hasLHS(id("x", expression())),
636 hasRHS(integerLiteral(equals(0)))),
637 binaryOperator(hasOperatorName("+"),
638 hasLHS(integerLiteral(equals(0))),
639 hasRHS(id("x", expression()))));
640
641 EXPECT_TRUE(matchAndVerifyResultTrue(
642 // The first branch of the matcher binds x to 0 but then fails.
643 // The second branch binds x to f() and succeeds.
644 "int f() { return 0 + f(); }",
645 matcher,
646 new VerifyIdIsBoundToStmt<CallExpr>("x")));
Manuel Klimek4da21662012-07-06 05:48:52 +0000647}
648
649TEST(HasType, TakesQualTypeMatcherAndMatchesExpr) {
650 TypeMatcher ClassX = hasDeclaration(record(hasName("X")));
651 EXPECT_TRUE(
652 matches("class X {}; void y(X &x) { x; }", expression(hasType(ClassX))));
653 EXPECT_TRUE(
654 notMatches("class X {}; void y(X *x) { x; }",
655 expression(hasType(ClassX))));
656 EXPECT_TRUE(
657 matches("class X {}; void y(X *x) { x; }",
658 expression(hasType(pointsTo(ClassX)))));
659}
660
661TEST(HasType, TakesQualTypeMatcherAndMatchesValueDecl) {
662 TypeMatcher ClassX = hasDeclaration(record(hasName("X")));
663 EXPECT_TRUE(
664 matches("class X {}; void y() { X x; }", variable(hasType(ClassX))));
665 EXPECT_TRUE(
666 notMatches("class X {}; void y() { X *x; }", variable(hasType(ClassX))));
667 EXPECT_TRUE(
668 matches("class X {}; void y() { X *x; }",
669 variable(hasType(pointsTo(ClassX)))));
670}
671
672TEST(HasType, TakesDeclMatcherAndMatchesExpr) {
673 DeclarationMatcher ClassX = record(hasName("X"));
674 EXPECT_TRUE(
675 matches("class X {}; void y(X &x) { x; }", expression(hasType(ClassX))));
676 EXPECT_TRUE(
677 notMatches("class X {}; void y(X *x) { x; }",
678 expression(hasType(ClassX))));
679}
680
681TEST(HasType, TakesDeclMatcherAndMatchesValueDecl) {
682 DeclarationMatcher ClassX = record(hasName("X"));
683 EXPECT_TRUE(
684 matches("class X {}; void y() { X x; }", variable(hasType(ClassX))));
685 EXPECT_TRUE(
686 notMatches("class X {}; void y() { X *x; }", variable(hasType(ClassX))));
687}
688
689TEST(Matcher, Call) {
690 // FIXME: Do we want to overload Call() to directly take
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000691 // Matcher<Decl>, too?
Manuel Klimek4da21662012-07-06 05:48:52 +0000692 StatementMatcher MethodX = call(hasDeclaration(method(hasName("x"))));
693
694 EXPECT_TRUE(matches("class Y { void x() { x(); } };", MethodX));
695 EXPECT_TRUE(notMatches("class Y { void x() {} };", MethodX));
696
697 StatementMatcher MethodOnY = call(on(hasType(record(hasName("Y")))));
698
699 EXPECT_TRUE(
700 matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
701 MethodOnY));
702 EXPECT_TRUE(
703 matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
704 MethodOnY));
705 EXPECT_TRUE(
706 notMatches("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
715 StatementMatcher MethodOnYPointer =
716 call(on(hasType(pointsTo(record(hasName("Y"))))));
717
718 EXPECT_TRUE(
719 matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
720 MethodOnYPointer));
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 notMatches("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}
734
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000735TEST(HasType, MatchesAsString) {
736 EXPECT_TRUE(
737 matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }",
738 call(on(hasType(asString("class Y *"))))));
739 EXPECT_TRUE(matches("class X { void x(int x) {} };",
740 method(hasParameter(0, hasType(asString("int"))))));
741 EXPECT_TRUE(matches("namespace ns { struct A {}; } struct B { ns::A a; };",
742 field(hasType(asString("ns::A")))));
743 EXPECT_TRUE(matches("namespace { struct A {}; } struct B { A a; };",
744 field(hasType(asString("struct <anonymous>::A")))));
745}
746
Manuel Klimek4da21662012-07-06 05:48:52 +0000747TEST(Matcher, OverloadedOperatorCall) {
748 StatementMatcher OpCall = overloadedOperatorCall();
749 // Unary operator
750 EXPECT_TRUE(matches("class Y { }; "
751 "bool operator!(Y x) { return false; }; "
752 "Y y; bool c = !y;", OpCall));
753 // No match -- special operators like "new", "delete"
754 // FIXME: operator new takes size_t, for which we need stddef.h, for which
755 // we need to figure out include paths in the test.
756 // EXPECT_TRUE(NotMatches("#include <stddef.h>\n"
757 // "class Y { }; "
758 // "void *operator new(size_t size) { return 0; } "
759 // "Y *y = new Y;", OpCall));
760 EXPECT_TRUE(notMatches("class Y { }; "
761 "void operator delete(void *p) { } "
762 "void a() {Y *y = new Y; delete y;}", OpCall));
763 // Binary operator
764 EXPECT_TRUE(matches("class Y { }; "
765 "bool operator&&(Y x, Y y) { return true; }; "
766 "Y a; Y b; bool c = a && b;",
767 OpCall));
768 // No match -- normal operator, not an overloaded one.
769 EXPECT_TRUE(notMatches("bool x = true, y = true; bool t = x && y;", OpCall));
770 EXPECT_TRUE(notMatches("int t = 5 << 2;", OpCall));
771}
772
773TEST(Matcher, HasOperatorNameForOverloadedOperatorCall) {
774 StatementMatcher OpCallAndAnd =
775 overloadedOperatorCall(hasOverloadedOperatorName("&&"));
776 EXPECT_TRUE(matches("class Y { }; "
777 "bool operator&&(Y x, Y y) { return true; }; "
778 "Y a; Y b; bool c = a && b;", OpCallAndAnd));
779 StatementMatcher OpCallLessLess =
780 overloadedOperatorCall(hasOverloadedOperatorName("<<"));
781 EXPECT_TRUE(notMatches("class Y { }; "
782 "bool operator&&(Y x, Y y) { return true; }; "
783 "Y a; Y b; bool c = a && b;",
784 OpCallLessLess));
785}
786
787TEST(Matcher, ThisPointerType) {
788 StatementMatcher MethodOnY = call(thisPointerType(record(hasName("Y"))));
789
790 EXPECT_TRUE(
791 matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
792 MethodOnY));
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
806 EXPECT_TRUE(matches(
807 "class Y {"
808 " public: virtual void x();"
809 "};"
810 "class X : public Y {"
811 " public: virtual void x();"
812 "};"
813 "void z() { X *x; x->Y::x(); }", MethodOnY));
814}
815
816TEST(Matcher, VariableUsage) {
817 StatementMatcher Reference =
818 declarationReference(to(
819 variable(hasInitializer(
820 call(thisPointerType(record(hasName("Y"))))))));
821
822 EXPECT_TRUE(matches(
823 "class Y {"
824 " public:"
825 " bool x() const;"
826 "};"
827 "void z(const Y &y) {"
828 " bool b = y.x();"
829 " if (b) {}"
830 "}", Reference));
831
832 EXPECT_TRUE(notMatches(
833 "class Y {"
834 " public:"
835 " bool x() const;"
836 "};"
837 "void z(const Y &y) {"
838 " bool b = y.x();"
839 "}", Reference));
840}
841
842TEST(Matcher, CalledVariable) {
843 StatementMatcher CallOnVariableY = expression(
844 call(on(declarationReference(to(variable(hasName("y")))))));
845
846 EXPECT_TRUE(matches(
847 "class Y { public: void x() { Y y; y.x(); } };", CallOnVariableY));
848 EXPECT_TRUE(matches(
849 "class Y { public: void x() const { Y y; y.x(); } };", CallOnVariableY));
850 EXPECT_TRUE(matches(
851 "class Y { public: void x(); };"
852 "class X : public Y { void z() { X 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(notMatches(
857 "class Y { public: void x(); };"
858 "class X : public Y { void z() { unsigned long y; ((X*)y)->x(); } };",
859 CallOnVariableY));
860}
861
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +0000862TEST(UnaryExprOrTypeTraitExpr, MatchesSizeOfAndAlignOf) {
863 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }",
864 unaryExprOrTypeTraitExpr()));
865 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }",
866 alignOfExpr(anything())));
867 // FIXME: Uncomment once alignof is enabled.
868 // EXPECT_TRUE(matches("void x() { int a = alignof(a); }",
869 // unaryExprOrTypeTraitExpr()));
870 // EXPECT_TRUE(notMatches("void x() { int a = alignof(a); }",
871 // sizeOfExpr()));
872}
873
874TEST(UnaryExpressionOrTypeTraitExpression, MatchesCorrectType) {
875 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }", sizeOfExpr(
876 hasArgumentOfType(asString("int")))));
877 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
878 hasArgumentOfType(asString("float")))));
879 EXPECT_TRUE(matches(
880 "struct A {}; void x() { A a; int b = sizeof(a); }",
881 sizeOfExpr(hasArgumentOfType(hasDeclaration(record(hasName("A")))))));
882 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
883 hasArgumentOfType(hasDeclaration(record(hasName("string")))))));
884}
885
Manuel Klimek4da21662012-07-06 05:48:52 +0000886TEST(MemberExpression, DoesNotMatchClasses) {
887 EXPECT_TRUE(notMatches("class Y { void x() {} };", memberExpression()));
888}
889
890TEST(MemberExpression, MatchesMemberFunctionCall) {
891 EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpression()));
892}
893
894TEST(MemberExpression, MatchesVariable) {
895 EXPECT_TRUE(
896 matches("class Y { void x() { this->y; } int y; };", memberExpression()));
897 EXPECT_TRUE(
898 matches("class Y { void x() { y; } int y; };", memberExpression()));
899 EXPECT_TRUE(
900 matches("class Y { void x() { Y y; y.y; } int y; };",
901 memberExpression()));
902}
903
904TEST(MemberExpression, MatchesStaticVariable) {
905 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
906 memberExpression()));
907 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
908 memberExpression()));
909 EXPECT_TRUE(notMatches("class Y { void x() { Y::y; } static int y; };",
910 memberExpression()));
911}
912
Daniel Jasper6a124492012-07-12 08:50:38 +0000913TEST(IsInteger, MatchesIntegers) {
914 EXPECT_TRUE(matches("int i = 0;", variable(hasType(isInteger()))));
915 EXPECT_TRUE(matches("long long i = 0; void f(long long) { }; void g() {f(i);}",
916 call(hasArgument(0, declarationReference(
917 to(variable(hasType(isInteger()))))))));
918}
919
920TEST(IsInteger, ReportsNoFalsePositives) {
921 EXPECT_TRUE(notMatches("int *i;", variable(hasType(isInteger()))));
922 EXPECT_TRUE(notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}",
923 call(hasArgument(0, declarationReference(
924 to(variable(hasType(isInteger()))))))));
925}
926
Manuel Klimek4da21662012-07-06 05:48:52 +0000927TEST(IsArrow, MatchesMemberVariablesViaArrow) {
928 EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };",
929 memberExpression(isArrow())));
930 EXPECT_TRUE(matches("class Y { void x() { y; } int y; };",
931 memberExpression(isArrow())));
932 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };",
933 memberExpression(isArrow())));
934}
935
936TEST(IsArrow, MatchesStaticMemberVariablesViaArrow) {
937 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
938 memberExpression(isArrow())));
939 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
940 memberExpression(isArrow())));
941 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } static int y; };",
942 memberExpression(isArrow())));
943}
944
945TEST(IsArrow, MatchesMemberCallsViaArrow) {
946 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
947 memberExpression(isArrow())));
948 EXPECT_TRUE(matches("class Y { void x() { x(); } };",
949 memberExpression(isArrow())));
950 EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",
951 memberExpression(isArrow())));
952}
953
954TEST(Callee, MatchesDeclarations) {
955 StatementMatcher CallMethodX = call(callee(method(hasName("x"))));
956
957 EXPECT_TRUE(matches("class Y { void x() { x(); } };", CallMethodX));
958 EXPECT_TRUE(notMatches("class Y { void x() {} };", CallMethodX));
959}
960
961TEST(Callee, MatchesMemberExpressions) {
962 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
963 call(callee(memberExpression()))));
964 EXPECT_TRUE(
965 notMatches("class Y { void x() { this->x(); } };", call(callee(call()))));
966}
967
968TEST(Function, MatchesFunctionDeclarations) {
969 StatementMatcher CallFunctionF = call(callee(function(hasName("f"))));
970
971 EXPECT_TRUE(matches("void f() { f(); }", CallFunctionF));
972 EXPECT_TRUE(notMatches("void f() { }", CallFunctionF));
973
Manuel Klimeke265c872012-07-10 14:21:30 +0000974#if !defined(_MSC_VER)
975 // FIXME: Make this work for MSVC.
Manuel Klimek4da21662012-07-06 05:48:52 +0000976 // Dependent contexts, but a non-dependent call.
977 EXPECT_TRUE(matches("void f(); template <int N> void g() { f(); }",
978 CallFunctionF));
979 EXPECT_TRUE(
980 matches("void f(); template <int N> struct S { void g() { f(); } };",
981 CallFunctionF));
Manuel Klimeke265c872012-07-10 14:21:30 +0000982#endif
Manuel Klimek4da21662012-07-06 05:48:52 +0000983
984 // Depedent calls don't match.
985 EXPECT_TRUE(
986 notMatches("void f(int); template <typename T> void g(T t) { f(t); }",
987 CallFunctionF));
988 EXPECT_TRUE(
989 notMatches("void f(int);"
990 "template <typename T> struct S { void g(T t) { f(t); } };",
991 CallFunctionF));
992}
993
994TEST(Matcher, Argument) {
995 StatementMatcher CallArgumentY = expression(call(
996 hasArgument(0, declarationReference(to(variable(hasName("y")))))));
997
998 EXPECT_TRUE(matches("void x(int) { int y; x(y); }", CallArgumentY));
999 EXPECT_TRUE(
1000 matches("class X { void x(int) { int y; x(y); } };", CallArgumentY));
1001 EXPECT_TRUE(notMatches("void x(int) { int z; x(z); }", CallArgumentY));
1002
1003 StatementMatcher WrongIndex = expression(call(
1004 hasArgument(42, declarationReference(to(variable(hasName("y")))))));
1005 EXPECT_TRUE(notMatches("void x(int) { int y; x(y); }", WrongIndex));
1006}
1007
1008TEST(Matcher, AnyArgument) {
1009 StatementMatcher CallArgumentY = expression(call(
1010 hasAnyArgument(declarationReference(to(variable(hasName("y")))))));
1011 EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
1012 EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
1013 EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
1014}
1015
1016TEST(Matcher, ArgumentCount) {
1017 StatementMatcher Call1Arg = expression(call(argumentCountIs(1)));
1018
1019 EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg));
1020 EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg));
1021 EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg));
1022}
1023
1024TEST(Matcher, References) {
1025 DeclarationMatcher ReferenceClassX = variable(
1026 hasType(references(record(hasName("X")))));
1027 EXPECT_TRUE(matches("class X {}; void y(X y) { X &x = y; }",
1028 ReferenceClassX));
1029 EXPECT_TRUE(
1030 matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
1031 EXPECT_TRUE(
1032 notMatches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
1033 EXPECT_TRUE(
1034 notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
1035}
1036
1037TEST(HasParameter, CallsInnerMatcher) {
1038 EXPECT_TRUE(matches("class X { void x(int) {} };",
1039 method(hasParameter(0, variable()))));
1040 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
1041 method(hasParameter(0, hasName("x")))));
1042}
1043
1044TEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) {
1045 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
1046 method(hasParameter(42, variable()))));
1047}
1048
1049TEST(HasType, MatchesParameterVariableTypesStrictly) {
1050 EXPECT_TRUE(matches("class X { void x(X x) {} };",
1051 method(hasParameter(0, hasType(record(hasName("X")))))));
1052 EXPECT_TRUE(notMatches("class X { void x(const X &x) {} };",
1053 method(hasParameter(0, hasType(record(hasName("X")))))));
1054 EXPECT_TRUE(matches("class X { void x(const X *x) {} };",
1055 method(hasParameter(0, hasType(pointsTo(record(hasName("X"))))))));
1056 EXPECT_TRUE(matches("class X { void x(const X &x) {} };",
1057 method(hasParameter(0, hasType(references(record(hasName("X"))))))));
1058}
1059
1060TEST(HasAnyParameter, MatchesIndependentlyOfPosition) {
1061 EXPECT_TRUE(matches("class Y {}; class X { void x(X x, Y y) {} };",
1062 method(hasAnyParameter(hasType(record(hasName("X")))))));
1063 EXPECT_TRUE(matches("class Y {}; class X { void x(Y y, X x) {} };",
1064 method(hasAnyParameter(hasType(record(hasName("X")))))));
1065}
1066
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001067TEST(Returns, MatchesReturnTypes) {
1068 EXPECT_TRUE(matches("class Y { int f() { return 1; } };",
1069 function(returns(asString("int")))));
1070 EXPECT_TRUE(notMatches("class Y { int f() { return 1; } };",
1071 function(returns(asString("float")))));
1072 EXPECT_TRUE(matches("class Y { Y getMe() { return *this; } };",
1073 function(returns(hasDeclaration(record(hasName("Y")))))));
1074}
1075
Manuel Klimek4da21662012-07-06 05:48:52 +00001076TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
1077 EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
1078 method(hasAnyParameter(hasType(record(hasName("X")))))));
1079}
1080
1081TEST(HasAnyParameter, DoesNotMatchThisPointer) {
1082 EXPECT_TRUE(notMatches("class Y {}; class X { void x() {} };",
1083 method(hasAnyParameter(hasType(pointsTo(record(hasName("X"))))))));
1084}
1085
1086TEST(HasName, MatchesParameterVariableDeclartions) {
1087 EXPECT_TRUE(matches("class Y {}; class X { void x(int x) {} };",
1088 method(hasAnyParameter(hasName("x")))));
1089 EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
1090 method(hasAnyParameter(hasName("x")))));
1091}
1092
1093TEST(Matcher, ConstructorCall) {
1094 StatementMatcher Constructor = expression(constructorCall());
1095
1096 EXPECT_TRUE(
1097 matches("class X { public: X(); }; void x() { X x; }", Constructor));
1098 EXPECT_TRUE(
1099 matches("class X { public: X(); }; void x() { X x = X(); }",
1100 Constructor));
1101 EXPECT_TRUE(
1102 matches("class X { public: X(int); }; void x() { X x = 0; }",
1103 Constructor));
1104 EXPECT_TRUE(matches("class X {}; void x(int) { X x; }", Constructor));
1105}
1106
1107TEST(Matcher, ConstructorArgument) {
1108 StatementMatcher Constructor = expression(constructorCall(
1109 hasArgument(0, declarationReference(to(variable(hasName("y")))))));
1110
1111 EXPECT_TRUE(
1112 matches("class X { public: X(int); }; void x() { int y; X x(y); }",
1113 Constructor));
1114 EXPECT_TRUE(
1115 matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
1116 Constructor));
1117 EXPECT_TRUE(
1118 matches("class X { public: X(int); }; void x() { int y; X x = y; }",
1119 Constructor));
1120 EXPECT_TRUE(
1121 notMatches("class X { public: X(int); }; void x() { int z; X x(z); }",
1122 Constructor));
1123
1124 StatementMatcher WrongIndex = expression(constructorCall(
1125 hasArgument(42, declarationReference(to(variable(hasName("y")))))));
1126 EXPECT_TRUE(
1127 notMatches("class X { public: X(int); }; void x() { int y; X x(y); }",
1128 WrongIndex));
1129}
1130
1131TEST(Matcher, ConstructorArgumentCount) {
1132 StatementMatcher Constructor1Arg =
1133 expression(constructorCall(argumentCountIs(1)));
1134
1135 EXPECT_TRUE(
1136 matches("class X { public: X(int); }; void x() { X x(0); }",
1137 Constructor1Arg));
1138 EXPECT_TRUE(
1139 matches("class X { public: X(int); }; void x() { X x = X(0); }",
1140 Constructor1Arg));
1141 EXPECT_TRUE(
1142 matches("class X { public: X(int); }; void x() { X x = 0; }",
1143 Constructor1Arg));
1144 EXPECT_TRUE(
1145 notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
1146 Constructor1Arg));
1147}
1148
1149TEST(Matcher, BindTemporaryExpression) {
1150 StatementMatcher TempExpression = expression(bindTemporaryExpression());
1151
1152 std::string ClassString = "class string { public: string(); ~string(); }; ";
1153
1154 EXPECT_TRUE(
1155 matches(ClassString +
1156 "string GetStringByValue();"
1157 "void FunctionTakesString(string s);"
1158 "void run() { FunctionTakesString(GetStringByValue()); }",
1159 TempExpression));
1160
1161 EXPECT_TRUE(
1162 notMatches(ClassString +
1163 "string* GetStringPointer(); "
1164 "void FunctionTakesStringPtr(string* s);"
1165 "void run() {"
1166 " string* s = GetStringPointer();"
1167 " FunctionTakesStringPtr(GetStringPointer());"
1168 " FunctionTakesStringPtr(s);"
1169 "}",
1170 TempExpression));
1171
1172 EXPECT_TRUE(
1173 notMatches("class no_dtor {};"
1174 "no_dtor GetObjByValue();"
1175 "void ConsumeObj(no_dtor param);"
1176 "void run() { ConsumeObj(GetObjByValue()); }",
1177 TempExpression));
1178}
1179
1180TEST(ConstructorDeclaration, SimpleCase) {
1181 EXPECT_TRUE(matches("class Foo { Foo(int i); };",
1182 constructor(ofClass(hasName("Foo")))));
1183 EXPECT_TRUE(notMatches("class Foo { Foo(int i); };",
1184 constructor(ofClass(hasName("Bar")))));
1185}
1186
1187TEST(ConstructorDeclaration, IsImplicit) {
1188 // This one doesn't match because the constructor is not added by the
1189 // compiler (it is not needed).
1190 EXPECT_TRUE(notMatches("class Foo { };",
1191 constructor(isImplicit())));
1192 // The compiler added the implicit default constructor.
1193 EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
1194 constructor(isImplicit())));
1195 EXPECT_TRUE(matches("class Foo { Foo(){} };",
1196 constructor(unless(isImplicit()))));
1197}
1198
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001199TEST(DestructorDeclaration, MatchesVirtualDestructor) {
1200 EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };",
1201 destructor(ofClass(hasName("Foo")))));
1202}
1203
1204TEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) {
1205 EXPECT_TRUE(notMatches("class Foo {};", destructor(ofClass(hasName("Foo")))));
1206}
1207
Manuel Klimek4da21662012-07-06 05:48:52 +00001208TEST(HasAnyConstructorInitializer, SimpleCase) {
1209 EXPECT_TRUE(notMatches(
1210 "class Foo { Foo() { } };",
1211 constructor(hasAnyConstructorInitializer(anything()))));
1212 EXPECT_TRUE(matches(
1213 "class Foo {"
1214 " Foo() : foo_() { }"
1215 " int foo_;"
1216 "};",
1217 constructor(hasAnyConstructorInitializer(anything()))));
1218}
1219
1220TEST(HasAnyConstructorInitializer, ForField) {
1221 static const char Code[] =
1222 "class Baz { };"
1223 "class Foo {"
1224 " Foo() : foo_() { }"
1225 " Baz foo_;"
1226 " Baz bar_;"
1227 "};";
1228 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1229 forField(hasType(record(hasName("Baz"))))))));
1230 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1231 forField(hasName("foo_"))))));
1232 EXPECT_TRUE(notMatches(Code, constructor(hasAnyConstructorInitializer(
1233 forField(hasType(record(hasName("Bar"))))))));
1234}
1235
1236TEST(HasAnyConstructorInitializer, WithInitializer) {
1237 static const char Code[] =
1238 "class Foo {"
1239 " Foo() : foo_(0) { }"
1240 " int foo_;"
1241 "};";
1242 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1243 withInitializer(integerLiteral(equals(0)))))));
1244 EXPECT_TRUE(notMatches(Code, constructor(hasAnyConstructorInitializer(
1245 withInitializer(integerLiteral(equals(1)))))));
1246}
1247
1248TEST(HasAnyConstructorInitializer, IsWritten) {
1249 static const char Code[] =
1250 "struct Bar { Bar(){} };"
1251 "class Foo {"
1252 " Foo() : foo_() { }"
1253 " Bar foo_;"
1254 " Bar bar_;"
1255 "};";
1256 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1257 allOf(forField(hasName("foo_")), isWritten())))));
1258 EXPECT_TRUE(notMatches(Code, constructor(hasAnyConstructorInitializer(
1259 allOf(forField(hasName("bar_")), isWritten())))));
1260 EXPECT_TRUE(matches(Code, constructor(hasAnyConstructorInitializer(
1261 allOf(forField(hasName("bar_")), unless(isWritten()))))));
1262}
1263
1264TEST(Matcher, NewExpression) {
1265 StatementMatcher New = expression(newExpression());
1266
1267 EXPECT_TRUE(matches("class X { public: X(); }; void x() { new X; }", New));
1268 EXPECT_TRUE(
1269 matches("class X { public: X(); }; void x() { new X(); }", New));
1270 EXPECT_TRUE(
1271 matches("class X { public: X(int); }; void x() { new X(0); }", New));
1272 EXPECT_TRUE(matches("class X {}; void x(int) { new X; }", New));
1273}
1274
1275TEST(Matcher, NewExpressionArgument) {
1276 StatementMatcher New = expression(constructorCall(
1277 hasArgument(
1278 0, declarationReference(to(variable(hasName("y")))))));
1279
1280 EXPECT_TRUE(
1281 matches("class X { public: X(int); }; void x() { int y; new X(y); }",
1282 New));
1283 EXPECT_TRUE(
1284 matches("class X { public: X(int); }; void x() { int y; new X(y); }",
1285 New));
1286 EXPECT_TRUE(
1287 notMatches("class X { public: X(int); }; void x() { int z; new X(z); }",
1288 New));
1289
1290 StatementMatcher WrongIndex = expression(constructorCall(
1291 hasArgument(
1292 42, declarationReference(to(variable(hasName("y")))))));
1293 EXPECT_TRUE(
1294 notMatches("class X { public: X(int); }; void x() { int y; new X(y); }",
1295 WrongIndex));
1296}
1297
1298TEST(Matcher, NewExpressionArgumentCount) {
1299 StatementMatcher New = constructorCall(argumentCountIs(1));
1300
1301 EXPECT_TRUE(
1302 matches("class X { public: X(int); }; void x() { new X(0); }", New));
1303 EXPECT_TRUE(
1304 notMatches("class X { public: X(int, int); }; void x() { new X(0, 0); }",
1305 New));
1306}
1307
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001308TEST(Matcher, DeleteExpression) {
1309 EXPECT_TRUE(matches("struct A {}; void f(A* a) { delete a; }",
1310 deleteExpression()));
1311}
1312
Manuel Klimek4da21662012-07-06 05:48:52 +00001313TEST(Matcher, DefaultArgument) {
1314 StatementMatcher Arg = defaultArgument();
1315
1316 EXPECT_TRUE(matches("void x(int, int = 0) { int y; x(y); }", Arg));
1317 EXPECT_TRUE(
1318 matches("class X { void x(int, int = 0) { int y; x(y); } };", Arg));
1319 EXPECT_TRUE(notMatches("void x(int, int = 0) { int y; x(y, 0); }", Arg));
1320}
1321
1322TEST(Matcher, StringLiterals) {
1323 StatementMatcher Literal = expression(stringLiteral());
1324 EXPECT_TRUE(matches("const char *s = \"string\";", Literal));
1325 // wide string
1326 EXPECT_TRUE(matches("const wchar_t *s = L\"string\";", Literal));
1327 // with escaped characters
1328 EXPECT_TRUE(matches("const char *s = \"\x05five\";", Literal));
1329 // no matching -- though the data type is the same, there is no string literal
1330 EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));
1331}
1332
1333TEST(Matcher, CharacterLiterals) {
1334 StatementMatcher CharLiteral = expression(characterLiteral());
1335 EXPECT_TRUE(matches("const char c = 'c';", CharLiteral));
1336 // wide character
1337 EXPECT_TRUE(matches("const char c = L'c';", CharLiteral));
1338 // wide character, Hex encoded, NOT MATCHED!
1339 EXPECT_TRUE(notMatches("const wchar_t c = 0x2126;", CharLiteral));
1340 EXPECT_TRUE(notMatches("const char c = 0x1;", CharLiteral));
1341}
1342
1343TEST(Matcher, IntegerLiterals) {
1344 StatementMatcher HasIntLiteral = expression(integerLiteral());
1345 EXPECT_TRUE(matches("int i = 10;", HasIntLiteral));
1346 EXPECT_TRUE(matches("int i = 0x1AB;", HasIntLiteral));
1347 EXPECT_TRUE(matches("int i = 10L;", HasIntLiteral));
1348 EXPECT_TRUE(matches("int i = 10U;", HasIntLiteral));
1349
1350 // Non-matching cases (character literals, float and double)
1351 EXPECT_TRUE(notMatches("int i = L'a';",
1352 HasIntLiteral)); // this is actually a character
1353 // literal cast to int
1354 EXPECT_TRUE(notMatches("int i = 'a';", HasIntLiteral));
1355 EXPECT_TRUE(notMatches("int i = 1e10;", HasIntLiteral));
1356 EXPECT_TRUE(notMatches("int i = 10.0;", HasIntLiteral));
1357}
1358
1359TEST(Matcher, Conditions) {
1360 StatementMatcher Condition = ifStmt(hasCondition(boolLiteral(equals(true))));
1361
1362 EXPECT_TRUE(matches("void x() { if (true) {} }", Condition));
1363 EXPECT_TRUE(notMatches("void x() { if (false) {} }", Condition));
1364 EXPECT_TRUE(notMatches("void x() { bool a = true; if (a) {} }", Condition));
1365 EXPECT_TRUE(notMatches("void x() { if (true || false) {} }", Condition));
1366 EXPECT_TRUE(notMatches("void x() { if (1) {} }", Condition));
1367}
1368
1369TEST(MatchBinaryOperator, HasOperatorName) {
1370 StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
1371
1372 EXPECT_TRUE(matches("void x() { true || false; }", OperatorOr));
1373 EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
1374}
1375
1376TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
1377 StatementMatcher OperatorTrueFalse =
1378 binaryOperator(hasLHS(boolLiteral(equals(true))),
1379 hasRHS(boolLiteral(equals(false))));
1380
1381 EXPECT_TRUE(matches("void x() { true || false; }", OperatorTrueFalse));
1382 EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse));
1383 EXPECT_TRUE(notMatches("void x() { false || true; }", OperatorTrueFalse));
1384}
1385
1386TEST(MatchBinaryOperator, HasEitherOperand) {
1387 StatementMatcher HasOperand =
1388 binaryOperator(hasEitherOperand(boolLiteral(equals(false))));
1389
1390 EXPECT_TRUE(matches("void x() { true || false; }", HasOperand));
1391 EXPECT_TRUE(matches("void x() { false && true; }", HasOperand));
1392 EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand));
1393}
1394
1395TEST(Matcher, BinaryOperatorTypes) {
1396 // Integration test that verifies the AST provides all binary operators in
1397 // a way we expect.
1398 // FIXME: Operator ','
1399 EXPECT_TRUE(
1400 matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(","))));
1401 EXPECT_TRUE(
1402 matches("bool b; bool c = (b = true);",
1403 binaryOperator(hasOperatorName("="))));
1404 EXPECT_TRUE(
1405 matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!="))));
1406 EXPECT_TRUE(
1407 matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("=="))));
1408 EXPECT_TRUE(matches("bool b = 1 < 2;", binaryOperator(hasOperatorName("<"))));
1409 EXPECT_TRUE(
1410 matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<="))));
1411 EXPECT_TRUE(
1412 matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<"))));
1413 EXPECT_TRUE(
1414 matches("int i = 1; int j = (i <<= 2);",
1415 binaryOperator(hasOperatorName("<<="))));
1416 EXPECT_TRUE(matches("bool b = 1 > 2;", binaryOperator(hasOperatorName(">"))));
1417 EXPECT_TRUE(
1418 matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">="))));
1419 EXPECT_TRUE(
1420 matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>"))));
1421 EXPECT_TRUE(
1422 matches("int i = 1; int j = (i >>= 2);",
1423 binaryOperator(hasOperatorName(">>="))));
1424 EXPECT_TRUE(
1425 matches("int i = 42 ^ 23;", binaryOperator(hasOperatorName("^"))));
1426 EXPECT_TRUE(
1427 matches("int i = 42; int j = (i ^= 42);",
1428 binaryOperator(hasOperatorName("^="))));
1429 EXPECT_TRUE(
1430 matches("int i = 42 % 23;", binaryOperator(hasOperatorName("%"))));
1431 EXPECT_TRUE(
1432 matches("int i = 42; int j = (i %= 42);",
1433 binaryOperator(hasOperatorName("%="))));
1434 EXPECT_TRUE(
1435 matches("bool b = 42 &23;", binaryOperator(hasOperatorName("&"))));
1436 EXPECT_TRUE(
1437 matches("bool b = true && false;",
1438 binaryOperator(hasOperatorName("&&"))));
1439 EXPECT_TRUE(
1440 matches("bool b = true; bool c = (b &= false);",
1441 binaryOperator(hasOperatorName("&="))));
1442 EXPECT_TRUE(
1443 matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|"))));
1444 EXPECT_TRUE(
1445 matches("bool b = true || false;",
1446 binaryOperator(hasOperatorName("||"))));
1447 EXPECT_TRUE(
1448 matches("bool b = true; bool c = (b |= false);",
1449 binaryOperator(hasOperatorName("|="))));
1450 EXPECT_TRUE(
1451 matches("int i = 42 *23;", binaryOperator(hasOperatorName("*"))));
1452 EXPECT_TRUE(
1453 matches("int i = 42; int j = (i *= 23);",
1454 binaryOperator(hasOperatorName("*="))));
1455 EXPECT_TRUE(
1456 matches("int i = 42 / 23;", binaryOperator(hasOperatorName("/"))));
1457 EXPECT_TRUE(
1458 matches("int i = 42; int j = (i /= 23);",
1459 binaryOperator(hasOperatorName("/="))));
1460 EXPECT_TRUE(
1461 matches("int i = 42 + 23;", binaryOperator(hasOperatorName("+"))));
1462 EXPECT_TRUE(
1463 matches("int i = 42; int j = (i += 23);",
1464 binaryOperator(hasOperatorName("+="))));
1465 EXPECT_TRUE(
1466 matches("int i = 42 - 23;", binaryOperator(hasOperatorName("-"))));
1467 EXPECT_TRUE(
1468 matches("int i = 42; int j = (i -= 23);",
1469 binaryOperator(hasOperatorName("-="))));
1470 EXPECT_TRUE(
1471 matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };",
1472 binaryOperator(hasOperatorName("->*"))));
1473 EXPECT_TRUE(
1474 matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };",
1475 binaryOperator(hasOperatorName(".*"))));
1476
1477 // Member expressions as operators are not supported in matches.
1478 EXPECT_TRUE(
1479 notMatches("struct A { void x(A *a) { a->x(this); } };",
1480 binaryOperator(hasOperatorName("->"))));
1481
1482 // Initializer assignments are not represented as operator equals.
1483 EXPECT_TRUE(
1484 notMatches("bool b = true;", binaryOperator(hasOperatorName("="))));
1485
1486 // Array indexing is not represented as operator.
1487 EXPECT_TRUE(notMatches("int a[42]; void x() { a[23]; }", unaryOperator()));
1488
1489 // Overloaded operators do not match at all.
1490 EXPECT_TRUE(notMatches(
1491 "struct A { bool operator&&(const A &a) const { return false; } };"
1492 "void x() { A a, b; a && b; }",
1493 binaryOperator()));
1494}
1495
1496TEST(MatchUnaryOperator, HasOperatorName) {
1497 StatementMatcher OperatorNot = unaryOperator(hasOperatorName("!"));
1498
1499 EXPECT_TRUE(matches("void x() { !true; } ", OperatorNot));
1500 EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
1501}
1502
1503TEST(MatchUnaryOperator, HasUnaryOperand) {
1504 StatementMatcher OperatorOnFalse =
1505 unaryOperator(hasUnaryOperand(boolLiteral(equals(false))));
1506
1507 EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse));
1508 EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse));
1509}
1510
1511TEST(Matcher, UnaryOperatorTypes) {
1512 // Integration test that verifies the AST provides all unary operators in
1513 // a way we expect.
1514 EXPECT_TRUE(matches("bool b = !true;", unaryOperator(hasOperatorName("!"))));
1515 EXPECT_TRUE(
1516 matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&"))));
1517 EXPECT_TRUE(matches("int i = ~ 1;", unaryOperator(hasOperatorName("~"))));
1518 EXPECT_TRUE(
1519 matches("bool *p; bool b = *p;", unaryOperator(hasOperatorName("*"))));
1520 EXPECT_TRUE(
1521 matches("int i; int j = +i;", unaryOperator(hasOperatorName("+"))));
1522 EXPECT_TRUE(
1523 matches("int i; int j = -i;", unaryOperator(hasOperatorName("-"))));
1524 EXPECT_TRUE(
1525 matches("int i; int j = ++i;", unaryOperator(hasOperatorName("++"))));
1526 EXPECT_TRUE(
1527 matches("int i; int j = i++;", unaryOperator(hasOperatorName("++"))));
1528 EXPECT_TRUE(
1529 matches("int i; int j = --i;", unaryOperator(hasOperatorName("--"))));
1530 EXPECT_TRUE(
1531 matches("int i; int j = i--;", unaryOperator(hasOperatorName("--"))));
1532
1533 // We don't match conversion operators.
1534 EXPECT_TRUE(notMatches("int i; double d = (double)i;", unaryOperator()));
1535
1536 // Function calls are not represented as operator.
1537 EXPECT_TRUE(notMatches("void f(); void x() { f(); }", unaryOperator()));
1538
1539 // Overloaded operators do not match at all.
1540 // FIXME: We probably want to add that.
1541 EXPECT_TRUE(notMatches(
1542 "struct A { bool operator!() const { return false; } };"
1543 "void x() { A a; !a; }", unaryOperator(hasOperatorName("!"))));
1544}
1545
1546TEST(Matcher, ConditionalOperator) {
1547 StatementMatcher Conditional = conditionalOperator(
1548 hasCondition(boolLiteral(equals(true))),
1549 hasTrueExpression(boolLiteral(equals(false))));
1550
1551 EXPECT_TRUE(matches("void x() { true ? false : true; }", Conditional));
1552 EXPECT_TRUE(notMatches("void x() { false ? false : true; }", Conditional));
1553 EXPECT_TRUE(notMatches("void x() { true ? true : false; }", Conditional));
1554
1555 StatementMatcher ConditionalFalse = conditionalOperator(
1556 hasFalseExpression(boolLiteral(equals(false))));
1557
1558 EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
1559 EXPECT_TRUE(
1560 notMatches("void x() { true ? false : true; }", ConditionalFalse));
1561}
1562
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001563TEST(ArraySubscriptMatchers, ArraySubscripts) {
1564 EXPECT_TRUE(matches("int i[2]; void f() { i[1] = 1; }",
1565 arraySubscriptExpr()));
1566 EXPECT_TRUE(notMatches("int i; void f() { i = 1; }",
1567 arraySubscriptExpr()));
1568}
1569
1570TEST(ArraySubscriptMatchers, ArrayIndex) {
1571 EXPECT_TRUE(matches(
1572 "int i[2]; void f() { i[1] = 1; }",
1573 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
1574 EXPECT_TRUE(matches(
1575 "int i[2]; void f() { 1[i] = 1; }",
1576 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
1577 EXPECT_TRUE(notMatches(
1578 "int i[2]; void f() { i[1] = 1; }",
1579 arraySubscriptExpr(hasIndex(integerLiteral(equals(0))))));
1580}
1581
1582TEST(ArraySubscriptMatchers, MatchesArrayBase) {
1583 EXPECT_TRUE(matches(
1584 "int i[2]; void f() { i[1] = 2; }",
1585 arraySubscriptExpr(hasBase(implicitCast(
1586 hasSourceExpression(declarationReference()))))));
1587}
1588
Manuel Klimek4da21662012-07-06 05:48:52 +00001589TEST(Matcher, HasNameSupportsNamespaces) {
1590 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1591 record(hasName("a::b::C"))));
1592 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1593 record(hasName("::a::b::C"))));
1594 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1595 record(hasName("b::C"))));
1596 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1597 record(hasName("C"))));
1598 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1599 record(hasName("c::b::C"))));
1600 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1601 record(hasName("a::c::C"))));
1602 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1603 record(hasName("a::b::A"))));
1604 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1605 record(hasName("::C"))));
1606 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1607 record(hasName("::b::C"))));
1608 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1609 record(hasName("z::a::b::C"))));
1610 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1611 record(hasName("a+b::C"))));
1612 EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
1613 record(hasName("C"))));
1614}
1615
1616TEST(Matcher, HasNameSupportsOuterClasses) {
1617 EXPECT_TRUE(
1618 matches("class A { class B { class C; }; };", record(hasName("A::B::C"))));
1619 EXPECT_TRUE(
1620 matches("class A { class B { class C; }; };",
1621 record(hasName("::A::B::C"))));
1622 EXPECT_TRUE(
1623 matches("class A { class B { class C; }; };", record(hasName("B::C"))));
1624 EXPECT_TRUE(
1625 matches("class A { class B { class C; }; };", record(hasName("C"))));
1626 EXPECT_TRUE(
1627 notMatches("class A { class B { class C; }; };",
1628 record(hasName("c::B::C"))));
1629 EXPECT_TRUE(
1630 notMatches("class A { class B { class C; }; };",
1631 record(hasName("A::c::C"))));
1632 EXPECT_TRUE(
1633 notMatches("class A { class B { class C; }; };",
1634 record(hasName("A::B::A"))));
1635 EXPECT_TRUE(
1636 notMatches("class A { class B { class C; }; };", record(hasName("::C"))));
1637 EXPECT_TRUE(
1638 notMatches("class A { class B { class C; }; };",
1639 record(hasName("::B::C"))));
1640 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
1641 record(hasName("z::A::B::C"))));
1642 EXPECT_TRUE(
1643 notMatches("class A { class B { class C; }; };",
1644 record(hasName("A+B::C"))));
1645}
1646
1647TEST(Matcher, IsDefinition) {
1648 DeclarationMatcher DefinitionOfClassA =
1649 record(hasName("A"), isDefinition());
1650 EXPECT_TRUE(matches("class A {};", DefinitionOfClassA));
1651 EXPECT_TRUE(notMatches("class A;", DefinitionOfClassA));
1652
1653 DeclarationMatcher DefinitionOfVariableA =
1654 variable(hasName("a"), isDefinition());
1655 EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));
1656 EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));
1657
1658 DeclarationMatcher DefinitionOfMethodA =
1659 method(hasName("a"), isDefinition());
1660 EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));
1661 EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));
1662}
1663
1664TEST(Matcher, OfClass) {
1665 StatementMatcher Constructor = constructorCall(hasDeclaration(method(
1666 ofClass(hasName("X")))));
1667
1668 EXPECT_TRUE(
1669 matches("class X { public: X(); }; void x(int) { X x; }", Constructor));
1670 EXPECT_TRUE(
1671 matches("class X { public: X(); }; void x(int) { X x = X(); }",
1672 Constructor));
1673 EXPECT_TRUE(
1674 notMatches("class Y { public: Y(); }; void x(int) { Y y; }",
1675 Constructor));
1676}
1677
1678TEST(Matcher, VisitsTemplateInstantiations) {
1679 EXPECT_TRUE(matches(
1680 "class A { public: void x(); };"
1681 "template <typename T> class B { public: void y() { T t; t.x(); } };"
1682 "void f() { B<A> b; b.y(); }", call(callee(method(hasName("x"))))));
1683
1684 EXPECT_TRUE(matches(
1685 "class A { public: void x(); };"
1686 "class C {"
1687 " public:"
1688 " template <typename T> class B { public: void y() { T t; t.x(); } };"
1689 "};"
1690 "void f() {"
1691 " C::B<A> b; b.y();"
1692 "}", record(hasName("C"),
1693 hasDescendant(call(callee(method(hasName("x"))))))));
1694}
1695
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001696TEST(Matcher, HandlesNullQualTypes) {
1697 // FIXME: Add a Type matcher so we can replace uses of this
1698 // variable with Type(True())
1699 const TypeMatcher AnyType = anything();
1700
1701 // We don't really care whether this matcher succeeds; we're testing that
1702 // it completes without crashing.
1703 EXPECT_TRUE(matches(
1704 "struct A { };"
1705 "template <typename T>"
1706 "void f(T t) {"
1707 " T local_t(t /* this becomes a null QualType in the AST */);"
1708 "}"
1709 "void g() {"
1710 " f(0);"
1711 "}",
1712 expression(hasType(TypeMatcher(
1713 anyOf(
1714 TypeMatcher(hasDeclaration(anything())),
1715 pointsTo(AnyType),
1716 references(AnyType)
1717 // Other QualType matchers should go here.
1718 ))))));
1719}
1720
Manuel Klimek4da21662012-07-06 05:48:52 +00001721// For testing AST_MATCHER_P().
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001722AST_MATCHER_P(Decl, just, internal::Matcher<Decl>, AMatcher) {
Manuel Klimek4da21662012-07-06 05:48:52 +00001723 // Make sure all special variables are used: node, match_finder,
1724 // bound_nodes_builder, and the parameter named 'AMatcher'.
1725 return AMatcher.matches(Node, Finder, Builder);
1726}
1727
1728TEST(AstMatcherPMacro, Works) {
1729 DeclarationMatcher HasClassB = just(has(id("b", record(hasName("B")))));
1730
1731 EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001732 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001733
1734 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001735 HasClassB, new VerifyIdIsBoundToDecl<Decl>("a")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001736
1737 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001738 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001739}
1740
1741AST_POLYMORPHIC_MATCHER_P(
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001742 polymorphicHas, internal::Matcher<Decl>, AMatcher) {
1743 TOOLING_COMPILE_ASSERT((llvm::is_same<NodeType, Decl>::value) ||
1744 (llvm::is_same<NodeType, Stmt>::value),
Manuel Klimek4da21662012-07-06 05:48:52 +00001745 assert_node_type_is_accessible);
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001746 internal::TypedBaseMatcher<Decl> ChildMatcher(AMatcher);
Manuel Klimek4da21662012-07-06 05:48:52 +00001747 return Finder->matchesChildOf(
1748 Node, ChildMatcher, Builder,
1749 ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
1750 ASTMatchFinder::BK_First);
1751}
1752
1753TEST(AstPolymorphicMatcherPMacro, Works) {
1754 DeclarationMatcher HasClassB = polymorphicHas(id("b", record(hasName("B"))));
1755
1756 EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001757 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001758
1759 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001760 HasClassB, new VerifyIdIsBoundToDecl<Decl>("a")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001761
1762 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00001763 HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
Manuel Klimek4da21662012-07-06 05:48:52 +00001764
1765 StatementMatcher StatementHasClassB =
1766 polymorphicHas(record(hasName("B")));
1767
1768 EXPECT_TRUE(matches("void x() { class B {}; }", StatementHasClassB));
1769}
1770
1771TEST(For, FindsForLoops) {
1772 EXPECT_TRUE(matches("void f() { for(;;); }", forStmt()));
1773 EXPECT_TRUE(matches("void f() { if(true) for(;;); }", forStmt()));
1774}
1775
Daniel Jasper6a124492012-07-12 08:50:38 +00001776TEST(For, ForLoopInternals) {
1777 EXPECT_TRUE(matches("void f(){ int i; for (; i < 3 ; ); }",
1778 forStmt(hasCondition(anything()))));
1779 EXPECT_TRUE(matches("void f() { for (int i = 0; ;); }",
1780 forStmt(hasLoopInit(anything()))));
1781}
1782
1783TEST(For, NegativeForLoopInternals) {
1784 EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }",
1785 forStmt(hasCondition(expression()))));
1786 EXPECT_TRUE(notMatches("void f() {int i; for (; i < 4; ++i) {} }",
1787 forStmt(hasLoopInit(anything()))));
1788}
1789
Manuel Klimek4da21662012-07-06 05:48:52 +00001790TEST(For, ReportsNoFalsePositives) {
1791 EXPECT_TRUE(notMatches("void f() { ; }", forStmt()));
1792 EXPECT_TRUE(notMatches("void f() { if(true); }", forStmt()));
1793}
1794
1795TEST(CompoundStatement, HandlesSimpleCases) {
1796 EXPECT_TRUE(notMatches("void f();", compoundStatement()));
1797 EXPECT_TRUE(matches("void f() {}", compoundStatement()));
1798 EXPECT_TRUE(matches("void f() {{}}", compoundStatement()));
1799}
1800
1801TEST(CompoundStatement, DoesNotMatchEmptyStruct) {
1802 // It's not a compound statement just because there's "{}" in the source
1803 // text. This is an AST search, not grep.
1804 EXPECT_TRUE(notMatches("namespace n { struct S {}; }",
1805 compoundStatement()));
1806 EXPECT_TRUE(matches("namespace n { struct S { void f() {{}} }; }",
1807 compoundStatement()));
1808}
1809
Daniel Jasper6a124492012-07-12 08:50:38 +00001810TEST(HasBody, FindsBodyOfForWhileDoLoops) {
Manuel Klimek4da21662012-07-06 05:48:52 +00001811 EXPECT_TRUE(matches("void f() { for(;;) {} }",
Daniel Jasper6a124492012-07-12 08:50:38 +00001812 forStmt(hasBody(compoundStatement()))));
Manuel Klimek4da21662012-07-06 05:48:52 +00001813 EXPECT_TRUE(notMatches("void f() { for(;;); }",
Daniel Jasper6a124492012-07-12 08:50:38 +00001814 forStmt(hasBody(compoundStatement()))));
1815 EXPECT_TRUE(matches("void f() { while(true) {} }",
1816 whileStmt(hasBody(compoundStatement()))));
1817 EXPECT_TRUE(matches("void f() { do {} while(true); }",
1818 doStmt(hasBody(compoundStatement()))));
Manuel Klimek4da21662012-07-06 05:48:52 +00001819}
1820
1821TEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
1822 // The simplest case: every compound statement is in a function
1823 // definition, and the function body itself must be a compound
1824 // statement.
1825 EXPECT_TRUE(matches("void f() { for (;;); }",
1826 compoundStatement(hasAnySubstatement(forStmt()))));
1827}
1828
1829TEST(HasAnySubstatement, IsNotRecursive) {
1830 // It's really "has any immediate substatement".
1831 EXPECT_TRUE(notMatches("void f() { if (true) for (;;); }",
1832 compoundStatement(hasAnySubstatement(forStmt()))));
1833}
1834
1835TEST(HasAnySubstatement, MatchesInNestedCompoundStatements) {
1836 EXPECT_TRUE(matches("void f() { if (true) { for (;;); } }",
1837 compoundStatement(hasAnySubstatement(forStmt()))));
1838}
1839
1840TEST(HasAnySubstatement, FindsSubstatementBetweenOthers) {
1841 EXPECT_TRUE(matches("void f() { 1; 2; 3; for (;;); 4; 5; 6; }",
1842 compoundStatement(hasAnySubstatement(forStmt()))));
1843}
1844
1845TEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) {
1846 EXPECT_TRUE(matches("void f() { }",
1847 compoundStatement(statementCountIs(0))));
1848 EXPECT_TRUE(notMatches("void f() {}",
1849 compoundStatement(statementCountIs(1))));
1850}
1851
1852TEST(StatementCountIs, AppearsToMatchOnlyOneCount) {
1853 EXPECT_TRUE(matches("void f() { 1; }",
1854 compoundStatement(statementCountIs(1))));
1855 EXPECT_TRUE(notMatches("void f() { 1; }",
1856 compoundStatement(statementCountIs(0))));
1857 EXPECT_TRUE(notMatches("void f() { 1; }",
1858 compoundStatement(statementCountIs(2))));
1859}
1860
1861TEST(StatementCountIs, WorksWithMultipleStatements) {
1862 EXPECT_TRUE(matches("void f() { 1; 2; 3; }",
1863 compoundStatement(statementCountIs(3))));
1864}
1865
1866TEST(StatementCountIs, WorksWithNestedCompoundStatements) {
1867 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1868 compoundStatement(statementCountIs(1))));
1869 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1870 compoundStatement(statementCountIs(2))));
1871 EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
1872 compoundStatement(statementCountIs(3))));
1873 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1874 compoundStatement(statementCountIs(4))));
1875}
1876
1877TEST(Member, WorksInSimplestCase) {
1878 EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
1879 memberExpression(member(hasName("first")))));
1880}
1881
1882TEST(Member, DoesNotMatchTheBaseExpression) {
1883 // Don't pick out the wrong part of the member expression, this should
1884 // be checking the member (name) only.
1885 EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
1886 memberExpression(member(hasName("first")))));
1887}
1888
1889TEST(Member, MatchesInMemberFunctionCall) {
1890 EXPECT_TRUE(matches("void f() {"
1891 " struct { void first() {}; } s;"
1892 " s.first();"
1893 "};",
1894 memberExpression(member(hasName("first")))));
1895}
1896
1897TEST(HasObjectExpression, DoesNotMatchMember) {
1898 EXPECT_TRUE(notMatches(
1899 "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
1900 memberExpression(hasObjectExpression(hasType(record(hasName("X")))))));
1901}
1902
1903TEST(HasObjectExpression, MatchesBaseOfVariable) {
1904 EXPECT_TRUE(matches(
1905 "struct X { int m; }; void f(X x) { x.m; }",
1906 memberExpression(hasObjectExpression(hasType(record(hasName("X")))))));
1907 EXPECT_TRUE(matches(
1908 "struct X { int m; }; void f(X* x) { x->m; }",
1909 memberExpression(hasObjectExpression(
1910 hasType(pointsTo(record(hasName("X"))))))));
1911}
1912
1913TEST(HasObjectExpression,
1914 MatchesObjectExpressionOfImplicitlyFormedMemberExpression) {
1915 EXPECT_TRUE(matches(
1916 "class X {}; struct S { X m; void f() { this->m; } };",
1917 memberExpression(hasObjectExpression(
1918 hasType(pointsTo(record(hasName("S"))))))));
1919 EXPECT_TRUE(matches(
1920 "class X {}; struct S { X m; void f() { m; } };",
1921 memberExpression(hasObjectExpression(
1922 hasType(pointsTo(record(hasName("S"))))))));
1923}
1924
1925TEST(Field, DoesNotMatchNonFieldMembers) {
1926 EXPECT_TRUE(notMatches("class X { void m(); };", field(hasName("m"))));
1927 EXPECT_TRUE(notMatches("class X { class m {}; };", field(hasName("m"))));
1928 EXPECT_TRUE(notMatches("class X { enum { m }; };", field(hasName("m"))));
1929 EXPECT_TRUE(notMatches("class X { enum m {}; };", field(hasName("m"))));
1930}
1931
1932TEST(Field, MatchesField) {
1933 EXPECT_TRUE(matches("class X { int m; };", field(hasName("m"))));
1934}
1935
1936TEST(IsConstQualified, MatchesConstInt) {
1937 EXPECT_TRUE(matches("const int i = 42;",
1938 variable(hasType(isConstQualified()))));
1939}
1940
1941TEST(IsConstQualified, MatchesConstPointer) {
1942 EXPECT_TRUE(matches("int i = 42; int* const p(&i);",
1943 variable(hasType(isConstQualified()))));
1944}
1945
1946TEST(IsConstQualified, MatchesThroughTypedef) {
1947 EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
1948 variable(hasType(isConstQualified()))));
1949 EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p(0);",
1950 variable(hasType(isConstQualified()))));
1951}
1952
1953TEST(IsConstQualified, DoesNotMatchInappropriately) {
1954 EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
1955 variable(hasType(isConstQualified()))));
1956 EXPECT_TRUE(notMatches("int const* p;",
1957 variable(hasType(isConstQualified()))));
1958}
1959
1960TEST(ReinterpretCast, MatchesSimpleCase) {
1961 EXPECT_TRUE(matches("char* p = reinterpret_cast<char*>(&p);",
1962 expression(reinterpretCast())));
1963}
1964
1965TEST(ReinterpretCast, DoesNotMatchOtherCasts) {
1966 EXPECT_TRUE(notMatches("char* p = (char*)(&p);",
1967 expression(reinterpretCast())));
1968 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
1969 expression(reinterpretCast())));
1970 EXPECT_TRUE(notMatches("void* p = static_cast<void*>(&p);",
1971 expression(reinterpretCast())));
1972 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
1973 "B b;"
1974 "D* p = dynamic_cast<D*>(&b);",
1975 expression(reinterpretCast())));
1976}
1977
1978TEST(FunctionalCast, MatchesSimpleCase) {
1979 std::string foo_class = "class Foo { public: Foo(char*); };";
1980 EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",
1981 expression(functionalCast())));
1982}
1983
1984TEST(FunctionalCast, DoesNotMatchOtherCasts) {
1985 std::string FooClass = "class Foo { public: Foo(char*); };";
1986 EXPECT_TRUE(
1987 notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",
1988 expression(functionalCast())));
1989 EXPECT_TRUE(
1990 notMatches(FooClass + "void r() { Foo f = \"hello world\"; }",
1991 expression(functionalCast())));
1992}
1993
1994TEST(DynamicCast, MatchesSimpleCase) {
1995 EXPECT_TRUE(matches("struct B { virtual ~B() {} }; struct D : B {};"
1996 "B b;"
1997 "D* p = dynamic_cast<D*>(&b);",
1998 expression(dynamicCast())));
1999}
2000
2001TEST(StaticCast, MatchesSimpleCase) {
2002 EXPECT_TRUE(matches("void* p(static_cast<void*>(&p));",
2003 expression(staticCast())));
2004}
2005
2006TEST(StaticCast, DoesNotMatchOtherCasts) {
2007 EXPECT_TRUE(notMatches("char* p = (char*)(&p);",
2008 expression(staticCast())));
2009 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
2010 expression(staticCast())));
2011 EXPECT_TRUE(notMatches("void* p = reinterpret_cast<char*>(&p);",
2012 expression(staticCast())));
2013 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
2014 "B b;"
2015 "D* p = dynamic_cast<D*>(&b);",
2016 expression(staticCast())));
2017}
2018
2019TEST(HasDestinationType, MatchesSimpleCase) {
2020 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
2021 expression(
2022 staticCast(hasDestinationType(
2023 pointsTo(TypeMatcher(anything())))))));
2024}
2025
2026TEST(HasSourceExpression, MatchesSimpleCase) {
2027 EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
2028 "void r() {string a_string; URL url = a_string; }",
2029 expression(implicitCast(
2030 hasSourceExpression(constructorCall())))));
2031}
2032
2033TEST(Statement, DoesNotMatchDeclarations) {
2034 EXPECT_TRUE(notMatches("class X {};", statement()));
2035}
2036
2037TEST(Statement, MatchesCompoundStatments) {
2038 EXPECT_TRUE(matches("void x() {}", statement()));
2039}
2040
2041TEST(DeclarationStatement, DoesNotMatchCompoundStatements) {
2042 EXPECT_TRUE(notMatches("void x() {}", declarationStatement()));
2043}
2044
2045TEST(DeclarationStatement, MatchesVariableDeclarationStatements) {
2046 EXPECT_TRUE(matches("void x() { int a; }", declarationStatement()));
2047}
2048
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002049TEST(InitListExpression, MatchesInitListExpression) {
2050 EXPECT_TRUE(matches("int a[] = { 1, 2 };",
2051 initListExpr(hasType(asString("int [2]")))));
2052 EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };",
2053 initListExpr(hasType(record(hasName("B"))))));
2054}
2055
2056TEST(UsingDeclaration, MatchesUsingDeclarations) {
2057 EXPECT_TRUE(matches("namespace X { int x; } using X::x;",
2058 usingDecl()));
2059}
2060
2061TEST(UsingDeclaration, MatchesShadowUsingDelcarations) {
2062 EXPECT_TRUE(matches("namespace f { int a; } using f::a;",
2063 usingDecl(hasAnyUsingShadowDecl(hasName("a")))));
2064}
2065
2066TEST(UsingDeclaration, MatchesSpecificTarget) {
2067 EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
2068 usingDecl(hasAnyUsingShadowDecl(
2069 hasTargetDecl(function())))));
2070 EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
2071 usingDecl(hasAnyUsingShadowDecl(
2072 hasTargetDecl(function())))));
2073}
2074
2075TEST(UsingDeclaration, ThroughUsingDeclaration) {
2076 EXPECT_TRUE(matches(
2077 "namespace a { void f(); } using a::f; void g() { f(); }",
2078 declarationReference(throughUsingDecl(anything()))));
2079 EXPECT_TRUE(notMatches(
2080 "namespace a { void f(); } using a::f; void g() { a::f(); }",
2081 declarationReference(throughUsingDecl(anything()))));
2082}
2083
Manuel Klimek4da21662012-07-06 05:48:52 +00002084TEST(While, MatchesWhileLoops) {
2085 EXPECT_TRUE(notMatches("void x() {}", whileStmt()));
2086 EXPECT_TRUE(matches("void x() { while(true); }", whileStmt()));
2087 EXPECT_TRUE(notMatches("void x() { do {} while(true); }", whileStmt()));
2088}
2089
2090TEST(Do, MatchesDoLoops) {
2091 EXPECT_TRUE(matches("void x() { do {} while(true); }", doStmt()));
2092 EXPECT_TRUE(matches("void x() { do ; while(false); }", doStmt()));
2093}
2094
2095TEST(Do, DoesNotMatchWhileLoops) {
2096 EXPECT_TRUE(notMatches("void x() { while(true) {} }", doStmt()));
2097}
2098
2099TEST(SwitchCase, MatchesCase) {
2100 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchCase()));
2101 EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchCase()));
2102 EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchCase()));
2103 EXPECT_TRUE(notMatches("void x() { switch(42) {} }", switchCase()));
2104}
2105
2106TEST(HasConditionVariableStatement, DoesNotMatchCondition) {
2107 EXPECT_TRUE(notMatches(
2108 "void x() { if(true) {} }",
2109 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2110 EXPECT_TRUE(notMatches(
2111 "void x() { int x; if((x = 42)) {} }",
2112 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2113}
2114
2115TEST(HasConditionVariableStatement, MatchesConditionVariables) {
2116 EXPECT_TRUE(matches(
2117 "void x() { if(int* a = 0) {} }",
2118 ifStmt(hasConditionVariableStatement(declarationStatement()))));
2119}
2120
2121TEST(ForEach, BindsOneNode) {
2122 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
2123 record(hasName("C"), forEach(id("x", field(hasName("x"))))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002124 new VerifyIdIsBoundToDecl<FieldDecl>("x", 1)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002125}
2126
2127TEST(ForEach, BindsMultipleNodes) {
2128 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
2129 record(hasName("C"), forEach(id("f", field()))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002130 new VerifyIdIsBoundToDecl<FieldDecl>("f", 3)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002131}
2132
2133TEST(ForEach, BindsRecursiveCombinations) {
2134 EXPECT_TRUE(matchAndVerifyResultTrue(
2135 "class C { class D { int x; int y; }; class E { int y; int z; }; };",
2136 record(hasName("C"), forEach(record(forEach(id("f", field()))))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002137 new VerifyIdIsBoundToDecl<FieldDecl>("f", 4)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002138}
2139
2140TEST(ForEachDescendant, BindsOneNode) {
2141 EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
2142 record(hasName("C"), forEachDescendant(id("x", field(hasName("x"))))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002143 new VerifyIdIsBoundToDecl<FieldDecl>("x", 1)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002144}
2145
2146TEST(ForEachDescendant, BindsMultipleNodes) {
2147 EXPECT_TRUE(matchAndVerifyResultTrue(
2148 "class C { class D { int x; int y; }; "
2149 " class E { class F { int y; int z; }; }; };",
2150 record(hasName("C"), forEachDescendant(id("f", field()))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002151 new VerifyIdIsBoundToDecl<FieldDecl>("f", 4)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002152}
2153
2154TEST(ForEachDescendant, BindsRecursiveCombinations) {
2155 EXPECT_TRUE(matchAndVerifyResultTrue(
2156 "class C { class D { "
2157 " class E { class F { class G { int y; int z; }; }; }; }; };",
2158 record(hasName("C"), forEachDescendant(record(
2159 forEachDescendant(id("f", field()))))),
Daniel Jaspere0e6b9e2012-07-10 20:20:19 +00002160 new VerifyIdIsBoundToDecl<FieldDecl>("f", 8)));
Manuel Klimek4da21662012-07-06 05:48:52 +00002161}
2162
2163
2164TEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) {
2165 // Make sure that we can both match the class by name (::X) and by the type
2166 // the template was instantiated with (via a field).
2167
2168 EXPECT_TRUE(matches(
2169 "template <typename T> class X {}; class A {}; X<A> x;",
2170 record(hasName("::X"), isTemplateInstantiation())));
2171
2172 EXPECT_TRUE(matches(
2173 "template <typename T> class X { T t; }; class A {}; X<A> x;",
2174 record(isTemplateInstantiation(), hasDescendant(
2175 field(hasType(record(hasName("A"))))))));
2176}
2177
2178TEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) {
2179 EXPECT_TRUE(matches(
2180 "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
2181 function(hasParameter(0, hasType(record(hasName("A")))),
2182 isTemplateInstantiation())));
2183}
2184
2185TEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) {
2186 EXPECT_TRUE(matches(
2187 "template <typename T> class X { T t; }; class A {};"
2188 "template class X<A>;",
2189 record(isTemplateInstantiation(), hasDescendant(
2190 field(hasType(record(hasName("A"))))))));
2191}
2192
2193TEST(IsTemplateInstantiation,
2194 MatchesInstantiationOfPartiallySpecializedClassTemplate) {
2195 EXPECT_TRUE(matches(
2196 "template <typename T> class X {};"
2197 "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
2198 record(hasName("::X"), isTemplateInstantiation())));
2199}
2200
2201TEST(IsTemplateInstantiation,
2202 MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
2203 EXPECT_TRUE(matches(
2204 "class A {};"
2205 "class X {"
2206 " template <typename U> class Y { U u; };"
2207 " Y<A> y;"
2208 "};",
2209 record(hasName("::X::Y"), isTemplateInstantiation())));
2210}
2211
2212TEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) {
2213 // FIXME: Figure out whether this makes sense. It doesn't affect the
2214 // normal use case as long as the uppermost instantiation always is marked
2215 // as template instantiation, but it might be confusing as a predicate.
2216 EXPECT_TRUE(matches(
2217 "class A {};"
2218 "template <typename T> class X {"
2219 " template <typename U> class Y { U u; };"
2220 " Y<T> y;"
2221 "}; X<A> x;",
2222 record(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
2223}
2224
2225TEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) {
2226 EXPECT_TRUE(notMatches(
2227 "template <typename T> class X {}; class A {};"
2228 "template <> class X<A> {}; X<A> x;",
2229 record(hasName("::X"), isTemplateInstantiation())));
2230}
2231
2232TEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) {
2233 EXPECT_TRUE(notMatches(
2234 "class A {}; class Y { A a; };",
2235 record(isTemplateInstantiation())));
2236}
2237
2238} // end namespace ast_matchers
2239} // end namespace clang