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