blob: 28b462e746f0bff37e85211f04f7486a0bf2a74d [file] [log] [blame]
Piotr Padlewskic6e05022016-05-17 19:22:57 +00001// unittests/ASTMatchers/ASTMatchersNarrowingTest.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/AST/PrettyPrinter.h"
12#include "clang/ASTMatchers/ASTMatchFinder.h"
13#include "clang/ASTMatchers/ASTMatchers.h"
14#include "clang/Tooling/Tooling.h"
15#include "llvm/ADT/Triple.h"
16#include "llvm/Support/Host.h"
17#include "gtest/gtest.h"
18
19namespace clang {
20namespace ast_matchers {
21
22
23TEST(AllOf, AllOverloadsWork) {
24 const char Program[] =
25 "struct T { };"
26 "int f(int, T*, int, int);"
27 "void g(int x) { T t; f(x, &t, 3, 4); }";
28 EXPECT_TRUE(matches(Program,
29 callExpr(allOf(callee(functionDecl(hasName("f"))),
30 hasArgument(0, declRefExpr(to(varDecl())))))));
31 EXPECT_TRUE(matches(Program,
32 callExpr(allOf(callee(functionDecl(hasName("f"))),
33 hasArgument(0, declRefExpr(to(varDecl()))),
34 hasArgument(1, hasType(pointsTo(
35 recordDecl(hasName("T")))))))));
36 EXPECT_TRUE(matches(Program,
37 callExpr(allOf(callee(functionDecl(hasName("f"))),
38 hasArgument(0, declRefExpr(to(varDecl()))),
39 hasArgument(1, hasType(pointsTo(
40 recordDecl(hasName("T"))))),
41 hasArgument(2, integerLiteral(equals(3)))))));
42 EXPECT_TRUE(matches(Program,
43 callExpr(allOf(callee(functionDecl(hasName("f"))),
44 hasArgument(0, declRefExpr(to(varDecl()))),
45 hasArgument(1, hasType(pointsTo(
46 recordDecl(hasName("T"))))),
47 hasArgument(2, integerLiteral(equals(3))),
48 hasArgument(3, integerLiteral(equals(4)))))));
49}
50
51TEST(DeclarationMatcher, MatchHas) {
52 DeclarationMatcher HasClassX = recordDecl(has(recordDecl(hasName("X"))));
53 EXPECT_TRUE(matches("class Y { class X {}; };", HasClassX));
54 EXPECT_TRUE(matches("class X {};", HasClassX));
55
56 DeclarationMatcher YHasClassX =
57 recordDecl(hasName("Y"), has(recordDecl(hasName("X"))));
58 EXPECT_TRUE(matches("class Y { class X {}; };", YHasClassX));
59 EXPECT_TRUE(notMatches("class X {};", YHasClassX));
60 EXPECT_TRUE(
61 notMatches("class Y { class Z { class X {}; }; };", YHasClassX));
62}
63
64TEST(DeclarationMatcher, MatchHasRecursiveAllOf) {
65 DeclarationMatcher Recursive =
66 recordDecl(
67 has(recordDecl(
68 has(recordDecl(hasName("X"))),
69 has(recordDecl(hasName("Y"))),
70 hasName("Z"))),
71 has(recordDecl(
72 has(recordDecl(hasName("A"))),
73 has(recordDecl(hasName("B"))),
74 hasName("C"))),
75 hasName("F"));
76
77 EXPECT_TRUE(matches(
78 "class F {"
79 " class Z {"
80 " class X {};"
81 " class Y {};"
82 " };"
83 " class C {"
84 " class A {};"
85 " class B {};"
86 " };"
87 "};", Recursive));
88
89 EXPECT_TRUE(matches(
90 "class F {"
91 " class Z {"
92 " class A {};"
93 " class X {};"
94 " class Y {};"
95 " };"
96 " class C {"
97 " class X {};"
98 " class A {};"
99 " class B {};"
100 " };"
101 "};", Recursive));
102
103 EXPECT_TRUE(matches(
104 "class O1 {"
105 " class O2 {"
106 " class F {"
107 " class Z {"
108 " class A {};"
109 " class X {};"
110 " class Y {};"
111 " };"
112 " class C {"
113 " class X {};"
114 " class A {};"
115 " class B {};"
116 " };"
117 " };"
118 " };"
119 "};", Recursive));
120}
121
122TEST(DeclarationMatcher, MatchHasRecursiveAnyOf) {
123 DeclarationMatcher Recursive =
124 recordDecl(
125 anyOf(
126 has(recordDecl(
127 anyOf(
128 has(recordDecl(
129 hasName("X"))),
130 has(recordDecl(
131 hasName("Y"))),
132 hasName("Z")))),
133 has(recordDecl(
134 anyOf(
135 hasName("C"),
136 has(recordDecl(
137 hasName("A"))),
138 has(recordDecl(
139 hasName("B")))))),
140 hasName("F")));
141
142 EXPECT_TRUE(matches("class F {};", Recursive));
143 EXPECT_TRUE(matches("class Z {};", Recursive));
144 EXPECT_TRUE(matches("class C {};", Recursive));
145 EXPECT_TRUE(matches("class M { class N { class X {}; }; };", Recursive));
146 EXPECT_TRUE(matches("class M { class N { class B {}; }; };", Recursive));
147 EXPECT_TRUE(
148 matches("class O1 { class O2 {"
149 " class M { class N { class B {}; }; }; "
150 "}; };", Recursive));
151}
152
153TEST(DeclarationMatcher, MatchNot) {
154 DeclarationMatcher NotClassX =
155 cxxRecordDecl(
156 isDerivedFrom("Y"),
157 unless(hasName("X")));
158 EXPECT_TRUE(notMatches("", NotClassX));
159 EXPECT_TRUE(notMatches("class Y {};", NotClassX));
160 EXPECT_TRUE(matches("class Y {}; class Z : public Y {};", NotClassX));
161 EXPECT_TRUE(notMatches("class Y {}; class X : public Y {};", NotClassX));
162 EXPECT_TRUE(
163 notMatches("class Y {}; class Z {}; class X : public Y {};",
164 NotClassX));
165
166 DeclarationMatcher ClassXHasNotClassY =
167 recordDecl(
168 hasName("X"),
169 has(recordDecl(hasName("Z"))),
170 unless(
171 has(recordDecl(hasName("Y")))));
172 EXPECT_TRUE(matches("class X { class Z {}; };", ClassXHasNotClassY));
173 EXPECT_TRUE(notMatches("class X { class Y {}; class Z {}; };",
174 ClassXHasNotClassY));
175
176 DeclarationMatcher NamedNotRecord =
177 namedDecl(hasName("Foo"), unless(recordDecl()));
178 EXPECT_TRUE(matches("void Foo(){}", NamedNotRecord));
179 EXPECT_TRUE(notMatches("struct Foo {};", NamedNotRecord));
180}
181
182TEST(CastExpression, HasCastKind) {
183 EXPECT_TRUE(matches("char *p = 0;",
184 castExpr(hasCastKind(CK_NullToPointer))));
185 EXPECT_TRUE(notMatches("char *p = 0;",
186 castExpr(hasCastKind(CK_DerivedToBase))));
187 EXPECT_TRUE(matches("char *p = 0;",
188 implicitCastExpr(hasCastKind(CK_NullToPointer))));
189}
190
191TEST(DeclarationMatcher, HasDescendant) {
192 DeclarationMatcher ZDescendantClassX =
193 recordDecl(
194 hasDescendant(recordDecl(hasName("X"))),
195 hasName("Z"));
196 EXPECT_TRUE(matches("class Z { class X {}; };", ZDescendantClassX));
197 EXPECT_TRUE(
198 matches("class Z { class Y { class X {}; }; };", ZDescendantClassX));
199 EXPECT_TRUE(
200 matches("class Z { class A { class Y { class X {}; }; }; };",
201 ZDescendantClassX));
202 EXPECT_TRUE(
203 matches("class Z { class A { class B { class Y { class X {}; }; }; }; };",
204 ZDescendantClassX));
205 EXPECT_TRUE(notMatches("class Z {};", ZDescendantClassX));
206
207 DeclarationMatcher ZDescendantClassXHasClassY =
208 recordDecl(
209 hasDescendant(recordDecl(has(recordDecl(hasName("Y"))),
210 hasName("X"))),
211 hasName("Z"));
212 EXPECT_TRUE(matches("class Z { class X { class Y {}; }; };",
213 ZDescendantClassXHasClassY));
214 EXPECT_TRUE(
215 matches("class Z { class A { class B { class X { class Y {}; }; }; }; };",
216 ZDescendantClassXHasClassY));
217 EXPECT_TRUE(notMatches(
218 "class Z {"
219 " class A {"
220 " class B {"
221 " class X {"
222 " class C {"
223 " class Y {};"
224 " };"
225 " };"
226 " }; "
227 " };"
228 "};", ZDescendantClassXHasClassY));
229
230 DeclarationMatcher ZDescendantClassXDescendantClassY =
231 recordDecl(
232 hasDescendant(recordDecl(hasDescendant(recordDecl(hasName("Y"))),
233 hasName("X"))),
234 hasName("Z"));
235 EXPECT_TRUE(
236 matches("class Z { class A { class X { class B { class Y {}; }; }; }; };",
237 ZDescendantClassXDescendantClassY));
238 EXPECT_TRUE(matches(
239 "class Z {"
240 " class A {"
241 " class X {"
242 " class B {"
243 " class Y {};"
244 " };"
245 " class Y {};"
246 " };"
247 " };"
248 "};", ZDescendantClassXDescendantClassY));
249}
250
251TEST(DeclarationMatcher, HasDescendantMemoization) {
252 DeclarationMatcher CannotMemoize =
253 decl(hasDescendant(typeLoc().bind("x")), has(decl()));
254 EXPECT_TRUE(matches("void f() { int i; }", CannotMemoize));
255}
256
257TEST(DeclarationMatcher, HasDescendantMemoizationUsesRestrictKind) {
258 auto Name = hasName("i");
259 auto VD = internal::Matcher<VarDecl>(Name).dynCastTo<Decl>();
260 auto RD = internal::Matcher<RecordDecl>(Name).dynCastTo<Decl>();
261 // Matching VD first should not make a cache hit for RD.
262 EXPECT_TRUE(notMatches("void f() { int i; }",
263 decl(hasDescendant(VD), hasDescendant(RD))));
264 EXPECT_TRUE(notMatches("void f() { int i; }",
265 decl(hasDescendant(RD), hasDescendant(VD))));
266 // Not matching RD first should not make a cache hit for VD either.
267 EXPECT_TRUE(matches("void f() { int i; }",
268 decl(anyOf(hasDescendant(RD), hasDescendant(VD)))));
269}
270
271TEST(DeclarationMatcher, HasAncestorMemoization) {
272 // This triggers an hasAncestor with a TemplateArgument in the bound nodes.
273 // That node can't be memoized so we have to check for it before trying to put
274 // it on the cache.
275 DeclarationMatcher CannotMemoize = classTemplateSpecializationDecl(
276 hasAnyTemplateArgument(templateArgument().bind("targ")),
277 forEach(fieldDecl(hasAncestor(forStmt()))));
278
279 EXPECT_TRUE(notMatches("template <typename T> struct S;"
280 "template <> struct S<int>{ int i; int j; };",
281 CannotMemoize));
282}
283
284TEST(DeclarationMatcher, HasAttr) {
285 EXPECT_TRUE(matches("struct __attribute__((warn_unused)) X {};",
286 decl(hasAttr(clang::attr::WarnUnused))));
287 EXPECT_FALSE(matches("struct X {};",
288 decl(hasAttr(clang::attr::WarnUnused))));
289}
290
291
292TEST(DeclarationMatcher, MatchAnyOf) {
293 DeclarationMatcher YOrZDerivedFromX = cxxRecordDecl(
294 anyOf(hasName("Y"), allOf(isDerivedFrom("X"), hasName("Z"))));
295 EXPECT_TRUE(matches("class X {}; class Z : public X {};", YOrZDerivedFromX));
296 EXPECT_TRUE(matches("class Y {};", YOrZDerivedFromX));
297 EXPECT_TRUE(
298 notMatches("class X {}; class W : public X {};", YOrZDerivedFromX));
299 EXPECT_TRUE(notMatches("class Z {};", YOrZDerivedFromX));
300
301 DeclarationMatcher XOrYOrZOrU =
302 recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U")));
303 EXPECT_TRUE(matches("class X {};", XOrYOrZOrU));
304 EXPECT_TRUE(notMatches("class V {};", XOrYOrZOrU));
305
306 DeclarationMatcher XOrYOrZOrUOrV =
307 recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U"),
308 hasName("V")));
309 EXPECT_TRUE(matches("class X {};", XOrYOrZOrUOrV));
310 EXPECT_TRUE(matches("class Y {};", XOrYOrZOrUOrV));
311 EXPECT_TRUE(matches("class Z {};", XOrYOrZOrUOrV));
312 EXPECT_TRUE(matches("class U {};", XOrYOrZOrUOrV));
313 EXPECT_TRUE(matches("class V {};", XOrYOrZOrUOrV));
314 EXPECT_TRUE(notMatches("class A {};", XOrYOrZOrUOrV));
315
316 StatementMatcher MixedTypes = stmt(anyOf(ifStmt(), binaryOperator()));
317 EXPECT_TRUE(matches("int F() { return 1 + 2; }", MixedTypes));
318 EXPECT_TRUE(matches("int F() { if (true) return 1; }", MixedTypes));
319 EXPECT_TRUE(notMatches("int F() { return 1; }", MixedTypes));
320
321 EXPECT_TRUE(
322 matches("void f() try { } catch (int) { } catch (...) { }",
323 cxxCatchStmt(anyOf(hasDescendant(varDecl()), isCatchAll()))));
324}
325
326TEST(DeclarationMatcher, ClassIsDerived) {
327 DeclarationMatcher IsDerivedFromX = cxxRecordDecl(isDerivedFrom("X"));
328
329 EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsDerivedFromX));
330 EXPECT_TRUE(notMatches("class X {};", IsDerivedFromX));
331 EXPECT_TRUE(notMatches("class X;", IsDerivedFromX));
332 EXPECT_TRUE(notMatches("class Y;", IsDerivedFromX));
333 EXPECT_TRUE(notMatches("", IsDerivedFromX));
334
335 DeclarationMatcher IsAX = cxxRecordDecl(isSameOrDerivedFrom("X"));
336
337 EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsAX));
338 EXPECT_TRUE(matches("class X {};", IsAX));
339 EXPECT_TRUE(matches("class X;", IsAX));
340 EXPECT_TRUE(notMatches("class Y;", IsAX));
341 EXPECT_TRUE(notMatches("", IsAX));
342
343 DeclarationMatcher ZIsDerivedFromX =
344 cxxRecordDecl(hasName("Z"), isDerivedFrom("X"));
345 EXPECT_TRUE(
346 matches("class X {}; class Y : public X {}; class Z : public Y {};",
347 ZIsDerivedFromX));
348 EXPECT_TRUE(
349 matches("class X {};"
350 "template<class T> class Y : public X {};"
351 "class Z : public Y<int> {};", ZIsDerivedFromX));
352 EXPECT_TRUE(matches("class X {}; template<class T> class Z : public X {};",
353 ZIsDerivedFromX));
354 EXPECT_TRUE(
355 matches("template<class T> class X {}; "
356 "template<class T> class Z : public X<T> {};",
357 ZIsDerivedFromX));
358 EXPECT_TRUE(
359 matches("template<class T, class U=T> class X {}; "
360 "template<class T> class Z : public X<T> {};",
361 ZIsDerivedFromX));
362 EXPECT_TRUE(
363 notMatches("template<class X> class A { class Z : public X {}; };",
364 ZIsDerivedFromX));
365 EXPECT_TRUE(
366 matches("template<class X> class A { public: class Z : public X {}; }; "
367 "class X{}; void y() { A<X>::Z z; }", ZIsDerivedFromX));
368 EXPECT_TRUE(
369 matches("template <class T> class X {}; "
370 "template<class Y> class A { class Z : public X<Y> {}; };",
371 ZIsDerivedFromX));
372 EXPECT_TRUE(
373 notMatches("template<template<class T> class X> class A { "
374 " class Z : public X<int> {}; };", ZIsDerivedFromX));
375 EXPECT_TRUE(
376 matches("template<template<class T> class X> class A { "
377 " public: class Z : public X<int> {}; }; "
378 "template<class T> class X {}; void y() { A<X>::Z z; }",
379 ZIsDerivedFromX));
380 EXPECT_TRUE(
381 notMatches("template<class X> class A { class Z : public X::D {}; };",
382 ZIsDerivedFromX));
383 EXPECT_TRUE(
384 matches("template<class X> class A { public: "
385 " class Z : public X::D {}; }; "
386 "class Y { public: class X {}; typedef X D; }; "
387 "void y() { A<Y>::Z z; }", ZIsDerivedFromX));
388 EXPECT_TRUE(
389 matches("class X {}; typedef X Y; class Z : public Y {};",
390 ZIsDerivedFromX));
391 EXPECT_TRUE(
392 matches("template<class T> class Y { typedef typename T::U X; "
393 " class Z : public X {}; };", ZIsDerivedFromX));
394 EXPECT_TRUE(matches("class X {}; class Z : public ::X {};",
395 ZIsDerivedFromX));
396 EXPECT_TRUE(
397 notMatches("template<class T> class X {}; "
398 "template<class T> class A { class Z : public X<T>::D {}; };",
399 ZIsDerivedFromX));
400 EXPECT_TRUE(
401 matches("template<class T> class X { public: typedef X<T> D; }; "
402 "template<class T> class A { public: "
403 " class Z : public X<T>::D {}; }; void y() { A<int>::Z z; }",
404 ZIsDerivedFromX));
405 EXPECT_TRUE(
406 notMatches("template<class X> class A { class Z : public X::D::E {}; };",
407 ZIsDerivedFromX));
408 EXPECT_TRUE(
409 matches("class X {}; typedef X V; typedef V W; class Z : public W {};",
410 ZIsDerivedFromX));
411 EXPECT_TRUE(
412 matches("class X {}; class Y : public X {}; "
413 "typedef Y V; typedef V W; class Z : public W {};",
414 ZIsDerivedFromX));
415 EXPECT_TRUE(
416 matches("template<class T, class U> class X {}; "
417 "template<class T> class A { class Z : public X<T, int> {}; };",
418 ZIsDerivedFromX));
419 EXPECT_TRUE(
420 notMatches("template<class X> class D { typedef X A; typedef A B; "
421 " typedef B C; class Z : public C {}; };",
422 ZIsDerivedFromX));
423 EXPECT_TRUE(
424 matches("class X {}; typedef X A; typedef A B; "
425 "class Z : public B {};", ZIsDerivedFromX));
426 EXPECT_TRUE(
427 matches("class X {}; typedef X A; typedef A B; typedef B C; "
428 "class Z : public C {};", ZIsDerivedFromX));
429 EXPECT_TRUE(
430 matches("class U {}; typedef U X; typedef X V; "
431 "class Z : public V {};", ZIsDerivedFromX));
432 EXPECT_TRUE(
433 matches("class Base {}; typedef Base X; "
434 "class Z : public Base {};", ZIsDerivedFromX));
435 EXPECT_TRUE(
436 matches("class Base {}; typedef Base Base2; typedef Base2 X; "
437 "class Z : public Base {};", ZIsDerivedFromX));
438 EXPECT_TRUE(
439 notMatches("class Base {}; class Base2 {}; typedef Base2 X; "
440 "class Z : public Base {};", ZIsDerivedFromX));
441 EXPECT_TRUE(
442 matches("class A {}; typedef A X; typedef A Y; "
443 "class Z : public Y {};", ZIsDerivedFromX));
444 EXPECT_TRUE(
445 notMatches("template <typename T> class Z;"
446 "template <> class Z<void> {};"
447 "template <typename T> class Z : public Z<void> {};",
448 IsDerivedFromX));
449 EXPECT_TRUE(
450 matches("template <typename T> class X;"
451 "template <> class X<void> {};"
452 "template <typename T> class X : public X<void> {};",
453 IsDerivedFromX));
454 EXPECT_TRUE(matches(
455 "class X {};"
456 "template <typename T> class Z;"
457 "template <> class Z<void> {};"
458 "template <typename T> class Z : public Z<void>, public X {};",
459 ZIsDerivedFromX));
460 EXPECT_TRUE(
461 notMatches("template<int> struct X;"
462 "template<int i> struct X : public X<i-1> {};",
463 cxxRecordDecl(isDerivedFrom(recordDecl(hasName("Some"))))));
464 EXPECT_TRUE(matches(
465 "struct A {};"
466 "template<int> struct X;"
467 "template<int i> struct X : public X<i-1> {};"
468 "template<> struct X<0> : public A {};"
469 "struct B : public X<42> {};",
470 cxxRecordDecl(hasName("B"), isDerivedFrom(recordDecl(hasName("A"))))));
471
472 // FIXME: Once we have better matchers for template type matching,
473 // get rid of the Variable(...) matching and match the right template
474 // declarations directly.
475 const char *RecursiveTemplateOneParameter =
476 "class Base1 {}; class Base2 {};"
477 "template <typename T> class Z;"
478 "template <> class Z<void> : public Base1 {};"
479 "template <> class Z<int> : public Base2 {};"
480 "template <> class Z<float> : public Z<void> {};"
481 "template <> class Z<double> : public Z<int> {};"
482 "template <typename T> class Z : public Z<float>, public Z<double> {};"
483 "void f() { Z<float> z_float; Z<double> z_double; Z<char> z_char; }";
484 EXPECT_TRUE(matches(
485 RecursiveTemplateOneParameter,
486 varDecl(hasName("z_float"),
487 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1")))))));
488 EXPECT_TRUE(notMatches(
489 RecursiveTemplateOneParameter,
490 varDecl(hasName("z_float"),
491 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2")))))));
492 EXPECT_TRUE(matches(
493 RecursiveTemplateOneParameter,
494 varDecl(hasName("z_char"),
495 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1"),
496 isDerivedFrom("Base2")))))));
497
498 const char *RecursiveTemplateTwoParameters =
499 "class Base1 {}; class Base2 {};"
500 "template <typename T1, typename T2> class Z;"
501 "template <typename T> class Z<void, T> : public Base1 {};"
502 "template <typename T> class Z<int, T> : public Base2 {};"
503 "template <typename T> class Z<float, T> : public Z<void, T> {};"
504 "template <typename T> class Z<double, T> : public Z<int, T> {};"
505 "template <typename T1, typename T2> class Z : "
506 " public Z<float, T2>, public Z<double, T2> {};"
507 "void f() { Z<float, void> z_float; Z<double, void> z_double; "
508 " Z<char, void> z_char; }";
509 EXPECT_TRUE(matches(
510 RecursiveTemplateTwoParameters,
511 varDecl(hasName("z_float"),
512 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1")))))));
513 EXPECT_TRUE(notMatches(
514 RecursiveTemplateTwoParameters,
515 varDecl(hasName("z_float"),
516 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2")))))));
517 EXPECT_TRUE(matches(
518 RecursiveTemplateTwoParameters,
519 varDecl(hasName("z_char"),
520 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1"),
521 isDerivedFrom("Base2")))))));
522 EXPECT_TRUE(matches(
523 "namespace ns { class X {}; class Y : public X {}; }",
524 cxxRecordDecl(isDerivedFrom("::ns::X"))));
525 EXPECT_TRUE(notMatches(
526 "class X {}; class Y : public X {};",
527 cxxRecordDecl(isDerivedFrom("::ns::X"))));
528
529 EXPECT_TRUE(matches(
530 "class X {}; class Y : public X {};",
531 cxxRecordDecl(isDerivedFrom(recordDecl(hasName("X")).bind("test")))));
532
533 EXPECT_TRUE(matches(
534 "template<typename T> class X {};"
535 "template<typename T> using Z = X<T>;"
536 "template <typename T> class Y : Z<T> {};",
537 cxxRecordDecl(isDerivedFrom(namedDecl(hasName("X"))))));
538}
539
Samuel Benzaquen49385c72016-06-28 14:08:56 +0000540TEST(DeclarationMatcher, IsLambda) {
541 const auto IsLambda = cxxMethodDecl(ofClass(cxxRecordDecl(isLambda())));
542 EXPECT_TRUE(matches("auto x = []{};", IsLambda));
543 EXPECT_TRUE(notMatches("struct S { void operator()() const; };", IsLambda));
544}
545
Piotr Padlewskic6e05022016-05-17 19:22:57 +0000546TEST(Matcher, BindMatchedNodes) {
547 DeclarationMatcher ClassX = has(recordDecl(hasName("::X")).bind("x"));
548
549 EXPECT_TRUE(matchAndVerifyResultTrue("class X {};",
550 ClassX, llvm::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("x")));
551
552 EXPECT_TRUE(matchAndVerifyResultFalse("class X {};",
553 ClassX, llvm::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("other-id")));
554
555 TypeMatcher TypeAHasClassB = hasDeclaration(
556 recordDecl(hasName("A"), has(recordDecl(hasName("B")).bind("b"))));
557
558 EXPECT_TRUE(matchAndVerifyResultTrue("class A { public: A *a; class B {}; };",
559 TypeAHasClassB,
560 llvm::make_unique<VerifyIdIsBoundTo<Decl>>("b")));
561
562 StatementMatcher MethodX =
563 callExpr(callee(cxxMethodDecl(hasName("x")))).bind("x");
564
565 EXPECT_TRUE(matchAndVerifyResultTrue("class A { void x() { x(); } };",
566 MethodX,
567 llvm::make_unique<VerifyIdIsBoundTo<CXXMemberCallExpr>>("x")));
568}
569
570TEST(Matcher, BindTheSameNameInAlternatives) {
571 StatementMatcher matcher = anyOf(
572 binaryOperator(hasOperatorName("+"),
573 hasLHS(expr().bind("x")),
574 hasRHS(integerLiteral(equals(0)))),
575 binaryOperator(hasOperatorName("+"),
576 hasLHS(integerLiteral(equals(0))),
577 hasRHS(expr().bind("x"))));
578
579 EXPECT_TRUE(matchAndVerifyResultTrue(
580 // The first branch of the matcher binds x to 0 but then fails.
581 // The second branch binds x to f() and succeeds.
582 "int f() { return 0 + f(); }",
583 matcher,
584 llvm::make_unique<VerifyIdIsBoundTo<CallExpr>>("x")));
585}
586
587TEST(Matcher, BindsIDForMemoizedResults) {
588 // Using the same matcher in two match expressions will make memoization
589 // kick in.
590 DeclarationMatcher ClassX = recordDecl(hasName("X")).bind("x");
591 EXPECT_TRUE(matchAndVerifyResultTrue(
592 "class A { class B { class X {}; }; };",
593 DeclarationMatcher(anyOf(
594 recordDecl(hasName("A"), hasDescendant(ClassX)),
595 recordDecl(hasName("B"), hasDescendant(ClassX)))),
596 llvm::make_unique<VerifyIdIsBoundTo<Decl>>("x", 2)));
597}
598
599TEST(HasType, MatchesAsString) {
600 EXPECT_TRUE(
601 matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }",
602 cxxMemberCallExpr(on(hasType(asString("class Y *"))))));
603 EXPECT_TRUE(
604 matches("class X { void x(int x) {} };",
605 cxxMethodDecl(hasParameter(0, hasType(asString("int"))))));
606 EXPECT_TRUE(matches("namespace ns { struct A {}; } struct B { ns::A a; };",
607 fieldDecl(hasType(asString("ns::A")))));
608 EXPECT_TRUE(matches("namespace { struct A {}; } struct B { A a; };",
609 fieldDecl(hasType(asString("struct (anonymous namespace)::A")))));
610}
611
612TEST(Matcher, HasOperatorNameForOverloadedOperatorCall) {
613 StatementMatcher OpCallAndAnd =
614 cxxOperatorCallExpr(hasOverloadedOperatorName("&&"));
615 EXPECT_TRUE(matches("class Y { }; "
616 "bool operator&&(Y x, Y y) { return true; }; "
617 "Y a; Y b; bool c = a && b;", OpCallAndAnd));
618 StatementMatcher OpCallLessLess =
619 cxxOperatorCallExpr(hasOverloadedOperatorName("<<"));
620 EXPECT_TRUE(notMatches("class Y { }; "
621 "bool operator&&(Y x, Y y) { return true; }; "
622 "Y a; Y b; bool c = a && b;",
623 OpCallLessLess));
624 StatementMatcher OpStarCall =
625 cxxOperatorCallExpr(hasOverloadedOperatorName("*"));
626 EXPECT_TRUE(matches("class Y; int operator*(Y &); void f(Y &y) { *y; }",
627 OpStarCall));
628 DeclarationMatcher ClassWithOpStar =
629 cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*")));
630 EXPECT_TRUE(matches("class Y { int operator*(); };",
631 ClassWithOpStar));
632 EXPECT_TRUE(notMatches("class Y { void myOperator(); };",
633 ClassWithOpStar)) ;
634 DeclarationMatcher AnyOpStar = functionDecl(hasOverloadedOperatorName("*"));
635 EXPECT_TRUE(matches("class Y; int operator*(Y &);", AnyOpStar));
636 EXPECT_TRUE(matches("class Y { int operator*(); };", AnyOpStar));
637}
638
639
640TEST(Matcher, NestedOverloadedOperatorCalls) {
641 EXPECT_TRUE(matchAndVerifyResultTrue(
642 "class Y { }; "
643 "Y& operator&&(Y& x, Y& y) { return x; }; "
644 "Y a; Y b; Y c; Y d = a && b && c;",
645 cxxOperatorCallExpr(hasOverloadedOperatorName("&&")).bind("x"),
646 llvm::make_unique<VerifyIdIsBoundTo<CXXOperatorCallExpr>>("x", 2)));
647 EXPECT_TRUE(matches("class Y { }; "
648 "Y& operator&&(Y& x, Y& y) { return x; }; "
649 "Y a; Y b; Y c; Y d = a && b && c;",
650 cxxOperatorCallExpr(hasParent(cxxOperatorCallExpr()))));
651 EXPECT_TRUE(
652 matches("class Y { }; "
653 "Y& operator&&(Y& x, Y& y) { return x; }; "
654 "Y a; Y b; Y c; Y d = a && b && c;",
655 cxxOperatorCallExpr(hasDescendant(cxxOperatorCallExpr()))));
656}
657
658TEST(Matcher, VarDecl_Storage) {
659 auto M = varDecl(hasName("X"), hasLocalStorage());
660 EXPECT_TRUE(matches("void f() { int X; }", M));
661 EXPECT_TRUE(notMatches("int X;", M));
662 EXPECT_TRUE(notMatches("void f() { static int X; }", M));
663
664 M = varDecl(hasName("X"), hasGlobalStorage());
665 EXPECT_TRUE(notMatches("void f() { int X; }", M));
666 EXPECT_TRUE(matches("int X;", M));
667 EXPECT_TRUE(matches("void f() { static int X; }", M));
668}
669
670TEST(Matcher, VarDecl_StorageDuration) {
671 std::string T =
672 "void f() { int x; static int y; } int a;";
673
674 EXPECT_TRUE(matches(T, varDecl(hasName("x"), hasAutomaticStorageDuration())));
675 EXPECT_TRUE(
676 notMatches(T, varDecl(hasName("y"), hasAutomaticStorageDuration())));
677 EXPECT_TRUE(
678 notMatches(T, varDecl(hasName("a"), hasAutomaticStorageDuration())));
679
680 EXPECT_TRUE(matches(T, varDecl(hasName("y"), hasStaticStorageDuration())));
681 EXPECT_TRUE(matches(T, varDecl(hasName("a"), hasStaticStorageDuration())));
682 EXPECT_TRUE(notMatches(T, varDecl(hasName("x"), hasStaticStorageDuration())));
683
684 // FIXME: It is really hard to test with thread_local itself because not all
685 // targets support TLS, which causes this to be an error depending on what
686 // platform the test is being run on. We do not have access to the TargetInfo
687 // object to be able to test whether the platform supports TLS or not.
688 EXPECT_TRUE(notMatches(T, varDecl(hasName("x"), hasThreadStorageDuration())));
689 EXPECT_TRUE(notMatches(T, varDecl(hasName("y"), hasThreadStorageDuration())));
690 EXPECT_TRUE(notMatches(T, varDecl(hasName("a"), hasThreadStorageDuration())));
691}
692
693TEST(Matcher, FindsVarDeclInFunctionParameter) {
694 EXPECT_TRUE(matches(
695 "void f(int i) {}",
696 varDecl(hasName("i"))));
697}
698
699TEST(UnaryExpressionOrTypeTraitExpression, MatchesCorrectType) {
700 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }", sizeOfExpr(
701 hasArgumentOfType(asString("int")))));
702 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
703 hasArgumentOfType(asString("float")))));
704 EXPECT_TRUE(matches(
705 "struct A {}; void x() { A a; int b = sizeof(a); }",
706 sizeOfExpr(hasArgumentOfType(hasDeclaration(recordDecl(hasName("A")))))));
707 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
708 hasArgumentOfType(hasDeclaration(recordDecl(hasName("string")))))));
709}
710
711TEST(IsInteger, MatchesIntegers) {
712 EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isInteger()))));
713 EXPECT_TRUE(matches(
714 "long long i = 0; void f(long long) { }; void g() {f(i);}",
715 callExpr(hasArgument(0, declRefExpr(
716 to(varDecl(hasType(isInteger()))))))));
717}
718
719TEST(IsInteger, ReportsNoFalsePositives) {
720 EXPECT_TRUE(notMatches("int *i;", varDecl(hasType(isInteger()))));
721 EXPECT_TRUE(notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}",
722 callExpr(hasArgument(0, declRefExpr(
723 to(varDecl(hasType(isInteger()))))))));
724}
725
726TEST(IsAnyPointer, MatchesPointers) {
727 EXPECT_TRUE(matches("int* i = nullptr;", varDecl(hasType(isAnyPointer()))));
728}
729
730TEST(IsAnyPointer, MatchesObjcPointer) {
731 EXPECT_TRUE(matchesObjC("@interface Foo @end Foo *f;",
732 varDecl(hasType(isAnyPointer()))));
733}
734
735TEST(IsAnyPointer, ReportsNoFalsePositives) {
736 EXPECT_TRUE(notMatches("int i = 0;", varDecl(hasType(isAnyPointer()))));
737}
738
739TEST(IsAnyCharacter, MatchesCharacters) {
740 EXPECT_TRUE(matches("char i = 0;", varDecl(hasType(isAnyCharacter()))));
741}
742
743TEST(IsAnyCharacter, ReportsNoFalsePositives) {
744 EXPECT_TRUE(notMatches("int i;", varDecl(hasType(isAnyCharacter()))));
745}
746
747TEST(IsArrow, MatchesMemberVariablesViaArrow) {
748 EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };",
749 memberExpr(isArrow())));
750 EXPECT_TRUE(matches("class Y { void x() { y; } int y; };",
751 memberExpr(isArrow())));
752 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };",
753 memberExpr(isArrow())));
754}
755
756TEST(IsArrow, MatchesStaticMemberVariablesViaArrow) {
757 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
758 memberExpr(isArrow())));
759 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
760 memberExpr(isArrow())));
761 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } static int y; };",
762 memberExpr(isArrow())));
763}
764
765TEST(IsArrow, MatchesMemberCallsViaArrow) {
766 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
767 memberExpr(isArrow())));
768 EXPECT_TRUE(matches("class Y { void x() { x(); } };",
769 memberExpr(isArrow())));
770 EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",
771 memberExpr(isArrow())));
772}
773
774TEST(ConversionDeclaration, IsExplicit) {
775 EXPECT_TRUE(matches("struct S { explicit operator int(); };",
776 cxxConversionDecl(isExplicit())));
777 EXPECT_TRUE(notMatches("struct S { operator int(); };",
778 cxxConversionDecl(isExplicit())));
779}
780
781TEST(Matcher, ArgumentCount) {
782 StatementMatcher Call1Arg = callExpr(argumentCountIs(1));
783
784 EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg));
785 EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg));
786 EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg));
787}
788
789TEST(Matcher, ParameterCount) {
790 DeclarationMatcher Function1Arg = functionDecl(parameterCountIs(1));
791 EXPECT_TRUE(matches("void f(int i) {}", Function1Arg));
792 EXPECT_TRUE(matches("class X { void f(int i) {} };", Function1Arg));
793 EXPECT_TRUE(notMatches("void f() {}", Function1Arg));
794 EXPECT_TRUE(notMatches("void f(int i, int j, int k) {}", Function1Arg));
795 EXPECT_TRUE(matches("void f(int i, ...) {};", Function1Arg));
796}
797
798TEST(Matcher, References) {
799 DeclarationMatcher ReferenceClassX = varDecl(
800 hasType(references(recordDecl(hasName("X")))));
801 EXPECT_TRUE(matches("class X {}; void y(X y) { X &x = y; }",
802 ReferenceClassX));
803 EXPECT_TRUE(
804 matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
805 // The match here is on the implicit copy constructor code for
806 // class X, not on code 'X x = y'.
807 EXPECT_TRUE(
808 matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
809 EXPECT_TRUE(
810 notMatches("class X {}; extern X x;", ReferenceClassX));
811 EXPECT_TRUE(
812 notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
813}
814
815TEST(QualType, hasLocalQualifiers) {
816 EXPECT_TRUE(notMatches("typedef const int const_int; const_int i = 1;",
817 varDecl(hasType(hasLocalQualifiers()))));
818 EXPECT_TRUE(matches("int *const j = nullptr;",
819 varDecl(hasType(hasLocalQualifiers()))));
820 EXPECT_TRUE(matches("int *volatile k;",
821 varDecl(hasType(hasLocalQualifiers()))));
822 EXPECT_TRUE(notMatches("int m;",
823 varDecl(hasType(hasLocalQualifiers()))));
824}
825
826TEST(IsExternC, MatchesExternCFunctionDeclarations) {
827 EXPECT_TRUE(matches("extern \"C\" void f() {}", functionDecl(isExternC())));
828 EXPECT_TRUE(matches("extern \"C\" { void f() {} }",
829 functionDecl(isExternC())));
830 EXPECT_TRUE(notMatches("void f() {}", functionDecl(isExternC())));
831}
832
833TEST(IsDefaulted, MatchesDefaultedFunctionDeclarations) {
834 EXPECT_TRUE(notMatches("class A { ~A(); };",
835 functionDecl(hasName("~A"), isDefaulted())));
836 EXPECT_TRUE(matches("class B { ~B() = default; };",
837 functionDecl(hasName("~B"), isDefaulted())));
838}
839
840TEST(IsDeleted, MatchesDeletedFunctionDeclarations) {
841 EXPECT_TRUE(
842 notMatches("void Func();", functionDecl(hasName("Func"), isDeleted())));
843 EXPECT_TRUE(matches("void Func() = delete;",
844 functionDecl(hasName("Func"), isDeleted())));
845}
846
847TEST(IsNoThrow, MatchesNoThrowFunctionDeclarations) {
848 EXPECT_TRUE(notMatches("void f();", functionDecl(isNoThrow())));
849 EXPECT_TRUE(notMatches("void f() throw(int);", functionDecl(isNoThrow())));
850 EXPECT_TRUE(
851 notMatches("void f() noexcept(false);", functionDecl(isNoThrow())));
852 EXPECT_TRUE(matches("void f() throw();", functionDecl(isNoThrow())));
853 EXPECT_TRUE(matches("void f() noexcept;", functionDecl(isNoThrow())));
Aaron Ballman230ad972016-06-07 17:34:45 +0000854
855 EXPECT_TRUE(notMatches("void f();", functionProtoType(isNoThrow())));
856 EXPECT_TRUE(notMatches("void f() throw(int);", functionProtoType(isNoThrow())));
857 EXPECT_TRUE(
858 notMatches("void f() noexcept(false);", functionProtoType(isNoThrow())));
859 EXPECT_TRUE(matches("void f() throw();", functionProtoType(isNoThrow())));
860 EXPECT_TRUE(matches("void f() noexcept;", functionProtoType(isNoThrow())));
Piotr Padlewskic6e05022016-05-17 19:22:57 +0000861}
862
863TEST(isConstexpr, MatchesConstexprDeclarations) {
864 EXPECT_TRUE(matches("constexpr int foo = 42;",
865 varDecl(hasName("foo"), isConstexpr())));
866 EXPECT_TRUE(matches("constexpr int bar();",
867 functionDecl(hasName("bar"), isConstexpr())));
868}
869
870TEST(TemplateArgumentCountIs, Matches) {
871 EXPECT_TRUE(
872 matches("template<typename T> struct C {}; C<int> c;",
873 classTemplateSpecializationDecl(templateArgumentCountIs(1))));
874 EXPECT_TRUE(
875 notMatches("template<typename T> struct C {}; C<int> c;",
876 classTemplateSpecializationDecl(templateArgumentCountIs(2))));
877
878 EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
879 templateSpecializationType(templateArgumentCountIs(1))));
880 EXPECT_TRUE(
881 notMatches("template<typename T> struct C {}; C<int> c;",
882 templateSpecializationType(templateArgumentCountIs(2))));
883}
884
885TEST(IsIntegral, Matches) {
886 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
887 classTemplateSpecializationDecl(
888 hasAnyTemplateArgument(isIntegral()))));
889 EXPECT_TRUE(notMatches("template<typename T> struct C {}; C<int> c;",
890 classTemplateSpecializationDecl(hasAnyTemplateArgument(
891 templateArgument(isIntegral())))));
892}
893
894TEST(EqualsIntegralValue, Matches) {
895 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
896 classTemplateSpecializationDecl(
897 hasAnyTemplateArgument(equalsIntegralValue("42")))));
898 EXPECT_TRUE(matches("template<int T> struct C {}; C<-42> c;",
899 classTemplateSpecializationDecl(
900 hasAnyTemplateArgument(equalsIntegralValue("-42")))));
901 EXPECT_TRUE(matches("template<int T> struct C {}; C<-0042> c;",
902 classTemplateSpecializationDecl(
903 hasAnyTemplateArgument(equalsIntegralValue("-34")))));
904 EXPECT_TRUE(notMatches("template<int T> struct C {}; C<42> c;",
905 classTemplateSpecializationDecl(hasAnyTemplateArgument(
906 equalsIntegralValue("0042")))));
907}
908
909TEST(Matcher, MatchesAccessSpecDecls) {
910 EXPECT_TRUE(matches("class C { public: int i; };", accessSpecDecl()));
911 EXPECT_TRUE(
912 matches("class C { public: int i; };", accessSpecDecl(isPublic())));
913 EXPECT_TRUE(
914 notMatches("class C { public: int i; };", accessSpecDecl(isProtected())));
915 EXPECT_TRUE(
916 notMatches("class C { public: int i; };", accessSpecDecl(isPrivate())));
917
918 EXPECT_TRUE(notMatches("class C { int i; };", accessSpecDecl()));
919}
920
921TEST(Matcher, MatchesFinal) {
922 EXPECT_TRUE(matches("class X final {};", cxxRecordDecl(isFinal())));
923 EXPECT_TRUE(matches("class X { virtual void f() final; };",
924 cxxMethodDecl(isFinal())));
925 EXPECT_TRUE(notMatches("class X {};", cxxRecordDecl(isFinal())));
926 EXPECT_TRUE(
927 notMatches("class X { virtual void f(); };", cxxMethodDecl(isFinal())));
928}
929
930TEST(Matcher, MatchesVirtualMethod) {
931 EXPECT_TRUE(matches("class X { virtual int f(); };",
932 cxxMethodDecl(isVirtual(), hasName("::X::f"))));
933 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isVirtual())));
934}
935
936TEST(Matcher, MatchesVirtualAsWrittenMethod) {
937 EXPECT_TRUE(matches("class A { virtual int f(); };"
938 "class B : public A { int f(); };",
939 cxxMethodDecl(isVirtualAsWritten(), hasName("::A::f"))));
940 EXPECT_TRUE(
941 notMatches("class A { virtual int f(); };"
942 "class B : public A { int f(); };",
943 cxxMethodDecl(isVirtualAsWritten(), hasName("::B::f"))));
944}
945
946TEST(Matcher, MatchesPureMethod) {
947 EXPECT_TRUE(matches("class X { virtual int f() = 0; };",
948 cxxMethodDecl(isPure(), hasName("::X::f"))));
949 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isPure())));
950}
951
952TEST(Matcher, MatchesCopyAssignmentOperator) {
953 EXPECT_TRUE(matches("class X { X &operator=(X); };",
954 cxxMethodDecl(isCopyAssignmentOperator())));
955 EXPECT_TRUE(matches("class X { X &operator=(X &); };",
956 cxxMethodDecl(isCopyAssignmentOperator())));
957 EXPECT_TRUE(matches("class X { X &operator=(const X &); };",
958 cxxMethodDecl(isCopyAssignmentOperator())));
959 EXPECT_TRUE(matches("class X { X &operator=(volatile X &); };",
960 cxxMethodDecl(isCopyAssignmentOperator())));
961 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &); };",
962 cxxMethodDecl(isCopyAssignmentOperator())));
963 EXPECT_TRUE(notMatches("class X { X &operator=(X &&); };",
964 cxxMethodDecl(isCopyAssignmentOperator())));
965}
966
967TEST(Matcher, MatchesMoveAssignmentOperator) {
968 EXPECT_TRUE(notMatches("class X { X &operator=(X); };",
969 cxxMethodDecl(isMoveAssignmentOperator())));
970 EXPECT_TRUE(matches("class X { X &operator=(X &&); };",
971 cxxMethodDecl(isMoveAssignmentOperator())));
972 EXPECT_TRUE(matches("class X { X &operator=(const X &&); };",
973 cxxMethodDecl(isMoveAssignmentOperator())));
974 EXPECT_TRUE(matches("class X { X &operator=(volatile X &&); };",
975 cxxMethodDecl(isMoveAssignmentOperator())));
976 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &&); };",
977 cxxMethodDecl(isMoveAssignmentOperator())));
978 EXPECT_TRUE(notMatches("class X { X &operator=(X &); };",
979 cxxMethodDecl(isMoveAssignmentOperator())));
980}
981
982TEST(Matcher, MatchesConstMethod) {
983 EXPECT_TRUE(
984 matches("struct A { void foo() const; };", cxxMethodDecl(isConst())));
985 EXPECT_TRUE(
986 notMatches("struct A { void foo(); };", cxxMethodDecl(isConst())));
987}
988
989TEST(Matcher, MatchesOverridingMethod) {
990 EXPECT_TRUE(matches("class X { virtual int f(); }; "
991 "class Y : public X { int f(); };",
992 cxxMethodDecl(isOverride(), hasName("::Y::f"))));
993 EXPECT_TRUE(notMatches("class X { virtual int f(); }; "
994 "class Y : public X { int f(); };",
995 cxxMethodDecl(isOverride(), hasName("::X::f"))));
996 EXPECT_TRUE(notMatches("class X { int f(); }; "
997 "class Y : public X { int f(); };",
998 cxxMethodDecl(isOverride())));
999 EXPECT_TRUE(notMatches("class X { int f(); int f(int); }; ",
1000 cxxMethodDecl(isOverride())));
1001 EXPECT_TRUE(
1002 matches("template <typename Base> struct Y : Base { void f() override;};",
1003 cxxMethodDecl(isOverride(), hasName("::Y::f"))));
1004}
1005
1006TEST(Matcher, ConstructorArgument) {
1007 StatementMatcher Constructor = cxxConstructExpr(
1008 hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
1009
1010 EXPECT_TRUE(
1011 matches("class X { public: X(int); }; void x() { int y; X x(y); }",
1012 Constructor));
1013 EXPECT_TRUE(
1014 matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
1015 Constructor));
1016 EXPECT_TRUE(
1017 matches("class X { public: X(int); }; void x() { int y; X x = y; }",
1018 Constructor));
1019 EXPECT_TRUE(
1020 notMatches("class X { public: X(int); }; void x() { int z; X x(z); }",
1021 Constructor));
1022
1023 StatementMatcher WrongIndex = cxxConstructExpr(
1024 hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
1025 EXPECT_TRUE(
1026 notMatches("class X { public: X(int); }; void x() { int y; X x(y); }",
1027 WrongIndex));
1028}
1029
1030TEST(Matcher, ConstructorArgumentCount) {
1031 StatementMatcher Constructor1Arg = cxxConstructExpr(argumentCountIs(1));
1032
1033 EXPECT_TRUE(
1034 matches("class X { public: X(int); }; void x() { X x(0); }",
1035 Constructor1Arg));
1036 EXPECT_TRUE(
1037 matches("class X { public: X(int); }; void x() { X x = X(0); }",
1038 Constructor1Arg));
1039 EXPECT_TRUE(
1040 matches("class X { public: X(int); }; void x() { X x = 0; }",
1041 Constructor1Arg));
1042 EXPECT_TRUE(
1043 notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
1044 Constructor1Arg));
1045}
1046
1047TEST(Matcher, ConstructorListInitialization) {
1048 StatementMatcher ConstructorListInit =
1049 cxxConstructExpr(isListInitialization());
1050
1051 EXPECT_TRUE(
1052 matches("class X { public: X(int); }; void x() { X x{0}; }",
1053 ConstructorListInit));
1054 EXPECT_FALSE(
1055 matches("class X { public: X(int); }; void x() { X x(0); }",
1056 ConstructorListInit));
1057}
1058
1059TEST(ConstructorDeclaration, IsImplicit) {
1060 // This one doesn't match because the constructor is not added by the
1061 // compiler (it is not needed).
1062 EXPECT_TRUE(notMatches("class Foo { };",
1063 cxxConstructorDecl(isImplicit())));
1064 // The compiler added the implicit default constructor.
1065 EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
1066 cxxConstructorDecl(isImplicit())));
1067 EXPECT_TRUE(matches("class Foo { Foo(){} };",
1068 cxxConstructorDecl(unless(isImplicit()))));
1069 // The compiler added an implicit assignment operator.
1070 EXPECT_TRUE(matches("struct A { int x; } a = {0}, b = a; void f() { a = b; }",
1071 cxxMethodDecl(isImplicit(), hasName("operator="))));
1072}
1073
1074TEST(ConstructorDeclaration, IsExplicit) {
1075 EXPECT_TRUE(matches("struct S { explicit S(int); };",
1076 cxxConstructorDecl(isExplicit())));
1077 EXPECT_TRUE(notMatches("struct S { S(int); };",
1078 cxxConstructorDecl(isExplicit())));
1079}
1080
1081TEST(ConstructorDeclaration, Kinds) {
1082 EXPECT_TRUE(matches("struct S { S(); };",
1083 cxxConstructorDecl(isDefaultConstructor())));
1084 EXPECT_TRUE(notMatches("struct S { S(); };",
1085 cxxConstructorDecl(isCopyConstructor())));
1086 EXPECT_TRUE(notMatches("struct S { S(); };",
1087 cxxConstructorDecl(isMoveConstructor())));
1088
1089 EXPECT_TRUE(notMatches("struct S { S(const S&); };",
1090 cxxConstructorDecl(isDefaultConstructor())));
1091 EXPECT_TRUE(matches("struct S { S(const S&); };",
1092 cxxConstructorDecl(isCopyConstructor())));
1093 EXPECT_TRUE(notMatches("struct S { S(const S&); };",
1094 cxxConstructorDecl(isMoveConstructor())));
1095
1096 EXPECT_TRUE(notMatches("struct S { S(S&&); };",
1097 cxxConstructorDecl(isDefaultConstructor())));
1098 EXPECT_TRUE(notMatches("struct S { S(S&&); };",
1099 cxxConstructorDecl(isCopyConstructor())));
1100 EXPECT_TRUE(matches("struct S { S(S&&); };",
1101 cxxConstructorDecl(isMoveConstructor())));
1102}
1103
1104TEST(ConstructorDeclaration, IsUserProvided) {
1105 EXPECT_TRUE(notMatches("struct S { int X = 0; };",
1106 cxxConstructorDecl(isUserProvided())));
1107 EXPECT_TRUE(notMatches("struct S { S() = default; };",
1108 cxxConstructorDecl(isUserProvided())));
1109 EXPECT_TRUE(notMatches("struct S { S() = delete; };",
1110 cxxConstructorDecl(isUserProvided())));
1111 EXPECT_TRUE(
1112 matches("struct S { S(); };", cxxConstructorDecl(isUserProvided())));
1113 EXPECT_TRUE(matches("struct S { S(); }; S::S(){}",
1114 cxxConstructorDecl(isUserProvided())));
1115}
1116
1117TEST(ConstructorDeclaration, IsDelegatingConstructor) {
1118 EXPECT_TRUE(notMatches("struct S { S(); S(int); int X; };",
1119 cxxConstructorDecl(isDelegatingConstructor())));
1120 EXPECT_TRUE(notMatches("struct S { S(){} S(int X) : X(X) {} int X; };",
1121 cxxConstructorDecl(isDelegatingConstructor())));
1122 EXPECT_TRUE(matches(
1123 "struct S { S() : S(0) {} S(int X) : X(X) {} int X; };",
1124 cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(0))));
1125 EXPECT_TRUE(matches(
1126 "struct S { S(); S(int X); int X; }; S::S(int X) : S() {}",
1127 cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(1))));
1128}
1129
1130TEST(StringLiteral, HasSize) {
1131 StatementMatcher Literal = stringLiteral(hasSize(4));
1132 EXPECT_TRUE(matches("const char *s = \"abcd\";", Literal));
1133 // wide string
1134 EXPECT_TRUE(matches("const wchar_t *s = L\"abcd\";", Literal));
1135 // with escaped characters
1136 EXPECT_TRUE(matches("const char *s = \"\x05\x06\x07\x08\";", Literal));
1137 // no matching, too small
1138 EXPECT_TRUE(notMatches("const char *s = \"ab\";", Literal));
1139}
1140
1141TEST(Matcher, HasNameSupportsNamespaces) {
1142 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1143 recordDecl(hasName("a::b::C"))));
1144 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1145 recordDecl(hasName("::a::b::C"))));
1146 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1147 recordDecl(hasName("b::C"))));
1148 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1149 recordDecl(hasName("C"))));
1150 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1151 recordDecl(hasName("c::b::C"))));
1152 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1153 recordDecl(hasName("a::c::C"))));
1154 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1155 recordDecl(hasName("a::b::A"))));
1156 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1157 recordDecl(hasName("::C"))));
1158 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1159 recordDecl(hasName("::b::C"))));
1160 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1161 recordDecl(hasName("z::a::b::C"))));
1162 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1163 recordDecl(hasName("a+b::C"))));
1164 EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
1165 recordDecl(hasName("C"))));
1166}
1167
1168TEST(Matcher, HasNameSupportsOuterClasses) {
1169 EXPECT_TRUE(
1170 matches("class A { class B { class C; }; };",
1171 recordDecl(hasName("A::B::C"))));
1172 EXPECT_TRUE(
1173 matches("class A { class B { class C; }; };",
1174 recordDecl(hasName("::A::B::C"))));
1175 EXPECT_TRUE(
1176 matches("class A { class B { class C; }; };",
1177 recordDecl(hasName("B::C"))));
1178 EXPECT_TRUE(
1179 matches("class A { class B { class C; }; };",
1180 recordDecl(hasName("C"))));
1181 EXPECT_TRUE(
1182 notMatches("class A { class B { class C; }; };",
1183 recordDecl(hasName("c::B::C"))));
1184 EXPECT_TRUE(
1185 notMatches("class A { class B { class C; }; };",
1186 recordDecl(hasName("A::c::C"))));
1187 EXPECT_TRUE(
1188 notMatches("class A { class B { class C; }; };",
1189 recordDecl(hasName("A::B::A"))));
1190 EXPECT_TRUE(
1191 notMatches("class A { class B { class C; }; };",
1192 recordDecl(hasName("::C"))));
1193 EXPECT_TRUE(
1194 notMatches("class A { class B { class C; }; };",
1195 recordDecl(hasName("::B::C"))));
1196 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
1197 recordDecl(hasName("z::A::B::C"))));
1198 EXPECT_TRUE(
1199 notMatches("class A { class B { class C; }; };",
1200 recordDecl(hasName("A+B::C"))));
1201}
1202
1203TEST(Matcher, HasNameSupportsInlinedNamespaces) {
1204 std::string code = "namespace a { inline namespace b { class C; } }";
1205 EXPECT_TRUE(matches(code, recordDecl(hasName("a::b::C"))));
1206 EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
1207 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::b::C"))));
1208 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
1209}
1210
1211TEST(Matcher, HasNameSupportsAnonymousNamespaces) {
1212 std::string code = "namespace a { namespace { class C; } }";
1213 EXPECT_TRUE(
1214 matches(code, recordDecl(hasName("a::(anonymous namespace)::C"))));
1215 EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
1216 EXPECT_TRUE(
1217 matches(code, recordDecl(hasName("::a::(anonymous namespace)::C"))));
1218 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
1219}
1220
1221TEST(Matcher, HasNameSupportsAnonymousOuterClasses) {
1222 EXPECT_TRUE(matches("class A { class { class C; } x; };",
1223 recordDecl(hasName("A::(anonymous class)::C"))));
1224 EXPECT_TRUE(matches("class A { class { class C; } x; };",
1225 recordDecl(hasName("::A::(anonymous class)::C"))));
1226 EXPECT_FALSE(matches("class A { class { class C; } x; };",
1227 recordDecl(hasName("::A::C"))));
1228 EXPECT_TRUE(matches("class A { struct { class C; } x; };",
1229 recordDecl(hasName("A::(anonymous struct)::C"))));
1230 EXPECT_TRUE(matches("class A { struct { class C; } x; };",
1231 recordDecl(hasName("::A::(anonymous struct)::C"))));
1232 EXPECT_FALSE(matches("class A { struct { class C; } x; };",
1233 recordDecl(hasName("::A::C"))));
1234}
1235
1236TEST(Matcher, HasNameSupportsFunctionScope) {
1237 std::string code =
1238 "namespace a { void F(int a) { struct S { int m; }; int i; } }";
1239 EXPECT_TRUE(matches(code, varDecl(hasName("i"))));
1240 EXPECT_FALSE(matches(code, varDecl(hasName("F()::i"))));
1241
1242 EXPECT_TRUE(matches(code, fieldDecl(hasName("m"))));
1243 EXPECT_TRUE(matches(code, fieldDecl(hasName("S::m"))));
1244 EXPECT_TRUE(matches(code, fieldDecl(hasName("F(int)::S::m"))));
1245 EXPECT_TRUE(matches(code, fieldDecl(hasName("a::F(int)::S::m"))));
1246 EXPECT_TRUE(matches(code, fieldDecl(hasName("::a::F(int)::S::m"))));
1247}
1248
1249TEST(Matcher, HasAnyName) {
1250 const std::string Code = "namespace a { namespace b { class C; } }";
1251
1252 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "a::b::C"))));
1253 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("a::b::C", "XX"))));
1254 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX::C", "a::b::C"))));
1255 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "C"))));
1256
1257 EXPECT_TRUE(notMatches(Code, recordDecl(hasAnyName("::C", "::b::C"))));
1258 EXPECT_TRUE(
1259 matches(Code, recordDecl(hasAnyName("::C", "::b::C", "::a::b::C"))));
1260
1261 std::vector<StringRef> Names = {"::C", "::b::C", "::a::b::C"};
1262 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName(Names))));
1263}
1264
1265TEST(Matcher, IsDefinition) {
1266 DeclarationMatcher DefinitionOfClassA =
1267 recordDecl(hasName("A"), isDefinition());
1268 EXPECT_TRUE(matches("class A {};", DefinitionOfClassA));
1269 EXPECT_TRUE(notMatches("class A;", DefinitionOfClassA));
1270
1271 DeclarationMatcher DefinitionOfVariableA =
1272 varDecl(hasName("a"), isDefinition());
1273 EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));
1274 EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));
1275
1276 DeclarationMatcher DefinitionOfMethodA =
1277 cxxMethodDecl(hasName("a"), isDefinition());
1278 EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));
1279 EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));
1280}
1281
1282TEST(Matcher, HandlesNullQualTypes) {
1283 // FIXME: Add a Type matcher so we can replace uses of this
1284 // variable with Type(True())
1285 const TypeMatcher AnyType = anything();
1286
1287 // We don't really care whether this matcher succeeds; we're testing that
1288 // it completes without crashing.
1289 EXPECT_TRUE(matches(
1290 "struct A { };"
1291 "template <typename T>"
1292 "void f(T t) {"
1293 " T local_t(t /* this becomes a null QualType in the AST */);"
1294 "}"
1295 "void g() {"
1296 " f(0);"
1297 "}",
1298 expr(hasType(TypeMatcher(
1299 anyOf(
1300 TypeMatcher(hasDeclaration(anything())),
1301 pointsTo(AnyType),
1302 references(AnyType)
1303 // Other QualType matchers should go here.
1304 ))))));
1305}
1306
1307
1308TEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) {
1309 EXPECT_TRUE(matches("void f() { }",
1310 compoundStmt(statementCountIs(0))));
1311 EXPECT_TRUE(notMatches("void f() {}",
1312 compoundStmt(statementCountIs(1))));
1313}
1314
1315TEST(StatementCountIs, AppearsToMatchOnlyOneCount) {
1316 EXPECT_TRUE(matches("void f() { 1; }",
1317 compoundStmt(statementCountIs(1))));
1318 EXPECT_TRUE(notMatches("void f() { 1; }",
1319 compoundStmt(statementCountIs(0))));
1320 EXPECT_TRUE(notMatches("void f() { 1; }",
1321 compoundStmt(statementCountIs(2))));
1322}
1323
1324TEST(StatementCountIs, WorksWithMultipleStatements) {
1325 EXPECT_TRUE(matches("void f() { 1; 2; 3; }",
1326 compoundStmt(statementCountIs(3))));
1327}
1328
1329TEST(StatementCountIs, WorksWithNestedCompoundStatements) {
1330 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1331 compoundStmt(statementCountIs(1))));
1332 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1333 compoundStmt(statementCountIs(2))));
1334 EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
1335 compoundStmt(statementCountIs(3))));
1336 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1337 compoundStmt(statementCountIs(4))));
1338}
1339
1340TEST(Member, WorksInSimplestCase) {
1341 EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
1342 memberExpr(member(hasName("first")))));
1343}
1344
1345TEST(Member, DoesNotMatchTheBaseExpression) {
1346 // Don't pick out the wrong part of the member expression, this should
1347 // be checking the member (name) only.
1348 EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
1349 memberExpr(member(hasName("first")))));
1350}
1351
1352TEST(Member, MatchesInMemberFunctionCall) {
1353 EXPECT_TRUE(matches("void f() {"
1354 " struct { void first() {}; } s;"
1355 " s.first();"
1356 "};",
1357 memberExpr(member(hasName("first")))));
1358}
1359
1360TEST(Member, MatchesMember) {
1361 EXPECT_TRUE(matches(
1362 "struct A { int i; }; void f() { A a; a.i = 2; }",
1363 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
1364 EXPECT_TRUE(notMatches(
1365 "struct A { float f; }; void f() { A a; a.f = 2.0f; }",
1366 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
1367}
1368
Aaron Ballman5c574342016-07-06 18:25:16 +00001369TEST(Member, BitFields) {
1370 EXPECT_TRUE(matches("class C { int a : 2; int b; };",
1371 fieldDecl(isBitField(), hasName("a"))));
1372 EXPECT_TRUE(notMatches("class C { int a : 2; int b; };",
1373 fieldDecl(isBitField(), hasName("b"))));
1374 EXPECT_TRUE(matches("class C { int a : 2; int b : 4; };",
1375 fieldDecl(isBitField(), hasBitWidth(2), hasName("a"))));
1376}
Piotr Padlewskic6e05022016-05-17 19:22:57 +00001377
1378TEST(Member, UnderstandsAccess) {
1379 EXPECT_TRUE(matches(
1380 "struct A { int i; };", fieldDecl(isPublic(), hasName("i"))));
1381 EXPECT_TRUE(notMatches(
1382 "struct A { int i; };", fieldDecl(isProtected(), hasName("i"))));
1383 EXPECT_TRUE(notMatches(
1384 "struct A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
1385
1386 EXPECT_TRUE(notMatches(
1387 "class A { int i; };", fieldDecl(isPublic(), hasName("i"))));
1388 EXPECT_TRUE(notMatches(
1389 "class A { int i; };", fieldDecl(isProtected(), hasName("i"))));
1390 EXPECT_TRUE(matches(
1391 "class A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
1392
1393 EXPECT_TRUE(notMatches(
1394 "class A { protected: int i; };", fieldDecl(isPublic(), hasName("i"))));
1395 EXPECT_TRUE(matches("class A { protected: int i; };",
1396 fieldDecl(isProtected(), hasName("i"))));
1397 EXPECT_TRUE(notMatches(
1398 "class A { protected: int i; };", fieldDecl(isPrivate(), hasName("i"))));
1399
1400 // Non-member decls have the AccessSpecifier AS_none and thus aren't matched.
1401 EXPECT_TRUE(notMatches("int i;", varDecl(isPublic(), hasName("i"))));
1402 EXPECT_TRUE(notMatches("int i;", varDecl(isProtected(), hasName("i"))));
1403 EXPECT_TRUE(notMatches("int i;", varDecl(isPrivate(), hasName("i"))));
1404}
1405
1406TEST(hasDynamicExceptionSpec, MatchesDynamicExceptionSpecifications) {
1407 EXPECT_TRUE(notMatches("void f();", functionDecl(hasDynamicExceptionSpec())));
1408 EXPECT_TRUE(notMatches("void g() noexcept;",
1409 functionDecl(hasDynamicExceptionSpec())));
1410 EXPECT_TRUE(notMatches("void h() noexcept(true);",
1411 functionDecl(hasDynamicExceptionSpec())));
1412 EXPECT_TRUE(notMatches("void i() noexcept(false);",
1413 functionDecl(hasDynamicExceptionSpec())));
1414 EXPECT_TRUE(
1415 matches("void j() throw();", functionDecl(hasDynamicExceptionSpec())));
1416 EXPECT_TRUE(
1417 matches("void k() throw(int);", functionDecl(hasDynamicExceptionSpec())));
1418 EXPECT_TRUE(
1419 matches("void l() throw(...);", functionDecl(hasDynamicExceptionSpec())));
Aaron Ballman230ad972016-06-07 17:34:45 +00001420
1421 EXPECT_TRUE(notMatches("void f();", functionProtoType(hasDynamicExceptionSpec())));
1422 EXPECT_TRUE(notMatches("void g() noexcept;",
1423 functionProtoType(hasDynamicExceptionSpec())));
1424 EXPECT_TRUE(notMatches("void h() noexcept(true);",
1425 functionProtoType(hasDynamicExceptionSpec())));
1426 EXPECT_TRUE(notMatches("void i() noexcept(false);",
1427 functionProtoType(hasDynamicExceptionSpec())));
1428 EXPECT_TRUE(
1429 matches("void j() throw();", functionProtoType(hasDynamicExceptionSpec())));
1430 EXPECT_TRUE(
1431 matches("void k() throw(int);", functionProtoType(hasDynamicExceptionSpec())));
1432 EXPECT_TRUE(
1433 matches("void l() throw(...);", functionProtoType(hasDynamicExceptionSpec())));
Piotr Padlewskic6e05022016-05-17 19:22:57 +00001434}
1435
1436TEST(HasObjectExpression, DoesNotMatchMember) {
1437 EXPECT_TRUE(notMatches(
1438 "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
1439 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
1440}
1441
1442TEST(HasObjectExpression, MatchesBaseOfVariable) {
1443 EXPECT_TRUE(matches(
1444 "struct X { int m; }; void f(X x) { x.m; }",
1445 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
1446 EXPECT_TRUE(matches(
1447 "struct X { int m; }; void f(X* x) { x->m; }",
1448 memberExpr(hasObjectExpression(
1449 hasType(pointsTo(recordDecl(hasName("X"))))))));
1450}
1451
1452TEST(HasObjectExpression,
1453 MatchesObjectExpressionOfImplicitlyFormedMemberExpression) {
1454 EXPECT_TRUE(matches(
1455 "class X {}; struct S { X m; void f() { this->m; } };",
1456 memberExpr(hasObjectExpression(
1457 hasType(pointsTo(recordDecl(hasName("S"))))))));
1458 EXPECT_TRUE(matches(
1459 "class X {}; struct S { X m; void f() { m; } };",
1460 memberExpr(hasObjectExpression(
1461 hasType(pointsTo(recordDecl(hasName("S"))))))));
1462}
1463
1464TEST(Field, DoesNotMatchNonFieldMembers) {
1465 EXPECT_TRUE(notMatches("class X { void m(); };", fieldDecl(hasName("m"))));
1466 EXPECT_TRUE(notMatches("class X { class m {}; };", fieldDecl(hasName("m"))));
1467 EXPECT_TRUE(notMatches("class X { enum { m }; };", fieldDecl(hasName("m"))));
1468 EXPECT_TRUE(notMatches("class X { enum m {}; };", fieldDecl(hasName("m"))));
1469}
1470
1471TEST(Field, MatchesField) {
1472 EXPECT_TRUE(matches("class X { int m; };", fieldDecl(hasName("m"))));
1473}
1474
1475TEST(IsVolatileQualified, QualifiersMatch) {
1476 EXPECT_TRUE(matches("volatile int i = 42;",
1477 varDecl(hasType(isVolatileQualified()))));
1478 EXPECT_TRUE(notMatches("volatile int *i;",
1479 varDecl(hasType(isVolatileQualified()))));
1480 EXPECT_TRUE(matches("typedef volatile int v_int; v_int i = 42;",
1481 varDecl(hasType(isVolatileQualified()))));
1482}
1483
1484TEST(IsConstQualified, MatchesConstInt) {
1485 EXPECT_TRUE(matches("const int i = 42;",
1486 varDecl(hasType(isConstQualified()))));
1487}
1488
1489TEST(IsConstQualified, MatchesConstPointer) {
1490 EXPECT_TRUE(matches("int i = 42; int* const p(&i);",
1491 varDecl(hasType(isConstQualified()))));
1492}
1493
1494TEST(IsConstQualified, MatchesThroughTypedef) {
1495 EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
1496 varDecl(hasType(isConstQualified()))));
1497 EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p(0);",
1498 varDecl(hasType(isConstQualified()))));
1499}
1500
1501TEST(IsConstQualified, DoesNotMatchInappropriately) {
1502 EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
1503 varDecl(hasType(isConstQualified()))));
1504 EXPECT_TRUE(notMatches("int const* p;",
1505 varDecl(hasType(isConstQualified()))));
1506}
1507
1508TEST(DeclCount, DeclCountIsCorrect) {
1509 EXPECT_TRUE(matches("void f() {int i,j;}",
1510 declStmt(declCountIs(2))));
1511 EXPECT_TRUE(notMatches("void f() {int i,j; int k;}",
1512 declStmt(declCountIs(3))));
1513 EXPECT_TRUE(notMatches("void f() {int i,j, k, l;}",
1514 declStmt(declCountIs(3))));
1515}
1516
1517
1518TEST(EachOf, TriggersForEachMatch) {
1519 EXPECT_TRUE(matchAndVerifyResultTrue(
1520 "class A { int a; int b; };",
1521 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
1522 has(fieldDecl(hasName("b")).bind("v")))),
1523 llvm::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 2)));
1524}
1525
1526TEST(EachOf, BehavesLikeAnyOfUnlessBothMatch) {
1527 EXPECT_TRUE(matchAndVerifyResultTrue(
1528 "class A { int a; int c; };",
1529 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
1530 has(fieldDecl(hasName("b")).bind("v")))),
1531 llvm::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 1)));
1532 EXPECT_TRUE(matchAndVerifyResultTrue(
1533 "class A { int c; int b; };",
1534 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
1535 has(fieldDecl(hasName("b")).bind("v")))),
1536 llvm::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 1)));
1537 EXPECT_TRUE(notMatches(
1538 "class A { int c; int d; };",
1539 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
1540 has(fieldDecl(hasName("b")).bind("v"))))));
1541}
1542
1543TEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) {
1544 // Make sure that we can both match the class by name (::X) and by the type
1545 // the template was instantiated with (via a field).
1546
1547 EXPECT_TRUE(matches(
1548 "template <typename T> class X {}; class A {}; X<A> x;",
1549 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
1550
1551 EXPECT_TRUE(matches(
1552 "template <typename T> class X { T t; }; class A {}; X<A> x;",
1553 cxxRecordDecl(isTemplateInstantiation(), hasDescendant(
1554 fieldDecl(hasType(recordDecl(hasName("A"))))))));
1555}
1556
1557TEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) {
1558 EXPECT_TRUE(matches(
1559 "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
1560 functionDecl(hasParameter(0, hasType(recordDecl(hasName("A")))),
1561 isTemplateInstantiation())));
1562}
1563
1564TEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) {
1565 EXPECT_TRUE(matches(
1566 "template <typename T> class X { T t; }; class A {};"
1567 "template class X<A>;",
1568 cxxRecordDecl(isTemplateInstantiation(), hasDescendant(
1569 fieldDecl(hasType(recordDecl(hasName("A"))))))));
1570}
1571
1572TEST(IsTemplateInstantiation,
1573 MatchesInstantiationOfPartiallySpecializedClassTemplate) {
1574 EXPECT_TRUE(matches(
1575 "template <typename T> class X {};"
1576 "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
1577 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
1578}
1579
1580TEST(IsTemplateInstantiation,
1581 MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
1582 EXPECT_TRUE(matches(
1583 "class A {};"
1584 "class X {"
1585 " template <typename U> class Y { U u; };"
1586 " Y<A> y;"
1587 "};",
1588 cxxRecordDecl(hasName("::X::Y"), isTemplateInstantiation())));
1589}
1590
1591TEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) {
1592 // FIXME: Figure out whether this makes sense. It doesn't affect the
1593 // normal use case as long as the uppermost instantiation always is marked
1594 // as template instantiation, but it might be confusing as a predicate.
1595 EXPECT_TRUE(matches(
1596 "class A {};"
1597 "template <typename T> class X {"
1598 " template <typename U> class Y { U u; };"
1599 " Y<T> y;"
1600 "}; X<A> x;",
1601 cxxRecordDecl(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
1602}
1603
1604TEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) {
1605 EXPECT_TRUE(notMatches(
1606 "template <typename T> class X {}; class A {};"
1607 "template <> class X<A> {}; X<A> x;",
1608 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
1609}
1610
1611TEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) {
1612 EXPECT_TRUE(notMatches(
1613 "class A {}; class Y { A a; };",
1614 cxxRecordDecl(isTemplateInstantiation())));
1615}
1616
1617TEST(IsInstantiated, MatchesInstantiation) {
1618 EXPECT_TRUE(
1619 matches("template<typename T> class A { T i; }; class Y { A<int> a; };",
1620 cxxRecordDecl(isInstantiated())));
1621}
1622
1623TEST(IsInstantiated, NotMatchesDefinition) {
1624 EXPECT_TRUE(notMatches("template<typename T> class A { T i; };",
1625 cxxRecordDecl(isInstantiated())));
1626}
1627
1628TEST(IsInTemplateInstantiation, MatchesInstantiationStmt) {
1629 EXPECT_TRUE(matches("template<typename T> struct A { A() { T i; } };"
1630 "class Y { A<int> a; }; Y y;",
1631 declStmt(isInTemplateInstantiation())));
1632}
1633
1634TEST(IsInTemplateInstantiation, NotMatchesDefinitionStmt) {
1635 EXPECT_TRUE(notMatches("template<typename T> struct A { void x() { T i; } };",
1636 declStmt(isInTemplateInstantiation())));
1637}
1638
1639TEST(IsInstantiated, MatchesFunctionInstantiation) {
1640 EXPECT_TRUE(
1641 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
1642 functionDecl(isInstantiated())));
1643}
1644
1645TEST(IsInstantiated, NotMatchesFunctionDefinition) {
1646 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
1647 varDecl(isInstantiated())));
1648}
1649
1650TEST(IsInTemplateInstantiation, MatchesFunctionInstantiationStmt) {
1651 EXPECT_TRUE(
1652 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
1653 declStmt(isInTemplateInstantiation())));
1654}
1655
1656TEST(IsInTemplateInstantiation, NotMatchesFunctionDefinitionStmt) {
1657 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
1658 declStmt(isInTemplateInstantiation())));
1659}
1660
1661TEST(IsInTemplateInstantiation, Sharing) {
1662 auto Matcher = binaryOperator(unless(isInTemplateInstantiation()));
1663 // FIXME: Node sharing is an implementation detail, exposing it is ugly
1664 // and makes the matcher behave in non-obvious ways.
1665 EXPECT_TRUE(notMatches(
1666 "int j; template<typename T> void A(T t) { j += 42; } void x() { A(0); }",
1667 Matcher));
1668 EXPECT_TRUE(matches(
1669 "int j; template<typename T> void A(T t) { j += t; } void x() { A(0); }",
1670 Matcher));
1671}
1672
1673TEST(IsExplicitTemplateSpecialization,
1674 DoesNotMatchPrimaryTemplate) {
1675 EXPECT_TRUE(notMatches(
1676 "template <typename T> class X {};",
1677 cxxRecordDecl(isExplicitTemplateSpecialization())));
1678 EXPECT_TRUE(notMatches(
1679 "template <typename T> void f(T t);",
1680 functionDecl(isExplicitTemplateSpecialization())));
1681}
1682
1683TEST(IsExplicitTemplateSpecialization,
1684 DoesNotMatchExplicitTemplateInstantiations) {
1685 EXPECT_TRUE(notMatches(
1686 "template <typename T> class X {};"
1687 "template class X<int>; extern template class X<long>;",
1688 cxxRecordDecl(isExplicitTemplateSpecialization())));
1689 EXPECT_TRUE(notMatches(
1690 "template <typename T> void f(T t) {}"
1691 "template void f(int t); extern template void f(long t);",
1692 functionDecl(isExplicitTemplateSpecialization())));
1693}
1694
1695TEST(IsExplicitTemplateSpecialization,
1696 DoesNotMatchImplicitTemplateInstantiations) {
1697 EXPECT_TRUE(notMatches(
1698 "template <typename T> class X {}; X<int> x;",
1699 cxxRecordDecl(isExplicitTemplateSpecialization())));
1700 EXPECT_TRUE(notMatches(
1701 "template <typename T> void f(T t); void g() { f(10); }",
1702 functionDecl(isExplicitTemplateSpecialization())));
1703}
1704
1705TEST(IsExplicitTemplateSpecialization,
1706 MatchesExplicitTemplateSpecializations) {
1707 EXPECT_TRUE(matches(
1708 "template <typename T> class X {};"
1709 "template<> class X<int> {};",
1710 cxxRecordDecl(isExplicitTemplateSpecialization())));
1711 EXPECT_TRUE(matches(
1712 "template <typename T> void f(T t) {}"
1713 "template<> void f(int t) {}",
1714 functionDecl(isExplicitTemplateSpecialization())));
1715}
1716
1717TEST(TypeMatching, MatchesBool) {
1718 EXPECT_TRUE(matches("struct S { bool func(); };",
1719 cxxMethodDecl(returns(booleanType()))));
1720 EXPECT_TRUE(notMatches("struct S { void func(); };",
1721 cxxMethodDecl(returns(booleanType()))));
1722}
1723
1724TEST(TypeMatching, MatchesVoid) {
1725 EXPECT_TRUE(matches("struct S { void func(); };",
1726 cxxMethodDecl(returns(voidType()))));
1727}
1728
1729TEST(TypeMatching, MatchesRealFloats) {
1730 EXPECT_TRUE(matches("struct S { float func(); };",
1731 cxxMethodDecl(returns(realFloatingPointType()))));
1732 EXPECT_TRUE(notMatches("struct S { int func(); };",
1733 cxxMethodDecl(returns(realFloatingPointType()))));
1734 EXPECT_TRUE(matches("struct S { long double func(); };",
1735 cxxMethodDecl(returns(realFloatingPointType()))));
1736}
1737
1738TEST(TypeMatching, MatchesArrayTypes) {
1739 EXPECT_TRUE(matches("int a[] = {2,3};", arrayType()));
1740 EXPECT_TRUE(matches("int a[42];", arrayType()));
1741 EXPECT_TRUE(matches("void f(int b) { int a[b]; }", arrayType()));
1742
1743 EXPECT_TRUE(notMatches("struct A {}; A a[7];",
1744 arrayType(hasElementType(builtinType()))));
1745
1746 EXPECT_TRUE(matches(
1747 "int const a[] = { 2, 3 };",
1748 qualType(arrayType(hasElementType(builtinType())))));
1749 EXPECT_TRUE(matches(
1750 "int const a[] = { 2, 3 };",
1751 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
1752 EXPECT_TRUE(matches(
1753 "typedef const int T; T x[] = { 1, 2 };",
1754 qualType(isConstQualified(), arrayType())));
1755
1756 EXPECT_TRUE(notMatches(
1757 "int a[] = { 2, 3 };",
1758 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
1759 EXPECT_TRUE(notMatches(
1760 "int a[] = { 2, 3 };",
1761 qualType(arrayType(hasElementType(isConstQualified(), builtinType())))));
1762 EXPECT_TRUE(notMatches(
1763 "int const a[] = { 2, 3 };",
1764 qualType(arrayType(hasElementType(builtinType())),
1765 unless(isConstQualified()))));
1766
1767 EXPECT_TRUE(matches("int a[2];",
1768 constantArrayType(hasElementType(builtinType()))));
1769 EXPECT_TRUE(matches("const int a = 0;", qualType(isInteger())));
1770}
1771
1772TEST(TypeMatching, DecayedType) {
1773 EXPECT_TRUE(matches("void f(int i[]);", valueDecl(hasType(decayedType(hasDecayedType(pointerType()))))));
1774 EXPECT_TRUE(notMatches("int i[7];", decayedType()));
1775}
1776
1777TEST(TypeMatching, MatchesComplexTypes) {
1778 EXPECT_TRUE(matches("_Complex float f;", complexType()));
1779 EXPECT_TRUE(matches(
1780 "_Complex float f;",
1781 complexType(hasElementType(builtinType()))));
1782 EXPECT_TRUE(notMatches(
1783 "_Complex float f;",
1784 complexType(hasElementType(isInteger()))));
1785}
1786
1787TEST(NS, Anonymous) {
1788 EXPECT_TRUE(notMatches("namespace N {}", namespaceDecl(isAnonymous())));
1789 EXPECT_TRUE(matches("namespace {}", namespaceDecl(isAnonymous())));
1790}
1791
1792TEST(EqualsBoundNodeMatcher, QualType) {
1793 EXPECT_TRUE(matches(
1794 "int i = 1;", varDecl(hasType(qualType().bind("type")),
1795 hasInitializer(ignoringParenImpCasts(
1796 hasType(qualType(equalsBoundNode("type"))))))));
1797 EXPECT_TRUE(notMatches("int i = 1.f;",
1798 varDecl(hasType(qualType().bind("type")),
1799 hasInitializer(ignoringParenImpCasts(hasType(
1800 qualType(equalsBoundNode("type"))))))));
1801}
1802
1803TEST(EqualsBoundNodeMatcher, NonMatchingTypes) {
1804 EXPECT_TRUE(notMatches(
1805 "int i = 1;", varDecl(namedDecl(hasName("i")).bind("name"),
1806 hasInitializer(ignoringParenImpCasts(
1807 hasType(qualType(equalsBoundNode("type"))))))));
1808}
1809
1810TEST(EqualsBoundNodeMatcher, Stmt) {
1811 EXPECT_TRUE(
1812 matches("void f() { if(true) {} }",
1813 stmt(allOf(ifStmt().bind("if"),
1814 hasParent(stmt(has(stmt(equalsBoundNode("if")))))))));
1815
1816 EXPECT_TRUE(notMatches(
1817 "void f() { if(true) { if (true) {} } }",
1818 stmt(allOf(ifStmt().bind("if"), has(stmt(equalsBoundNode("if")))))));
1819}
1820
1821TEST(EqualsBoundNodeMatcher, Decl) {
1822 EXPECT_TRUE(matches(
1823 "class X { class Y {}; };",
1824 decl(allOf(recordDecl(hasName("::X::Y")).bind("record"),
1825 hasParent(decl(has(decl(equalsBoundNode("record")))))))));
1826
1827 EXPECT_TRUE(notMatches("class X { class Y {}; };",
1828 decl(allOf(recordDecl(hasName("::X")).bind("record"),
1829 has(decl(equalsBoundNode("record")))))));
1830}
1831
1832TEST(EqualsBoundNodeMatcher, Type) {
1833 EXPECT_TRUE(matches(
1834 "class X { int a; int b; };",
1835 recordDecl(
1836 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
1837 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
1838
1839 EXPECT_TRUE(notMatches(
1840 "class X { int a; double b; };",
1841 recordDecl(
1842 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
1843 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
1844}
1845
1846TEST(EqualsBoundNodeMatcher, UsingForEachDescendant) {
1847 EXPECT_TRUE(matchAndVerifyResultTrue(
1848 "int f() {"
1849 " if (1) {"
1850 " int i = 9;"
1851 " }"
1852 " int j = 10;"
1853 " {"
1854 " float k = 9.0;"
1855 " }"
1856 " return 0;"
1857 "}",
1858 // Look for variable declarations within functions whose type is the same
1859 // as the function return type.
1860 functionDecl(returns(qualType().bind("type")),
1861 forEachDescendant(varDecl(hasType(
1862 qualType(equalsBoundNode("type")))).bind("decl"))),
1863 // Only i and j should match, not k.
1864 llvm::make_unique<VerifyIdIsBoundTo<VarDecl>>("decl", 2)));
1865}
1866
1867TEST(EqualsBoundNodeMatcher, FiltersMatchedCombinations) {
1868 EXPECT_TRUE(matchAndVerifyResultTrue(
1869 "void f() {"
1870 " int x;"
1871 " double d;"
1872 " x = d + x - d + x;"
1873 "}",
1874 functionDecl(
1875 hasName("f"), forEachDescendant(varDecl().bind("d")),
1876 forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d")))))),
1877 llvm::make_unique<VerifyIdIsBoundTo<VarDecl>>("d", 5)));
1878}
1879
1880TEST(EqualsBoundNodeMatcher, UnlessDescendantsOfAncestorsMatch) {
1881 EXPECT_TRUE(matchAndVerifyResultTrue(
1882 "struct StringRef { int size() const; const char* data() const; };"
1883 "void f(StringRef v) {"
1884 " v.data();"
1885 "}",
1886 cxxMemberCallExpr(
1887 callee(cxxMethodDecl(hasName("data"))),
1888 on(declRefExpr(to(
1889 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
1890 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
1891 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
1892 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
1893 .bind("data"),
1894 llvm::make_unique<VerifyIdIsBoundTo<Expr>>("data", 1)));
1895
1896 EXPECT_FALSE(matches(
1897 "struct StringRef { int size() const; const char* data() const; };"
1898 "void f(StringRef v) {"
1899 " v.data();"
1900 " v.size();"
1901 "}",
1902 cxxMemberCallExpr(
1903 callee(cxxMethodDecl(hasName("data"))),
1904 on(declRefExpr(to(
1905 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
1906 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
1907 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
1908 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
1909 .bind("data")));
1910}
1911
1912TEST(NullPointerConstants, Basic) {
1913 EXPECT_TRUE(matches("#define NULL ((void *)0)\n"
1914 "void *v1 = NULL;", expr(nullPointerConstant())));
1915 EXPECT_TRUE(matches("void *v2 = nullptr;", expr(nullPointerConstant())));
1916 EXPECT_TRUE(matches("void *v3 = __null;", expr(nullPointerConstant())));
1917 EXPECT_TRUE(matches("char *cp = (char *)0;", expr(nullPointerConstant())));
1918 EXPECT_TRUE(matches("int *ip = 0;", expr(nullPointerConstant())));
1919 EXPECT_TRUE(notMatches("int i = 0;", expr(nullPointerConstant())));
1920}
1921
1922} // namespace ast_matchers
1923} // namespace clang