blob: 1527eacb6ab761f7125c1ae071e6c39fd4940f86 [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
Clement Courbet42517592016-07-12 06:36:00 +0000726TEST(IsSignedInteger, MatchesSignedIntegers) {
727 EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isSignedInteger()))));
728 EXPECT_TRUE(notMatches("unsigned i = 0;",
729 varDecl(hasType(isSignedInteger()))));
730}
731
732TEST(IsUnsignedInteger, MatchesUnsignedIntegers) {
733 EXPECT_TRUE(notMatches("int i = 0;", varDecl(hasType(isUnsignedInteger()))));
734 EXPECT_TRUE(matches("unsigned i = 0;",
735 varDecl(hasType(isUnsignedInteger()))));
736}
737
Piotr Padlewskic6e05022016-05-17 19:22:57 +0000738TEST(IsAnyPointer, MatchesPointers) {
739 EXPECT_TRUE(matches("int* i = nullptr;", varDecl(hasType(isAnyPointer()))));
740}
741
742TEST(IsAnyPointer, MatchesObjcPointer) {
743 EXPECT_TRUE(matchesObjC("@interface Foo @end Foo *f;",
744 varDecl(hasType(isAnyPointer()))));
745}
746
747TEST(IsAnyPointer, ReportsNoFalsePositives) {
748 EXPECT_TRUE(notMatches("int i = 0;", varDecl(hasType(isAnyPointer()))));
749}
750
751TEST(IsAnyCharacter, MatchesCharacters) {
752 EXPECT_TRUE(matches("char i = 0;", varDecl(hasType(isAnyCharacter()))));
753}
754
755TEST(IsAnyCharacter, ReportsNoFalsePositives) {
756 EXPECT_TRUE(notMatches("int i;", varDecl(hasType(isAnyCharacter()))));
757}
758
759TEST(IsArrow, MatchesMemberVariablesViaArrow) {
760 EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };",
761 memberExpr(isArrow())));
762 EXPECT_TRUE(matches("class Y { void x() { y; } int y; };",
763 memberExpr(isArrow())));
764 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };",
765 memberExpr(isArrow())));
766}
767
768TEST(IsArrow, MatchesStaticMemberVariablesViaArrow) {
769 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
770 memberExpr(isArrow())));
771 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
772 memberExpr(isArrow())));
773 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } static int y; };",
774 memberExpr(isArrow())));
775}
776
777TEST(IsArrow, MatchesMemberCallsViaArrow) {
778 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
779 memberExpr(isArrow())));
780 EXPECT_TRUE(matches("class Y { void x() { x(); } };",
781 memberExpr(isArrow())));
782 EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",
783 memberExpr(isArrow())));
784}
785
786TEST(ConversionDeclaration, IsExplicit) {
787 EXPECT_TRUE(matches("struct S { explicit operator int(); };",
788 cxxConversionDecl(isExplicit())));
789 EXPECT_TRUE(notMatches("struct S { operator int(); };",
790 cxxConversionDecl(isExplicit())));
791}
792
793TEST(Matcher, ArgumentCount) {
794 StatementMatcher Call1Arg = callExpr(argumentCountIs(1));
795
796 EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg));
797 EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg));
798 EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg));
799}
800
801TEST(Matcher, ParameterCount) {
802 DeclarationMatcher Function1Arg = functionDecl(parameterCountIs(1));
803 EXPECT_TRUE(matches("void f(int i) {}", Function1Arg));
804 EXPECT_TRUE(matches("class X { void f(int i) {} };", Function1Arg));
805 EXPECT_TRUE(notMatches("void f() {}", Function1Arg));
806 EXPECT_TRUE(notMatches("void f(int i, int j, int k) {}", Function1Arg));
807 EXPECT_TRUE(matches("void f(int i, ...) {};", Function1Arg));
808}
809
810TEST(Matcher, References) {
811 DeclarationMatcher ReferenceClassX = varDecl(
812 hasType(references(recordDecl(hasName("X")))));
813 EXPECT_TRUE(matches("class X {}; void y(X y) { X &x = y; }",
814 ReferenceClassX));
815 EXPECT_TRUE(
816 matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
817 // The match here is on the implicit copy constructor code for
818 // class X, not on code 'X x = y'.
819 EXPECT_TRUE(
820 matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
821 EXPECT_TRUE(
822 notMatches("class X {}; extern X x;", ReferenceClassX));
823 EXPECT_TRUE(
824 notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
825}
826
827TEST(QualType, hasLocalQualifiers) {
828 EXPECT_TRUE(notMatches("typedef const int const_int; const_int i = 1;",
829 varDecl(hasType(hasLocalQualifiers()))));
830 EXPECT_TRUE(matches("int *const j = nullptr;",
831 varDecl(hasType(hasLocalQualifiers()))));
832 EXPECT_TRUE(matches("int *volatile k;",
833 varDecl(hasType(hasLocalQualifiers()))));
834 EXPECT_TRUE(notMatches("int m;",
835 varDecl(hasType(hasLocalQualifiers()))));
836}
837
838TEST(IsExternC, MatchesExternCFunctionDeclarations) {
839 EXPECT_TRUE(matches("extern \"C\" void f() {}", functionDecl(isExternC())));
840 EXPECT_TRUE(matches("extern \"C\" { void f() {} }",
841 functionDecl(isExternC())));
842 EXPECT_TRUE(notMatches("void f() {}", functionDecl(isExternC())));
843}
844
Benjamin Kramer87e6d992016-08-04 10:02:03 +0000845TEST(IsExternC, MatchesExternCVariableDeclarations) {
846 EXPECT_TRUE(matches("extern \"C\" int i;", varDecl(isExternC())));
847 EXPECT_TRUE(matches("extern \"C\" { int i; }", varDecl(isExternC())));
848 EXPECT_TRUE(notMatches("int i;", varDecl(isExternC())));
849}
850
Piotr Padlewskic6e05022016-05-17 19:22:57 +0000851TEST(IsDefaulted, MatchesDefaultedFunctionDeclarations) {
852 EXPECT_TRUE(notMatches("class A { ~A(); };",
853 functionDecl(hasName("~A"), isDefaulted())));
854 EXPECT_TRUE(matches("class B { ~B() = default; };",
855 functionDecl(hasName("~B"), isDefaulted())));
856}
857
858TEST(IsDeleted, MatchesDeletedFunctionDeclarations) {
859 EXPECT_TRUE(
860 notMatches("void Func();", functionDecl(hasName("Func"), isDeleted())));
861 EXPECT_TRUE(matches("void Func() = delete;",
862 functionDecl(hasName("Func"), isDeleted())));
863}
864
865TEST(IsNoThrow, MatchesNoThrowFunctionDeclarations) {
866 EXPECT_TRUE(notMatches("void f();", functionDecl(isNoThrow())));
867 EXPECT_TRUE(notMatches("void f() throw(int);", functionDecl(isNoThrow())));
868 EXPECT_TRUE(
869 notMatches("void f() noexcept(false);", functionDecl(isNoThrow())));
870 EXPECT_TRUE(matches("void f() throw();", functionDecl(isNoThrow())));
871 EXPECT_TRUE(matches("void f() noexcept;", functionDecl(isNoThrow())));
Aaron Ballman230ad972016-06-07 17:34:45 +0000872
873 EXPECT_TRUE(notMatches("void f();", functionProtoType(isNoThrow())));
874 EXPECT_TRUE(notMatches("void f() throw(int);", functionProtoType(isNoThrow())));
875 EXPECT_TRUE(
876 notMatches("void f() noexcept(false);", functionProtoType(isNoThrow())));
877 EXPECT_TRUE(matches("void f() throw();", functionProtoType(isNoThrow())));
878 EXPECT_TRUE(matches("void f() noexcept;", functionProtoType(isNoThrow())));
Piotr Padlewskic6e05022016-05-17 19:22:57 +0000879}
880
881TEST(isConstexpr, MatchesConstexprDeclarations) {
882 EXPECT_TRUE(matches("constexpr int foo = 42;",
883 varDecl(hasName("foo"), isConstexpr())));
884 EXPECT_TRUE(matches("constexpr int bar();",
885 functionDecl(hasName("bar"), isConstexpr())));
886}
887
888TEST(TemplateArgumentCountIs, Matches) {
889 EXPECT_TRUE(
890 matches("template<typename T> struct C {}; C<int> c;",
891 classTemplateSpecializationDecl(templateArgumentCountIs(1))));
892 EXPECT_TRUE(
893 notMatches("template<typename T> struct C {}; C<int> c;",
894 classTemplateSpecializationDecl(templateArgumentCountIs(2))));
895
896 EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
897 templateSpecializationType(templateArgumentCountIs(1))));
898 EXPECT_TRUE(
899 notMatches("template<typename T> struct C {}; C<int> c;",
900 templateSpecializationType(templateArgumentCountIs(2))));
901}
902
903TEST(IsIntegral, Matches) {
904 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
905 classTemplateSpecializationDecl(
906 hasAnyTemplateArgument(isIntegral()))));
907 EXPECT_TRUE(notMatches("template<typename T> struct C {}; C<int> c;",
908 classTemplateSpecializationDecl(hasAnyTemplateArgument(
909 templateArgument(isIntegral())))));
910}
911
912TEST(EqualsIntegralValue, Matches) {
913 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
914 classTemplateSpecializationDecl(
915 hasAnyTemplateArgument(equalsIntegralValue("42")))));
916 EXPECT_TRUE(matches("template<int T> struct C {}; C<-42> c;",
917 classTemplateSpecializationDecl(
918 hasAnyTemplateArgument(equalsIntegralValue("-42")))));
919 EXPECT_TRUE(matches("template<int T> struct C {}; C<-0042> c;",
920 classTemplateSpecializationDecl(
921 hasAnyTemplateArgument(equalsIntegralValue("-34")))));
922 EXPECT_TRUE(notMatches("template<int T> struct C {}; C<42> c;",
923 classTemplateSpecializationDecl(hasAnyTemplateArgument(
924 equalsIntegralValue("0042")))));
925}
926
927TEST(Matcher, MatchesAccessSpecDecls) {
928 EXPECT_TRUE(matches("class C { public: int i; };", accessSpecDecl()));
929 EXPECT_TRUE(
930 matches("class C { public: int i; };", accessSpecDecl(isPublic())));
931 EXPECT_TRUE(
932 notMatches("class C { public: int i; };", accessSpecDecl(isProtected())));
933 EXPECT_TRUE(
934 notMatches("class C { public: int i; };", accessSpecDecl(isPrivate())));
935
936 EXPECT_TRUE(notMatches("class C { int i; };", accessSpecDecl()));
937}
938
939TEST(Matcher, MatchesFinal) {
940 EXPECT_TRUE(matches("class X final {};", cxxRecordDecl(isFinal())));
941 EXPECT_TRUE(matches("class X { virtual void f() final; };",
942 cxxMethodDecl(isFinal())));
943 EXPECT_TRUE(notMatches("class X {};", cxxRecordDecl(isFinal())));
944 EXPECT_TRUE(
945 notMatches("class X { virtual void f(); };", cxxMethodDecl(isFinal())));
946}
947
948TEST(Matcher, MatchesVirtualMethod) {
949 EXPECT_TRUE(matches("class X { virtual int f(); };",
950 cxxMethodDecl(isVirtual(), hasName("::X::f"))));
951 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isVirtual())));
952}
953
954TEST(Matcher, MatchesVirtualAsWrittenMethod) {
955 EXPECT_TRUE(matches("class A { virtual int f(); };"
956 "class B : public A { int f(); };",
957 cxxMethodDecl(isVirtualAsWritten(), hasName("::A::f"))));
958 EXPECT_TRUE(
959 notMatches("class A { virtual int f(); };"
960 "class B : public A { int f(); };",
961 cxxMethodDecl(isVirtualAsWritten(), hasName("::B::f"))));
962}
963
964TEST(Matcher, MatchesPureMethod) {
965 EXPECT_TRUE(matches("class X { virtual int f() = 0; };",
966 cxxMethodDecl(isPure(), hasName("::X::f"))));
967 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isPure())));
968}
969
970TEST(Matcher, MatchesCopyAssignmentOperator) {
971 EXPECT_TRUE(matches("class X { X &operator=(X); };",
972 cxxMethodDecl(isCopyAssignmentOperator())));
973 EXPECT_TRUE(matches("class X { X &operator=(X &); };",
974 cxxMethodDecl(isCopyAssignmentOperator())));
975 EXPECT_TRUE(matches("class X { X &operator=(const X &); };",
976 cxxMethodDecl(isCopyAssignmentOperator())));
977 EXPECT_TRUE(matches("class X { X &operator=(volatile X &); };",
978 cxxMethodDecl(isCopyAssignmentOperator())));
979 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &); };",
980 cxxMethodDecl(isCopyAssignmentOperator())));
981 EXPECT_TRUE(notMatches("class X { X &operator=(X &&); };",
982 cxxMethodDecl(isCopyAssignmentOperator())));
983}
984
985TEST(Matcher, MatchesMoveAssignmentOperator) {
986 EXPECT_TRUE(notMatches("class X { X &operator=(X); };",
987 cxxMethodDecl(isMoveAssignmentOperator())));
988 EXPECT_TRUE(matches("class X { X &operator=(X &&); };",
989 cxxMethodDecl(isMoveAssignmentOperator())));
990 EXPECT_TRUE(matches("class X { X &operator=(const X &&); };",
991 cxxMethodDecl(isMoveAssignmentOperator())));
992 EXPECT_TRUE(matches("class X { X &operator=(volatile X &&); };",
993 cxxMethodDecl(isMoveAssignmentOperator())));
994 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &&); };",
995 cxxMethodDecl(isMoveAssignmentOperator())));
996 EXPECT_TRUE(notMatches("class X { X &operator=(X &); };",
997 cxxMethodDecl(isMoveAssignmentOperator())));
998}
999
1000TEST(Matcher, MatchesConstMethod) {
1001 EXPECT_TRUE(
1002 matches("struct A { void foo() const; };", cxxMethodDecl(isConst())));
1003 EXPECT_TRUE(
1004 notMatches("struct A { void foo(); };", cxxMethodDecl(isConst())));
1005}
1006
1007TEST(Matcher, MatchesOverridingMethod) {
1008 EXPECT_TRUE(matches("class X { virtual int f(); }; "
1009 "class Y : public X { int f(); };",
1010 cxxMethodDecl(isOverride(), hasName("::Y::f"))));
1011 EXPECT_TRUE(notMatches("class X { virtual int f(); }; "
1012 "class Y : public X { int f(); };",
1013 cxxMethodDecl(isOverride(), hasName("::X::f"))));
1014 EXPECT_TRUE(notMatches("class X { int f(); }; "
1015 "class Y : public X { int f(); };",
1016 cxxMethodDecl(isOverride())));
1017 EXPECT_TRUE(notMatches("class X { int f(); int f(int); }; ",
1018 cxxMethodDecl(isOverride())));
1019 EXPECT_TRUE(
1020 matches("template <typename Base> struct Y : Base { void f() override;};",
1021 cxxMethodDecl(isOverride(), hasName("::Y::f"))));
1022}
1023
1024TEST(Matcher, ConstructorArgument) {
1025 StatementMatcher Constructor = cxxConstructExpr(
1026 hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
1027
1028 EXPECT_TRUE(
1029 matches("class X { public: X(int); }; void x() { int y; X x(y); }",
1030 Constructor));
1031 EXPECT_TRUE(
1032 matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
1033 Constructor));
1034 EXPECT_TRUE(
1035 matches("class X { public: X(int); }; void x() { int y; X x = y; }",
1036 Constructor));
1037 EXPECT_TRUE(
1038 notMatches("class X { public: X(int); }; void x() { int z; X x(z); }",
1039 Constructor));
1040
1041 StatementMatcher WrongIndex = cxxConstructExpr(
1042 hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
1043 EXPECT_TRUE(
1044 notMatches("class X { public: X(int); }; void x() { int y; X x(y); }",
1045 WrongIndex));
1046}
1047
1048TEST(Matcher, ConstructorArgumentCount) {
1049 StatementMatcher Constructor1Arg = cxxConstructExpr(argumentCountIs(1));
1050
1051 EXPECT_TRUE(
1052 matches("class X { public: X(int); }; void x() { X x(0); }",
1053 Constructor1Arg));
1054 EXPECT_TRUE(
1055 matches("class X { public: X(int); }; void x() { X x = X(0); }",
1056 Constructor1Arg));
1057 EXPECT_TRUE(
1058 matches("class X { public: X(int); }; void x() { X x = 0; }",
1059 Constructor1Arg));
1060 EXPECT_TRUE(
1061 notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
1062 Constructor1Arg));
1063}
1064
1065TEST(Matcher, ConstructorListInitialization) {
1066 StatementMatcher ConstructorListInit =
1067 cxxConstructExpr(isListInitialization());
1068
1069 EXPECT_TRUE(
1070 matches("class X { public: X(int); }; void x() { X x{0}; }",
1071 ConstructorListInit));
1072 EXPECT_FALSE(
1073 matches("class X { public: X(int); }; void x() { X x(0); }",
1074 ConstructorListInit));
1075}
1076
1077TEST(ConstructorDeclaration, IsImplicit) {
1078 // This one doesn't match because the constructor is not added by the
1079 // compiler (it is not needed).
1080 EXPECT_TRUE(notMatches("class Foo { };",
1081 cxxConstructorDecl(isImplicit())));
1082 // The compiler added the implicit default constructor.
1083 EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
1084 cxxConstructorDecl(isImplicit())));
1085 EXPECT_TRUE(matches("class Foo { Foo(){} };",
1086 cxxConstructorDecl(unless(isImplicit()))));
1087 // The compiler added an implicit assignment operator.
1088 EXPECT_TRUE(matches("struct A { int x; } a = {0}, b = a; void f() { a = b; }",
1089 cxxMethodDecl(isImplicit(), hasName("operator="))));
1090}
1091
1092TEST(ConstructorDeclaration, IsExplicit) {
1093 EXPECT_TRUE(matches("struct S { explicit S(int); };",
1094 cxxConstructorDecl(isExplicit())));
1095 EXPECT_TRUE(notMatches("struct S { S(int); };",
1096 cxxConstructorDecl(isExplicit())));
1097}
1098
1099TEST(ConstructorDeclaration, Kinds) {
1100 EXPECT_TRUE(matches("struct S { S(); };",
1101 cxxConstructorDecl(isDefaultConstructor())));
1102 EXPECT_TRUE(notMatches("struct S { S(); };",
1103 cxxConstructorDecl(isCopyConstructor())));
1104 EXPECT_TRUE(notMatches("struct S { S(); };",
1105 cxxConstructorDecl(isMoveConstructor())));
1106
1107 EXPECT_TRUE(notMatches("struct S { S(const S&); };",
1108 cxxConstructorDecl(isDefaultConstructor())));
1109 EXPECT_TRUE(matches("struct S { S(const S&); };",
1110 cxxConstructorDecl(isCopyConstructor())));
1111 EXPECT_TRUE(notMatches("struct S { S(const S&); };",
1112 cxxConstructorDecl(isMoveConstructor())));
1113
1114 EXPECT_TRUE(notMatches("struct S { S(S&&); };",
1115 cxxConstructorDecl(isDefaultConstructor())));
1116 EXPECT_TRUE(notMatches("struct S { S(S&&); };",
1117 cxxConstructorDecl(isCopyConstructor())));
1118 EXPECT_TRUE(matches("struct S { S(S&&); };",
1119 cxxConstructorDecl(isMoveConstructor())));
1120}
1121
1122TEST(ConstructorDeclaration, IsUserProvided) {
1123 EXPECT_TRUE(notMatches("struct S { int X = 0; };",
1124 cxxConstructorDecl(isUserProvided())));
1125 EXPECT_TRUE(notMatches("struct S { S() = default; };",
1126 cxxConstructorDecl(isUserProvided())));
1127 EXPECT_TRUE(notMatches("struct S { S() = delete; };",
1128 cxxConstructorDecl(isUserProvided())));
1129 EXPECT_TRUE(
1130 matches("struct S { S(); };", cxxConstructorDecl(isUserProvided())));
1131 EXPECT_TRUE(matches("struct S { S(); }; S::S(){}",
1132 cxxConstructorDecl(isUserProvided())));
1133}
1134
1135TEST(ConstructorDeclaration, IsDelegatingConstructor) {
1136 EXPECT_TRUE(notMatches("struct S { S(); S(int); int X; };",
1137 cxxConstructorDecl(isDelegatingConstructor())));
1138 EXPECT_TRUE(notMatches("struct S { S(){} S(int X) : X(X) {} int X; };",
1139 cxxConstructorDecl(isDelegatingConstructor())));
1140 EXPECT_TRUE(matches(
1141 "struct S { S() : S(0) {} S(int X) : X(X) {} int X; };",
1142 cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(0))));
1143 EXPECT_TRUE(matches(
1144 "struct S { S(); S(int X); int X; }; S::S(int X) : S() {}",
1145 cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(1))));
1146}
1147
1148TEST(StringLiteral, HasSize) {
1149 StatementMatcher Literal = stringLiteral(hasSize(4));
1150 EXPECT_TRUE(matches("const char *s = \"abcd\";", Literal));
1151 // wide string
1152 EXPECT_TRUE(matches("const wchar_t *s = L\"abcd\";", Literal));
1153 // with escaped characters
1154 EXPECT_TRUE(matches("const char *s = \"\x05\x06\x07\x08\";", Literal));
1155 // no matching, too small
1156 EXPECT_TRUE(notMatches("const char *s = \"ab\";", Literal));
1157}
1158
1159TEST(Matcher, HasNameSupportsNamespaces) {
1160 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1161 recordDecl(hasName("a::b::C"))));
1162 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1163 recordDecl(hasName("::a::b::C"))));
1164 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1165 recordDecl(hasName("b::C"))));
1166 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
1167 recordDecl(hasName("C"))));
1168 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1169 recordDecl(hasName("c::b::C"))));
1170 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1171 recordDecl(hasName("a::c::C"))));
1172 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1173 recordDecl(hasName("a::b::A"))));
1174 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1175 recordDecl(hasName("::C"))));
1176 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1177 recordDecl(hasName("::b::C"))));
1178 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1179 recordDecl(hasName("z::a::b::C"))));
1180 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
1181 recordDecl(hasName("a+b::C"))));
1182 EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
1183 recordDecl(hasName("C"))));
1184}
1185
1186TEST(Matcher, HasNameSupportsOuterClasses) {
1187 EXPECT_TRUE(
1188 matches("class A { class B { class C; }; };",
1189 recordDecl(hasName("A::B::C"))));
1190 EXPECT_TRUE(
1191 matches("class A { class B { class C; }; };",
1192 recordDecl(hasName("::A::B::C"))));
1193 EXPECT_TRUE(
1194 matches("class A { class B { class C; }; };",
1195 recordDecl(hasName("B::C"))));
1196 EXPECT_TRUE(
1197 matches("class A { class B { class C; }; };",
1198 recordDecl(hasName("C"))));
1199 EXPECT_TRUE(
1200 notMatches("class A { class B { class C; }; };",
1201 recordDecl(hasName("c::B::C"))));
1202 EXPECT_TRUE(
1203 notMatches("class A { class B { class C; }; };",
1204 recordDecl(hasName("A::c::C"))));
1205 EXPECT_TRUE(
1206 notMatches("class A { class B { class C; }; };",
1207 recordDecl(hasName("A::B::A"))));
1208 EXPECT_TRUE(
1209 notMatches("class A { class B { class C; }; };",
1210 recordDecl(hasName("::C"))));
1211 EXPECT_TRUE(
1212 notMatches("class A { class B { class C; }; };",
1213 recordDecl(hasName("::B::C"))));
1214 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
1215 recordDecl(hasName("z::A::B::C"))));
1216 EXPECT_TRUE(
1217 notMatches("class A { class B { class C; }; };",
1218 recordDecl(hasName("A+B::C"))));
1219}
1220
1221TEST(Matcher, HasNameSupportsInlinedNamespaces) {
1222 std::string code = "namespace a { inline namespace b { class C; } }";
1223 EXPECT_TRUE(matches(code, recordDecl(hasName("a::b::C"))));
1224 EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
1225 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::b::C"))));
1226 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
1227}
1228
1229TEST(Matcher, HasNameSupportsAnonymousNamespaces) {
1230 std::string code = "namespace a { namespace { class C; } }";
1231 EXPECT_TRUE(
1232 matches(code, recordDecl(hasName("a::(anonymous namespace)::C"))));
1233 EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
1234 EXPECT_TRUE(
1235 matches(code, recordDecl(hasName("::a::(anonymous namespace)::C"))));
1236 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
1237}
1238
1239TEST(Matcher, HasNameSupportsAnonymousOuterClasses) {
1240 EXPECT_TRUE(matches("class A { class { class C; } x; };",
1241 recordDecl(hasName("A::(anonymous class)::C"))));
1242 EXPECT_TRUE(matches("class A { class { class C; } x; };",
1243 recordDecl(hasName("::A::(anonymous class)::C"))));
1244 EXPECT_FALSE(matches("class A { class { class C; } x; };",
1245 recordDecl(hasName("::A::C"))));
1246 EXPECT_TRUE(matches("class A { struct { class C; } x; };",
1247 recordDecl(hasName("A::(anonymous struct)::C"))));
1248 EXPECT_TRUE(matches("class A { struct { class C; } x; };",
1249 recordDecl(hasName("::A::(anonymous struct)::C"))));
1250 EXPECT_FALSE(matches("class A { struct { class C; } x; };",
1251 recordDecl(hasName("::A::C"))));
1252}
1253
1254TEST(Matcher, HasNameSupportsFunctionScope) {
1255 std::string code =
1256 "namespace a { void F(int a) { struct S { int m; }; int i; } }";
1257 EXPECT_TRUE(matches(code, varDecl(hasName("i"))));
1258 EXPECT_FALSE(matches(code, varDecl(hasName("F()::i"))));
1259
1260 EXPECT_TRUE(matches(code, fieldDecl(hasName("m"))));
1261 EXPECT_TRUE(matches(code, fieldDecl(hasName("S::m"))));
1262 EXPECT_TRUE(matches(code, fieldDecl(hasName("F(int)::S::m"))));
1263 EXPECT_TRUE(matches(code, fieldDecl(hasName("a::F(int)::S::m"))));
1264 EXPECT_TRUE(matches(code, fieldDecl(hasName("::a::F(int)::S::m"))));
1265}
1266
1267TEST(Matcher, HasAnyName) {
1268 const std::string Code = "namespace a { namespace b { class C; } }";
1269
1270 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "a::b::C"))));
1271 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("a::b::C", "XX"))));
1272 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX::C", "a::b::C"))));
1273 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "C"))));
1274
1275 EXPECT_TRUE(notMatches(Code, recordDecl(hasAnyName("::C", "::b::C"))));
1276 EXPECT_TRUE(
1277 matches(Code, recordDecl(hasAnyName("::C", "::b::C", "::a::b::C"))));
1278
1279 std::vector<StringRef> Names = {"::C", "::b::C", "::a::b::C"};
1280 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName(Names))));
1281}
1282
1283TEST(Matcher, IsDefinition) {
1284 DeclarationMatcher DefinitionOfClassA =
1285 recordDecl(hasName("A"), isDefinition());
1286 EXPECT_TRUE(matches("class A {};", DefinitionOfClassA));
1287 EXPECT_TRUE(notMatches("class A;", DefinitionOfClassA));
1288
1289 DeclarationMatcher DefinitionOfVariableA =
1290 varDecl(hasName("a"), isDefinition());
1291 EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));
1292 EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));
1293
1294 DeclarationMatcher DefinitionOfMethodA =
1295 cxxMethodDecl(hasName("a"), isDefinition());
1296 EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));
1297 EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));
1298}
1299
1300TEST(Matcher, HandlesNullQualTypes) {
1301 // FIXME: Add a Type matcher so we can replace uses of this
1302 // variable with Type(True())
1303 const TypeMatcher AnyType = anything();
1304
1305 // We don't really care whether this matcher succeeds; we're testing that
1306 // it completes without crashing.
1307 EXPECT_TRUE(matches(
1308 "struct A { };"
1309 "template <typename T>"
1310 "void f(T t) {"
1311 " T local_t(t /* this becomes a null QualType in the AST */);"
1312 "}"
1313 "void g() {"
1314 " f(0);"
1315 "}",
1316 expr(hasType(TypeMatcher(
1317 anyOf(
1318 TypeMatcher(hasDeclaration(anything())),
1319 pointsTo(AnyType),
1320 references(AnyType)
1321 // Other QualType matchers should go here.
1322 ))))));
1323}
1324
1325
1326TEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) {
1327 EXPECT_TRUE(matches("void f() { }",
1328 compoundStmt(statementCountIs(0))));
1329 EXPECT_TRUE(notMatches("void f() {}",
1330 compoundStmt(statementCountIs(1))));
1331}
1332
1333TEST(StatementCountIs, AppearsToMatchOnlyOneCount) {
1334 EXPECT_TRUE(matches("void f() { 1; }",
1335 compoundStmt(statementCountIs(1))));
1336 EXPECT_TRUE(notMatches("void f() { 1; }",
1337 compoundStmt(statementCountIs(0))));
1338 EXPECT_TRUE(notMatches("void f() { 1; }",
1339 compoundStmt(statementCountIs(2))));
1340}
1341
1342TEST(StatementCountIs, WorksWithMultipleStatements) {
1343 EXPECT_TRUE(matches("void f() { 1; 2; 3; }",
1344 compoundStmt(statementCountIs(3))));
1345}
1346
1347TEST(StatementCountIs, WorksWithNestedCompoundStatements) {
1348 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1349 compoundStmt(statementCountIs(1))));
1350 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1351 compoundStmt(statementCountIs(2))));
1352 EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
1353 compoundStmt(statementCountIs(3))));
1354 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
1355 compoundStmt(statementCountIs(4))));
1356}
1357
1358TEST(Member, WorksInSimplestCase) {
1359 EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
1360 memberExpr(member(hasName("first")))));
1361}
1362
1363TEST(Member, DoesNotMatchTheBaseExpression) {
1364 // Don't pick out the wrong part of the member expression, this should
1365 // be checking the member (name) only.
1366 EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
1367 memberExpr(member(hasName("first")))));
1368}
1369
1370TEST(Member, MatchesInMemberFunctionCall) {
1371 EXPECT_TRUE(matches("void f() {"
1372 " struct { void first() {}; } s;"
1373 " s.first();"
1374 "};",
1375 memberExpr(member(hasName("first")))));
1376}
1377
1378TEST(Member, MatchesMember) {
1379 EXPECT_TRUE(matches(
1380 "struct A { int i; }; void f() { A a; a.i = 2; }",
1381 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
1382 EXPECT_TRUE(notMatches(
1383 "struct A { float f; }; void f() { A a; a.f = 2.0f; }",
1384 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
1385}
1386
Aaron Ballman5c574342016-07-06 18:25:16 +00001387TEST(Member, BitFields) {
1388 EXPECT_TRUE(matches("class C { int a : 2; int b; };",
1389 fieldDecl(isBitField(), hasName("a"))));
1390 EXPECT_TRUE(notMatches("class C { int a : 2; int b; };",
1391 fieldDecl(isBitField(), hasName("b"))));
1392 EXPECT_TRUE(matches("class C { int a : 2; int b : 4; };",
1393 fieldDecl(isBitField(), hasBitWidth(2), hasName("a"))));
1394}
Piotr Padlewskic6e05022016-05-17 19:22:57 +00001395
1396TEST(Member, UnderstandsAccess) {
1397 EXPECT_TRUE(matches(
1398 "struct A { int i; };", fieldDecl(isPublic(), hasName("i"))));
1399 EXPECT_TRUE(notMatches(
1400 "struct A { int i; };", fieldDecl(isProtected(), hasName("i"))));
1401 EXPECT_TRUE(notMatches(
1402 "struct A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
1403
1404 EXPECT_TRUE(notMatches(
1405 "class A { int i; };", fieldDecl(isPublic(), hasName("i"))));
1406 EXPECT_TRUE(notMatches(
1407 "class A { int i; };", fieldDecl(isProtected(), hasName("i"))));
1408 EXPECT_TRUE(matches(
1409 "class A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
1410
1411 EXPECT_TRUE(notMatches(
1412 "class A { protected: int i; };", fieldDecl(isPublic(), hasName("i"))));
1413 EXPECT_TRUE(matches("class A { protected: int i; };",
1414 fieldDecl(isProtected(), hasName("i"))));
1415 EXPECT_TRUE(notMatches(
1416 "class A { protected: int i; };", fieldDecl(isPrivate(), hasName("i"))));
1417
1418 // Non-member decls have the AccessSpecifier AS_none and thus aren't matched.
1419 EXPECT_TRUE(notMatches("int i;", varDecl(isPublic(), hasName("i"))));
1420 EXPECT_TRUE(notMatches("int i;", varDecl(isProtected(), hasName("i"))));
1421 EXPECT_TRUE(notMatches("int i;", varDecl(isPrivate(), hasName("i"))));
1422}
1423
1424TEST(hasDynamicExceptionSpec, MatchesDynamicExceptionSpecifications) {
1425 EXPECT_TRUE(notMatches("void f();", functionDecl(hasDynamicExceptionSpec())));
1426 EXPECT_TRUE(notMatches("void g() noexcept;",
1427 functionDecl(hasDynamicExceptionSpec())));
1428 EXPECT_TRUE(notMatches("void h() noexcept(true);",
1429 functionDecl(hasDynamicExceptionSpec())));
1430 EXPECT_TRUE(notMatches("void i() noexcept(false);",
1431 functionDecl(hasDynamicExceptionSpec())));
1432 EXPECT_TRUE(
1433 matches("void j() throw();", functionDecl(hasDynamicExceptionSpec())));
1434 EXPECT_TRUE(
1435 matches("void k() throw(int);", functionDecl(hasDynamicExceptionSpec())));
1436 EXPECT_TRUE(
1437 matches("void l() throw(...);", functionDecl(hasDynamicExceptionSpec())));
Aaron Ballman230ad972016-06-07 17:34:45 +00001438
1439 EXPECT_TRUE(notMatches("void f();", functionProtoType(hasDynamicExceptionSpec())));
1440 EXPECT_TRUE(notMatches("void g() noexcept;",
1441 functionProtoType(hasDynamicExceptionSpec())));
1442 EXPECT_TRUE(notMatches("void h() noexcept(true);",
1443 functionProtoType(hasDynamicExceptionSpec())));
1444 EXPECT_TRUE(notMatches("void i() noexcept(false);",
1445 functionProtoType(hasDynamicExceptionSpec())));
1446 EXPECT_TRUE(
1447 matches("void j() throw();", functionProtoType(hasDynamicExceptionSpec())));
1448 EXPECT_TRUE(
1449 matches("void k() throw(int);", functionProtoType(hasDynamicExceptionSpec())));
1450 EXPECT_TRUE(
1451 matches("void l() throw(...);", functionProtoType(hasDynamicExceptionSpec())));
Piotr Padlewskic6e05022016-05-17 19:22:57 +00001452}
1453
1454TEST(HasObjectExpression, DoesNotMatchMember) {
1455 EXPECT_TRUE(notMatches(
1456 "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
1457 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
1458}
1459
1460TEST(HasObjectExpression, MatchesBaseOfVariable) {
1461 EXPECT_TRUE(matches(
1462 "struct X { int m; }; void f(X x) { x.m; }",
1463 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
1464 EXPECT_TRUE(matches(
1465 "struct X { int m; }; void f(X* x) { x->m; }",
1466 memberExpr(hasObjectExpression(
1467 hasType(pointsTo(recordDecl(hasName("X"))))))));
1468}
1469
1470TEST(HasObjectExpression,
1471 MatchesObjectExpressionOfImplicitlyFormedMemberExpression) {
1472 EXPECT_TRUE(matches(
1473 "class X {}; struct S { X m; void f() { this->m; } };",
1474 memberExpr(hasObjectExpression(
1475 hasType(pointsTo(recordDecl(hasName("S"))))))));
1476 EXPECT_TRUE(matches(
1477 "class X {}; struct S { X m; void f() { m; } };",
1478 memberExpr(hasObjectExpression(
1479 hasType(pointsTo(recordDecl(hasName("S"))))))));
1480}
1481
1482TEST(Field, DoesNotMatchNonFieldMembers) {
1483 EXPECT_TRUE(notMatches("class X { void m(); };", fieldDecl(hasName("m"))));
1484 EXPECT_TRUE(notMatches("class X { class m {}; };", fieldDecl(hasName("m"))));
1485 EXPECT_TRUE(notMatches("class X { enum { m }; };", fieldDecl(hasName("m"))));
1486 EXPECT_TRUE(notMatches("class X { enum m {}; };", fieldDecl(hasName("m"))));
1487}
1488
1489TEST(Field, MatchesField) {
1490 EXPECT_TRUE(matches("class X { int m; };", fieldDecl(hasName("m"))));
1491}
1492
1493TEST(IsVolatileQualified, QualifiersMatch) {
1494 EXPECT_TRUE(matches("volatile int i = 42;",
1495 varDecl(hasType(isVolatileQualified()))));
1496 EXPECT_TRUE(notMatches("volatile int *i;",
1497 varDecl(hasType(isVolatileQualified()))));
1498 EXPECT_TRUE(matches("typedef volatile int v_int; v_int i = 42;",
1499 varDecl(hasType(isVolatileQualified()))));
1500}
1501
1502TEST(IsConstQualified, MatchesConstInt) {
1503 EXPECT_TRUE(matches("const int i = 42;",
1504 varDecl(hasType(isConstQualified()))));
1505}
1506
1507TEST(IsConstQualified, MatchesConstPointer) {
1508 EXPECT_TRUE(matches("int i = 42; int* const p(&i);",
1509 varDecl(hasType(isConstQualified()))));
1510}
1511
1512TEST(IsConstQualified, MatchesThroughTypedef) {
1513 EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
1514 varDecl(hasType(isConstQualified()))));
1515 EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p(0);",
1516 varDecl(hasType(isConstQualified()))));
1517}
1518
1519TEST(IsConstQualified, DoesNotMatchInappropriately) {
1520 EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
1521 varDecl(hasType(isConstQualified()))));
1522 EXPECT_TRUE(notMatches("int const* p;",
1523 varDecl(hasType(isConstQualified()))));
1524}
1525
1526TEST(DeclCount, DeclCountIsCorrect) {
1527 EXPECT_TRUE(matches("void f() {int i,j;}",
1528 declStmt(declCountIs(2))));
1529 EXPECT_TRUE(notMatches("void f() {int i,j; int k;}",
1530 declStmt(declCountIs(3))));
1531 EXPECT_TRUE(notMatches("void f() {int i,j, k, l;}",
1532 declStmt(declCountIs(3))));
1533}
1534
1535
1536TEST(EachOf, TriggersForEachMatch) {
1537 EXPECT_TRUE(matchAndVerifyResultTrue(
1538 "class A { int a; int b; };",
1539 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
1540 has(fieldDecl(hasName("b")).bind("v")))),
1541 llvm::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 2)));
1542}
1543
1544TEST(EachOf, BehavesLikeAnyOfUnlessBothMatch) {
1545 EXPECT_TRUE(matchAndVerifyResultTrue(
1546 "class A { int a; int c; };",
1547 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
1548 has(fieldDecl(hasName("b")).bind("v")))),
1549 llvm::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 1)));
1550 EXPECT_TRUE(matchAndVerifyResultTrue(
1551 "class A { int c; int b; };",
1552 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
1553 has(fieldDecl(hasName("b")).bind("v")))),
1554 llvm::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 1)));
1555 EXPECT_TRUE(notMatches(
1556 "class A { int c; int d; };",
1557 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
1558 has(fieldDecl(hasName("b")).bind("v"))))));
1559}
1560
1561TEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) {
1562 // Make sure that we can both match the class by name (::X) and by the type
1563 // the template was instantiated with (via a field).
1564
1565 EXPECT_TRUE(matches(
1566 "template <typename T> class X {}; class A {}; X<A> x;",
1567 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
1568
1569 EXPECT_TRUE(matches(
1570 "template <typename T> class X { T t; }; class A {}; X<A> x;",
1571 cxxRecordDecl(isTemplateInstantiation(), hasDescendant(
1572 fieldDecl(hasType(recordDecl(hasName("A"))))))));
1573}
1574
1575TEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) {
1576 EXPECT_TRUE(matches(
1577 "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
1578 functionDecl(hasParameter(0, hasType(recordDecl(hasName("A")))),
1579 isTemplateInstantiation())));
1580}
1581
1582TEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) {
1583 EXPECT_TRUE(matches(
1584 "template <typename T> class X { T t; }; class A {};"
1585 "template class X<A>;",
1586 cxxRecordDecl(isTemplateInstantiation(), hasDescendant(
1587 fieldDecl(hasType(recordDecl(hasName("A"))))))));
1588}
1589
1590TEST(IsTemplateInstantiation,
1591 MatchesInstantiationOfPartiallySpecializedClassTemplate) {
1592 EXPECT_TRUE(matches(
1593 "template <typename T> class X {};"
1594 "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
1595 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
1596}
1597
1598TEST(IsTemplateInstantiation,
1599 MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
1600 EXPECT_TRUE(matches(
1601 "class A {};"
1602 "class X {"
1603 " template <typename U> class Y { U u; };"
1604 " Y<A> y;"
1605 "};",
1606 cxxRecordDecl(hasName("::X::Y"), isTemplateInstantiation())));
1607}
1608
1609TEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) {
1610 // FIXME: Figure out whether this makes sense. It doesn't affect the
1611 // normal use case as long as the uppermost instantiation always is marked
1612 // as template instantiation, but it might be confusing as a predicate.
1613 EXPECT_TRUE(matches(
1614 "class A {};"
1615 "template <typename T> class X {"
1616 " template <typename U> class Y { U u; };"
1617 " Y<T> y;"
1618 "}; X<A> x;",
1619 cxxRecordDecl(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
1620}
1621
1622TEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) {
1623 EXPECT_TRUE(notMatches(
1624 "template <typename T> class X {}; class A {};"
1625 "template <> class X<A> {}; X<A> x;",
1626 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
1627}
1628
1629TEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) {
1630 EXPECT_TRUE(notMatches(
1631 "class A {}; class Y { A a; };",
1632 cxxRecordDecl(isTemplateInstantiation())));
1633}
1634
1635TEST(IsInstantiated, MatchesInstantiation) {
1636 EXPECT_TRUE(
1637 matches("template<typename T> class A { T i; }; class Y { A<int> a; };",
1638 cxxRecordDecl(isInstantiated())));
1639}
1640
1641TEST(IsInstantiated, NotMatchesDefinition) {
1642 EXPECT_TRUE(notMatches("template<typename T> class A { T i; };",
1643 cxxRecordDecl(isInstantiated())));
1644}
1645
1646TEST(IsInTemplateInstantiation, MatchesInstantiationStmt) {
1647 EXPECT_TRUE(matches("template<typename T> struct A { A() { T i; } };"
1648 "class Y { A<int> a; }; Y y;",
1649 declStmt(isInTemplateInstantiation())));
1650}
1651
1652TEST(IsInTemplateInstantiation, NotMatchesDefinitionStmt) {
1653 EXPECT_TRUE(notMatches("template<typename T> struct A { void x() { T i; } };",
1654 declStmt(isInTemplateInstantiation())));
1655}
1656
1657TEST(IsInstantiated, MatchesFunctionInstantiation) {
1658 EXPECT_TRUE(
1659 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
1660 functionDecl(isInstantiated())));
1661}
1662
1663TEST(IsInstantiated, NotMatchesFunctionDefinition) {
1664 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
1665 varDecl(isInstantiated())));
1666}
1667
1668TEST(IsInTemplateInstantiation, MatchesFunctionInstantiationStmt) {
1669 EXPECT_TRUE(
1670 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
1671 declStmt(isInTemplateInstantiation())));
1672}
1673
1674TEST(IsInTemplateInstantiation, NotMatchesFunctionDefinitionStmt) {
1675 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
1676 declStmt(isInTemplateInstantiation())));
1677}
1678
1679TEST(IsInTemplateInstantiation, Sharing) {
1680 auto Matcher = binaryOperator(unless(isInTemplateInstantiation()));
1681 // FIXME: Node sharing is an implementation detail, exposing it is ugly
1682 // and makes the matcher behave in non-obvious ways.
1683 EXPECT_TRUE(notMatches(
1684 "int j; template<typename T> void A(T t) { j += 42; } void x() { A(0); }",
1685 Matcher));
1686 EXPECT_TRUE(matches(
1687 "int j; template<typename T> void A(T t) { j += t; } void x() { A(0); }",
1688 Matcher));
1689}
1690
1691TEST(IsExplicitTemplateSpecialization,
1692 DoesNotMatchPrimaryTemplate) {
1693 EXPECT_TRUE(notMatches(
1694 "template <typename T> class X {};",
1695 cxxRecordDecl(isExplicitTemplateSpecialization())));
1696 EXPECT_TRUE(notMatches(
1697 "template <typename T> void f(T t);",
1698 functionDecl(isExplicitTemplateSpecialization())));
1699}
1700
1701TEST(IsExplicitTemplateSpecialization,
1702 DoesNotMatchExplicitTemplateInstantiations) {
1703 EXPECT_TRUE(notMatches(
1704 "template <typename T> class X {};"
1705 "template class X<int>; extern template class X<long>;",
1706 cxxRecordDecl(isExplicitTemplateSpecialization())));
1707 EXPECT_TRUE(notMatches(
1708 "template <typename T> void f(T t) {}"
1709 "template void f(int t); extern template void f(long t);",
1710 functionDecl(isExplicitTemplateSpecialization())));
1711}
1712
1713TEST(IsExplicitTemplateSpecialization,
1714 DoesNotMatchImplicitTemplateInstantiations) {
1715 EXPECT_TRUE(notMatches(
1716 "template <typename T> class X {}; X<int> x;",
1717 cxxRecordDecl(isExplicitTemplateSpecialization())));
1718 EXPECT_TRUE(notMatches(
1719 "template <typename T> void f(T t); void g() { f(10); }",
1720 functionDecl(isExplicitTemplateSpecialization())));
1721}
1722
1723TEST(IsExplicitTemplateSpecialization,
1724 MatchesExplicitTemplateSpecializations) {
1725 EXPECT_TRUE(matches(
1726 "template <typename T> class X {};"
1727 "template<> class X<int> {};",
1728 cxxRecordDecl(isExplicitTemplateSpecialization())));
1729 EXPECT_TRUE(matches(
1730 "template <typename T> void f(T t) {}"
1731 "template<> void f(int t) {}",
1732 functionDecl(isExplicitTemplateSpecialization())));
1733}
1734
1735TEST(TypeMatching, MatchesBool) {
1736 EXPECT_TRUE(matches("struct S { bool func(); };",
1737 cxxMethodDecl(returns(booleanType()))));
1738 EXPECT_TRUE(notMatches("struct S { void func(); };",
1739 cxxMethodDecl(returns(booleanType()))));
1740}
1741
1742TEST(TypeMatching, MatchesVoid) {
1743 EXPECT_TRUE(matches("struct S { void func(); };",
1744 cxxMethodDecl(returns(voidType()))));
1745}
1746
1747TEST(TypeMatching, MatchesRealFloats) {
1748 EXPECT_TRUE(matches("struct S { float func(); };",
1749 cxxMethodDecl(returns(realFloatingPointType()))));
1750 EXPECT_TRUE(notMatches("struct S { int func(); };",
1751 cxxMethodDecl(returns(realFloatingPointType()))));
1752 EXPECT_TRUE(matches("struct S { long double func(); };",
1753 cxxMethodDecl(returns(realFloatingPointType()))));
1754}
1755
1756TEST(TypeMatching, MatchesArrayTypes) {
1757 EXPECT_TRUE(matches("int a[] = {2,3};", arrayType()));
1758 EXPECT_TRUE(matches("int a[42];", arrayType()));
1759 EXPECT_TRUE(matches("void f(int b) { int a[b]; }", arrayType()));
1760
1761 EXPECT_TRUE(notMatches("struct A {}; A a[7];",
1762 arrayType(hasElementType(builtinType()))));
1763
1764 EXPECT_TRUE(matches(
1765 "int const a[] = { 2, 3 };",
1766 qualType(arrayType(hasElementType(builtinType())))));
1767 EXPECT_TRUE(matches(
1768 "int const a[] = { 2, 3 };",
1769 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
1770 EXPECT_TRUE(matches(
1771 "typedef const int T; T x[] = { 1, 2 };",
1772 qualType(isConstQualified(), arrayType())));
1773
1774 EXPECT_TRUE(notMatches(
1775 "int a[] = { 2, 3 };",
1776 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
1777 EXPECT_TRUE(notMatches(
1778 "int a[] = { 2, 3 };",
1779 qualType(arrayType(hasElementType(isConstQualified(), builtinType())))));
1780 EXPECT_TRUE(notMatches(
1781 "int const a[] = { 2, 3 };",
1782 qualType(arrayType(hasElementType(builtinType())),
1783 unless(isConstQualified()))));
1784
1785 EXPECT_TRUE(matches("int a[2];",
1786 constantArrayType(hasElementType(builtinType()))));
1787 EXPECT_TRUE(matches("const int a = 0;", qualType(isInteger())));
1788}
1789
1790TEST(TypeMatching, DecayedType) {
1791 EXPECT_TRUE(matches("void f(int i[]);", valueDecl(hasType(decayedType(hasDecayedType(pointerType()))))));
1792 EXPECT_TRUE(notMatches("int i[7];", decayedType()));
1793}
1794
1795TEST(TypeMatching, MatchesComplexTypes) {
1796 EXPECT_TRUE(matches("_Complex float f;", complexType()));
1797 EXPECT_TRUE(matches(
1798 "_Complex float f;",
1799 complexType(hasElementType(builtinType()))));
1800 EXPECT_TRUE(notMatches(
1801 "_Complex float f;",
1802 complexType(hasElementType(isInteger()))));
1803}
1804
1805TEST(NS, Anonymous) {
1806 EXPECT_TRUE(notMatches("namespace N {}", namespaceDecl(isAnonymous())));
1807 EXPECT_TRUE(matches("namespace {}", namespaceDecl(isAnonymous())));
1808}
1809
1810TEST(EqualsBoundNodeMatcher, QualType) {
1811 EXPECT_TRUE(matches(
1812 "int i = 1;", varDecl(hasType(qualType().bind("type")),
1813 hasInitializer(ignoringParenImpCasts(
1814 hasType(qualType(equalsBoundNode("type"))))))));
1815 EXPECT_TRUE(notMatches("int i = 1.f;",
1816 varDecl(hasType(qualType().bind("type")),
1817 hasInitializer(ignoringParenImpCasts(hasType(
1818 qualType(equalsBoundNode("type"))))))));
1819}
1820
1821TEST(EqualsBoundNodeMatcher, NonMatchingTypes) {
1822 EXPECT_TRUE(notMatches(
1823 "int i = 1;", varDecl(namedDecl(hasName("i")).bind("name"),
1824 hasInitializer(ignoringParenImpCasts(
1825 hasType(qualType(equalsBoundNode("type"))))))));
1826}
1827
1828TEST(EqualsBoundNodeMatcher, Stmt) {
1829 EXPECT_TRUE(
1830 matches("void f() { if(true) {} }",
1831 stmt(allOf(ifStmt().bind("if"),
1832 hasParent(stmt(has(stmt(equalsBoundNode("if")))))))));
1833
1834 EXPECT_TRUE(notMatches(
1835 "void f() { if(true) { if (true) {} } }",
1836 stmt(allOf(ifStmt().bind("if"), has(stmt(equalsBoundNode("if")))))));
1837}
1838
1839TEST(EqualsBoundNodeMatcher, Decl) {
1840 EXPECT_TRUE(matches(
1841 "class X { class Y {}; };",
1842 decl(allOf(recordDecl(hasName("::X::Y")).bind("record"),
1843 hasParent(decl(has(decl(equalsBoundNode("record")))))))));
1844
1845 EXPECT_TRUE(notMatches("class X { class Y {}; };",
1846 decl(allOf(recordDecl(hasName("::X")).bind("record"),
1847 has(decl(equalsBoundNode("record")))))));
1848}
1849
1850TEST(EqualsBoundNodeMatcher, Type) {
1851 EXPECT_TRUE(matches(
1852 "class X { int a; int b; };",
1853 recordDecl(
1854 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
1855 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
1856
1857 EXPECT_TRUE(notMatches(
1858 "class X { int a; double b; };",
1859 recordDecl(
1860 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
1861 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
1862}
1863
1864TEST(EqualsBoundNodeMatcher, UsingForEachDescendant) {
1865 EXPECT_TRUE(matchAndVerifyResultTrue(
1866 "int f() {"
1867 " if (1) {"
1868 " int i = 9;"
1869 " }"
1870 " int j = 10;"
1871 " {"
1872 " float k = 9.0;"
1873 " }"
1874 " return 0;"
1875 "}",
1876 // Look for variable declarations within functions whose type is the same
1877 // as the function return type.
1878 functionDecl(returns(qualType().bind("type")),
1879 forEachDescendant(varDecl(hasType(
1880 qualType(equalsBoundNode("type")))).bind("decl"))),
1881 // Only i and j should match, not k.
1882 llvm::make_unique<VerifyIdIsBoundTo<VarDecl>>("decl", 2)));
1883}
1884
1885TEST(EqualsBoundNodeMatcher, FiltersMatchedCombinations) {
1886 EXPECT_TRUE(matchAndVerifyResultTrue(
1887 "void f() {"
1888 " int x;"
1889 " double d;"
1890 " x = d + x - d + x;"
1891 "}",
1892 functionDecl(
1893 hasName("f"), forEachDescendant(varDecl().bind("d")),
1894 forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d")))))),
1895 llvm::make_unique<VerifyIdIsBoundTo<VarDecl>>("d", 5)));
1896}
1897
1898TEST(EqualsBoundNodeMatcher, UnlessDescendantsOfAncestorsMatch) {
1899 EXPECT_TRUE(matchAndVerifyResultTrue(
1900 "struct StringRef { int size() const; const char* data() const; };"
1901 "void f(StringRef v) {"
1902 " v.data();"
1903 "}",
1904 cxxMemberCallExpr(
1905 callee(cxxMethodDecl(hasName("data"))),
1906 on(declRefExpr(to(
1907 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
1908 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
1909 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
1910 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
1911 .bind("data"),
1912 llvm::make_unique<VerifyIdIsBoundTo<Expr>>("data", 1)));
1913
1914 EXPECT_FALSE(matches(
1915 "struct StringRef { int size() const; const char* data() const; };"
1916 "void f(StringRef v) {"
1917 " v.data();"
1918 " v.size();"
1919 "}",
1920 cxxMemberCallExpr(
1921 callee(cxxMethodDecl(hasName("data"))),
1922 on(declRefExpr(to(
1923 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
1924 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
1925 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
1926 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
1927 .bind("data")));
1928}
1929
1930TEST(NullPointerConstants, Basic) {
1931 EXPECT_TRUE(matches("#define NULL ((void *)0)\n"
1932 "void *v1 = NULL;", expr(nullPointerConstant())));
1933 EXPECT_TRUE(matches("void *v2 = nullptr;", expr(nullPointerConstant())));
1934 EXPECT_TRUE(matches("void *v3 = __null;", expr(nullPointerConstant())));
1935 EXPECT_TRUE(matches("char *cp = (char *)0;", expr(nullPointerConstant())));
1936 EXPECT_TRUE(matches("int *ip = 0;", expr(nullPointerConstant())));
1937 EXPECT_TRUE(notMatches("int i = 0;", expr(nullPointerConstant())));
1938}
1939
Aaron Ballmana086b9f2016-08-17 13:10:42 +00001940TEST(HasExternalFormalLinkage, Basic) {
1941 EXPECT_TRUE(matches("int a = 0;", namedDecl(hasExternalFormalLinkage())));
1942 EXPECT_TRUE(
1943 notMatches("static int a = 0;", namedDecl(hasExternalFormalLinkage())));
1944 EXPECT_TRUE(notMatches("static void f(void) { int a = 0; }",
1945 namedDecl(hasExternalFormalLinkage())));
1946 EXPECT_TRUE(matches("void f(void) { int a = 0; }",
1947 namedDecl(hasExternalFormalLinkage())));
1948
1949 // Despite having internal semantic linkage, the anonymous namespace member
1950 // has external linkage because the member has a unique name in all
1951 // translation units.
1952 EXPECT_TRUE(matches("namespace { int a = 0; }",
1953 namedDecl(hasExternalFormalLinkage())));
1954}
1955
Piotr Padlewskic6e05022016-05-17 19:22:57 +00001956} // namespace ast_matchers
1957} // namespace clang