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