1 // unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp - AST matcher unit tests//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "ASTMatchersTest.h"
10 #include "clang/AST/PrettyPrinter.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
12 #include "clang/ASTMatchers/ASTMatchers.h"
13 #include "clang/Tooling/Tooling.h"
14 #include "llvm/TargetParser/Host.h"
15 #include "llvm/TargetParser/Triple.h"
16 #include "gtest/gtest.h"
19 namespace ast_matchers
{
21 TEST_P(ASTMatchersTest
, IsExpandedFromMacro_MatchesInFile
) {
22 StringRef input
= R
"cc(
23 #define MY_MACRO(a) (4 + (a))
24 void Test() { MY_MACRO(4); }
26 EXPECT_TRUE(matches(input
, binaryOperator(isExpandedFromMacro("MY_MACRO"))));
29 TEST_P(ASTMatchersTest
, IsExpandedFromMacro_MatchesNested
) {
30 StringRef input
= R
"cc(
31 #define MY_MACRO(a) (4 + (a))
32 #define WRAPPER(a) MY_MACRO(a)
33 void Test() { WRAPPER(4); }
35 EXPECT_TRUE(matches(input
, binaryOperator(isExpandedFromMacro("MY_MACRO"))));
38 TEST_P(ASTMatchersTest
, IsExpandedFromMacro_MatchesIntermediate
) {
39 StringRef input
= R
"cc(
40 #define IMPL(a) (4 + (a))
41 #define MY_MACRO(a) IMPL(a)
42 #define WRAPPER(a) MY_MACRO(a)
43 void Test() { WRAPPER(4); }
45 EXPECT_TRUE(matches(input
, binaryOperator(isExpandedFromMacro("MY_MACRO"))));
48 TEST_P(ASTMatchersTest
, IsExpandedFromMacro_MatchesTransitive
) {
49 StringRef input
= R
"cc(
50 #define MY_MACRO(a) (4 + (a))
51 #define WRAPPER(a) MY_MACRO(a)
52 void Test() { WRAPPER(4); }
54 EXPECT_TRUE(matches(input
, binaryOperator(isExpandedFromMacro("WRAPPER"))));
57 TEST_P(ASTMatchersTest
, IsExpandedFromMacro_MatchesArgument
) {
58 StringRef input
= R
"cc(
59 #define MY_MACRO(a) (4 + (a))
65 EXPECT_TRUE(matches(input
, declRefExpr(isExpandedFromMacro("MY_MACRO"))));
68 // Like IsExpandedFromMacro_MatchesArgument, but the argument is itself a
70 TEST_P(ASTMatchersTest
, IsExpandedFromMacro_MatchesArgumentMacroExpansion
) {
71 StringRef input
= R
"cc(
72 #define MY_MACRO(a) (4 + (a))
73 #define IDENTITY(a) (a)
75 IDENTITY(MY_MACRO(2));
78 EXPECT_TRUE(matches(input
, binaryOperator(isExpandedFromMacro("IDENTITY"))));
81 TEST_P(ASTMatchersTest
, IsExpandedFromMacro_MatchesWhenInArgument
) {
82 StringRef input
= R
"cc(
83 #define MY_MACRO(a) (4 + (a))
84 #define IDENTITY(a) (a)
86 IDENTITY(MY_MACRO(2));
89 EXPECT_TRUE(matches(input
, binaryOperator(isExpandedFromMacro("MY_MACRO"))));
92 TEST_P(ASTMatchersTest
, IsExpandedFromMacro_MatchesObjectMacro
) {
93 StringRef input
= R
"cc(
99 EXPECT_TRUE(matches(input
, binaryOperator(isExpandedFromMacro("PLUS"))));
102 TEST(IsExpandedFromMacro
, MatchesFromCommandLine
) {
103 StringRef input
= R
"cc(
104 void Test() { FOUR_PLUS_FOUR; }
106 EXPECT_TRUE(matchesConditionally(
107 input
, binaryOperator(isExpandedFromMacro("FOUR_PLUS_FOUR")), true,
108 {"-std=c++11", "-DFOUR_PLUS_FOUR=4+4"}));
111 TEST_P(ASTMatchersTest
, IsExpandedFromMacro_NotMatchesBeginOnly
) {
112 StringRef input
= R
"cc(
114 void Test() { ONE_PLUS 4; }
117 notMatches(input
, binaryOperator(isExpandedFromMacro("ONE_PLUS"))));
120 TEST_P(ASTMatchersTest
, IsExpandedFromMacro_NotMatchesEndOnly
) {
121 StringRef input
= R
"cc(
123 void Test() { 4 PLUS_ONE; }
126 notMatches(input
, binaryOperator(isExpandedFromMacro("PLUS_ONE"))));
129 TEST_P(ASTMatchersTest
, IsExpandedFromMacro_NotMatchesDifferentMacro
) {
130 StringRef input
= R
"cc(
131 #define MY_MACRO(a) (4 + (a))
132 void Test() { MY_MACRO(4); }
134 EXPECT_TRUE(notMatches(input
, binaryOperator(isExpandedFromMacro("OTHER"))));
137 TEST_P(ASTMatchersTest
, IsExpandedFromMacro_NotMatchesDifferentInstances
) {
138 StringRef input
= R
"cc(
140 void Test() { FOUR + FOUR; }
142 EXPECT_TRUE(notMatches(input
, binaryOperator(isExpandedFromMacro("FOUR"))));
145 TEST(IsExpandedFromMacro
, IsExpandedFromMacro_MatchesDecls
) {
146 StringRef input
= R
"cc(
147 #define MY_MACRO(a) int i = a;
148 void Test() { MY_MACRO(4); }
150 EXPECT_TRUE(matches(input
, varDecl(isExpandedFromMacro("MY_MACRO"))));
153 TEST(IsExpandedFromMacro
, IsExpandedFromMacro_MatchesTypelocs
) {
154 StringRef input
= R
"cc(
156 void Test() { MY_TYPE i = 4; }
158 EXPECT_TRUE(matches(input
, typeLoc(isExpandedFromMacro("MY_TYPE"))));
161 TEST_P(ASTMatchersTest
, AllOf
) {
162 const char Program
[] = "struct T { };"
163 "int f(int, struct T*, int, int);"
164 "void g(int x) { struct T t; f(x, &t, 3, 4); }";
166 Program
, callExpr(allOf(callee(functionDecl(hasName("f"))),
167 hasArgument(0, declRefExpr(to(varDecl())))))));
171 allOf(callee(functionDecl(hasName("f"))),
172 hasArgument(0, declRefExpr(to(varDecl()))),
173 hasArgument(1, hasType(pointsTo(recordDecl(hasName("T")))))))));
175 Program
, callExpr(allOf(
176 callee(functionDecl(hasName("f"))),
177 hasArgument(0, declRefExpr(to(varDecl()))),
178 hasArgument(1, hasType(pointsTo(recordDecl(hasName("T"))))),
179 hasArgument(2, integerLiteral(equals(3)))))));
181 Program
, callExpr(allOf(
182 callee(functionDecl(hasName("f"))),
183 hasArgument(0, declRefExpr(to(varDecl()))),
184 hasArgument(1, hasType(pointsTo(recordDecl(hasName("T"))))),
185 hasArgument(2, integerLiteral(equals(3))),
186 hasArgument(3, integerLiteral(equals(4)))))));
189 TEST_P(ASTMatchersTest
, Has
) {
190 if (!GetParam().isCXX()) {
191 // FIXME: Add a test for `has()` that does not depend on C++.
195 DeclarationMatcher HasClassX
= recordDecl(has(recordDecl(hasName("X"))));
196 EXPECT_TRUE(matches("class Y { class X {}; };", HasClassX
));
197 EXPECT_TRUE(matches("class X {};", HasClassX
));
199 DeclarationMatcher YHasClassX
=
200 recordDecl(hasName("Y"), has(recordDecl(hasName("X"))));
201 EXPECT_TRUE(matches("class Y { class X {}; };", YHasClassX
));
202 EXPECT_TRUE(notMatches("class X {};", YHasClassX
));
203 EXPECT_TRUE(notMatches("class Y { class Z { class X {}; }; };", YHasClassX
));
206 TEST_P(ASTMatchersTest
, Has_RecursiveAllOf
) {
207 if (!GetParam().isCXX()) {
211 DeclarationMatcher Recursive
=
212 recordDecl(has(recordDecl(has(recordDecl(hasName("X"))),
213 has(recordDecl(hasName("Y"))), hasName("Z"))),
214 has(recordDecl(has(recordDecl(hasName("A"))),
215 has(recordDecl(hasName("B"))), hasName("C"))),
218 EXPECT_TRUE(matches("class F {"
230 EXPECT_TRUE(matches("class F {"
244 EXPECT_TRUE(matches("class O1 {"
263 TEST_P(ASTMatchersTest
, Has_RecursiveAnyOf
) {
264 if (!GetParam().isCXX()) {
268 DeclarationMatcher Recursive
= recordDecl(
269 anyOf(has(recordDecl(anyOf(has(recordDecl(hasName("X"))),
270 has(recordDecl(hasName("Y"))), hasName("Z")))),
271 has(recordDecl(anyOf(hasName("C"), has(recordDecl(hasName("A"))),
272 has(recordDecl(hasName("B")))))),
275 EXPECT_TRUE(matches("class F {};", Recursive
));
276 EXPECT_TRUE(matches("class Z {};", Recursive
));
277 EXPECT_TRUE(matches("class C {};", Recursive
));
278 EXPECT_TRUE(matches("class M { class N { class X {}; }; };", Recursive
));
279 EXPECT_TRUE(matches("class M { class N { class B {}; }; };", Recursive
));
280 EXPECT_TRUE(matches("class O1 { class O2 {"
281 " class M { class N { class B {}; }; }; "
286 TEST_P(ASTMatchersTest
, Unless
) {
287 if (!GetParam().isCXX()) {
288 // FIXME: Add a test for `unless()` that does not depend on C++.
292 DeclarationMatcher NotClassX
=
293 cxxRecordDecl(isDerivedFrom("Y"), unless(hasName("X")));
294 EXPECT_TRUE(notMatches("", NotClassX
));
295 EXPECT_TRUE(notMatches("class Y {};", NotClassX
));
296 EXPECT_TRUE(matches("class Y {}; class Z : public Y {};", NotClassX
));
297 EXPECT_TRUE(notMatches("class Y {}; class X : public Y {};", NotClassX
));
299 notMatches("class Y {}; class Z {}; class X : public Y {};", NotClassX
));
301 DeclarationMatcher ClassXHasNotClassY
=
302 recordDecl(hasName("X"), has(recordDecl(hasName("Z"))),
303 unless(has(recordDecl(hasName("Y")))));
304 EXPECT_TRUE(matches("class X { class Z {}; };", ClassXHasNotClassY
));
306 notMatches("class X { class Y {}; class Z {}; };", ClassXHasNotClassY
));
308 DeclarationMatcher NamedNotRecord
=
309 namedDecl(hasName("Foo"), unless(recordDecl()));
310 EXPECT_TRUE(matches("void Foo(){}", NamedNotRecord
));
311 EXPECT_TRUE(notMatches("struct Foo {};", NamedNotRecord
));
314 TEST_P(ASTMatchersTest
, HasCastKind
) {
316 matches("char *p = 0;",
318 varDecl(has(castExpr(hasCastKind(CK_NullToPointer
)))))));
319 EXPECT_TRUE(notMatches(
322 varDecl(has(castExpr(hasCastKind(CK_DerivedToBase
)))))));
323 EXPECT_TRUE(matches("char *p = 0;",
324 traverse(TK_AsIs
, varDecl(has(implicitCastExpr(
325 hasCastKind(CK_NullToPointer
)))))));
328 TEST_P(ASTMatchersTest
, HasDescendant
) {
329 if (!GetParam().isCXX()) {
330 // FIXME: Add a test for `hasDescendant()` that does not depend on C++.
334 DeclarationMatcher ZDescendantClassX
=
335 recordDecl(hasDescendant(recordDecl(hasName("X"))), hasName("Z"));
336 EXPECT_TRUE(matches("class Z { class X {}; };", ZDescendantClassX
));
338 matches("class Z { class Y { class X {}; }; };", ZDescendantClassX
));
339 EXPECT_TRUE(matches("class Z { class A { class Y { class X {}; }; }; };",
342 matches("class Z { class A { class B { class Y { class X {}; }; }; }; };",
344 EXPECT_TRUE(notMatches("class Z {};", ZDescendantClassX
));
346 DeclarationMatcher ZDescendantClassXHasClassY
= recordDecl(
347 hasDescendant(recordDecl(has(recordDecl(hasName("Y"))), hasName("X"))),
349 EXPECT_TRUE(matches("class Z { class X { class Y {}; }; };",
350 ZDescendantClassXHasClassY
));
352 matches("class Z { class A { class B { class X { class Y {}; }; }; }; };",
353 ZDescendantClassXHasClassY
));
354 EXPECT_TRUE(notMatches("class Z {"
365 ZDescendantClassXHasClassY
));
367 DeclarationMatcher ZDescendantClassXDescendantClassY
=
368 recordDecl(hasDescendant(recordDecl(
369 hasDescendant(recordDecl(hasName("Y"))), hasName("X"))),
372 matches("class Z { class A { class X { class B { class Y {}; }; }; }; };",
373 ZDescendantClassXDescendantClassY
));
374 EXPECT_TRUE(matches("class Z {"
384 ZDescendantClassXDescendantClassY
));
387 TEST_P(ASTMatchersTest
, HasDescendant_Memoization
) {
388 DeclarationMatcher CannotMemoize
=
389 decl(hasDescendant(typeLoc().bind("x")), has(decl()));
390 EXPECT_TRUE(matches("void f() { int i; }", CannotMemoize
));
393 TEST_P(ASTMatchersTest
, HasDescendant_MemoizationUsesRestrictKind
) {
394 auto Name
= hasName("i");
395 auto VD
= internal::Matcher
<VarDecl
>(Name
).dynCastTo
<Decl
>();
396 auto RD
= internal::Matcher
<RecordDecl
>(Name
).dynCastTo
<Decl
>();
397 // Matching VD first should not make a cache hit for RD.
398 EXPECT_TRUE(notMatches("void f() { int i; }",
399 decl(hasDescendant(VD
), hasDescendant(RD
))));
400 EXPECT_TRUE(notMatches("void f() { int i; }",
401 decl(hasDescendant(RD
), hasDescendant(VD
))));
402 // Not matching RD first should not make a cache hit for VD either.
403 EXPECT_TRUE(matches("void f() { int i; }",
404 decl(anyOf(hasDescendant(RD
), hasDescendant(VD
)))));
407 TEST_P(ASTMatchersTest
, HasAncestor_Memoization
) {
408 if (!GetParam().isCXX()) {
412 // This triggers an hasAncestor with a TemplateArgument in the bound nodes.
413 // That node can't be memoized so we have to check for it before trying to put
415 DeclarationMatcher CannotMemoize
= classTemplateSpecializationDecl(
416 hasAnyTemplateArgument(templateArgument().bind("targ")),
417 forEach(fieldDecl(hasAncestor(forStmt()))));
419 EXPECT_TRUE(notMatches("template <typename T> struct S;"
420 "template <> struct S<int>{ int i; int j; };",
424 TEST_P(ASTMatchersTest
, HasAttr
) {
425 EXPECT_TRUE(matches("struct __attribute__((warn_unused)) X {};",
426 decl(hasAttr(clang::attr::WarnUnused
))));
427 EXPECT_FALSE(matches("struct X {};", decl(hasAttr(clang::attr::WarnUnused
))));
430 TEST_P(ASTMatchersTest
, AnyOf
) {
431 if (!GetParam().isCXX()) {
432 // FIXME: Add a test for `anyOf()` that does not depend on C++.
436 DeclarationMatcher YOrZDerivedFromX
= cxxRecordDecl(
437 anyOf(hasName("Y"), allOf(isDerivedFrom("X"), hasName("Z"))));
438 EXPECT_TRUE(matches("class X {}; class Z : public X {};", YOrZDerivedFromX
));
439 EXPECT_TRUE(matches("class Y {};", YOrZDerivedFromX
));
441 notMatches("class X {}; class W : public X {};", YOrZDerivedFromX
));
442 EXPECT_TRUE(notMatches("class Z {};", YOrZDerivedFromX
));
444 DeclarationMatcher XOrYOrZOrU
=
445 recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U")));
446 EXPECT_TRUE(matches("class X {};", XOrYOrZOrU
));
447 EXPECT_TRUE(notMatches("class V {};", XOrYOrZOrU
));
449 DeclarationMatcher XOrYOrZOrUOrV
= recordDecl(anyOf(
450 hasName("X"), hasName("Y"), hasName("Z"), hasName("U"), hasName("V")));
451 EXPECT_TRUE(matches("class X {};", XOrYOrZOrUOrV
));
452 EXPECT_TRUE(matches("class Y {};", XOrYOrZOrUOrV
));
453 EXPECT_TRUE(matches("class Z {};", XOrYOrZOrUOrV
));
454 EXPECT_TRUE(matches("class U {};", XOrYOrZOrUOrV
));
455 EXPECT_TRUE(matches("class V {};", XOrYOrZOrUOrV
));
456 EXPECT_TRUE(notMatches("class A {};", XOrYOrZOrUOrV
));
458 StatementMatcher MixedTypes
= stmt(anyOf(ifStmt(), binaryOperator()));
459 EXPECT_TRUE(matches("int F() { return 1 + 2; }", MixedTypes
));
460 EXPECT_TRUE(matches("int F() { if (true) return 1; }", MixedTypes
));
461 EXPECT_TRUE(notMatches("int F() { return 1; }", MixedTypes
));
464 matches("void f() try { } catch (int) { } catch (...) { }",
465 cxxCatchStmt(anyOf(hasDescendant(varDecl()), isCatchAll()))));
468 TEST_P(ASTMatchersTest
, MapAnyOf
) {
469 if (!GetParam().isCXX()) {
473 if (GetParam().hasDelayedTemplateParsing()) {
477 StringRef Code
= R
"cpp(
484 auto trueExpr
= cxxBoolLiteral(equals(true));
485 auto falseExpr
= cxxBoolLiteral(equals(false));
488 Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
489 mapAnyOf(ifStmt
, forStmt
).with(hasCondition(trueExpr
)))));
491 Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
492 mapAnyOf(ifStmt
, forStmt
).with(hasCondition(falseExpr
)))));
495 matches(Code
, cxxBoolLiteral(equals(true),
496 hasAncestor(mapAnyOf(ifStmt
, forStmt
)))));
499 matches(Code
, cxxBoolLiteral(equals(false),
500 hasAncestor(mapAnyOf(ifStmt
, forStmt
)))));
503 notMatches(Code
, floatLiteral(hasAncestor(mapAnyOf(ifStmt
, forStmt
)))));
515 EXPECT_TRUE(matches(Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
516 mapAnyOf(callExpr
, cxxConstructExpr
)
517 .with(hasArgument(0, trueExpr
)))));
518 EXPECT_TRUE(matches(Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
519 mapAnyOf(callExpr
, cxxConstructExpr
)
520 .with(hasArgument(0, falseExpr
)))));
523 matches(Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
524 mapAnyOf(callExpr
, cxxConstructExpr
)
525 .with(hasArgument(0, expr()),
526 hasDeclaration(functionDecl())))));
528 EXPECT_TRUE(matches(Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
529 mapAnyOf(callExpr
, cxxConstructExpr
))));
532 Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
533 mapAnyOf(callExpr
, cxxConstructExpr
).bind("call"))));
538 bool operator!=(const HasOpNeqMem& other) const
546 bool operator!=(const HasOpFree& lhs, const HasOpFree& rhs)
587 traverse(TK_IgnoreUnlessSpelledInSource
,
588 mapAnyOf(binaryOperator
, cxxOperatorCallExpr
)
589 .with(hasOperatorName("!="),
590 forFunction(functionDecl(hasName("binop"))),
591 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
592 hasRHS(declRefExpr(to(varDecl(hasName("s2")))))))));
596 traverse(TK_IgnoreUnlessSpelledInSource
,
597 mapAnyOf(binaryOperator
, cxxOperatorCallExpr
)
598 .with(hasOperatorName("!="),
599 forFunction(functionDecl(hasName("opMem"))),
600 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
601 hasRHS(declRefExpr(to(varDecl(hasName("s2")))))))));
605 traverse(TK_IgnoreUnlessSpelledInSource
,
606 mapAnyOf(binaryOperator
, cxxOperatorCallExpr
)
607 .with(hasOperatorName("!="),
608 forFunction(functionDecl(hasName("opFree"))),
609 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
610 hasRHS(declRefExpr(to(varDecl(hasName("s2")))))))));
613 Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
614 mapAnyOf(binaryOperator
, cxxOperatorCallExpr
)
615 .with(hasOperatorName("!="),
616 forFunction(functionDecl(hasName("binop"))),
618 declRefExpr(to(varDecl(hasName("s1"))))),
620 declRefExpr(to(varDecl(hasName("s2")))))))));
623 Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
624 mapAnyOf(binaryOperator
, cxxOperatorCallExpr
)
625 .with(hasOperatorName("!="),
626 forFunction(functionDecl(hasName("opMem"))),
628 declRefExpr(to(varDecl(hasName("s1"))))),
630 declRefExpr(to(varDecl(hasName("s2")))))))));
633 Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
634 mapAnyOf(binaryOperator
, cxxOperatorCallExpr
)
635 .with(hasOperatorName("!="),
636 forFunction(functionDecl(hasName("opFree"))),
638 declRefExpr(to(varDecl(hasName("s1"))))),
640 declRefExpr(to(varDecl(hasName("s2")))))))));
645 TK_IgnoreUnlessSpelledInSource
,
646 mapAnyOf(binaryOperator
, cxxOperatorCallExpr
)
647 .with(hasOperatorName("!="),
648 forFunction(functionDecl(hasName("binop"))),
649 hasOperands(declRefExpr(to(varDecl(hasName("s1")))),
650 declRefExpr(to(varDecl(hasName("s2"))))),
651 hasOperands(declRefExpr(to(varDecl(hasName("s2")))),
652 declRefExpr(to(varDecl(hasName("s1")))))))));
657 TK_IgnoreUnlessSpelledInSource
,
658 mapAnyOf(binaryOperator
, cxxOperatorCallExpr
)
659 .with(hasOperatorName("!="),
660 forFunction(functionDecl(hasName("opMem"))),
661 hasOperands(declRefExpr(to(varDecl(hasName("s1")))),
662 declRefExpr(to(varDecl(hasName("s2"))))),
663 hasOperands(declRefExpr(to(varDecl(hasName("s2")))),
664 declRefExpr(to(varDecl(hasName("s1")))))))));
669 TK_IgnoreUnlessSpelledInSource
,
670 mapAnyOf(binaryOperator
, cxxOperatorCallExpr
)
671 .with(hasOperatorName("!="),
672 forFunction(functionDecl(hasName("opFree"))),
673 hasOperands(declRefExpr(to(varDecl(hasName("s1")))),
674 declRefExpr(to(varDecl(hasName("s2"))))),
675 hasOperands(declRefExpr(to(varDecl(hasName("s2")))),
676 declRefExpr(to(varDecl(hasName("s1")))))))));
679 Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
680 mapAnyOf(binaryOperator
, cxxOperatorCallExpr
)
681 .with(hasAnyOperatorName("==", "!="),
682 forFunction(functionDecl(hasName("binop")))))));
685 Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
686 mapAnyOf(binaryOperator
, cxxOperatorCallExpr
)
687 .with(hasAnyOperatorName("==", "!="),
688 forFunction(functionDecl(hasName("opMem")))))));
691 Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
692 mapAnyOf(binaryOperator
, cxxOperatorCallExpr
)
693 .with(hasAnyOperatorName("==", "!="),
694 forFunction(functionDecl(hasName("opFree")))))));
697 Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
699 hasOperatorName("!="),
700 forFunction(functionDecl(hasName("binop"))),
701 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
702 hasRHS(declRefExpr(to(varDecl(hasName("s2")))))))));
705 Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
707 hasOperatorName("!="),
708 forFunction(functionDecl(hasName("opMem"))),
709 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
710 hasRHS(declRefExpr(to(varDecl(hasName("s2")))))))));
713 Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
715 hasOperatorName("!="),
716 forFunction(functionDecl(hasName("opFree"))),
717 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
718 hasRHS(declRefExpr(to(varDecl(hasName("s2")))))))));
721 Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
723 hasOperatorName("!="),
724 forFunction(functionDecl(hasName("templ"))),
725 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
726 hasRHS(declRefExpr(to(varDecl(hasName("s2")))))))));
731 bool operator==(const HasOpEq &) const;
743 struct strong_ordering {
745 constexpr operator int() const { return n; }
746 static const strong_ordering equal, greater, less;
748 constexpr strong_ordering strong_ordering::equal = {0};
749 constexpr strong_ordering strong_ordering::greater = {1};
750 constexpr strong_ordering strong_ordering::less = {-1};
753 struct HasSpaceshipMem {
755 constexpr auto operator<=>(const HasSpaceshipMem&) const = default;
767 EXPECT_TRUE(matchesConditionally(
770 TK_IgnoreUnlessSpelledInSource
,
771 binaryOperation(hasOperatorName("!="),
772 forFunction(functionDecl(hasName("inverse"))),
773 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
774 hasRHS(declRefExpr(to(varDecl(hasName("s2"))))))),
775 true, {"-std=c++20"}));
777 EXPECT_TRUE(matchesConditionally(
780 TK_IgnoreUnlessSpelledInSource
,
781 binaryOperation(hasOperatorName("!="),
782 forFunction(functionDecl(hasName("rewritten"))),
783 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
784 hasRHS(declRefExpr(to(varDecl(hasName("s2"))))))),
785 true, {"-std=c++20"}));
790 bool operator!() const
798 bool operator!(HasOpBangFree const&)
826 Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
827 mapAnyOf(unaryOperator
, cxxOperatorCallExpr
)
828 .with(hasOperatorName("!"),
829 forFunction(functionDecl(hasName("unop"))),
831 declRefExpr(to(varDecl(hasName("s1")))))))));
834 Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
835 mapAnyOf(unaryOperator
, cxxOperatorCallExpr
)
836 .with(hasOperatorName("!"),
837 forFunction(functionDecl(hasName("opMem"))),
839 declRefExpr(to(varDecl(hasName("s1")))))))));
842 Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
843 mapAnyOf(unaryOperator
, cxxOperatorCallExpr
)
844 .with(hasOperatorName("!"),
845 forFunction(functionDecl(hasName("opFree"))),
847 declRefExpr(to(varDecl(hasName("s1")))))))));
850 Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
851 mapAnyOf(unaryOperator
, cxxOperatorCallExpr
)
852 .with(hasAnyOperatorName("+", "!"),
853 forFunction(functionDecl(hasName("unop")))))));
856 Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
857 mapAnyOf(unaryOperator
, cxxOperatorCallExpr
)
858 .with(hasAnyOperatorName("+", "!"),
859 forFunction(functionDecl(hasName("opMem")))))));
862 Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
863 mapAnyOf(unaryOperator
, cxxOperatorCallExpr
)
864 .with(hasAnyOperatorName("+", "!"),
865 forFunction(functionDecl(hasName("opFree")))))));
868 struct ConstructorTakesInt
870 ConstructorTakesInt(int i) {}
873 void callTakesInt(int i)
885 ConstructorTakesInt cti(42);
890 Code
, traverse(TK_IgnoreUnlessSpelledInSource
,
891 invocation(forFunction(functionDecl(hasName("doCall"))),
892 hasArgument(0, integerLiteral(equals(42))),
893 hasAnyArgument(integerLiteral(equals(42))),
894 forEachArgumentWithParam(
895 integerLiteral(equals(42)),
896 parmVarDecl(hasName("i")))))));
901 TK_IgnoreUnlessSpelledInSource
,
902 invocation(forFunction(functionDecl(hasName("doConstruct"))),
903 hasArgument(0, integerLiteral(equals(42))),
904 hasAnyArgument(integerLiteral(equals(42))),
905 forEachArgumentWithParam(integerLiteral(equals(42)),
906 parmVarDecl(hasName("i")))))));
909 TEST_P(ASTMatchersTest
, IsDerivedFrom
) {
910 if (!GetParam().isCXX()) {
914 DeclarationMatcher IsDerivedFromX
= cxxRecordDecl(isDerivedFrom("X"));
916 EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsDerivedFromX
));
917 EXPECT_TRUE(notMatches("class X {};", IsDerivedFromX
));
918 EXPECT_TRUE(notMatches("class X;", IsDerivedFromX
));
919 EXPECT_TRUE(notMatches("class Y;", IsDerivedFromX
));
920 EXPECT_TRUE(notMatches("", IsDerivedFromX
));
921 EXPECT_TRUE(matches("class X {}; template<int N> class Y : Y<N-1>, X {};",
923 EXPECT_TRUE(matches("class X {}; template<int N> class Y : X, Y<N-1> {};",
926 DeclarationMatcher IsZDerivedFromX
=
927 cxxRecordDecl(hasName("Z"), isDerivedFrom("X"));
928 EXPECT_TRUE(matches("class X {};"
929 "template<int N> class Y : Y<N-1> {};"
930 "template<> class Y<0> : X {};"
931 "class Z : Y<1> {};",
934 DeclarationMatcher IsDirectlyDerivedFromX
=
935 cxxRecordDecl(isDirectlyDerivedFrom("X"));
938 matches("class X {}; class Y : public X {};", IsDirectlyDerivedFromX
));
939 EXPECT_TRUE(notMatches("class X {};", IsDirectlyDerivedFromX
));
940 EXPECT_TRUE(notMatches("class X;", IsDirectlyDerivedFromX
));
941 EXPECT_TRUE(notMatches("class Y;", IsDirectlyDerivedFromX
));
942 EXPECT_TRUE(notMatches("", IsDirectlyDerivedFromX
));
944 DeclarationMatcher IsAX
= cxxRecordDecl(isSameOrDerivedFrom("X"));
946 EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsAX
));
947 EXPECT_TRUE(matches("class X {};", IsAX
));
948 EXPECT_TRUE(matches("class X;", IsAX
));
949 EXPECT_TRUE(notMatches("class Y;", IsAX
));
950 EXPECT_TRUE(notMatches("", IsAX
));
952 DeclarationMatcher ZIsDerivedFromX
=
953 cxxRecordDecl(hasName("Z"), isDerivedFrom("X"));
954 DeclarationMatcher ZIsDirectlyDerivedFromX
=
955 cxxRecordDecl(hasName("Z"), isDirectlyDerivedFrom("X"));
957 matches("class X {}; class Y : public X {}; class Z : public Y {};",
960 notMatches("class X {}; class Y : public X {}; class Z : public Y {};",
961 ZIsDirectlyDerivedFromX
));
962 EXPECT_TRUE(matches("class X {};"
963 "template<class T> class Y : public X {};"
964 "class Z : public Y<int> {};",
966 EXPECT_TRUE(notMatches("class X {};"
967 "template<class T> class Y : public X {};"
968 "class Z : public Y<int> {};",
969 ZIsDirectlyDerivedFromX
));
970 EXPECT_TRUE(matches("class X {}; template<class T> class Z : public X {};",
972 EXPECT_TRUE(matches("template<class T> class X {}; "
973 "template<class T> class Z : public X<T> {};",
975 EXPECT_TRUE(matches("template<class T, class U=T> class X {}; "
976 "template<class T> class Z : public X<T> {};",
979 notMatches("template<class X> class A { class Z : public X {}; };",
982 matches("template<class X> class A { public: class Z : public X {}; }; "
983 "class X{}; void y() { A<X>::Z z; }",
986 matches("template <class T> class X {}; "
987 "template<class Y> class A { class Z : public X<Y> {}; };",
989 EXPECT_TRUE(notMatches("template<template<class T> class X> class A { "
990 " class Z : public X<int> {}; };",
992 EXPECT_TRUE(matches("template<template<class T> class X> class A { "
993 " public: class Z : public X<int> {}; }; "
994 "template<class T> class X {}; void y() { A<X>::Z z; }",
997 notMatches("template<class X> class A { class Z : public X::D {}; };",
999 EXPECT_TRUE(matches("template<class X> class A { public: "
1000 " class Z : public X::D {}; }; "
1001 "class Y { public: class X {}; typedef X D; }; "
1002 "void y() { A<Y>::Z z; }",
1004 EXPECT_TRUE(matches("class X {}; typedef X Y; class Z : public Y {};",
1006 EXPECT_TRUE(matches("template<class T> class Y { typedef typename T::U X; "
1007 " class Z : public X {}; };",
1009 EXPECT_TRUE(matches("class X {}; class Z : public ::X {};", ZIsDerivedFromX
));
1011 notMatches("template<class T> class X {}; "
1012 "template<class T> class A { class Z : public X<T>::D {}; };",
1015 matches("template<class T> class X { public: typedef X<T> D; }; "
1016 "template<class T> class A { public: "
1017 " class Z : public X<T>::D {}; }; void y() { A<int>::Z z; }",
1020 notMatches("template<class X> class A { class Z : public X::D::E {}; };",
1023 matches("class X {}; typedef X V; typedef V W; class Z : public W {};",
1025 EXPECT_TRUE(matches("class X {}; class Y : public X {}; "
1026 "typedef Y V; typedef V W; class Z : public W {};",
1028 EXPECT_TRUE(notMatches("class X {}; class Y : public X {}; "
1029 "typedef Y V; typedef V W; class Z : public W {};",
1030 ZIsDirectlyDerivedFromX
));
1032 matches("template<class T, class U> class X {}; "
1033 "template<class T> class A { class Z : public X<T, int> {}; };",
1036 notMatches("template<class X> class D { typedef X A; typedef A B; "
1037 " typedef B C; class Z : public C {}; };",
1039 EXPECT_TRUE(matches("class X {}; typedef X A; typedef A B; "
1040 "class Z : public B {};",
1042 EXPECT_TRUE(matches("class X {}; typedef X A; typedef A B; typedef B C; "
1043 "class Z : public C {};",
1045 EXPECT_TRUE(matches("class U {}; typedef U X; typedef X V; "
1046 "class Z : public V {};",
1048 EXPECT_TRUE(matches("class Base {}; typedef Base X; "
1049 "class Z : public Base {};",
1051 EXPECT_TRUE(matches("class Base {}; typedef Base Base2; typedef Base2 X; "
1052 "class Z : public Base {};",
1054 EXPECT_TRUE(notMatches("class Base {}; class Base2 {}; typedef Base2 X; "
1055 "class Z : public Base {};",
1057 EXPECT_TRUE(matches("class A {}; typedef A X; typedef A Y; "
1058 "class Z : public Y {};",
1060 EXPECT_TRUE(notMatches("template <typename T> class Z;"
1061 "template <> class Z<void> {};"
1062 "template <typename T> class Z : public Z<void> {};",
1064 EXPECT_TRUE(matches("template <typename T> class X;"
1065 "template <> class X<void> {};"
1066 "template <typename T> class X : public X<void> {};",
1069 matches("class X {};"
1070 "template <typename T> class Z;"
1071 "template <> class Z<void> {};"
1072 "template <typename T> class Z : public Z<void>, public X {};",
1075 notMatches("template<int> struct X;"
1076 "template<int i> struct X : public X<i-1> {};",
1077 cxxRecordDecl(isDerivedFrom(recordDecl(hasName("Some"))))));
1078 EXPECT_TRUE(matches(
1080 "template<int> struct X;"
1081 "template<int i> struct X : public X<i-1> {};"
1082 "template<> struct X<0> : public A {};"
1083 "struct B : public X<42> {};",
1084 cxxRecordDecl(hasName("B"), isDerivedFrom(recordDecl(hasName("A"))))));
1085 EXPECT_TRUE(notMatches(
1087 "template<int> struct X;"
1088 "template<int i> struct X : public X<i-1> {};"
1089 "template<> struct X<0> : public A {};"
1090 "struct B : public X<42> {};",
1091 cxxRecordDecl(hasName("B"),
1092 isDirectlyDerivedFrom(recordDecl(hasName("A"))))));
1094 // FIXME: Once we have better matchers for template type matching,
1095 // get rid of the Variable(...) matching and match the right template
1096 // declarations directly.
1097 const char *RecursiveTemplateOneParameter
=
1098 "class Base1 {}; class Base2 {};"
1099 "template <typename T> class Z;"
1100 "template <> class Z<void> : public Base1 {};"
1101 "template <> class Z<int> : public Base2 {};"
1102 "template <> class Z<float> : public Z<void> {};"
1103 "template <> class Z<double> : public Z<int> {};"
1104 "template <typename T> class Z : public Z<float>, public Z<double> {};"
1105 "void f() { Z<float> z_float; Z<double> z_double; Z<char> z_char; }";
1106 EXPECT_TRUE(matches(
1107 RecursiveTemplateOneParameter
,
1108 varDecl(hasName("z_float"),
1109 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1")))))));
1110 EXPECT_TRUE(notMatches(
1111 RecursiveTemplateOneParameter
,
1112 varDecl(hasName("z_float"),
1113 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2")))))));
1115 matches(RecursiveTemplateOneParameter
,
1116 varDecl(hasName("z_char"),
1117 hasInitializer(hasType(cxxRecordDecl(
1118 isDerivedFrom("Base1"), isDerivedFrom("Base2")))))));
1120 const char *RecursiveTemplateTwoParameters
=
1121 "class Base1 {}; class Base2 {};"
1122 "template <typename T1, typename T2> class Z;"
1123 "template <typename T> class Z<void, T> : public Base1 {};"
1124 "template <typename T> class Z<int, T> : public Base2 {};"
1125 "template <typename T> class Z<float, T> : public Z<void, T> {};"
1126 "template <typename T> class Z<double, T> : public Z<int, T> {};"
1127 "template <typename T1, typename T2> class Z : "
1128 " public Z<float, T2>, public Z<double, T2> {};"
1129 "void f() { Z<float, void> z_float; Z<double, void> z_double; "
1130 " Z<char, void> z_char; }";
1131 EXPECT_TRUE(matches(
1132 RecursiveTemplateTwoParameters
,
1133 varDecl(hasName("z_float"),
1134 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1")))))));
1135 EXPECT_TRUE(notMatches(
1136 RecursiveTemplateTwoParameters
,
1137 varDecl(hasName("z_float"),
1138 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2")))))));
1140 matches(RecursiveTemplateTwoParameters
,
1141 varDecl(hasName("z_char"),
1142 hasInitializer(hasType(cxxRecordDecl(
1143 isDerivedFrom("Base1"), isDerivedFrom("Base2")))))));
1144 EXPECT_TRUE(matches("namespace ns { class X {}; class Y : public X {}; }",
1145 cxxRecordDecl(isDerivedFrom("::ns::X"))));
1146 EXPECT_TRUE(notMatches("class X {}; class Y : public X {};",
1147 cxxRecordDecl(isDerivedFrom("::ns::X"))));
1149 EXPECT_TRUE(matches(
1150 "class X {}; class Y : public X {};",
1151 cxxRecordDecl(isDerivedFrom(recordDecl(hasName("X")).bind("test")))));
1153 EXPECT_TRUE(matches("template<typename T> class X {};"
1154 "template<typename T> using Z = X<T>;"
1155 "template <typename T> class Y : Z<T> {};",
1156 cxxRecordDecl(isDerivedFrom(namedDecl(hasName("X"))))));
1159 TEST_P(ASTMatchersTest
, IsDerivedFrom_EmptyName
) {
1160 if (!GetParam().isCXX()) {
1164 const char *const Code
= "class X {}; class Y : public X {};";
1165 EXPECT_TRUE(notMatches(Code
, cxxRecordDecl(isDerivedFrom(""))));
1166 EXPECT_TRUE(notMatches(Code
, cxxRecordDecl(isDirectlyDerivedFrom(""))));
1167 EXPECT_TRUE(notMatches(Code
, cxxRecordDecl(isSameOrDerivedFrom(""))));
1170 TEST_P(ASTMatchersTest
, IsDerivedFrom_ObjC
) {
1171 DeclarationMatcher IsDerivedFromX
= objcInterfaceDecl(isDerivedFrom("X"));
1173 matchesObjC("@interface X @end @interface Y : X @end", IsDerivedFromX
));
1174 EXPECT_TRUE(matchesObjC(
1175 "@interface X @end @interface Y<__covariant ObjectType> : X @end",
1177 EXPECT_TRUE(matchesObjC(
1178 "@interface X @end @compatibility_alias Y X; @interface Z : Y @end",
1180 EXPECT_TRUE(matchesObjC(
1181 "@interface X @end typedef X Y; @interface Z : Y @end", IsDerivedFromX
));
1182 EXPECT_TRUE(notMatchesObjC("@interface X @end", IsDerivedFromX
));
1183 EXPECT_TRUE(notMatchesObjC("@class X;", IsDerivedFromX
));
1184 EXPECT_TRUE(notMatchesObjC("@class Y;", IsDerivedFromX
));
1185 EXPECT_TRUE(notMatchesObjC("@interface X @end @compatibility_alias Y X;",
1187 EXPECT_TRUE(notMatchesObjC("@interface X @end typedef X Y;", IsDerivedFromX
));
1189 DeclarationMatcher IsDirectlyDerivedFromX
=
1190 objcInterfaceDecl(isDirectlyDerivedFrom("X"));
1191 EXPECT_TRUE(matchesObjC("@interface X @end @interface Y : X @end",
1192 IsDirectlyDerivedFromX
));
1193 EXPECT_TRUE(matchesObjC(
1194 "@interface X @end @interface Y<__covariant ObjectType> : X @end",
1195 IsDirectlyDerivedFromX
));
1196 EXPECT_TRUE(matchesObjC(
1197 "@interface X @end @compatibility_alias Y X; @interface Z : Y @end",
1198 IsDirectlyDerivedFromX
));
1200 matchesObjC("@interface X @end typedef X Y; @interface Z : Y @end",
1201 IsDirectlyDerivedFromX
));
1202 EXPECT_TRUE(notMatchesObjC("@interface X @end", IsDirectlyDerivedFromX
));
1203 EXPECT_TRUE(notMatchesObjC("@class X;", IsDirectlyDerivedFromX
));
1204 EXPECT_TRUE(notMatchesObjC("@class Y;", IsDirectlyDerivedFromX
));
1205 EXPECT_TRUE(notMatchesObjC("@interface X @end @compatibility_alias Y X;",
1206 IsDirectlyDerivedFromX
));
1208 notMatchesObjC("@interface X @end typedef X Y;", IsDirectlyDerivedFromX
));
1210 DeclarationMatcher IsAX
= objcInterfaceDecl(isSameOrDerivedFrom("X"));
1211 EXPECT_TRUE(matchesObjC("@interface X @end @interface Y : X @end", IsAX
));
1212 EXPECT_TRUE(matchesObjC("@interface X @end", IsAX
));
1213 EXPECT_TRUE(matchesObjC("@class X;", IsAX
));
1214 EXPECT_TRUE(notMatchesObjC("@interface Y @end", IsAX
));
1215 EXPECT_TRUE(notMatchesObjC("@class Y;", IsAX
));
1217 DeclarationMatcher ZIsDerivedFromX
=
1218 objcInterfaceDecl(hasName("Z"), isDerivedFrom("X"));
1219 DeclarationMatcher ZIsDirectlyDerivedFromX
=
1220 objcInterfaceDecl(hasName("Z"), isDirectlyDerivedFrom("X"));
1221 EXPECT_TRUE(matchesObjC(
1222 "@interface X @end @interface Y : X @end @interface Z : Y @end",
1224 EXPECT_TRUE(matchesObjC("@interface X @end @interface Y : X @end typedef Y "
1225 "V; typedef V W; @interface Z : W @end",
1227 EXPECT_TRUE(matchesObjC(
1228 "@interface X @end typedef X Y; @interface Z : Y @end", ZIsDerivedFromX
));
1230 matchesObjC("@interface X @end typedef X Y; @interface Z : Y @end",
1231 ZIsDirectlyDerivedFromX
));
1232 EXPECT_TRUE(matchesObjC(
1233 "@interface A @end typedef A X; typedef A Y; @interface Z : Y @end",
1235 EXPECT_TRUE(matchesObjC(
1236 "@interface A @end typedef A X; typedef A Y; @interface Z : Y @end",
1237 ZIsDirectlyDerivedFromX
));
1238 EXPECT_TRUE(matchesObjC(
1239 "@interface X @end @compatibility_alias Y X; @interface Z : Y @end",
1241 EXPECT_TRUE(matchesObjC(
1242 "@interface X @end @compatibility_alias Y X; @interface Z : Y @end",
1243 ZIsDirectlyDerivedFromX
));
1244 EXPECT_TRUE(matchesObjC(
1245 "@interface Y @end @compatibility_alias X Y; @interface Z : Y @end",
1247 EXPECT_TRUE(matchesObjC(
1248 "@interface Y @end @compatibility_alias X Y; @interface Z : Y @end",
1249 ZIsDirectlyDerivedFromX
));
1250 EXPECT_TRUE(matchesObjC(
1251 "@interface A @end @compatibility_alias X A; @compatibility_alias Y A;"
1252 "@interface Z : Y @end",
1254 EXPECT_TRUE(matchesObjC(
1255 "@interface A @end @compatibility_alias X A; @compatibility_alias Y A;"
1256 "@interface Z : Y @end",
1257 ZIsDirectlyDerivedFromX
));
1258 EXPECT_TRUE(matchesObjC(
1259 "@interface Y @end typedef Y X; @interface Z : X @end", ZIsDerivedFromX
));
1261 matchesObjC("@interface Y @end typedef Y X; @interface Z : X @end",
1262 ZIsDirectlyDerivedFromX
));
1264 matchesObjC("@interface A @end @compatibility_alias Y A; typedef Y X;"
1265 "@interface Z : A @end",
1268 matchesObjC("@interface A @end @compatibility_alias Y A; typedef Y X;"
1269 "@interface Z : A @end",
1270 ZIsDirectlyDerivedFromX
));
1272 matchesObjC("@interface A @end typedef A Y; @compatibility_alias X Y;"
1273 "@interface Z : A @end",
1276 matchesObjC("@interface A @end typedef A Y; @compatibility_alias X Y;"
1277 "@interface Z : A @end",
1278 ZIsDirectlyDerivedFromX
));
1281 TEST_P(ASTMatchersTest
, IsLambda
) {
1282 if (!GetParam().isCXX11OrLater()) {
1286 const auto IsLambda
= cxxMethodDecl(ofClass(cxxRecordDecl(isLambda())));
1287 EXPECT_TRUE(matches("auto x = []{};", IsLambda
));
1288 EXPECT_TRUE(notMatches("struct S { void operator()() const; };", IsLambda
));
1291 TEST_P(ASTMatchersTest
, Bind
) {
1292 DeclarationMatcher ClassX
= has(recordDecl(hasName("::X")).bind("x"));
1294 EXPECT_TRUE(matchAndVerifyResultTrue(
1295 "class X {};", ClassX
,
1296 std::make_unique
<VerifyIdIsBoundTo
<CXXRecordDecl
>>("x")));
1298 EXPECT_TRUE(matchAndVerifyResultFalse(
1299 "class X {};", ClassX
,
1300 std::make_unique
<VerifyIdIsBoundTo
<CXXRecordDecl
>>("other-id")));
1302 TypeMatcher TypeAHasClassB
= hasDeclaration(
1303 recordDecl(hasName("A"), has(recordDecl(hasName("B")).bind("b"))));
1305 EXPECT_TRUE(matchAndVerifyResultTrue(
1306 "class A { public: A *a; class B {}; };", TypeAHasClassB
,
1307 std::make_unique
<VerifyIdIsBoundTo
<Decl
>>("b")));
1309 StatementMatcher MethodX
=
1310 callExpr(callee(cxxMethodDecl(hasName("x")))).bind("x");
1312 EXPECT_TRUE(matchAndVerifyResultTrue(
1313 "class A { void x() { x(); } };", MethodX
,
1314 std::make_unique
<VerifyIdIsBoundTo
<CXXMemberCallExpr
>>("x")));
1317 TEST_P(ASTMatchersTest
, Bind_SameNameInAlternatives
) {
1318 StatementMatcher matcher
= anyOf(
1319 binaryOperator(hasOperatorName("+"), hasLHS(expr().bind("x")),
1320 hasRHS(integerLiteral(equals(0)))),
1321 binaryOperator(hasOperatorName("+"), hasLHS(integerLiteral(equals(0))),
1322 hasRHS(expr().bind("x"))));
1324 EXPECT_TRUE(matchAndVerifyResultTrue(
1325 // The first branch of the matcher binds x to 0 but then fails.
1326 // The second branch binds x to f() and succeeds.
1327 "int f() { return 0 + f(); }", matcher
,
1328 std::make_unique
<VerifyIdIsBoundTo
<CallExpr
>>("x")));
1331 TEST_P(ASTMatchersTest
, Bind_BindsIDForMemoizedResults
) {
1332 // Using the same matcher in two match expressions will make memoization
1334 DeclarationMatcher ClassX
= recordDecl(hasName("X")).bind("x");
1335 EXPECT_TRUE(matchAndVerifyResultTrue(
1336 "class A { class B { class X {}; }; };",
1338 anyOf(recordDecl(hasName("A"), hasDescendant(ClassX
)),
1339 recordDecl(hasName("B"), hasDescendant(ClassX
)))),
1340 std::make_unique
<VerifyIdIsBoundTo
<Decl
>>("x", 2)));
1343 TEST_P(ASTMatchersTest
, HasType_MatchesAsString
) {
1344 if (!GetParam().isCXX()) {
1345 // FIXME: Add a test for `hasType()` that does not depend on C++.
1350 matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }",
1351 cxxMemberCallExpr(on(hasType(asString("Y *"))))));
1353 matches("class X { void x(int x) {} };",
1354 cxxMethodDecl(hasParameter(0, hasType(asString("int"))))));
1355 EXPECT_TRUE(matches("namespace ns { struct A {}; } struct B { ns::A a; };",
1356 fieldDecl(hasType(asString("ns::A")))));
1357 EXPECT_TRUE(matches("namespace { struct A {}; } struct B { A a; };",
1358 fieldDecl(hasType(asString("A")))));
1361 TEST_P(ASTMatchersTest
, HasOverloadedOperatorName
) {
1362 if (!GetParam().isCXX()) {
1366 StatementMatcher OpCallAndAnd
=
1367 cxxOperatorCallExpr(hasOverloadedOperatorName("&&"));
1368 EXPECT_TRUE(matches("class Y { }; "
1369 "bool operator&&(Y x, Y y) { return true; }; "
1370 "Y a; Y b; bool c = a && b;",
1372 StatementMatcher OpCallLessLess
=
1373 cxxOperatorCallExpr(hasOverloadedOperatorName("<<"));
1374 EXPECT_TRUE(notMatches("class Y { }; "
1375 "bool operator&&(Y x, Y y) { return true; }; "
1376 "Y a; Y b; bool c = a && b;",
1378 StatementMatcher OpStarCall
=
1379 cxxOperatorCallExpr(hasOverloadedOperatorName("*"));
1381 matches("class Y; int operator*(Y &); void f(Y &y) { *y; }", OpStarCall
));
1382 DeclarationMatcher ClassWithOpStar
=
1383 cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*")));
1384 EXPECT_TRUE(matches("class Y { int operator*(); };", ClassWithOpStar
));
1385 EXPECT_TRUE(notMatches("class Y { void myOperator(); };", ClassWithOpStar
));
1386 DeclarationMatcher AnyOpStar
= functionDecl(hasOverloadedOperatorName("*"));
1387 EXPECT_TRUE(matches("class Y; int operator*(Y &);", AnyOpStar
));
1388 EXPECT_TRUE(matches("class Y { int operator*(); };", AnyOpStar
));
1389 DeclarationMatcher AnyAndOp
=
1390 functionDecl(hasAnyOverloadedOperatorName("&", "&&"));
1391 EXPECT_TRUE(matches("class Y; Y operator&(Y &, Y &);", AnyAndOp
));
1392 EXPECT_TRUE(matches("class Y; Y operator&&(Y &, Y &);", AnyAndOp
));
1393 EXPECT_TRUE(matches("class Y { Y operator&(Y &); };", AnyAndOp
));
1394 EXPECT_TRUE(matches("class Y { Y operator&&(Y &); };", AnyAndOp
));
1397 TEST_P(ASTMatchersTest
, HasOverloadedOperatorName_MatchesNestedCalls
) {
1398 if (!GetParam().isCXX()) {
1402 EXPECT_TRUE(matchAndVerifyResultTrue(
1404 "Y& operator&&(Y& x, Y& y) { return x; }; "
1405 "Y a; Y b; Y c; Y d = a && b && c;",
1406 cxxOperatorCallExpr(hasOverloadedOperatorName("&&")).bind("x"),
1407 std::make_unique
<VerifyIdIsBoundTo
<CXXOperatorCallExpr
>>("x", 2)));
1408 EXPECT_TRUE(matches("class Y { }; "
1409 "Y& operator&&(Y& x, Y& y) { return x; }; "
1410 "Y a; Y b; Y c; Y d = a && b && c;",
1411 cxxOperatorCallExpr(hasParent(cxxOperatorCallExpr()))));
1413 matches("class Y { }; "
1414 "Y& operator&&(Y& x, Y& y) { return x; }; "
1415 "Y a; Y b; Y c; Y d = a && b && c;",
1416 cxxOperatorCallExpr(hasDescendant(cxxOperatorCallExpr()))));
1419 TEST_P(ASTMatchersTest
, HasLocalStorage
) {
1420 auto M
= varDecl(hasName("X"), hasLocalStorage());
1421 EXPECT_TRUE(matches("void f() { int X; }", M
));
1422 EXPECT_TRUE(notMatches("int X;", M
));
1423 EXPECT_TRUE(notMatches("void f() { static int X; }", M
));
1426 TEST_P(ASTMatchersTest
, HasGlobalStorage
) {
1427 auto M
= varDecl(hasName("X"), hasGlobalStorage());
1428 EXPECT_TRUE(notMatches("void f() { int X; }", M
));
1429 EXPECT_TRUE(matches("int X;", M
));
1430 EXPECT_TRUE(matches("void f() { static int X; }", M
));
1433 TEST_P(ASTMatchersTest
, IsStaticLocal
) {
1434 auto M
= varDecl(isStaticLocal());
1435 EXPECT_TRUE(matches("void f() { static int X; }", M
));
1436 EXPECT_TRUE(notMatches("static int X;", M
));
1437 EXPECT_TRUE(notMatches("void f() { int X; }", M
));
1438 EXPECT_TRUE(notMatches("int X;", M
));
1441 TEST_P(ASTMatchersTest
, IsInitCapture
) {
1442 if (!GetParam().isCXX11OrLater()) {
1445 auto M
= varDecl(hasName("vd"), isInitCapture());
1446 EXPECT_TRUE(notMatches(
1447 "int main() { int vd = 3; auto f = [vd]() { return vd; }; }", M
));
1449 if (!GetParam().isCXX14OrLater()) {
1452 EXPECT_TRUE(matches("int main() { auto f = [vd=3]() { return vd; }; }", M
));
1453 EXPECT_TRUE(matches(
1454 "int main() { int x = 3; auto f = [vd=x]() { return vd; }; }", M
));
1457 TEST_P(ASTMatchersTest
, StorageDuration
) {
1459 "void f() { int x; static int y; } int a;static int b;extern int c;";
1461 EXPECT_TRUE(matches(T
, varDecl(hasName("x"), hasAutomaticStorageDuration())));
1463 notMatches(T
, varDecl(hasName("y"), hasAutomaticStorageDuration())));
1465 notMatches(T
, varDecl(hasName("a"), hasAutomaticStorageDuration())));
1467 EXPECT_TRUE(matches(T
, varDecl(hasName("y"), hasStaticStorageDuration())));
1468 EXPECT_TRUE(matches(T
, varDecl(hasName("a"), hasStaticStorageDuration())));
1469 EXPECT_TRUE(matches(T
, varDecl(hasName("b"), hasStaticStorageDuration())));
1470 EXPECT_TRUE(matches(T
, varDecl(hasName("c"), hasStaticStorageDuration())));
1471 EXPECT_TRUE(notMatches(T
, varDecl(hasName("x"), hasStaticStorageDuration())));
1473 // FIXME: Add thread_local variables to the source code snippet.
1474 EXPECT_TRUE(notMatches(T
, varDecl(hasName("x"), hasThreadStorageDuration())));
1475 EXPECT_TRUE(notMatches(T
, varDecl(hasName("y"), hasThreadStorageDuration())));
1476 EXPECT_TRUE(notMatches(T
, varDecl(hasName("a"), hasThreadStorageDuration())));
1479 TEST_P(ASTMatchersTest
, VarDecl_MatchesFunctionParameter
) {
1480 EXPECT_TRUE(matches("void f(int i) {}", varDecl(hasName("i"))));
1483 TEST_P(ASTMatchersTest
, SizeOfExpr_MatchesCorrectType
) {
1484 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }",
1485 sizeOfExpr(hasArgumentOfType(asString("int")))));
1486 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }",
1487 sizeOfExpr(hasArgumentOfType(asString("float")))));
1488 EXPECT_TRUE(matches(
1489 "struct A {}; void x() { struct A a; int b = sizeof(a); }",
1490 sizeOfExpr(hasArgumentOfType(hasDeclaration(recordDecl(hasName("A")))))));
1491 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }",
1492 sizeOfExpr(hasArgumentOfType(
1493 hasDeclaration(recordDecl(hasName("string")))))));
1496 TEST_P(ASTMatchersTest
, IsInteger_MatchesIntegers
) {
1497 EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isInteger()))));
1499 matches("long long i = 0; void f(long long) { }; void g() {f(i);}",
1500 callExpr(hasArgument(
1501 0, declRefExpr(to(varDecl(hasType(isInteger()))))))));
1504 TEST_P(ASTMatchersTest
, IsInteger_ReportsNoFalsePositives
) {
1505 if (!GetParam().isCXX()) {
1506 // FIXME: Add a similar negative test for `isInteger()` that does not depend
1511 EXPECT_TRUE(notMatches("int *i;", varDecl(hasType(isInteger()))));
1513 notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}",
1514 callExpr(hasArgument(
1515 0, declRefExpr(to(varDecl(hasType(isInteger()))))))));
1518 TEST_P(ASTMatchersTest
, IsSignedInteger_MatchesSignedIntegers
) {
1519 EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isSignedInteger()))));
1521 notMatches("unsigned i = 0;", varDecl(hasType(isSignedInteger()))));
1524 TEST_P(ASTMatchersTest
, IsUnsignedInteger_MatchesUnsignedIntegers
) {
1525 EXPECT_TRUE(notMatches("int i = 0;", varDecl(hasType(isUnsignedInteger()))));
1527 matches("unsigned i = 0;", varDecl(hasType(isUnsignedInteger()))));
1530 TEST_P(ASTMatchersTest
, IsAnyPointer_MatchesPointers
) {
1531 if (!GetParam().isCXX11OrLater()) {
1532 // FIXME: Add a test for `isAnyPointer()` that does not depend on C++.
1536 EXPECT_TRUE(matches("int* i = nullptr;", varDecl(hasType(isAnyPointer()))));
1539 TEST_P(ASTMatchersTest
, IsAnyPointer_MatchesObjcPointer
) {
1540 EXPECT_TRUE(matchesObjC("@interface Foo @end Foo *f;",
1541 varDecl(hasType(isAnyPointer()))));
1544 TEST_P(ASTMatchersTest
, IsAnyPointer_ReportsNoFalsePositives
) {
1545 EXPECT_TRUE(notMatches("int i = 0;", varDecl(hasType(isAnyPointer()))));
1548 TEST_P(ASTMatchersTest
, IsAnyCharacter_MatchesCharacters
) {
1549 EXPECT_TRUE(matches("char i = 0;", varDecl(hasType(isAnyCharacter()))));
1552 TEST_P(ASTMatchersTest
, IsAnyCharacter_ReportsNoFalsePositives
) {
1553 EXPECT_TRUE(notMatches("int i;", varDecl(hasType(isAnyCharacter()))));
1556 TEST_P(ASTMatchersTest
, IsArrow_MatchesMemberVariablesViaArrow
) {
1557 if (!GetParam().isCXX()) {
1558 // FIXME: Add a test for `isArrow()` that does not depend on C++.
1561 if (GetParam().hasDelayedTemplateParsing()) {
1562 // FIXME: Fix this test to work with delayed template parsing.
1566 EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };",
1567 memberExpr(isArrow())));
1569 matches("class Y { void x() { y; } int y; };", memberExpr(isArrow())));
1570 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };",
1571 memberExpr(isArrow())));
1572 EXPECT_TRUE(matches("template <class T> class Y { void x() { this->m; } };",
1573 cxxDependentScopeMemberExpr(isArrow())));
1575 notMatches("template <class T> class Y { void x() { (*this).m; } };",
1576 cxxDependentScopeMemberExpr(isArrow())));
1579 TEST_P(ASTMatchersTest
, IsArrow_MatchesStaticMemberVariablesViaArrow
) {
1580 if (!GetParam().isCXX()) {
1581 // FIXME: Add a test for `isArrow()` that does not depend on C++.
1585 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
1586 memberExpr(isArrow())));
1587 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
1588 memberExpr(isArrow())));
1589 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } static int y; };",
1590 memberExpr(isArrow())));
1593 TEST_P(ASTMatchersTest
, IsArrow_MatchesMemberCallsViaArrow
) {
1594 if (!GetParam().isCXX()) {
1595 // FIXME: Add a test for `isArrow()` that does not depend on C++.
1598 if (GetParam().hasDelayedTemplateParsing()) {
1599 // FIXME: Fix this test to work with delayed template parsing.
1604 matches("class Y { void x() { this->x(); } };", memberExpr(isArrow())));
1605 EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpr(isArrow())));
1606 EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",
1607 memberExpr(isArrow())));
1609 matches("class Y { template <class T> void x() { this->x<T>(); } };",
1610 unresolvedMemberExpr(isArrow())));
1611 EXPECT_TRUE(matches("class Y { template <class T> void x() { x<T>(); } };",
1612 unresolvedMemberExpr(isArrow())));
1614 notMatches("class Y { template <class T> void x() { (*this).x<T>(); } };",
1615 unresolvedMemberExpr(isArrow())));
1618 TEST_P(ASTMatchersTest
, IsExplicit_CXXConversionDecl
) {
1619 if (!GetParam().isCXX11OrLater()) {
1623 EXPECT_TRUE(matches("struct S { explicit operator int(); };",
1624 cxxConversionDecl(isExplicit())));
1625 EXPECT_TRUE(notMatches("struct S { operator int(); };",
1626 cxxConversionDecl(isExplicit())));
1629 TEST_P(ASTMatchersTest
, IsExplicit_CXXConversionDecl_CXX20
) {
1630 if (!GetParam().isCXX20OrLater()) {
1635 notMatches("template<bool b> struct S { explicit(b) operator int(); };",
1636 cxxConversionDecl(isExplicit())));
1637 EXPECT_TRUE(matches("struct S { explicit(true) operator int(); };",
1638 cxxConversionDecl(isExplicit())));
1639 EXPECT_TRUE(notMatches("struct S { explicit(false) operator int(); };",
1640 cxxConversionDecl(isExplicit())));
1643 TEST_P(ASTMatchersTest
, ArgumentCountAtLeast_CallExpr
) {
1644 StatementMatcher Call2PlusArgs
= callExpr(argumentCountAtLeast(2));
1646 EXPECT_TRUE(notMatches("void x(void) { x(); }", Call2PlusArgs
));
1647 EXPECT_TRUE(notMatches("void x(int) { x(0); }", Call2PlusArgs
));
1648 EXPECT_TRUE(matches("void x(int, int) { x(0, 0); }", Call2PlusArgs
));
1649 EXPECT_TRUE(matches("void x(int, int, int) { x(0, 0, 0); }", Call2PlusArgs
));
1651 if (!GetParam().isCXX()) {
1656 notMatches("void x(int = 1) { x(); }", traverse(TK_AsIs
, Call2PlusArgs
)));
1657 EXPECT_TRUE(matches("void x(int, int = 1) { x(0); }",
1658 traverse(TK_AsIs
, Call2PlusArgs
)));
1659 EXPECT_TRUE(matches("void x(int, int = 1, int = 1) { x(0); }",
1660 traverse(TK_AsIs
, Call2PlusArgs
)));
1661 EXPECT_TRUE(matches("void x(int, int, int = 1) { x(0, 0); }",
1662 traverse(TK_AsIs
, Call2PlusArgs
)));
1663 EXPECT_TRUE(matches("void x(int, int, int, int = 1) { x(0, 0, 0); }",
1664 traverse(TK_AsIs
, Call2PlusArgs
)));
1667 notMatches("void x(int = 1) { x(); }",
1668 traverse(TK_IgnoreUnlessSpelledInSource
, Call2PlusArgs
)));
1670 notMatches("void x(int, int = 1) { x(0); }",
1671 traverse(TK_IgnoreUnlessSpelledInSource
, Call2PlusArgs
)));
1673 notMatches("void x(int, int = 1, int = 1) { x(0); }",
1674 traverse(TK_IgnoreUnlessSpelledInSource
, Call2PlusArgs
)));
1675 EXPECT_TRUE(matches("void x(int, int, int = 1) { x(0, 0); }",
1676 traverse(TK_IgnoreUnlessSpelledInSource
, Call2PlusArgs
)));
1677 EXPECT_TRUE(matches("void x(int, int, int, int = 1) { x(0, 0, 0); }",
1678 traverse(TK_IgnoreUnlessSpelledInSource
, Call2PlusArgs
)));
1681 TEST_P(ASTMatchersTest
, ArgumentCountAtLeast_CallExpr_CXX
) {
1682 if (!GetParam().isCXX()) {
1686 StatementMatcher Call2PlusArgs
= callExpr(argumentCountAtLeast(2));
1687 EXPECT_TRUE(notMatches("class X { void x() { x(); } };", Call2PlusArgs
));
1688 EXPECT_TRUE(notMatches("class X { void x(int) { x(0); } };", Call2PlusArgs
));
1690 matches("class X { void x(int, int) { x(0, 0); } };", Call2PlusArgs
));
1691 EXPECT_TRUE(matches("class X { void x(int, int, int) { x(0, 0, 0); } };",
1694 EXPECT_TRUE(notMatches("class X { void x(int = 1) { x(0); } };",
1695 traverse(TK_AsIs
, Call2PlusArgs
)));
1696 EXPECT_TRUE(matches("class X { void x(int, int = 1) { x(0); } };",
1697 traverse(TK_AsIs
, Call2PlusArgs
)));
1698 EXPECT_TRUE(matches("class X { void x(int, int = 1, int = 1) { x(0); } };",
1699 traverse(TK_AsIs
, Call2PlusArgs
)));
1700 EXPECT_TRUE(matches("class X { void x(int, int, int = 1) { x(0, 0); } };",
1701 traverse(TK_AsIs
, Call2PlusArgs
)));
1703 matches("class X { void x(int, int, int, int = 1) { x(0, 0, 0); } };",
1704 traverse(TK_AsIs
, Call2PlusArgs
)));
1707 notMatches("class X { void x(int = 1) { x(0); } };",
1708 traverse(TK_IgnoreUnlessSpelledInSource
, Call2PlusArgs
)));
1710 notMatches("class X { void x(int, int = 1) { x(0); } };",
1711 traverse(TK_IgnoreUnlessSpelledInSource
, Call2PlusArgs
)));
1713 notMatches("class X { void x(int, int = 1, int = 1) { x(0); } };",
1714 traverse(TK_IgnoreUnlessSpelledInSource
, Call2PlusArgs
)));
1715 EXPECT_TRUE(matches("class X { void x(int, int, int = 1) { x(0, 0); } };",
1716 traverse(TK_IgnoreUnlessSpelledInSource
, Call2PlusArgs
)));
1718 matches("class X { void x(int, int, int, int = 1) { x(0, 0, 0); } };",
1719 traverse(TK_IgnoreUnlessSpelledInSource
, Call2PlusArgs
)));
1722 notMatches("class X { static void x() { x(); } };", Call2PlusArgs
));
1724 notMatches("class X { static void x(int) { x(0); } };", Call2PlusArgs
));
1725 EXPECT_TRUE(matches("class X { static void x(int, int) { x(0, 0); } };",
1728 matches("class X { static void x(int, int, int) { x(0, 0, 0); } };",
1732 TEST_P(ASTMatchersTest
, ArgumentCountIs_CallExpr
) {
1733 StatementMatcher Call1Arg
= callExpr(argumentCountIs(1));
1735 EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg
));
1736 EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg
));
1739 TEST_P(ASTMatchersTest
, ArgumentCountIs_CallExpr_CXX
) {
1740 if (!GetParam().isCXX()) {
1744 StatementMatcher Call1Arg
= callExpr(argumentCountIs(1));
1745 EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg
));
1748 TEST_P(ASTMatchersTest
, ParameterCountIs
) {
1749 DeclarationMatcher Function1Arg
= functionDecl(parameterCountIs(1));
1750 EXPECT_TRUE(matches("void f(int i) {}", Function1Arg
));
1751 EXPECT_TRUE(notMatches("void f() {}", Function1Arg
));
1752 EXPECT_TRUE(notMatches("void f(int i, int j, int k) {}", Function1Arg
));
1753 EXPECT_TRUE(matches("void f(int i, ...) {};", Function1Arg
));
1756 TEST_P(ASTMatchersTest
, ParameterCountIs_CXX
) {
1757 if (!GetParam().isCXX()) {
1761 DeclarationMatcher Function1Arg
= functionDecl(parameterCountIs(1));
1762 EXPECT_TRUE(matches("class X { void f(int i) {} };", Function1Arg
));
1765 TEST_P(ASTMatchersTest
, References
) {
1766 if (!GetParam().isCXX()) {
1767 // FIXME: Add a test for `references()` that does not depend on C++.
1771 DeclarationMatcher ReferenceClassX
=
1772 varDecl(hasType(references(recordDecl(hasName("X")))));
1774 matches("class X {}; void y(X y) { X &x = y; }", ReferenceClassX
));
1776 matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX
));
1777 // The match here is on the implicit copy constructor code for
1778 // class X, not on code 'X x = y'.
1779 EXPECT_TRUE(matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX
));
1780 EXPECT_TRUE(notMatches("class X {}; extern X x;", ReferenceClassX
));
1782 notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX
));
1785 TEST_P(ASTMatchersTest
, HasLocalQualifiers
) {
1786 if (!GetParam().isCXX11OrLater()) {
1787 // FIXME: Add a test for `hasLocalQualifiers()` that does not depend on C++.
1791 EXPECT_TRUE(notMatches("typedef const int const_int; const_int i = 1;",
1792 varDecl(hasType(hasLocalQualifiers()))));
1793 EXPECT_TRUE(matches("int *const j = nullptr;",
1794 varDecl(hasType(hasLocalQualifiers()))));
1796 matches("int *volatile k;", varDecl(hasType(hasLocalQualifiers()))));
1797 EXPECT_TRUE(notMatches("int m;", varDecl(hasType(hasLocalQualifiers()))));
1800 TEST_P(ASTMatchersTest
, IsExternC_MatchesExternCFunctionDeclarations
) {
1801 if (!GetParam().isCXX()) {
1805 EXPECT_TRUE(matches("extern \"C\" void f() {}", functionDecl(isExternC())));
1807 matches("extern \"C\" { void f() {} }", functionDecl(isExternC())));
1808 EXPECT_TRUE(notMatches("void f() {}", functionDecl(isExternC())));
1811 TEST_P(ASTMatchersTest
, IsExternC_MatchesExternCVariableDeclarations
) {
1812 if (!GetParam().isCXX()) {
1816 EXPECT_TRUE(matches("extern \"C\" int i;", varDecl(isExternC())));
1817 EXPECT_TRUE(matches("extern \"C\" { int i; }", varDecl(isExternC())));
1818 EXPECT_TRUE(notMatches("int i;", varDecl(isExternC())));
1821 TEST_P(ASTMatchersTest
, IsStaticStorageClass
) {
1823 matches("static void f() {}", functionDecl(isStaticStorageClass())));
1824 EXPECT_TRUE(matches("static int i = 1;", varDecl(isStaticStorageClass())));
1825 EXPECT_TRUE(notMatches("int i = 1;", varDecl(isStaticStorageClass())));
1826 EXPECT_TRUE(notMatches("extern int i;", varDecl(isStaticStorageClass())));
1827 EXPECT_TRUE(notMatches("void f() {}", functionDecl(isStaticStorageClass())));
1830 TEST_P(ASTMatchersTest
, IsDefaulted
) {
1831 if (!GetParam().isCXX()) {
1835 EXPECT_TRUE(notMatches("class A { ~A(); };",
1836 functionDecl(hasName("~A"), isDefaulted())));
1837 EXPECT_TRUE(matches("class B { ~B() = default; };",
1838 functionDecl(hasName("~B"), isDefaulted())));
1841 TEST_P(ASTMatchersTest
, IsDeleted
) {
1842 if (!GetParam().isCXX()) {
1847 notMatches("void Func();", functionDecl(hasName("Func"), isDeleted())));
1848 EXPECT_TRUE(matches("void Func() = delete;",
1849 functionDecl(hasName("Func"), isDeleted())));
1852 TEST_P(ASTMatchersTest
, IsNoThrow_DynamicExceptionSpec
) {
1853 if (!GetParam().supportsCXXDynamicExceptionSpecification()) {
1857 EXPECT_TRUE(notMatches("void f();", functionDecl(isNoThrow())));
1858 EXPECT_TRUE(notMatches("void f() throw(int);", functionDecl(isNoThrow())));
1859 EXPECT_TRUE(matches("void f() throw();", functionDecl(isNoThrow())));
1861 EXPECT_TRUE(notMatches("void f();", functionProtoType(isNoThrow())));
1863 notMatches("void f() throw(int);", functionProtoType(isNoThrow())));
1864 EXPECT_TRUE(matches("void f() throw();", functionProtoType(isNoThrow())));
1867 TEST_P(ASTMatchersTest
, IsNoThrow_CXX11
) {
1868 if (!GetParam().isCXX11OrLater()) {
1873 notMatches("void f() noexcept(false);", functionDecl(isNoThrow())));
1874 EXPECT_TRUE(matches("void f() noexcept;", functionDecl(isNoThrow())));
1877 notMatches("void f() noexcept(false);", functionProtoType(isNoThrow())));
1878 EXPECT_TRUE(matches("void f() noexcept;", functionProtoType(isNoThrow())));
1881 TEST_P(ASTMatchersTest
, IsConsteval
) {
1882 if (!GetParam().isCXX20OrLater())
1885 EXPECT_TRUE(matches("consteval int bar();",
1886 functionDecl(hasName("bar"), isConsteval())));
1887 EXPECT_TRUE(notMatches("constexpr int bar();",
1888 functionDecl(hasName("bar"), isConsteval())));
1890 notMatches("int bar();", functionDecl(hasName("bar"), isConsteval())));
1893 TEST_P(ASTMatchersTest
, IsConsteval_MatchesIfConsteval
) {
1894 if (!GetParam().isCXX20OrLater())
1897 EXPECT_TRUE(matches("void baz() { if consteval {} }", ifStmt(isConsteval())));
1899 matches("void baz() { if ! consteval {} }", ifStmt(isConsteval())));
1900 EXPECT_TRUE(matches("void baz() { if ! consteval {} else {} }",
1901 ifStmt(isConsteval())));
1903 matches("void baz() { if not consteval {} }", ifStmt(isConsteval())));
1904 EXPECT_TRUE(notMatches("void baz() { if constexpr(1 > 0) {} }",
1905 ifStmt(isConsteval())));
1907 notMatches("void baz() { if (1 > 0) {} }", ifStmt(isConsteval())));
1910 TEST_P(ASTMatchersTest
, IsConstexpr
) {
1911 if (!GetParam().isCXX11OrLater()) {
1915 EXPECT_TRUE(matches("constexpr int foo = 42;",
1916 varDecl(hasName("foo"), isConstexpr())));
1917 EXPECT_TRUE(matches("constexpr int bar();",
1918 functionDecl(hasName("bar"), isConstexpr())));
1921 TEST_P(ASTMatchersTest
, IsConstexpr_MatchesIfConstexpr
) {
1922 if (!GetParam().isCXX17OrLater()) {
1927 matches("void baz() { if constexpr(1 > 0) {} }", ifStmt(isConstexpr())));
1929 notMatches("void baz() { if (1 > 0) {} }", ifStmt(isConstexpr())));
1932 TEST_P(ASTMatchersTest
, IsConstinit
) {
1933 if (!GetParam().isCXX20OrLater())
1936 EXPECT_TRUE(matches("constinit int foo = 1;",
1937 varDecl(hasName("foo"), isConstinit())));
1938 EXPECT_TRUE(matches("extern constinit int foo;",
1939 varDecl(hasName("foo"), isConstinit())));
1940 EXPECT_TRUE(matches("constinit const char* foo = \"bar\";",
1941 varDecl(hasName("foo"), isConstinit())));
1943 notMatches("[[clang::require_constant_initialization]] int foo = 1;",
1944 varDecl(hasName("foo"), isConstinit())));
1945 EXPECT_TRUE(notMatches("constexpr int foo = 1;",
1946 varDecl(hasName("foo"), isConstinit())));
1947 EXPECT_TRUE(notMatches("static inline int foo = 1;",
1948 varDecl(hasName("foo"), isConstinit())));
1951 TEST_P(ASTMatchersTest
, HasInitStatement_MatchesSelectionInitializers
) {
1952 EXPECT_TRUE(notMatches("void baz() { if (1 > 0) {} }",
1953 ifStmt(hasInitStatement(anything()))));
1954 EXPECT_TRUE(notMatches("void baz(int i) { switch (i) { default: break; } }",
1955 switchStmt(hasInitStatement(anything()))));
1958 TEST_P(ASTMatchersTest
, HasInitStatement_MatchesSelectionInitializers_CXX
) {
1959 if (!GetParam().isCXX()) {
1963 EXPECT_TRUE(notMatches("void baz() { if (int i = 1) {} }",
1964 ifStmt(hasInitStatement(anything()))));
1967 TEST_P(ASTMatchersTest
, HasInitStatement_MatchesSelectionInitializers_CXX17
) {
1968 if (!GetParam().isCXX17OrLater()) {
1972 EXPECT_TRUE(matches("void baz() { if (int i = 1; i > 0) {} }",
1973 ifStmt(hasInitStatement(anything()))));
1975 matches("void baz(int i) { switch (int j = i; j) { default: break; } }",
1976 switchStmt(hasInitStatement(anything()))));
1979 TEST_P(ASTMatchersTest
, HasInitStatement_MatchesRangeForInitializers
) {
1980 if (!GetParam().isCXX20OrLater()) {
1984 EXPECT_TRUE(matches("void baz() {"
1986 "for (auto &arr = items; auto &item : arr) {}"
1988 cxxForRangeStmt(hasInitStatement(anything()))));
1989 EXPECT_TRUE(notMatches("void baz() {"
1991 "for (auto &item : items) {}"
1993 cxxForRangeStmt(hasInitStatement(anything()))));
1996 TEST_P(ASTMatchersTest
, TemplateArgumentCountIs
) {
1997 if (!GetParam().isCXX()) {
2002 matches("template<typename T> struct C {}; C<int> c;",
2003 classTemplateSpecializationDecl(templateArgumentCountIs(1))));
2005 notMatches("template<typename T> struct C {}; C<int> c;",
2006 classTemplateSpecializationDecl(templateArgumentCountIs(2))));
2008 EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
2009 templateSpecializationType(templateArgumentCountIs(1))));
2011 notMatches("template<typename T> struct C {}; C<int> c;",
2012 templateSpecializationType(templateArgumentCountIs(2))));
2015 TEST_P(ASTMatchersTest
, IsIntegral
) {
2016 if (!GetParam().isCXX()) {
2020 EXPECT_TRUE(matches(
2021 "template<int T> struct C {}; C<42> c;",
2022 classTemplateSpecializationDecl(hasAnyTemplateArgument(isIntegral()))));
2023 EXPECT_TRUE(notMatches("template<typename T> struct C {}; C<int> c;",
2024 classTemplateSpecializationDecl(hasAnyTemplateArgument(
2025 templateArgument(isIntegral())))));
2028 TEST_P(ASTMatchersTest
, EqualsIntegralValue
) {
2029 if (!GetParam().isCXX()) {
2033 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
2034 classTemplateSpecializationDecl(
2035 hasAnyTemplateArgument(equalsIntegralValue("42")))));
2036 EXPECT_TRUE(matches("template<int T> struct C {}; C<-42> c;",
2037 classTemplateSpecializationDecl(
2038 hasAnyTemplateArgument(equalsIntegralValue("-42")))));
2039 EXPECT_TRUE(matches("template<int T> struct C {}; C<-0042> c;",
2040 classTemplateSpecializationDecl(
2041 hasAnyTemplateArgument(equalsIntegralValue("-34")))));
2042 EXPECT_TRUE(notMatches("template<int T> struct C {}; C<42> c;",
2043 classTemplateSpecializationDecl(hasAnyTemplateArgument(
2044 equalsIntegralValue("0042")))));
2047 TEST_P(ASTMatchersTest
, AccessSpecDecl
) {
2048 if (!GetParam().isCXX()) {
2052 EXPECT_TRUE(matches("class C { public: int i; };", accessSpecDecl()));
2054 matches("class C { public: int i; };", accessSpecDecl(isPublic())));
2056 notMatches("class C { public: int i; };", accessSpecDecl(isProtected())));
2058 notMatches("class C { public: int i; };", accessSpecDecl(isPrivate())));
2060 EXPECT_TRUE(notMatches("class C { int i; };", accessSpecDecl()));
2063 TEST_P(ASTMatchersTest
, IsFinal
) {
2064 if (!GetParam().isCXX11OrLater()) {
2068 EXPECT_TRUE(matches("class X final {};", cxxRecordDecl(isFinal())));
2069 EXPECT_TRUE(matches("class X { virtual void f() final; };",
2070 cxxMethodDecl(isFinal())));
2071 EXPECT_TRUE(notMatches("class X {};", cxxRecordDecl(isFinal())));
2073 notMatches("class X { virtual void f(); };", cxxMethodDecl(isFinal())));
2076 TEST_P(ASTMatchersTest
, IsVirtual
) {
2077 if (!GetParam().isCXX()) {
2081 EXPECT_TRUE(matches("class X { virtual int f(); };",
2082 cxxMethodDecl(isVirtual(), hasName("::X::f"))));
2083 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isVirtual())));
2086 TEST_P(ASTMatchersTest
, IsVirtualAsWritten
) {
2087 if (!GetParam().isCXX()) {
2091 EXPECT_TRUE(matches("class A { virtual int f(); };"
2092 "class B : public A { int f(); };",
2093 cxxMethodDecl(isVirtualAsWritten(), hasName("::A::f"))));
2095 notMatches("class A { virtual int f(); };"
2096 "class B : public A { int f(); };",
2097 cxxMethodDecl(isVirtualAsWritten(), hasName("::B::f"))));
2100 TEST_P(ASTMatchersTest
, IsPure
) {
2101 if (!GetParam().isCXX()) {
2105 EXPECT_TRUE(matches("class X { virtual int f() = 0; };",
2106 cxxMethodDecl(isPure(), hasName("::X::f"))));
2107 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isPure())));
2110 TEST_P(ASTMatchersTest
, IsCopyAssignmentOperator
) {
2111 if (!GetParam().isCXX()) {
2115 auto CopyAssignment
=
2116 cxxMethodDecl(isCopyAssignmentOperator(), unless(isImplicit()));
2117 EXPECT_TRUE(matches("class X { X &operator=(X); };", CopyAssignment
));
2118 EXPECT_TRUE(matches("class X { X &operator=(X &); };", CopyAssignment
));
2119 EXPECT_TRUE(matches("class X { X &operator=(const X &); };", CopyAssignment
));
2120 EXPECT_TRUE(matches("class X { X &operator=(volatile X &); };", //
2122 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &); };",
2124 EXPECT_TRUE(notMatches("class X { X &operator=(X &&); };", CopyAssignment
));
2127 TEST_P(ASTMatchersTest
, IsMoveAssignmentOperator
) {
2128 if (!GetParam().isCXX()) {
2132 auto MoveAssignment
=
2133 cxxMethodDecl(isMoveAssignmentOperator(), unless(isImplicit()));
2134 EXPECT_TRUE(notMatches("class X { X &operator=(X); };", MoveAssignment
));
2135 EXPECT_TRUE(matches("class X { X &operator=(X &&); };", MoveAssignment
));
2136 EXPECT_TRUE(matches("class X { X &operator=(const X &&); };", //
2138 EXPECT_TRUE(matches("class X { X &operator=(volatile X &&); };", //
2140 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &&); };",
2142 EXPECT_TRUE(notMatches("class X { X &operator=(X &); };", MoveAssignment
));
2145 TEST_P(ASTMatchersTest
, IsConst
) {
2146 if (!GetParam().isCXX()) {
2151 matches("struct A { void foo() const; };", cxxMethodDecl(isConst())));
2153 notMatches("struct A { void foo(); };", cxxMethodDecl(isConst())));
2156 TEST_P(ASTMatchersTest
, IsOverride
) {
2157 if (!GetParam().isCXX()) {
2161 EXPECT_TRUE(matches("class X { virtual int f(); }; "
2162 "class Y : public X { int f(); };",
2163 cxxMethodDecl(isOverride(), hasName("::Y::f"))));
2164 EXPECT_TRUE(notMatches("class X { virtual int f(); }; "
2165 "class Y : public X { int f(); };",
2166 cxxMethodDecl(isOverride(), hasName("::X::f"))));
2167 EXPECT_TRUE(notMatches("class X { int f(); }; "
2168 "class Y : public X { int f(); };",
2169 cxxMethodDecl(isOverride())));
2170 EXPECT_TRUE(notMatches("class X { int f(); int f(int); }; ",
2171 cxxMethodDecl(isOverride())));
2173 matches("template <typename Base> struct Y : Base { void f() override;};",
2174 cxxMethodDecl(isOverride(), hasName("::Y::f"))));
2177 TEST_P(ASTMatchersTest
, HasArgument_CXXConstructorDecl
) {
2178 if (!GetParam().isCXX()) {
2182 auto Constructor
= traverse(
2184 cxxConstructExpr(hasArgument(0, declRefExpr(to(varDecl(hasName("y")))))));
2186 EXPECT_TRUE(matches(
2187 "class X { public: X(int); }; void x() { int y; X x(y); }", Constructor
));
2189 matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
2192 matches("class X { public: X(int); }; void x() { int y; X x = y; }",
2194 EXPECT_TRUE(notMatches(
2195 "class X { public: X(int); }; void x() { int z; X x(z); }", Constructor
));
2197 StatementMatcher WrongIndex
=
2198 traverse(TK_AsIs
, cxxConstructExpr(hasArgument(
2199 42, declRefExpr(to(varDecl(hasName("y")))))));
2200 EXPECT_TRUE(notMatches(
2201 "class X { public: X(int); }; void x() { int y; X x(y); }", WrongIndex
));
2204 TEST_P(ASTMatchersTest
, ArgumentCountIs_CXXConstructExpr
) {
2205 if (!GetParam().isCXX()) {
2209 auto Constructor1Arg
=
2210 traverse(TK_AsIs
, cxxConstructExpr(argumentCountIs(1)));
2212 EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x(0); }",
2214 EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x = X(0); }",
2216 EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x = 0; }",
2219 notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
2223 TEST(ASTMatchersTest
, NamesMember_CXXDependentScopeMemberExpr
) {
2225 // Member functions:
2227 auto Code
= "template <typename T> struct S{ void mem(); }; template "
2228 "<typename T> void x() { S<T> s; s.mem(); }";
2230 EXPECT_TRUE(matches(
2232 cxxDependentScopeMemberExpr(
2233 hasObjectExpression(declRefExpr(hasType(elaboratedType(namesType(
2234 templateSpecializationType(hasDeclaration(classTemplateDecl(
2235 has(cxxRecordDecl(has(cxxMethodDecl(hasName("mem"))
2236 .bind("templMem")))))))))))),
2237 memberHasSameNameAsBoundNode("templMem"))));
2240 matches(Code
, cxxDependentScopeMemberExpr(hasMemberName("mem"))));
2243 // Member variables:
2245 auto Code
= "template <typename T> struct S{ int mem; }; template "
2246 "<typename T> void x() { S<T> s; s.mem; }";
2249 matches(Code
, cxxDependentScopeMemberExpr(hasMemberName("mem"))));
2251 EXPECT_TRUE(matches(
2253 cxxDependentScopeMemberExpr(
2254 hasObjectExpression(declRefExpr(
2255 hasType(elaboratedType(namesType(templateSpecializationType(
2256 hasDeclaration(classTemplateDecl(has(cxxRecordDecl(has(
2257 fieldDecl(hasName("mem")).bind("templMem")))))))))))),
2258 memberHasSameNameAsBoundNode("templMem"))));
2261 // static member variables:
2263 auto Code
= "template <typename T> struct S{ static int mem; }; template "
2264 "<typename T> void x() { S<T> s; s.mem; }";
2267 matches(Code
, cxxDependentScopeMemberExpr(hasMemberName("mem"))));
2269 EXPECT_TRUE(matches(
2271 cxxDependentScopeMemberExpr(
2272 hasObjectExpression(declRefExpr(
2273 hasType(elaboratedType(namesType(templateSpecializationType(
2274 hasDeclaration(classTemplateDecl(has(cxxRecordDecl(
2275 has(varDecl(hasName("mem")).bind("templMem")))))))))))),
2276 memberHasSameNameAsBoundNode("templMem"))));
2280 template <typename T>
2282 bool operator==(int) const { return true; }
2285 template <typename T>
2292 EXPECT_TRUE(matches(
2293 Code
, cxxDependentScopeMemberExpr(hasMemberName("operator=="))));
2296 // other named decl:
2298 auto Code
= "template <typename T> struct S{ static int mem; }; struct "
2300 "<typename T> void x() { S<T> s; s.mem; }";
2302 EXPECT_TRUE(matches(
2304 translationUnitDecl(has(cxxRecordDecl(hasName("mem"))),
2305 hasDescendant(cxxDependentScopeMemberExpr()))));
2307 EXPECT_FALSE(matches(
2309 translationUnitDecl(has(cxxRecordDecl(hasName("mem")).bind("templMem")),
2310 hasDescendant(cxxDependentScopeMemberExpr(
2311 memberHasSameNameAsBoundNode("templMem"))))));
2315 TEST(ASTMatchersTest
, ArgumentCountIs_CXXUnresolvedConstructExpr
) {
2317 "template <typename T> struct S{}; template <typename T> void "
2318 "x() { auto s = S<T>(); }";
2320 EXPECT_TRUE(matches(Code
, cxxUnresolvedConstructExpr(argumentCountIs(0))));
2321 EXPECT_TRUE(notMatches(Code
, cxxUnresolvedConstructExpr(argumentCountIs(1))));
2324 TEST(ASTMatchersTest
, HasArgument_CXXUnresolvedConstructExpr
) {
2326 "template <typename T> struct S{ S(int){} }; template <typename "
2327 "T> void x() { int y; auto s = S<T>(y); }";
2328 EXPECT_TRUE(matches(Code
, cxxUnresolvedConstructExpr(hasArgument(
2329 0, declRefExpr(to(varDecl(hasName("y"))))))));
2331 notMatches(Code
, cxxUnresolvedConstructExpr(hasArgument(
2332 0, declRefExpr(to(varDecl(hasName("x"))))))));
2335 TEST_P(ASTMatchersTest
, IsListInitialization
) {
2336 if (!GetParam().isCXX11OrLater()) {
2340 auto ConstructorListInit
=
2341 traverse(TK_AsIs
, varDecl(has(cxxConstructExpr(isListInitialization()))));
2343 EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x{0}; }",
2344 ConstructorListInit
));
2345 EXPECT_FALSE(matches("class X { public: X(int); }; void x() { X x(0); }",
2346 ConstructorListInit
));
2349 TEST_P(ASTMatchersTest
, IsImplicit_CXXConstructorDecl
) {
2350 if (!GetParam().isCXX()) {
2354 // This one doesn't match because the constructor is not added by the
2355 // compiler (it is not needed).
2356 EXPECT_TRUE(notMatches("class Foo { };", cxxConstructorDecl(isImplicit())));
2357 // The compiler added the implicit default constructor.
2358 EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
2359 cxxConstructorDecl(isImplicit())));
2360 EXPECT_TRUE(matches("class Foo { Foo(){} };",
2361 cxxConstructorDecl(unless(isImplicit()))));
2362 // The compiler added an implicit assignment operator.
2363 EXPECT_TRUE(matches("struct A { int x; } a = {0}, b = a; void f() { a = b; }",
2364 cxxMethodDecl(isImplicit(), hasName("operator="))));
2367 TEST_P(ASTMatchersTest
, IsExplicit_CXXConstructorDecl
) {
2368 if (!GetParam().isCXX()) {
2372 EXPECT_TRUE(matches("struct S { explicit S(int); };",
2373 cxxConstructorDecl(isExplicit())));
2375 notMatches("struct S { S(int); };", cxxConstructorDecl(isExplicit())));
2378 TEST_P(ASTMatchersTest
, IsExplicit_CXXConstructorDecl_CXX20
) {
2379 if (!GetParam().isCXX20OrLater()) {
2383 EXPECT_TRUE(notMatches("template<bool b> struct S { explicit(b) S(int);};",
2384 cxxConstructorDecl(isExplicit())));
2385 EXPECT_TRUE(matches("struct S { explicit(true) S(int);};",
2386 cxxConstructorDecl(isExplicit())));
2387 EXPECT_TRUE(notMatches("struct S { explicit(false) S(int);};",
2388 cxxConstructorDecl(isExplicit())));
2391 TEST_P(ASTMatchersTest
, IsExplicit_CXXDeductionGuideDecl
) {
2392 if (!GetParam().isCXX17OrLater()) {
2396 EXPECT_TRUE(notMatches("template<typename T> struct S { S(int);};"
2397 "S(int) -> S<int>;",
2398 cxxDeductionGuideDecl(isExplicit())));
2399 EXPECT_TRUE(matches("template<typename T> struct S { S(int);};"
2400 "explicit S(int) -> S<int>;",
2401 cxxDeductionGuideDecl(isExplicit())));
2404 TEST_P(ASTMatchersTest
, IsExplicit_CXXDeductionGuideDecl_CXX20
) {
2405 if (!GetParam().isCXX20OrLater()) {
2409 EXPECT_TRUE(matches("template<typename T> struct S { S(int);};"
2410 "explicit(true) S(int) -> S<int>;",
2411 cxxDeductionGuideDecl(isExplicit())));
2412 EXPECT_TRUE(notMatches("template<typename T> struct S { S(int);};"
2413 "explicit(false) S(int) -> S<int>;",
2414 cxxDeductionGuideDecl(isExplicit())));
2416 notMatches("template<typename T> struct S { S(int);};"
2417 "template<bool b = true> explicit(b) S(int) -> S<int>;",
2418 cxxDeductionGuideDecl(isExplicit())));
2421 TEST_P(ASTMatchersTest
, CXXConstructorDecl_Kinds
) {
2422 if (!GetParam().isCXX()) {
2427 matches("struct S { S(); };", cxxConstructorDecl(isDefaultConstructor(),
2428 unless(isImplicit()))));
2429 EXPECT_TRUE(notMatches(
2430 "struct S { S(); };",
2431 cxxConstructorDecl(isCopyConstructor(), unless(isImplicit()))));
2432 EXPECT_TRUE(notMatches(
2433 "struct S { S(); };",
2434 cxxConstructorDecl(isMoveConstructor(), unless(isImplicit()))));
2436 EXPECT_TRUE(notMatches(
2437 "struct S { S(const S&); };",
2438 cxxConstructorDecl(isDefaultConstructor(), unless(isImplicit()))));
2440 matches("struct S { S(const S&); };",
2441 cxxConstructorDecl(isCopyConstructor(), unless(isImplicit()))));
2442 EXPECT_TRUE(notMatches(
2443 "struct S { S(const S&); };",
2444 cxxConstructorDecl(isMoveConstructor(), unless(isImplicit()))));
2446 EXPECT_TRUE(notMatches(
2447 "struct S { S(S&&); };",
2448 cxxConstructorDecl(isDefaultConstructor(), unless(isImplicit()))));
2449 EXPECT_TRUE(notMatches(
2450 "struct S { S(S&&); };",
2451 cxxConstructorDecl(isCopyConstructor(), unless(isImplicit()))));
2453 matches("struct S { S(S&&); };",
2454 cxxConstructorDecl(isMoveConstructor(), unless(isImplicit()))));
2457 TEST_P(ASTMatchersTest
, IsUserProvided
) {
2458 if (!GetParam().isCXX11OrLater()) {
2462 EXPECT_TRUE(notMatches("struct S { int X = 0; };",
2463 cxxConstructorDecl(isUserProvided())));
2464 EXPECT_TRUE(notMatches("struct S { S() = default; };",
2465 cxxConstructorDecl(isUserProvided())));
2466 EXPECT_TRUE(notMatches("struct S { S() = delete; };",
2467 cxxConstructorDecl(isUserProvided())));
2469 matches("struct S { S(); };", cxxConstructorDecl(isUserProvided())));
2470 EXPECT_TRUE(matches("struct S { S(); }; S::S(){}",
2471 cxxConstructorDecl(isUserProvided())));
2474 TEST_P(ASTMatchersTest
, IsDelegatingConstructor
) {
2475 if (!GetParam().isCXX11OrLater()) {
2479 EXPECT_TRUE(notMatches("struct S { S(); S(int); int X; };",
2480 cxxConstructorDecl(isDelegatingConstructor())));
2481 EXPECT_TRUE(notMatches("struct S { S(){} S(int X) : X(X) {} int X; };",
2482 cxxConstructorDecl(isDelegatingConstructor())));
2483 EXPECT_TRUE(matches(
2484 "struct S { S() : S(0) {} S(int X) : X(X) {} int X; };",
2485 cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(0))));
2486 EXPECT_TRUE(matches(
2487 "struct S { S(); S(int X); int X; }; S::S(int X) : S() {}",
2488 cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(1))));
2491 TEST_P(ASTMatchersTest
, HasSize
) {
2492 StatementMatcher Literal
= stringLiteral(hasSize(4));
2493 EXPECT_TRUE(matches("const char *s = \"abcd\";", Literal
));
2494 // with escaped characters
2495 EXPECT_TRUE(matches("const char *s = \"\x05\x06\x07\x08\";", Literal
));
2496 // no matching, too small
2497 EXPECT_TRUE(notMatches("const char *s = \"ab\";", Literal
));
2500 TEST_P(ASTMatchersTest
, HasSize_CXX
) {
2501 if (!GetParam().isCXX()) {
2502 // FIXME: Fix this test to also work in non-C++ language modes.
2506 StatementMatcher Literal
= stringLiteral(hasSize(4));
2508 EXPECT_TRUE(matches("const wchar_t *s = L\"abcd\";", Literal
));
2511 TEST_P(ASTMatchersTest
, HasName_MatchesNamespaces
) {
2512 if (!GetParam().isCXX()) {
2516 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
2517 recordDecl(hasName("a::b::C"))));
2518 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
2519 recordDecl(hasName("::a::b::C"))));
2520 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
2521 recordDecl(hasName("b::C"))));
2522 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
2523 recordDecl(hasName("C"))));
2524 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2525 recordDecl(hasName("c::b::C"))));
2526 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2527 recordDecl(hasName("a::c::C"))));
2528 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2529 recordDecl(hasName("a::b::A"))));
2530 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2531 recordDecl(hasName("::C"))));
2532 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2533 recordDecl(hasName("::b::C"))));
2534 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2535 recordDecl(hasName("z::a::b::C"))));
2536 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2537 recordDecl(hasName("a+b::C"))));
2538 EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
2539 recordDecl(hasName("C"))));
2542 TEST_P(ASTMatchersTest
, HasName_MatchesOuterClasses
) {
2543 if (!GetParam().isCXX()) {
2547 EXPECT_TRUE(matches("class A { class B { class C; }; };",
2548 recordDecl(hasName("A::B::C"))));
2549 EXPECT_TRUE(matches("class A { class B { class C; }; };",
2550 recordDecl(hasName("::A::B::C"))));
2551 EXPECT_TRUE(matches("class A { class B { class C; }; };",
2552 recordDecl(hasName("B::C"))));
2554 matches("class A { class B { class C; }; };", recordDecl(hasName("C"))));
2555 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2556 recordDecl(hasName("c::B::C"))));
2557 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2558 recordDecl(hasName("A::c::C"))));
2559 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2560 recordDecl(hasName("A::B::A"))));
2561 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2562 recordDecl(hasName("::C"))));
2563 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2564 recordDecl(hasName("::B::C"))));
2565 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2566 recordDecl(hasName("z::A::B::C"))));
2567 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2568 recordDecl(hasName("A+B::C"))));
2571 TEST_P(ASTMatchersTest
, HasName_MatchesInlinedNamespaces
) {
2572 if (!GetParam().isCXX()) {
2576 StringRef code
= "namespace a { inline namespace b { class C; } }";
2577 EXPECT_TRUE(matches(code
, recordDecl(hasName("a::b::C"))));
2578 EXPECT_TRUE(matches(code
, recordDecl(hasName("a::C"))));
2579 EXPECT_TRUE(matches(code
, recordDecl(hasName("::a::b::C"))));
2580 EXPECT_TRUE(matches(code
, recordDecl(hasName("::a::C"))));
2583 TEST_P(ASTMatchersTest
, HasName_MatchesAnonymousNamespaces
) {
2584 if (!GetParam().isCXX()) {
2588 StringRef code
= "namespace a { namespace { class C; } }";
2590 matches(code
, recordDecl(hasName("a::(anonymous namespace)::C"))));
2591 EXPECT_TRUE(matches(code
, recordDecl(hasName("a::C"))));
2593 matches(code
, recordDecl(hasName("::a::(anonymous namespace)::C"))));
2594 EXPECT_TRUE(matches(code
, recordDecl(hasName("::a::C"))));
2597 TEST_P(ASTMatchersTest
, HasName_MatchesAnonymousOuterClasses
) {
2598 if (!GetParam().isCXX()) {
2602 EXPECT_TRUE(matches("class A { class { class C; } x; };",
2603 recordDecl(hasName("A::(anonymous class)::C"))));
2604 EXPECT_TRUE(matches("class A { class { class C; } x; };",
2605 recordDecl(hasName("::A::(anonymous class)::C"))));
2606 EXPECT_FALSE(matches("class A { class { class C; } x; };",
2607 recordDecl(hasName("::A::C"))));
2608 EXPECT_TRUE(matches("class A { struct { class C; } x; };",
2609 recordDecl(hasName("A::(anonymous struct)::C"))));
2610 EXPECT_TRUE(matches("class A { struct { class C; } x; };",
2611 recordDecl(hasName("::A::(anonymous struct)::C"))));
2612 EXPECT_FALSE(matches("class A { struct { class C; } x; };",
2613 recordDecl(hasName("::A::C"))));
2616 TEST_P(ASTMatchersTest
, HasName_MatchesFunctionScope
) {
2617 if (!GetParam().isCXX()) {
2622 "namespace a { void F(int a) { struct S { int m; }; int i; } }";
2623 EXPECT_TRUE(matches(code
, varDecl(hasName("i"))));
2624 EXPECT_FALSE(matches(code
, varDecl(hasName("F()::i"))));
2626 EXPECT_TRUE(matches(code
, fieldDecl(hasName("m"))));
2627 EXPECT_TRUE(matches(code
, fieldDecl(hasName("S::m"))));
2628 EXPECT_TRUE(matches(code
, fieldDecl(hasName("F(int)::S::m"))));
2629 EXPECT_TRUE(matches(code
, fieldDecl(hasName("a::F(int)::S::m"))));
2630 EXPECT_TRUE(matches(code
, fieldDecl(hasName("::a::F(int)::S::m"))));
2633 TEST_P(ASTMatchersTest
, HasName_QualifiedStringMatchesThroughLinkage
) {
2634 if (!GetParam().isCXX()) {
2638 // https://bugs.llvm.org/show_bug.cgi?id=42193
2639 StringRef code
= R
"cpp(namespace foo { extern "C
" void test(); })cpp";
2640 EXPECT_TRUE(matches(code
, functionDecl(hasName("test"))));
2641 EXPECT_TRUE(matches(code
, functionDecl(hasName("foo::test"))));
2642 EXPECT_TRUE(matches(code
, functionDecl(hasName("::foo::test"))));
2643 EXPECT_TRUE(notMatches(code
, functionDecl(hasName("::test"))));
2645 code
= R
"cpp(namespace foo { extern "C
" { void test(); } })cpp";
2646 EXPECT_TRUE(matches(code
, functionDecl(hasName("test"))));
2647 EXPECT_TRUE(matches(code
, functionDecl(hasName("foo::test"))));
2648 EXPECT_TRUE(matches(code
, functionDecl(hasName("::foo::test"))));
2649 EXPECT_TRUE(notMatches(code
, functionDecl(hasName("::test"))));
2652 TEST_P(ASTMatchersTest
, HasAnyName
) {
2653 if (!GetParam().isCXX()) {
2654 // FIXME: Add a test for `hasAnyName()` that does not depend on C++.
2658 StringRef Code
= "namespace a { namespace b { class C; } }";
2660 EXPECT_TRUE(matches(Code
, recordDecl(hasAnyName("XX", "a::b::C"))));
2661 EXPECT_TRUE(matches(Code
, recordDecl(hasAnyName("a::b::C", "XX"))));
2662 EXPECT_TRUE(matches(Code
, recordDecl(hasAnyName("XX::C", "a::b::C"))));
2663 EXPECT_TRUE(matches(Code
, recordDecl(hasAnyName("XX", "C"))));
2665 EXPECT_TRUE(notMatches(Code
, recordDecl(hasAnyName("::C", "::b::C"))));
2667 matches(Code
, recordDecl(hasAnyName("::C", "::b::C", "::a::b::C"))));
2669 std::vector
<StringRef
> Names
= {"::C", "::b::C", "::a::b::C"};
2670 EXPECT_TRUE(matches(Code
, recordDecl(hasAnyName(Names
))));
2673 TEST_P(ASTMatchersTest
, IsDefinition
) {
2674 DeclarationMatcher DefinitionOfClassA
=
2675 recordDecl(hasName("A"), isDefinition());
2676 EXPECT_TRUE(matches("struct A {};", DefinitionOfClassA
));
2677 EXPECT_TRUE(notMatches("struct A;", DefinitionOfClassA
));
2679 DeclarationMatcher DefinitionOfVariableA
=
2680 varDecl(hasName("a"), isDefinition());
2681 EXPECT_TRUE(matches("int a;", DefinitionOfVariableA
));
2682 EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA
));
2685 TEST_P(ASTMatchersTest
, IsDefinition_CXX
) {
2686 if (!GetParam().isCXX()) {
2690 DeclarationMatcher DefinitionOfMethodA
=
2691 cxxMethodDecl(hasName("a"), isDefinition());
2692 EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA
));
2693 EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA
));
2695 DeclarationMatcher DefinitionOfObjCMethodA
=
2696 objcMethodDecl(hasName("a"), isDefinition());
2697 EXPECT_TRUE(matchesObjC("@interface A @end "
2698 "@implementation A; -(void)a {} @end",
2699 DefinitionOfObjCMethodA
));
2701 notMatchesObjC("@interface A; - (void)a; @end", DefinitionOfObjCMethodA
));
2704 TEST_P(ASTMatchersTest
, HandlesNullQualTypes
) {
2705 if (!GetParam().isCXX()) {
2706 // FIXME: Add an equivalent test that does not depend on C++.
2710 // FIXME: Add a Type matcher so we can replace uses of this
2711 // variable with Type(True())
2712 const TypeMatcher AnyType
= anything();
2714 // We don't really care whether this matcher succeeds; we're testing that
2715 // it completes without crashing.
2716 EXPECT_TRUE(matches(
2718 "template <typename T>"
2720 " T local_t(t /* this becomes a null QualType in the AST */);"
2725 expr(hasType(TypeMatcher(anyOf(TypeMatcher(hasDeclaration(anything())),
2726 pointsTo(AnyType
), references(AnyType
)
2727 // Other QualType matchers should go here.
2731 TEST_P(ASTMatchersTest
, ObjCIvarRefExpr
) {
2732 StringRef ObjCString
=
2733 "@interface A @end "
2734 "@implementation A { A *x; } - (void) func { x = 0; } @end";
2735 EXPECT_TRUE(matchesObjC(ObjCString
, objcIvarRefExpr()));
2736 EXPECT_TRUE(matchesObjC(
2737 ObjCString
, objcIvarRefExpr(hasDeclaration(namedDecl(hasName("x"))))));
2738 EXPECT_FALSE(matchesObjC(
2739 ObjCString
, objcIvarRefExpr(hasDeclaration(namedDecl(hasName("y"))))));
2742 TEST_P(ASTMatchersTest
, BlockExpr
) {
2743 EXPECT_TRUE(matchesObjC("void f() { ^{}(); }", blockExpr()));
2746 TEST_P(ASTMatchersTest
,
2747 StatementCountIs_FindsNoStatementsInAnEmptyCompoundStatement
) {
2748 EXPECT_TRUE(matches("void f() { }", compoundStmt(statementCountIs(0))));
2749 EXPECT_TRUE(notMatches("void f() {}", compoundStmt(statementCountIs(1))));
2752 TEST_P(ASTMatchersTest
, StatementCountIs_AppearsToMatchOnlyOneCount
) {
2753 EXPECT_TRUE(matches("void f() { 1; }", compoundStmt(statementCountIs(1))));
2754 EXPECT_TRUE(notMatches("void f() { 1; }", compoundStmt(statementCountIs(0))));
2755 EXPECT_TRUE(notMatches("void f() { 1; }", compoundStmt(statementCountIs(2))));
2758 TEST_P(ASTMatchersTest
, StatementCountIs_WorksWithMultipleStatements
) {
2760 matches("void f() { 1; 2; 3; }", compoundStmt(statementCountIs(3))));
2763 TEST_P(ASTMatchersTest
, StatementCountIs_WorksWithNestedCompoundStatements
) {
2764 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
2765 compoundStmt(statementCountIs(1))));
2766 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
2767 compoundStmt(statementCountIs(2))));
2768 EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
2769 compoundStmt(statementCountIs(3))));
2770 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
2771 compoundStmt(statementCountIs(4))));
2774 TEST_P(ASTMatchersTest
, Member_WorksInSimplestCase
) {
2775 if (!GetParam().isCXX()) {
2776 // FIXME: Add a test for `member()` that does not depend on C++.
2779 EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
2780 memberExpr(member(hasName("first")))));
2783 TEST_P(ASTMatchersTest
, Member_DoesNotMatchTheBaseExpression
) {
2784 if (!GetParam().isCXX()) {
2785 // FIXME: Add a test for `member()` that does not depend on C++.
2789 // Don't pick out the wrong part of the member expression, this should
2790 // be checking the member (name) only.
2791 EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
2792 memberExpr(member(hasName("first")))));
2795 TEST_P(ASTMatchersTest
, Member_MatchesInMemberFunctionCall
) {
2796 if (!GetParam().isCXX()) {
2800 EXPECT_TRUE(matches("void f() {"
2801 " struct { void first() {}; } s;"
2804 memberExpr(member(hasName("first")))));
2807 TEST_P(ASTMatchersTest
, FieldDecl
) {
2809 matches("struct A { int i; }; void f() { struct A a; a.i = 2; }",
2810 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
2812 notMatches("struct A { float f; }; void f() { struct A a; a.f = 2.0f; }",
2813 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
2816 TEST_P(ASTMatchersTest
, IsBitField
) {
2817 EXPECT_TRUE(matches("struct C { int a : 2; int b; };",
2818 fieldDecl(isBitField(), hasName("a"))));
2819 EXPECT_TRUE(notMatches("struct C { int a : 2; int b; };",
2820 fieldDecl(isBitField(), hasName("b"))));
2821 EXPECT_TRUE(matches("struct C { int a : 2; int b : 4; };",
2822 fieldDecl(isBitField(), hasBitWidth(2), hasName("a"))));
2825 TEST_P(ASTMatchersTest
, HasInClassInitializer
) {
2826 if (!GetParam().isCXX()) {
2831 matches("class C { int a = 2; int b; };",
2832 fieldDecl(hasInClassInitializer(integerLiteral(equals(2))),
2835 notMatches("class C { int a = 2; int b; };",
2836 fieldDecl(hasInClassInitializer(anything()), hasName("b"))));
2839 TEST_P(ASTMatchersTest
, IsPublic_IsProtected_IsPrivate
) {
2840 if (!GetParam().isCXX()) {
2845 matches("struct A { int i; };", fieldDecl(isPublic(), hasName("i"))));
2846 EXPECT_TRUE(notMatches("struct A { int i; };",
2847 fieldDecl(isProtected(), hasName("i"))));
2849 notMatches("struct A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
2852 notMatches("class A { int i; };", fieldDecl(isPublic(), hasName("i"))));
2853 EXPECT_TRUE(notMatches("class A { int i; };",
2854 fieldDecl(isProtected(), hasName("i"))));
2856 matches("class A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
2858 EXPECT_TRUE(notMatches("class A { protected: int i; };",
2859 fieldDecl(isPublic(), hasName("i"))));
2860 EXPECT_TRUE(matches("class A { protected: int i; };",
2861 fieldDecl(isProtected(), hasName("i"))));
2862 EXPECT_TRUE(notMatches("class A { protected: int i; };",
2863 fieldDecl(isPrivate(), hasName("i"))));
2865 // Non-member decls have the AccessSpecifier AS_none and thus aren't matched.
2866 EXPECT_TRUE(notMatches("int i;", varDecl(isPublic(), hasName("i"))));
2867 EXPECT_TRUE(notMatches("int i;", varDecl(isProtected(), hasName("i"))));
2868 EXPECT_TRUE(notMatches("int i;", varDecl(isPrivate(), hasName("i"))));
2871 TEST_P(ASTMatchersTest
,
2872 HasDynamicExceptionSpec_MatchesDynamicExceptionSpecifications
) {
2873 if (!GetParam().supportsCXXDynamicExceptionSpecification()) {
2877 EXPECT_TRUE(notMatches("void f();", functionDecl(hasDynamicExceptionSpec())));
2879 matches("void j() throw();", functionDecl(hasDynamicExceptionSpec())));
2881 matches("void k() throw(int);", functionDecl(hasDynamicExceptionSpec())));
2883 matches("void l() throw(...);", functionDecl(hasDynamicExceptionSpec())));
2886 notMatches("void f();", functionProtoType(hasDynamicExceptionSpec())));
2887 EXPECT_TRUE(matches("void j() throw();",
2888 functionProtoType(hasDynamicExceptionSpec())));
2889 EXPECT_TRUE(matches("void k() throw(int);",
2890 functionProtoType(hasDynamicExceptionSpec())));
2891 EXPECT_TRUE(matches("void l() throw(...);",
2892 functionProtoType(hasDynamicExceptionSpec())));
2895 TEST_P(ASTMatchersTest
,
2896 HasDynamicExceptionSpec_MatchesDynamicExceptionSpecifications_CXX11
) {
2897 if (!GetParam().isCXX11OrLater()) {
2901 EXPECT_TRUE(notMatches("void g() noexcept;",
2902 functionDecl(hasDynamicExceptionSpec())));
2903 EXPECT_TRUE(notMatches("void h() noexcept(true);",
2904 functionDecl(hasDynamicExceptionSpec())));
2905 EXPECT_TRUE(notMatches("void i() noexcept(false);",
2906 functionDecl(hasDynamicExceptionSpec())));
2908 EXPECT_TRUE(notMatches("void g() noexcept;",
2909 functionProtoType(hasDynamicExceptionSpec())));
2910 EXPECT_TRUE(notMatches("void h() noexcept(true);",
2911 functionProtoType(hasDynamicExceptionSpec())));
2912 EXPECT_TRUE(notMatches("void i() noexcept(false);",
2913 functionProtoType(hasDynamicExceptionSpec())));
2916 TEST_P(ASTMatchersTest
, HasObjectExpression_DoesNotMatchMember
) {
2917 if (!GetParam().isCXX()) {
2921 EXPECT_TRUE(notMatches(
2922 "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
2923 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
2926 TEST_P(ASTMatchersTest
, HasObjectExpression_MatchesBaseOfVariable
) {
2927 EXPECT_TRUE(matches(
2928 "struct X { int m; }; void f(struct X x) { x.m; }",
2929 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
2930 EXPECT_TRUE(matches("struct X { int m; }; void f(struct X* x) { x->m; }",
2931 memberExpr(hasObjectExpression(
2932 hasType(pointsTo(recordDecl(hasName("X"))))))));
2935 TEST_P(ASTMatchersTest
, HasObjectExpression_MatchesBaseOfVariable_CXX
) {
2936 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
2937 // FIXME: Fix this test to work with delayed template parsing.
2941 EXPECT_TRUE(matches("template <class T> struct X { void f() { T t; t.m; } };",
2942 cxxDependentScopeMemberExpr(hasObjectExpression(
2943 declRefExpr(to(namedDecl(hasName("t"))))))));
2945 matches("template <class T> struct X { void f() { T t; t->m; } };",
2946 cxxDependentScopeMemberExpr(hasObjectExpression(
2947 declRefExpr(to(namedDecl(hasName("t"))))))));
2950 TEST_P(ASTMatchersTest
, HasObjectExpression_MatchesBaseOfMemberFunc
) {
2951 if (!GetParam().isCXX()) {
2955 EXPECT_TRUE(matches(
2956 "struct X { void f(); }; void g(X x) { x.f(); }",
2957 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
2960 TEST_P(ASTMatchersTest
, HasObjectExpression_MatchesBaseOfMemberFunc_Template
) {
2961 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
2962 // FIXME: Fix this test to work with delayed template parsing.
2966 EXPECT_TRUE(matches("struct X { template <class T> void f(); };"
2967 "template <class T> void g(X x) { x.f<T>(); }",
2968 unresolvedMemberExpr(hasObjectExpression(
2969 hasType(recordDecl(hasName("X")))))));
2970 EXPECT_TRUE(matches("template <class T> void f(T t) { t.g(); }",
2971 cxxDependentScopeMemberExpr(hasObjectExpression(
2972 declRefExpr(to(namedDecl(hasName("t"))))))));
2975 TEST_P(ASTMatchersTest
, HasObjectExpression_ImplicitlyFormedMemberExpression
) {
2976 if (!GetParam().isCXX()) {
2980 EXPECT_TRUE(matches("class X {}; struct S { X m; void f() { this->m; } };",
2981 memberExpr(hasObjectExpression(
2982 hasType(pointsTo(recordDecl(hasName("S"))))))));
2983 EXPECT_TRUE(matches("class X {}; struct S { X m; void f() { m; } };",
2984 memberExpr(hasObjectExpression(
2985 hasType(pointsTo(recordDecl(hasName("S"))))))));
2988 TEST_P(ASTMatchersTest
, FieldDecl_DoesNotMatchNonFieldMembers
) {
2989 if (!GetParam().isCXX()) {
2993 EXPECT_TRUE(notMatches("class X { void m(); };", fieldDecl(hasName("m"))));
2994 EXPECT_TRUE(notMatches("class X { class m {}; };", fieldDecl(hasName("m"))));
2995 EXPECT_TRUE(notMatches("class X { enum { m }; };", fieldDecl(hasName("m"))));
2996 EXPECT_TRUE(notMatches("class X { enum m {}; };", fieldDecl(hasName("m"))));
2999 TEST_P(ASTMatchersTest
, FieldDecl_MatchesField
) {
3000 EXPECT_TRUE(matches("struct X { int m; };", fieldDecl(hasName("m"))));
3003 TEST_P(ASTMatchersTest
, IsVolatileQualified
) {
3005 matches("volatile int i = 42;", varDecl(hasType(isVolatileQualified()))));
3007 notMatches("volatile int *i;", varDecl(hasType(isVolatileQualified()))));
3008 EXPECT_TRUE(matches("typedef volatile int v_int; v_int i = 42;",
3009 varDecl(hasType(isVolatileQualified()))));
3012 TEST_P(ASTMatchersTest
, IsConstQualified_MatchesConstInt
) {
3014 matches("const int i = 42;", varDecl(hasType(isConstQualified()))));
3017 TEST_P(ASTMatchersTest
, IsConstQualified_MatchesConstPointer
) {
3018 EXPECT_TRUE(matches("int i = 42; int* const p = &i;",
3019 varDecl(hasType(isConstQualified()))));
3022 TEST_P(ASTMatchersTest
, IsConstQualified_MatchesThroughTypedef
) {
3023 EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
3024 varDecl(hasType(isConstQualified()))));
3025 EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p = ((int*)0);",
3026 varDecl(hasType(isConstQualified()))));
3029 TEST_P(ASTMatchersTest
, IsConstQualified_DoesNotMatchInappropriately
) {
3030 EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
3031 varDecl(hasType(isConstQualified()))));
3033 notMatches("int const* p;", varDecl(hasType(isConstQualified()))));
3036 TEST_P(ASTMatchersTest
, DeclCountIs_DeclCountIsCorrect
) {
3037 EXPECT_TRUE(matches("void f() {int i,j;}", declStmt(declCountIs(2))));
3039 notMatches("void f() {int i,j; int k;}", declStmt(declCountIs(3))));
3041 notMatches("void f() {int i,j, k, l;}", declStmt(declCountIs(3))));
3044 TEST_P(ASTMatchersTest
, EachOf_TriggersForEachMatch
) {
3045 EXPECT_TRUE(matchAndVerifyResultTrue(
3046 "class A { int a; int b; };",
3047 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
3048 has(fieldDecl(hasName("b")).bind("v")))),
3049 std::make_unique
<VerifyIdIsBoundTo
<FieldDecl
>>("v", 2)));
3052 TEST_P(ASTMatchersTest
, EachOf_BehavesLikeAnyOfUnlessBothMatch
) {
3053 EXPECT_TRUE(matchAndVerifyResultTrue(
3054 "struct A { int a; int c; };",
3055 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
3056 has(fieldDecl(hasName("b")).bind("v")))),
3057 std::make_unique
<VerifyIdIsBoundTo
<FieldDecl
>>("v", 1)));
3058 EXPECT_TRUE(matchAndVerifyResultTrue(
3059 "struct A { int c; int b; };",
3060 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
3061 has(fieldDecl(hasName("b")).bind("v")))),
3062 std::make_unique
<VerifyIdIsBoundTo
<FieldDecl
>>("v", 1)));
3064 notMatches("struct A { int c; int d; };",
3065 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
3066 has(fieldDecl(hasName("b")).bind("v"))))));
3069 TEST_P(ASTMatchersTest
, Optionally_SubmatchersDoNotMatch
) {
3070 EXPECT_TRUE(matchAndVerifyResultFalse(
3071 "class A { int a; int b; };",
3072 recordDecl(optionally(has(fieldDecl(hasName("c")).bind("c")))),
3073 std::make_unique
<VerifyIdIsBoundTo
<FieldDecl
>>("c")));
3077 TEST_P(ASTMatchersTest
, Optionally_SubmatchersDoNotMatchButPreserveBindings
) {
3078 StringRef Code
= "class A { int a; int b; };";
3079 auto Matcher
= recordDecl(decl().bind("decl"),
3080 optionally(has(fieldDecl(hasName("c")).bind("v"))));
3081 // "decl" is still bound.
3082 EXPECT_TRUE(matchAndVerifyResultTrue(
3083 Code
, Matcher
, std::make_unique
<VerifyIdIsBoundTo
<RecordDecl
>>("decl")));
3084 // "v" is not bound, but the match still suceeded.
3085 EXPECT_TRUE(matchAndVerifyResultFalse(
3086 Code
, Matcher
, std::make_unique
<VerifyIdIsBoundTo
<FieldDecl
>>("v")));
3089 TEST_P(ASTMatchersTest
, Optionally_SubmatchersMatch
) {
3090 EXPECT_TRUE(matchAndVerifyResultTrue(
3091 "class A { int a; int c; };",
3092 recordDecl(optionally(has(fieldDecl(hasName("a")).bind("v")))),
3093 std::make_unique
<VerifyIdIsBoundTo
<FieldDecl
>>("v")));
3096 TEST_P(ASTMatchersTest
,
3097 IsTemplateInstantiation_MatchesImplicitClassTemplateInstantiation
) {
3098 if (!GetParam().isCXX()) {
3102 // Make sure that we can both match the class by name (::X) and by the type
3103 // the template was instantiated with (via a field).
3106 matches("template <typename T> class X {}; class A {}; X<A> x;",
3107 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
3109 EXPECT_TRUE(matches(
3110 "template <typename T> class X { T t; }; class A {}; X<A> x;",
3112 isTemplateInstantiation(),
3113 hasDescendant(fieldDecl(hasType(recordDecl(hasName("A"))))))));
3116 TEST_P(ASTMatchersTest
,
3117 IsTemplateInstantiation_MatchesImplicitFunctionTemplateInstantiation
) {
3118 if (!GetParam().isCXX()) {
3122 EXPECT_TRUE(matches(
3123 "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
3124 functionDecl(hasParameter(0, hasType(recordDecl(hasName("A")))),
3125 isTemplateInstantiation())));
3128 TEST_P(ASTMatchersTest
,
3129 IsTemplateInstantiation_MatchesExplicitClassTemplateInstantiation
) {
3130 if (!GetParam().isCXX()) {
3134 EXPECT_TRUE(matches("template <typename T> class X { T t; }; class A {};"
3135 "template class X<A>;",
3136 cxxRecordDecl(isTemplateInstantiation(),
3137 hasDescendant(fieldDecl(
3138 hasType(recordDecl(hasName("A"))))))));
3140 // Make sure that we match the instantiation instead of the template
3141 // definition by checking whether the member function is present.
3143 matches("template <typename T> class X { void f() { T t; } };"
3144 "extern template class X<int>;",
3145 cxxRecordDecl(isTemplateInstantiation(),
3146 unless(hasDescendant(varDecl(hasName("t")))))));
3151 IsTemplateInstantiation_MatchesInstantiationOfPartiallySpecializedClassTemplate
) {
3152 if (!GetParam().isCXX()) {
3157 matches("template <typename T> class X {};"
3158 "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
3159 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
3164 IsTemplateInstantiation_MatchesInstantiationOfClassTemplateNestedInNonTemplate
) {
3165 if (!GetParam().isCXX()) {
3170 matches("class A {};"
3172 " template <typename U> class Y { U u; };"
3175 cxxRecordDecl(hasName("::X::Y"), isTemplateInstantiation())));
3180 IsTemplateInstantiation_DoesNotMatchInstantiationsInsideOfInstantiation
) {
3181 if (!GetParam().isCXX()) {
3185 // FIXME: Figure out whether this makes sense. It doesn't affect the
3186 // normal use case as long as the uppermost instantiation always is marked
3187 // as template instantiation, but it might be confusing as a predicate.
3188 EXPECT_TRUE(matches(
3190 "template <typename T> class X {"
3191 " template <typename U> class Y { U u; };"
3194 cxxRecordDecl(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
3199 IsTemplateInstantiation_DoesNotMatchExplicitClassTemplateSpecialization
) {
3200 if (!GetParam().isCXX()) {
3205 notMatches("template <typename T> class X {}; class A {};"
3206 "template <> class X<A> {}; X<A> x;",
3207 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
3210 TEST_P(ASTMatchersTest
, IsTemplateInstantiation_DoesNotMatchNonTemplate
) {
3211 if (!GetParam().isCXX()) {
3215 EXPECT_TRUE(notMatches("class A {}; class Y { A a; };",
3216 cxxRecordDecl(isTemplateInstantiation())));
3219 TEST_P(ASTMatchersTest
, IsInstantiated_MatchesInstantiation
) {
3220 if (!GetParam().isCXX()) {
3225 matches("template<typename T> class A { T i; }; class Y { A<int> a; };",
3226 cxxRecordDecl(isInstantiated())));
3229 TEST_P(ASTMatchersTest
, IsInstantiated_NotMatchesDefinition
) {
3230 if (!GetParam().isCXX()) {
3234 EXPECT_TRUE(notMatches("template<typename T> class A { T i; };",
3235 cxxRecordDecl(isInstantiated())));
3238 TEST_P(ASTMatchersTest
, IsInTemplateInstantiation_MatchesInstantiationStmt
) {
3239 if (!GetParam().isCXX()) {
3243 EXPECT_TRUE(matches("template<typename T> struct A { A() { T i; } };"
3244 "class Y { A<int> a; }; Y y;",
3245 declStmt(isInTemplateInstantiation())));
3248 TEST_P(ASTMatchersTest
, IsInTemplateInstantiation_NotMatchesDefinitionStmt
) {
3249 if (!GetParam().isCXX()) {
3253 EXPECT_TRUE(notMatches("template<typename T> struct A { void x() { T i; } };",
3254 declStmt(isInTemplateInstantiation())));
3257 TEST_P(ASTMatchersTest
, IsInstantiated_MatchesFunctionInstantiation
) {
3258 if (!GetParam().isCXX()) {
3263 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
3264 functionDecl(isInstantiated())));
3267 TEST_P(ASTMatchersTest
, IsInstantiated_NotMatchesFunctionDefinition
) {
3268 if (!GetParam().isCXX()) {
3272 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
3273 varDecl(isInstantiated())));
3276 TEST_P(ASTMatchersTest
,
3277 IsInTemplateInstantiation_MatchesFunctionInstantiationStmt
) {
3278 if (!GetParam().isCXX()) {
3283 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
3284 declStmt(isInTemplateInstantiation())));
3287 TEST_P(ASTMatchersTest
,
3288 IsInTemplateInstantiation_NotMatchesFunctionDefinitionStmt
) {
3289 if (!GetParam().isCXX()) {
3293 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
3294 declStmt(isInTemplateInstantiation())));
3297 TEST_P(ASTMatchersTest
, IsInTemplateInstantiation_Sharing
) {
3298 if (!GetParam().isCXX()) {
3302 auto Matcher
= binaryOperator(unless(isInTemplateInstantiation()));
3303 // FIXME: Node sharing is an implementation detail, exposing it is ugly
3304 // and makes the matcher behave in non-obvious ways.
3305 EXPECT_TRUE(notMatches(
3306 "int j; template<typename T> void A(T t) { j += 42; } void x() { A(0); }",
3308 EXPECT_TRUE(matches(
3309 "int j; template<typename T> void A(T t) { j += t; } void x() { A(0); }",
3313 TEST_P(ASTMatchersTest
, IsInstantiationDependent_MatchesNonValueTypeDependent
) {
3314 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3315 // FIXME: Fix this test to work with delayed template parsing.
3319 EXPECT_TRUE(matches(
3320 "template<typename T> void f() { (void) sizeof(sizeof(T() + T())); }",
3321 expr(isInstantiationDependent())));
3324 TEST_P(ASTMatchersTest
, IsInstantiationDependent_MatchesValueDependent
) {
3325 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3326 // FIXME: Fix this test to work with delayed template parsing.
3330 EXPECT_TRUE(matches("template<int T> int f() { return T; }",
3331 expr(isInstantiationDependent())));
3334 TEST_P(ASTMatchersTest
, IsInstantiationDependent_MatchesTypeDependent
) {
3335 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3336 // FIXME: Fix this test to work with delayed template parsing.
3340 EXPECT_TRUE(matches("template<typename T> T f() { return T(); }",
3341 expr(isInstantiationDependent())));
3344 TEST_P(ASTMatchersTest
, IsTypeDependent_MatchesTypeDependent
) {
3345 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3346 // FIXME: Fix this test to work with delayed template parsing.
3350 EXPECT_TRUE(matches("template<typename T> T f() { return T(); }",
3351 expr(isTypeDependent())));
3354 TEST_P(ASTMatchersTest
, IsTypeDependent_NotMatchesValueDependent
) {
3355 if (!GetParam().isCXX()) {
3359 EXPECT_TRUE(notMatches("template<int T> int f() { return T; }",
3360 expr(isTypeDependent())));
3363 TEST_P(ASTMatchersTest
, IsValueDependent_MatchesValueDependent
) {
3364 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3365 // FIXME: Fix this test to work with delayed template parsing.
3369 EXPECT_TRUE(matches("template<int T> int f() { return T; }",
3370 expr(isValueDependent())));
3373 TEST_P(ASTMatchersTest
, IsValueDependent_MatchesTypeDependent
) {
3374 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3375 // FIXME: Fix this test to work with delayed template parsing.
3379 EXPECT_TRUE(matches("template<typename T> T f() { return T(); }",
3380 expr(isValueDependent())));
3383 TEST_P(ASTMatchersTest
, IsValueDependent_MatchesInstantiationDependent
) {
3384 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3385 // FIXME: Fix this test to work with delayed template parsing.
3389 EXPECT_TRUE(matches(
3390 "template<typename T> void f() { (void) sizeof(sizeof(T() + T())); }",
3391 expr(isValueDependent())));
3394 TEST_P(ASTMatchersTest
,
3395 IsExplicitTemplateSpecialization_DoesNotMatchPrimaryTemplate
) {
3396 if (!GetParam().isCXX()) {
3400 EXPECT_TRUE(notMatches("template <typename T> class X {};",
3401 cxxRecordDecl(isExplicitTemplateSpecialization())));
3402 EXPECT_TRUE(notMatches("template <typename T> void f(T t);",
3403 functionDecl(isExplicitTemplateSpecialization())));
3408 IsExplicitTemplateSpecialization_DoesNotMatchExplicitTemplateInstantiations
) {
3409 if (!GetParam().isCXX()) {
3414 notMatches("template <typename T> class X {};"
3415 "template class X<int>; extern template class X<long>;",
3416 cxxRecordDecl(isExplicitTemplateSpecialization())));
3418 notMatches("template <typename T> void f(T t) {}"
3419 "template void f(int t); extern template void f(long t);",
3420 functionDecl(isExplicitTemplateSpecialization())));
3425 IsExplicitTemplateSpecialization_DoesNotMatchImplicitTemplateInstantiations
) {
3426 if (!GetParam().isCXX()) {
3430 EXPECT_TRUE(notMatches("template <typename T> class X {}; X<int> x;",
3431 cxxRecordDecl(isExplicitTemplateSpecialization())));
3433 notMatches("template <typename T> void f(T t); void g() { f(10); }",
3434 functionDecl(isExplicitTemplateSpecialization())));
3439 IsExplicitTemplateSpecialization_MatchesExplicitTemplateSpecializations
) {
3440 if (!GetParam().isCXX()) {
3444 EXPECT_TRUE(matches("template <typename T> class X {};"
3445 "template<> class X<int> {};",
3446 cxxRecordDecl(isExplicitTemplateSpecialization())));
3447 EXPECT_TRUE(matches("template <typename T> void f(T t) {}"
3448 "template<> void f(int t) {}",
3449 functionDecl(isExplicitTemplateSpecialization())));
3452 TEST_P(ASTMatchersTest
, IsNoReturn
) {
3453 EXPECT_TRUE(notMatches("void func();", functionDecl(isNoReturn())));
3454 EXPECT_TRUE(notMatches("void func() {}", functionDecl(isNoReturn())));
3456 EXPECT_TRUE(matches("__attribute__((noreturn)) void func();",
3457 functionDecl(isNoReturn())));
3458 EXPECT_TRUE(matches("__attribute__((noreturn)) void func() {}",
3459 functionDecl(isNoReturn())));
3461 EXPECT_TRUE(matches("_Noreturn void func();", functionDecl(isNoReturn())));
3462 EXPECT_TRUE(matches("_Noreturn void func() {}", functionDecl(isNoReturn())));
3465 TEST_P(ASTMatchersTest
, IsNoReturn_CXX
) {
3466 if (!GetParam().isCXX()) {
3471 notMatches("struct S { void func(); };", functionDecl(isNoReturn())));
3473 notMatches("struct S { void func() {} };", functionDecl(isNoReturn())));
3475 EXPECT_TRUE(notMatches("struct S { static void func(); };",
3476 functionDecl(isNoReturn())));
3477 EXPECT_TRUE(notMatches("struct S { static void func() {} };",
3478 functionDecl(isNoReturn())));
3480 EXPECT_TRUE(notMatches("struct S { S(); };", functionDecl(isNoReturn())));
3481 EXPECT_TRUE(notMatches("struct S { S() {} };", functionDecl(isNoReturn())));
3485 EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) void func(); };",
3486 functionDecl(isNoReturn())));
3487 EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) void func() {} };",
3488 functionDecl(isNoReturn())));
3491 matches("struct S { __attribute__((noreturn)) static void func(); };",
3492 functionDecl(isNoReturn())));
3494 matches("struct S { __attribute__((noreturn)) static void func() {} };",
3495 functionDecl(isNoReturn())));
3497 EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) S(); };",
3498 functionDecl(isNoReturn())));
3499 EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) S() {} };",
3500 functionDecl(isNoReturn())));
3503 TEST_P(ASTMatchersTest
, IsNoReturn_CXX11Attribute
) {
3504 if (!GetParam().isCXX11OrLater()) {
3508 EXPECT_TRUE(matches("[[noreturn]] void func();", functionDecl(isNoReturn())));
3510 matches("[[noreturn]] void func() {}", functionDecl(isNoReturn())));
3512 EXPECT_TRUE(matches("struct S { [[noreturn]] void func(); };",
3513 functionDecl(isNoReturn())));
3514 EXPECT_TRUE(matches("struct S { [[noreturn]] void func() {} };",
3515 functionDecl(isNoReturn())));
3517 EXPECT_TRUE(matches("struct S { [[noreturn]] static void func(); };",
3518 functionDecl(isNoReturn())));
3519 EXPECT_TRUE(matches("struct S { [[noreturn]] static void func() {} };",
3520 functionDecl(isNoReturn())));
3523 matches("struct S { [[noreturn]] S(); };", functionDecl(isNoReturn())));
3525 matches("struct S { [[noreturn]] S() {} };", functionDecl(isNoReturn())));
3528 TEST_P(ASTMatchersTest
, BooleanType
) {
3529 if (!GetParam().isCXX()) {
3530 // FIXME: Add a test for `booleanType()` that does not depend on C++.
3534 EXPECT_TRUE(matches("struct S { bool func(); };",
3535 cxxMethodDecl(returns(booleanType()))));
3536 EXPECT_TRUE(notMatches("struct S { void func(); };",
3537 cxxMethodDecl(returns(booleanType()))));
3540 TEST_P(ASTMatchersTest
, VoidType
) {
3541 if (!GetParam().isCXX()) {
3542 // FIXME: Add a test for `voidType()` that does not depend on C++.
3546 EXPECT_TRUE(matches("struct S { void func(); };",
3547 cxxMethodDecl(returns(voidType()))));
3550 TEST_P(ASTMatchersTest
, RealFloatingPointType
) {
3551 if (!GetParam().isCXX()) {
3552 // FIXME: Add a test for `realFloatingPointType()` that does not depend on
3557 EXPECT_TRUE(matches("struct S { float func(); };",
3558 cxxMethodDecl(returns(realFloatingPointType()))));
3559 EXPECT_TRUE(notMatches("struct S { int func(); };",
3560 cxxMethodDecl(returns(realFloatingPointType()))));
3561 EXPECT_TRUE(matches("struct S { long double func(); };",
3562 cxxMethodDecl(returns(realFloatingPointType()))));
3565 TEST_P(ASTMatchersTest
, ArrayType
) {
3566 EXPECT_TRUE(matches("int a[] = {2,3};", arrayType()));
3567 EXPECT_TRUE(matches("int a[42];", arrayType()));
3568 EXPECT_TRUE(matches("void f(int b) { int a[b]; }", arrayType()));
3570 EXPECT_TRUE(notMatches("struct A {}; struct A a[7];",
3571 arrayType(hasElementType(builtinType()))));
3573 EXPECT_TRUE(matches("int const a[] = { 2, 3 };",
3574 qualType(arrayType(hasElementType(builtinType())))));
3575 EXPECT_TRUE(matches(
3576 "int const a[] = { 2, 3 };",
3577 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
3578 EXPECT_TRUE(matches("typedef const int T; T x[] = { 1, 2 };",
3579 qualType(isConstQualified(), arrayType())));
3581 EXPECT_TRUE(notMatches(
3582 "int a[] = { 2, 3 };",
3583 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
3584 EXPECT_TRUE(notMatches(
3585 "int a[] = { 2, 3 };",
3586 qualType(arrayType(hasElementType(isConstQualified(), builtinType())))));
3587 EXPECT_TRUE(notMatches("int const a[] = { 2, 3 };",
3588 qualType(arrayType(hasElementType(builtinType())),
3589 unless(isConstQualified()))));
3592 matches("int a[2];", constantArrayType(hasElementType(builtinType()))));
3593 EXPECT_TRUE(matches("const int a = 0;", qualType(isInteger())));
3596 TEST_P(ASTMatchersTest
, DecayedType
) {
3598 matches("void f(int i[]);",
3599 valueDecl(hasType(decayedType(hasDecayedType(pointerType()))))));
3600 EXPECT_TRUE(notMatches("int i[7];", decayedType()));
3603 TEST_P(ASTMatchersTest
, ComplexType
) {
3604 EXPECT_TRUE(matches("_Complex float f;", complexType()));
3606 matches("_Complex float f;", complexType(hasElementType(builtinType()))));
3607 EXPECT_TRUE(notMatches("_Complex float f;",
3608 complexType(hasElementType(isInteger()))));
3611 TEST_P(ASTMatchersTest
, IsAnonymous
) {
3612 if (!GetParam().isCXX()) {
3616 EXPECT_TRUE(notMatches("namespace N {}", namespaceDecl(isAnonymous())));
3617 EXPECT_TRUE(matches("namespace {}", namespaceDecl(isAnonymous())));
3620 TEST_P(ASTMatchersTest
, InStdNamespace
) {
3621 if (!GetParam().isCXX()) {
3625 EXPECT_TRUE(notMatches("class vector {};"
3634 cxxRecordDecl(hasName("vector"), isInStdNamespace())));
3636 EXPECT_TRUE(matches("namespace std {"
3639 cxxRecordDecl(hasName("vector"), isInStdNamespace())));
3642 TEST_P(ASTMatchersTest
, InAnonymousNamespace
) {
3643 if (!GetParam().isCXX()) {
3648 notMatches("class vector {};"
3652 cxxRecordDecl(hasName("vector"), isInAnonymousNamespace())));
3655 matches("namespace {"
3658 cxxRecordDecl(hasName("vector"), isInAnonymousNamespace())));
3661 matches("namespace foo {"
3666 cxxRecordDecl(hasName("vector"), isInAnonymousNamespace())));
3669 matches("namespace {"
3674 cxxRecordDecl(hasName("vector"), isInAnonymousNamespace())));
3677 TEST_P(ASTMatchersTest
, InStdNamespace_CXX11
) {
3678 if (!GetParam().isCXX11OrLater()) {
3682 EXPECT_TRUE(matches("namespace std {"
3683 " inline namespace __1 {"
3687 cxxRecordDecl(hasName("vector"), isInStdNamespace())));
3688 EXPECT_TRUE(notMatches("namespace std {"
3689 " inline namespace __1 {"
3690 " inline namespace __fs {"
3691 " namespace filesystem {"
3692 " inline namespace v1 {"
3699 cxxRecordDecl(hasName("path"), isInStdNamespace())));
3701 matches("namespace std {"
3702 " inline namespace __1 {"
3703 " inline namespace __fs {"
3704 " namespace filesystem {"
3705 " inline namespace v1 {"
3712 cxxRecordDecl(hasName("path"),
3713 hasAncestor(namespaceDecl(hasName("filesystem"),
3714 isInStdNamespace())))));
3717 TEST_P(ASTMatchersTest
, EqualsBoundNodeMatcher_QualType
) {
3718 EXPECT_TRUE(matches(
3719 "int i = 1;", varDecl(hasType(qualType().bind("type")),
3720 hasInitializer(ignoringParenImpCasts(
3721 hasType(qualType(equalsBoundNode("type"))))))));
3722 EXPECT_TRUE(notMatches("int i = 1.f;",
3723 varDecl(hasType(qualType().bind("type")),
3724 hasInitializer(ignoringParenImpCasts(hasType(
3725 qualType(equalsBoundNode("type"))))))));
3728 TEST_P(ASTMatchersTest
, EqualsBoundNodeMatcher_NonMatchingTypes
) {
3729 EXPECT_TRUE(notMatches(
3730 "int i = 1;", varDecl(namedDecl(hasName("i")).bind("name"),
3731 hasInitializer(ignoringParenImpCasts(
3732 hasType(qualType(equalsBoundNode("type"))))))));
3735 TEST_P(ASTMatchersTest
, EqualsBoundNodeMatcher_Stmt
) {
3737 matches("void f() { if(1) {} }",
3738 stmt(allOf(ifStmt().bind("if"),
3739 hasParent(stmt(has(stmt(equalsBoundNode("if")))))))));
3741 EXPECT_TRUE(notMatches(
3742 "void f() { if(1) { if (1) {} } }",
3743 stmt(allOf(ifStmt().bind("if"), has(stmt(equalsBoundNode("if")))))));
3746 TEST_P(ASTMatchersTest
, EqualsBoundNodeMatcher_Decl
) {
3747 if (!GetParam().isCXX()) {
3748 // FIXME: Add a test for `equalsBoundNode()` for declarations that does not
3753 EXPECT_TRUE(matches(
3754 "class X { class Y {}; };",
3755 decl(allOf(recordDecl(hasName("::X::Y")).bind("record"),
3756 hasParent(decl(has(decl(equalsBoundNode("record")))))))));
3758 EXPECT_TRUE(notMatches("class X { class Y {}; };",
3759 decl(allOf(recordDecl(hasName("::X")).bind("record"),
3760 has(decl(equalsBoundNode("record")))))));
3763 TEST_P(ASTMatchersTest
, EqualsBoundNodeMatcher_Type
) {
3764 if (!GetParam().isCXX()) {
3765 // FIXME: Add a test for `equalsBoundNode()` for types that does not depend
3769 EXPECT_TRUE(matches(
3770 "class X { int a; int b; };",
3772 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
3773 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
3775 EXPECT_TRUE(notMatches(
3776 "class X { int a; double b; };",
3778 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
3779 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
3782 TEST_P(ASTMatchersTest
, EqualsBoundNodeMatcher_UsingForEachDescendant
) {
3783 EXPECT_TRUE(matchAndVerifyResultTrue(
3794 // Look for variable declarations within functions whose type is the same
3795 // as the function return type.
3797 returns(qualType().bind("type")),
3798 forEachDescendant(varDecl(hasType(qualType(equalsBoundNode("type"))))
3800 // Only i and j should match, not k.
3801 std::make_unique
<VerifyIdIsBoundTo
<VarDecl
>>("decl", 2)));
3804 TEST_P(ASTMatchersTest
, EqualsBoundNodeMatcher_FiltersMatchedCombinations
) {
3805 EXPECT_TRUE(matchAndVerifyResultTrue(
3809 " x = d + x - d + x;"
3812 hasName("f"), forEachDescendant(varDecl().bind("d")),
3813 forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d")))))),
3814 std::make_unique
<VerifyIdIsBoundTo
<VarDecl
>>("d", 5)));
3817 TEST_P(ASTMatchersTest
,
3818 EqualsBoundNodeMatcher_UnlessDescendantsOfAncestorsMatch
) {
3819 EXPECT_TRUE(matchAndVerifyResultTrue(
3820 "struct StringRef { int size() const; const char* data() const; };"
3821 "void f(StringRef v) {"
3825 callee(cxxMethodDecl(hasName("data"))),
3827 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
3828 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
3829 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
3830 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
3832 std::make_unique
<VerifyIdIsBoundTo
<Expr
>>("data", 1)));
3834 EXPECT_FALSE(matches(
3835 "struct StringRef { int size() const; const char* data() const; };"
3836 "void f(StringRef v) {"
3841 callee(cxxMethodDecl(hasName("data"))),
3843 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
3844 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
3845 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
3846 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
3850 TEST_P(ASTMatchersTest
, NullPointerConstant
) {
3851 EXPECT_TRUE(matches("#define NULL ((void *)0)\n"
3853 expr(nullPointerConstant())));
3854 EXPECT_TRUE(matches("char *cp = (char *)0;", expr(nullPointerConstant())));
3855 EXPECT_TRUE(matches("int *ip = 0;", expr(nullPointerConstant())));
3856 EXPECT_FALSE(matches("int i = 0;", expr(nullPointerConstant())));
3859 TEST_P(ASTMatchersTest
, NullPointerConstant_GNUNull
) {
3860 if (!GetParam().isCXX()) {
3864 EXPECT_TRUE(matches("void *p = __null;", expr(nullPointerConstant())));
3867 TEST_P(ASTMatchersTest
, NullPointerConstant_GNUNullInTemplate
) {
3868 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3869 // FIXME: Fix this test to work with delayed template parsing.
3873 const char kTest
[] = R
"(
3874 template <typename T>
3876 MyTemplate() : field_(__null) {}
3880 EXPECT_TRUE(matches(kTest
, expr(nullPointerConstant())));
3883 TEST_P(ASTMatchersTest
, NullPointerConstant_CXX11Nullptr
) {
3884 if (!GetParam().isCXX11OrLater()) {
3888 EXPECT_TRUE(matches("void *p = nullptr;", expr(nullPointerConstant())));
3891 TEST_P(ASTMatchersTest
, HasExternalFormalLinkage
) {
3892 EXPECT_TRUE(matches("int a = 0;",
3893 namedDecl(hasName("a"), hasExternalFormalLinkage())));
3894 EXPECT_TRUE(notMatches("static int a = 0;",
3895 namedDecl(hasName("a"), hasExternalFormalLinkage())));
3896 EXPECT_TRUE(notMatches("static void f(void) { int a = 0; }",
3897 namedDecl(hasName("a"), hasExternalFormalLinkage())));
3898 EXPECT_TRUE(notMatches("void f(void) { int a = 0; }",
3899 namedDecl(hasName("a"), hasExternalFormalLinkage())));
3902 TEST_P(ASTMatchersTest
, HasExternalFormalLinkage_CXX
) {
3903 if (!GetParam().isCXX()) {
3907 EXPECT_TRUE(notMatches("namespace { int a = 0; }",
3908 namedDecl(hasName("a"), hasExternalFormalLinkage())));
3911 TEST_P(ASTMatchersTest
, HasDefaultArgument
) {
3912 if (!GetParam().isCXX()) {
3917 matches("void x(int val = 0) {}", parmVarDecl(hasDefaultArgument())));
3919 notMatches("void x(int val) {}", parmVarDecl(hasDefaultArgument())));
3922 TEST_P(ASTMatchersTest
, IsAtPosition
) {
3923 EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1))));
3924 EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(0))));
3925 EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1))));
3926 EXPECT_TRUE(notMatches("void x(int val) {}", parmVarDecl(isAtPosition(1))));
3929 TEST_P(ASTMatchersTest
, IsAtPosition_FunctionDecl
) {
3930 EXPECT_TRUE(matches("void x(int a);", parmVarDecl(isAtPosition(0))));
3931 EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(0))));
3932 EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(1))));
3933 EXPECT_TRUE(notMatches("void x(int val);", parmVarDecl(isAtPosition(1))));
3936 TEST_P(ASTMatchersTest
, IsAtPosition_Lambda
) {
3937 if (!GetParam().isCXX11OrLater()) {
3942 matches("void x() { [](int a) {}; }", parmVarDecl(isAtPosition(0))));
3943 EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",
3944 parmVarDecl(isAtPosition(0))));
3945 EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",
3946 parmVarDecl(isAtPosition(1))));
3948 notMatches("void x() { [](int val) {}; }", parmVarDecl(isAtPosition(1))));
3951 TEST_P(ASTMatchersTest
, IsAtPosition_BlockDecl
) {
3952 EXPECT_TRUE(matchesObjC(
3953 "void func() { void (^my_block)(int arg) = ^void(int arg) {}; } ",
3954 parmVarDecl(isAtPosition(0))));
3956 EXPECT_TRUE(matchesObjC("void func() { void (^my_block)(int x, int y) = "
3957 "^void(int x, int y) {}; } ",
3958 parmVarDecl(isAtPosition(1))));
3960 EXPECT_TRUE(notMatchesObjC(
3961 "void func() { void (^my_block)(int arg) = ^void(int arg) {}; } ",
3962 parmVarDecl(isAtPosition(1))));
3965 TEST_P(ASTMatchersTest
, IsArray
) {
3966 if (!GetParam().isCXX()) {
3970 EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",
3971 cxxNewExpr(isArray())));
3974 TEST_P(ASTMatchersTest
, HasArraySize
) {
3975 if (!GetParam().isCXX()) {
3979 EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",
3980 cxxNewExpr(hasArraySize(
3981 ignoringParenImpCasts(integerLiteral(equals(10)))))));
3984 TEST_P(ASTMatchersTest
, HasDefinition_MatchesStructDefinition
) {
3985 if (!GetParam().isCXX()) {
3989 EXPECT_TRUE(matches("struct x {};", cxxRecordDecl(hasDefinition())));
3990 EXPECT_TRUE(notMatches("struct x;", cxxRecordDecl(hasDefinition())));
3993 TEST_P(ASTMatchersTest
, HasDefinition_MatchesClassDefinition
) {
3994 if (!GetParam().isCXX()) {
3998 EXPECT_TRUE(matches("class x {};", cxxRecordDecl(hasDefinition())));
3999 EXPECT_TRUE(notMatches("class x;", cxxRecordDecl(hasDefinition())));
4002 TEST_P(ASTMatchersTest
, HasDefinition_MatchesUnionDefinition
) {
4003 if (!GetParam().isCXX()) {
4007 EXPECT_TRUE(matches("union x {};", cxxRecordDecl(hasDefinition())));
4008 EXPECT_TRUE(notMatches("union x;", cxxRecordDecl(hasDefinition())));
4011 TEST_P(ASTMatchersTest
, IsScoped_MatchesScopedEnum
) {
4012 if (!GetParam().isCXX11OrLater()) {
4015 EXPECT_TRUE(matches("enum class X {};", enumDecl(isScoped())));
4018 TEST_P(ASTMatchersTest
, IsScoped_NotMatchesRegularEnum
) {
4019 EXPECT_TRUE(notMatches("enum E { E1 };", enumDecl(isScoped())));
4022 TEST_P(ASTMatchersTest
, IsStruct
) {
4023 EXPECT_TRUE(matches("struct S {};", tagDecl(isStruct())));
4026 TEST_P(ASTMatchersTest
, IsUnion
) {
4027 EXPECT_TRUE(matches("union U {};", tagDecl(isUnion())));
4030 TEST_P(ASTMatchersTest
, IsEnum
) {
4031 EXPECT_TRUE(matches("enum E { E1 };", tagDecl(isEnum())));
4034 TEST_P(ASTMatchersTest
, IsClass
) {
4035 if (!GetParam().isCXX()) {
4039 EXPECT_TRUE(matches("class C {};", tagDecl(isClass())));
4042 TEST_P(ASTMatchersTest
, HasTrailingReturn_MatchesTrailingReturn
) {
4043 if (!GetParam().isCXX11OrLater()) {
4047 EXPECT_TRUE(matches("auto Y() -> int { return 0; }",
4048 functionDecl(hasTrailingReturn())));
4049 EXPECT_TRUE(matches("auto X() -> int;", functionDecl(hasTrailingReturn())));
4051 notMatches("int X() { return 0; }", functionDecl(hasTrailingReturn())));
4052 EXPECT_TRUE(notMatches("int X();", functionDecl(hasTrailingReturn())));
4053 EXPECT_TRUE(notMatches("void X();", functionDecl(hasTrailingReturn())));
4056 TEST_P(ASTMatchersTest
, HasTrailingReturn_MatchesLambdaTrailingReturn
) {
4057 if (!GetParam().isCXX11OrLater()) {
4061 EXPECT_TRUE(matches(
4062 "auto lambda2 = [](double x, double y) -> double {return x + y;};",
4063 functionDecl(hasTrailingReturn())));
4065 notMatches("auto lambda2 = [](double x, double y) {return x + y;};",
4066 functionDecl(hasTrailingReturn())));
4069 TEST_P(ASTMatchersTest
, IsAssignmentOperator
) {
4070 if (!GetParam().isCXX()) {
4074 StatementMatcher BinAsgmtOperator
= binaryOperator(isAssignmentOperator());
4075 StatementMatcher CXXAsgmtOperator
=
4076 cxxOperatorCallExpr(isAssignmentOperator());
4078 EXPECT_TRUE(matches("void x() { int a; a += 1; }", BinAsgmtOperator
));
4079 EXPECT_TRUE(matches("void x() { int a; a = 2; }", BinAsgmtOperator
));
4080 EXPECT_TRUE(matches("void x() { int a; a &= 3; }", BinAsgmtOperator
));
4081 EXPECT_TRUE(matches("struct S { S& operator=(const S&); };"
4082 "void x() { S s1, s2; s1 = s2; }",
4085 notMatches("void x() { int a; if(a == 0) return; }", BinAsgmtOperator
));
4088 TEST_P(ASTMatchersTest
, IsComparisonOperator
) {
4089 if (!GetParam().isCXX()) {
4093 StatementMatcher BinCompOperator
= binaryOperator(isComparisonOperator());
4094 StatementMatcher CXXCompOperator
=
4095 cxxOperatorCallExpr(isComparisonOperator());
4097 EXPECT_TRUE(matches("void x() { int a; a == 1; }", BinCompOperator
));
4098 EXPECT_TRUE(matches("void x() { int a; a > 2; }", BinCompOperator
));
4099 EXPECT_TRUE(matches("struct S { bool operator==(const S&); };"
4100 "void x() { S s1, s2; bool b1 = s1 == s2; }",
4103 notMatches("void x() { int a; if(a = 0) return; }", BinCompOperator
));
4106 TEST_P(ASTMatchersTest
, isRightFold
) {
4107 if (!GetParam().isCXX17OrLater()) {
4111 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4112 "return (0 + ... + args); }",
4113 cxxFoldExpr(isRightFold())));
4114 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4115 "return (args + ... + 0); }",
4116 cxxFoldExpr(isRightFold())));
4117 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4118 "return (... + args); };",
4119 cxxFoldExpr(isRightFold())));
4120 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4121 "return (args + ...); };",
4122 cxxFoldExpr(isRightFold())));
4125 TEST_P(ASTMatchersTest
, isLeftFold
) {
4126 if (!GetParam().isCXX17OrLater()) {
4130 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4131 "return (0 + ... + args); }",
4132 cxxFoldExpr(isLeftFold())));
4133 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4134 "return (args + ... + 0); }",
4135 cxxFoldExpr(isLeftFold())));
4136 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4137 "return (... + args); };",
4138 cxxFoldExpr(isLeftFold())));
4139 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4140 "return (args + ...); };",
4141 cxxFoldExpr(isLeftFold())));
4144 TEST_P(ASTMatchersTest
, isUnaryFold
) {
4145 if (!GetParam().isCXX17OrLater()) {
4149 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4150 "return (0 + ... + args); }",
4151 cxxFoldExpr(isUnaryFold())));
4152 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4153 "return (args + ... + 0); }",
4154 cxxFoldExpr(isUnaryFold())));
4155 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4156 "return (... + args); };",
4157 cxxFoldExpr(isUnaryFold())));
4158 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4159 "return (args + ...); };",
4160 cxxFoldExpr(isUnaryFold())));
4163 TEST_P(ASTMatchersTest
, isBinaryFold
) {
4164 if (!GetParam().isCXX17OrLater()) {
4168 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4169 "return (0 + ... + args); }",
4170 cxxFoldExpr(isBinaryFold())));
4171 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4172 "return (args + ... + 0); }",
4173 cxxFoldExpr(isBinaryFold())));
4174 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4175 "return (... + args); };",
4176 cxxFoldExpr(isBinaryFold())));
4177 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4178 "return (args + ...); };",
4179 cxxFoldExpr(isBinaryFold())));
4182 TEST_P(ASTMatchersTest
, hasOperator
) {
4183 if (!GetParam().isCXX17OrLater()) {
4187 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4188 "return (0 + ... + args); }",
4189 cxxFoldExpr(hasOperatorName("+"))));
4190 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4191 "return (... + args); };",
4192 cxxFoldExpr(hasOperatorName("+"))));
4195 matches("template <typename... Args> auto multiply(Args... args) { "
4196 "return (0 * ... * args); }",
4197 cxxFoldExpr(hasOperatorName("+"))));
4199 matches("template <typename... Args> auto multiply(Args... args) { "
4200 "return (... * args); };",
4201 cxxFoldExpr(hasOperatorName("+"))));
4204 TEST_P(ASTMatchersTest
, IsMain
) {
4205 EXPECT_TRUE(matches("int main() {}", functionDecl(isMain())));
4207 EXPECT_TRUE(notMatches("int main2() {}", functionDecl(isMain())));
4210 TEST_P(ASTMatchersTest
, OMPExecutableDirective_IsStandaloneDirective
) {
4211 auto Matcher
= ompExecutableDirective(isStandaloneDirective());
4213 StringRef Source0
= R
"(
4215 #pragma omp parallel
4218 EXPECT_TRUE(notMatchesWithOpenMP(Source0
, Matcher
));
4220 StringRef Source1
= R
"(
4222 #pragma omp taskyield
4224 EXPECT_TRUE(matchesWithOpenMP(Source1
, Matcher
));
4227 TEST_P(ASTMatchersTest
, OMPExecutableDirective_HasStructuredBlock
) {
4228 StringRef Source0
= R
"(
4230 #pragma omp parallel
4233 EXPECT_TRUE(matchesWithOpenMP(
4234 Source0
, ompExecutableDirective(hasStructuredBlock(nullStmt()))));
4236 StringRef Source1
= R
"(
4238 #pragma omp parallel
4241 EXPECT_TRUE(notMatchesWithOpenMP(
4242 Source1
, ompExecutableDirective(hasStructuredBlock(nullStmt()))));
4243 EXPECT_TRUE(matchesWithOpenMP(
4244 Source1
, ompExecutableDirective(hasStructuredBlock(compoundStmt()))));
4246 StringRef Source2
= R
"(
4248 #pragma omp taskyield
4251 EXPECT_TRUE(notMatchesWithOpenMP(
4252 Source2
, ompExecutableDirective(hasStructuredBlock(anything()))));
4255 TEST_P(ASTMatchersTest
, OMPExecutableDirective_HasClause
) {
4256 auto Matcher
= ompExecutableDirective(hasAnyClause(anything()));
4258 StringRef Source0
= R
"(
4262 EXPECT_TRUE(notMatchesWithOpenMP(Source0
, Matcher
));
4264 StringRef Source1
= R
"(
4266 #pragma omp parallel
4269 EXPECT_TRUE(notMatchesWithOpenMP(Source1
, Matcher
));
4271 StringRef Source2
= R
"(
4273 #pragma omp parallel default(none)
4276 EXPECT_TRUE(matchesWithOpenMP(Source2
, Matcher
));
4278 StringRef Source3
= R
"(
4280 #pragma omp parallel default(shared)
4283 EXPECT_TRUE(matchesWithOpenMP(Source3
, Matcher
));
4285 StringRef Source4
= R
"(
4287 #pragma omp parallel default(firstprivate)
4290 EXPECT_TRUE(matchesWithOpenMP51(Source4
, Matcher
));
4292 StringRef Source5
= R
"(
4294 #pragma omp parallel num_threads(x)
4297 EXPECT_TRUE(matchesWithOpenMP(Source5
, Matcher
));
4300 TEST_P(ASTMatchersTest
, OMPDefaultClause_IsNoneKind
) {
4302 ompExecutableDirective(hasAnyClause(ompDefaultClause(isNoneKind())));
4304 StringRef Source0
= R
"(
4308 EXPECT_TRUE(notMatchesWithOpenMP(Source0
, Matcher
));
4310 StringRef Source1
= R
"(
4312 #pragma omp parallel
4315 EXPECT_TRUE(notMatchesWithOpenMP(Source1
, Matcher
));
4317 StringRef Source2
= R
"(
4319 #pragma omp parallel default(none)
4322 EXPECT_TRUE(matchesWithOpenMP(Source2
, Matcher
));
4324 StringRef Source3
= R
"(
4326 #pragma omp parallel default(shared)
4329 EXPECT_TRUE(notMatchesWithOpenMP(Source3
, Matcher
));
4331 StringRef Source4
= R
"(
4333 #pragma omp parallel default(firstprivate)
4336 EXPECT_TRUE(notMatchesWithOpenMP51(Source4
, Matcher
));
4338 StringRef Source5
= R
"(
4340 #pragma omp parallel default(private)
4343 EXPECT_TRUE(notMatchesWithOpenMP51(Source5
, Matcher
));
4345 const std::string Source6
= R
"(
4347 #pragma omp parallel num_threads(x)
4350 EXPECT_TRUE(notMatchesWithOpenMP(Source6
, Matcher
));
4353 TEST_P(ASTMatchersTest
, OMPDefaultClause_IsSharedKind
) {
4355 ompExecutableDirective(hasAnyClause(ompDefaultClause(isSharedKind())));
4357 StringRef Source0
= R
"(
4361 EXPECT_TRUE(notMatchesWithOpenMP(Source0
, Matcher
));
4363 StringRef Source1
= R
"(
4365 #pragma omp parallel
4368 EXPECT_TRUE(notMatchesWithOpenMP(Source1
, Matcher
));
4370 StringRef Source2
= R
"(
4372 #pragma omp parallel default(shared)
4375 EXPECT_TRUE(matchesWithOpenMP(Source2
, Matcher
));
4377 StringRef Source3
= R
"(
4379 #pragma omp parallel default(none)
4382 EXPECT_TRUE(notMatchesWithOpenMP(Source3
, Matcher
));
4384 StringRef Source4
= R
"(
4386 #pragma omp parallel default(firstprivate)
4389 EXPECT_TRUE(notMatchesWithOpenMP51(Source4
, Matcher
));
4391 StringRef Source5
= R
"(
4393 #pragma omp parallel default(private)
4396 EXPECT_TRUE(notMatchesWithOpenMP51(Source5
, Matcher
));
4398 const std::string Source6
= R
"(
4400 #pragma omp parallel num_threads(x)
4403 EXPECT_TRUE(notMatchesWithOpenMP(Source6
, Matcher
));
4406 TEST(OMPDefaultClause
, isFirstPrivateKind
) {
4407 auto Matcher
= ompExecutableDirective(
4408 hasAnyClause(ompDefaultClause(isFirstPrivateKind())));
4410 const std::string Source0
= R
"(
4414 EXPECT_TRUE(notMatchesWithOpenMP(Source0
, Matcher
));
4416 const std::string Source1
= R
"(
4418 #pragma omp parallel
4421 EXPECT_TRUE(notMatchesWithOpenMP(Source1
, Matcher
));
4423 const std::string Source2
= R
"(
4425 #pragma omp parallel default(shared)
4428 EXPECT_TRUE(notMatchesWithOpenMP(Source2
, Matcher
));
4430 const std::string Source3
= R
"(
4432 #pragma omp parallel default(none)
4435 EXPECT_TRUE(notMatchesWithOpenMP(Source3
, Matcher
));
4437 const std::string Source4
= R
"(
4439 #pragma omp parallel default(firstprivate)
4442 EXPECT_TRUE(matchesWithOpenMP51(Source4
, Matcher
));
4444 const std::string Source5
= R
"(
4446 #pragma omp parallel default(private)
4449 EXPECT_TRUE(notMatchesWithOpenMP51(Source5
, Matcher
));
4451 const std::string Source6
= R
"(
4453 #pragma omp parallel num_threads(x)
4456 EXPECT_TRUE(notMatchesWithOpenMP(Source6
, Matcher
));
4459 TEST(OMPDefaultClause
, istPrivateKind
) {
4461 ompExecutableDirective(hasAnyClause(ompDefaultClause(isPrivateKind())));
4463 const std::string Source0
= R
"(
4467 EXPECT_TRUE(notMatchesWithOpenMP(Source0
, Matcher
));
4469 const std::string Source1
= R
"(
4471 #pragma omp parallel
4474 EXPECT_TRUE(notMatchesWithOpenMP(Source1
, Matcher
));
4476 const std::string Source2
= R
"(
4478 #pragma omp parallel default(shared)
4481 EXPECT_TRUE(notMatchesWithOpenMP(Source2
, Matcher
));
4483 const std::string Source3
= R
"(
4485 #pragma omp parallel default(none)
4488 EXPECT_TRUE(notMatchesWithOpenMP(Source3
, Matcher
));
4490 const std::string Source4
= R
"(
4492 #pragma omp parallel default(firstprivate)
4495 EXPECT_TRUE(notMatchesWithOpenMP51(Source4
, Matcher
));
4497 const std::string Source5
= R
"(
4499 #pragma omp parallel default(private)
4502 EXPECT_TRUE(matchesWithOpenMP51(Source5
, Matcher
));
4504 const std::string Source6
= R
"(
4506 #pragma omp parallel num_threads(x)
4509 EXPECT_TRUE(notMatchesWithOpenMP(Source6
, Matcher
));
4512 TEST_P(ASTMatchersTest
, OMPExecutableDirective_IsAllowedToContainClauseKind
) {
4513 auto Matcher
= ompExecutableDirective(
4514 isAllowedToContainClauseKind(llvm::omp::OMPC_default
));
4516 StringRef Source0
= R
"(
4520 EXPECT_TRUE(notMatchesWithOpenMP(Source0
, Matcher
));
4522 StringRef Source1
= R
"(
4524 #pragma omp parallel
4527 EXPECT_TRUE(matchesWithOpenMP(Source1
, Matcher
));
4529 StringRef Source2
= R
"(
4531 #pragma omp parallel default(none)
4534 EXPECT_TRUE(matchesWithOpenMP(Source2
, Matcher
));
4536 StringRef Source3
= R
"(
4538 #pragma omp parallel default(shared)
4541 EXPECT_TRUE(matchesWithOpenMP(Source3
, Matcher
));
4543 StringRef Source4
= R
"(
4545 #pragma omp parallel default(firstprivate)
4548 EXPECT_TRUE(matchesWithOpenMP51(Source4
, Matcher
));
4550 StringRef Source5
= R
"(
4552 #pragma omp parallel default(private)
4555 EXPECT_TRUE(matchesWithOpenMP51(Source5
, Matcher
));
4557 StringRef Source6
= R
"(
4559 #pragma omp parallel num_threads(x)
4562 EXPECT_TRUE(matchesWithOpenMP(Source6
, Matcher
));
4564 StringRef Source7
= R
"(
4566 #pragma omp taskyield
4568 EXPECT_TRUE(notMatchesWithOpenMP(Source7
, Matcher
));
4570 StringRef Source8
= R
"(
4575 EXPECT_TRUE(matchesWithOpenMP(Source8
, Matcher
));
4578 TEST_P(ASTMatchersTest
, HasAnyBase_DirectBase
) {
4579 if (!GetParam().isCXX()) {
4582 EXPECT_TRUE(matches(
4584 "struct ExpectedMatch : Base {};",
4585 cxxRecordDecl(hasName("ExpectedMatch"),
4586 hasAnyBase(hasType(cxxRecordDecl(hasName("Base")))))));
4589 TEST_P(ASTMatchersTest
, HasAnyBase_IndirectBase
) {
4590 if (!GetParam().isCXX()) {
4593 EXPECT_TRUE(matches(
4595 "struct Intermediate : Base {};"
4596 "struct ExpectedMatch : Intermediate {};",
4597 cxxRecordDecl(hasName("ExpectedMatch"),
4598 hasAnyBase(hasType(cxxRecordDecl(hasName("Base")))))));
4601 TEST_P(ASTMatchersTest
, HasAnyBase_NoBase
) {
4602 if (!GetParam().isCXX()) {
4605 EXPECT_TRUE(notMatches("struct Foo {};"
4607 cxxRecordDecl(hasAnyBase(hasType(cxxRecordDecl())))));
4610 TEST_P(ASTMatchersTest
, HasAnyBase_IsPublic_Public
) {
4611 if (!GetParam().isCXX()) {
4614 EXPECT_TRUE(matches("class Base {};"
4615 "class Derived : public Base {};",
4616 cxxRecordDecl(hasAnyBase(isPublic()))));
4619 TEST_P(ASTMatchersTest
, HasAnyBase_IsPublic_DefaultAccessSpecifierPublic
) {
4620 if (!GetParam().isCXX()) {
4623 EXPECT_TRUE(matches("class Base {};"
4624 "struct Derived : Base {};",
4625 cxxRecordDecl(hasAnyBase(isPublic()))));
4628 TEST_P(ASTMatchersTest
, HasAnyBase_IsPublic_Private
) {
4629 if (!GetParam().isCXX()) {
4632 EXPECT_TRUE(notMatches("class Base {};"
4633 "class Derived : private Base {};",
4634 cxxRecordDecl(hasAnyBase(isPublic()))));
4637 TEST_P(ASTMatchersTest
, HasAnyBase_IsPublic_DefaultAccessSpecifierPrivate
) {
4638 if (!GetParam().isCXX()) {
4641 EXPECT_TRUE(notMatches("class Base {};"
4642 "class Derived : Base {};",
4643 cxxRecordDecl(hasAnyBase(isPublic()))));
4646 TEST_P(ASTMatchersTest
, HasAnyBase_IsPublic_Protected
) {
4647 if (!GetParam().isCXX()) {
4650 EXPECT_TRUE(notMatches("class Base {};"
4651 "class Derived : protected Base {};",
4652 cxxRecordDecl(hasAnyBase(isPublic()))));
4655 TEST_P(ASTMatchersTest
, HasAnyBase_IsPrivate_Private
) {
4656 if (!GetParam().isCXX()) {
4659 EXPECT_TRUE(matches("class Base {};"
4660 "class Derived : private Base {};",
4661 cxxRecordDecl(hasAnyBase(isPrivate()))));
4664 TEST_P(ASTMatchersTest
, HasAnyBase_IsPrivate_DefaultAccessSpecifierPrivate
) {
4665 if (!GetParam().isCXX()) {
4668 EXPECT_TRUE(matches("struct Base {};"
4669 "class Derived : Base {};",
4670 cxxRecordDecl(hasAnyBase(isPrivate()))));
4673 TEST_P(ASTMatchersTest
, HasAnyBase_IsPrivate_Public
) {
4674 if (!GetParam().isCXX()) {
4677 EXPECT_TRUE(notMatches("class Base {};"
4678 "class Derived : public Base {};",
4679 cxxRecordDecl(hasAnyBase(isPrivate()))));
4682 TEST_P(ASTMatchersTest
, HasAnyBase_IsPrivate_DefaultAccessSpecifierPublic
) {
4683 if (!GetParam().isCXX()) {
4686 EXPECT_TRUE(notMatches("class Base {};"
4687 "struct Derived : Base {};",
4688 cxxRecordDecl(hasAnyBase(isPrivate()))));
4691 TEST_P(ASTMatchersTest
, HasAnyBase_IsPrivate_Protected
) {
4692 if (!GetParam().isCXX()) {
4695 EXPECT_TRUE(notMatches("class Base {};"
4696 "class Derived : protected Base {};",
4697 cxxRecordDecl(hasAnyBase(isPrivate()))));
4700 TEST_P(ASTMatchersTest
, HasAnyBase_IsProtected_Protected
) {
4701 if (!GetParam().isCXX()) {
4704 EXPECT_TRUE(matches("class Base {};"
4705 "class Derived : protected Base {};",
4706 cxxRecordDecl(hasAnyBase(isProtected()))));
4709 TEST_P(ASTMatchersTest
, HasAnyBase_IsProtected_Public
) {
4710 if (!GetParam().isCXX()) {
4713 EXPECT_TRUE(notMatches("class Base {};"
4714 "class Derived : public Base {};",
4715 cxxRecordDecl(hasAnyBase(isProtected()))));
4718 TEST_P(ASTMatchersTest
, HasAnyBase_IsProtected_Private
) {
4719 if (!GetParam().isCXX()) {
4722 EXPECT_TRUE(notMatches("class Base {};"
4723 "class Derived : private Base {};",
4724 cxxRecordDecl(hasAnyBase(isProtected()))));
4727 TEST_P(ASTMatchersTest
, HasAnyBase_IsVirtual_Directly
) {
4728 if (!GetParam().isCXX()) {
4731 EXPECT_TRUE(matches("class Base {};"
4732 "class Derived : virtual Base {};",
4733 cxxRecordDecl(hasAnyBase(isVirtual()))));
4736 TEST_P(ASTMatchersTest
, HasAnyBase_IsVirtual_Indirectly
) {
4737 if (!GetParam().isCXX()) {
4741 matches("class Base {};"
4742 "class Intermediate : virtual Base {};"
4743 "class Derived : Intermediate {};",
4744 cxxRecordDecl(hasName("Derived"), hasAnyBase(isVirtual()))));
4747 TEST_P(ASTMatchersTest
, HasAnyBase_IsVirtual_NoVirtualBase
) {
4748 if (!GetParam().isCXX()) {
4751 EXPECT_TRUE(notMatches("class Base {};"
4752 "class Derived : Base {};",
4753 cxxRecordDecl(hasAnyBase(isVirtual()))));
4756 TEST_P(ASTMatchersTest
, HasDirectBase
) {
4757 if (!GetParam().isCXX()) {
4761 DeclarationMatcher ClassHasAnyDirectBase
=
4762 cxxRecordDecl(hasDirectBase(cxxBaseSpecifier()));
4763 EXPECT_TRUE(notMatches("class X {};", ClassHasAnyDirectBase
));
4764 EXPECT_TRUE(matches("class X {}; class Y : X {};", ClassHasAnyDirectBase
));
4765 EXPECT_TRUE(matches("class X {}; class Y : public virtual X {};",
4766 ClassHasAnyDirectBase
));
4768 EXPECT_TRUE(matches(
4771 class Derived : Base{};
4773 cxxRecordDecl(hasName("Derived"),
4774 hasDirectBase(hasType(cxxRecordDecl(hasName("Base")))))));
4776 StringRef MultiDerived
= R
"cc(
4779 class Derived : Base, Base2{};
4782 EXPECT_TRUE(matches(
4784 cxxRecordDecl(hasName("Derived"),
4785 hasDirectBase(hasType(cxxRecordDecl(hasName("Base")))))));
4786 EXPECT_TRUE(matches(
4788 cxxRecordDecl(hasName("Derived"),
4789 hasDirectBase(hasType(cxxRecordDecl(hasName("Base2")))))));
4791 StringRef Indirect
= R
"cc(
4793 class Intermediate : Base {};
4794 class Derived : Intermediate{};
4798 matches(Indirect
, cxxRecordDecl(hasName("Derived"),
4799 hasDirectBase(hasType(cxxRecordDecl(
4800 hasName("Intermediate")))))));
4801 EXPECT_TRUE(notMatches(
4803 cxxRecordDecl(hasName("Derived"),
4804 hasDirectBase(hasType(cxxRecordDecl(hasName("Base")))))));
4807 TEST_P(ASTMatchersTest
, CapturesThis
) {
4808 if (!GetParam().isCXX11OrLater()) {
4811 auto matcher
= lambdaExpr(hasAnyCapture(lambdaCapture(capturesThis())));
4812 EXPECT_TRUE(matches("class C { int cc; int f() { auto l = [this](){ return "
4813 "cc; }; return l(); } };",
4815 EXPECT_TRUE(matches("class C { int cc; int f() { auto l = [=](){ return cc; "
4816 "}; return l(); } };",
4818 EXPECT_TRUE(matches("class C { int cc; int f() { auto l = [&](){ return cc; "
4819 "}; return l(); } };",
4821 EXPECT_FALSE(matches("class C { int cc; int f() { auto l = [cc](){ return "
4822 "cc; }; return l(); } };",
4824 EXPECT_FALSE(matches("class C { int this; int f() { auto l = [this](){ "
4825 "return this; }; return l(); } };",
4829 TEST_P(ASTMatchersTest
, IsImplicit_LambdaCapture
) {
4830 if (!GetParam().isCXX11OrLater()) {
4833 auto matcher
= lambdaExpr(hasAnyCapture(
4834 lambdaCapture(isImplicit(), capturesVar(varDecl(hasName("cc"))))));
4836 matches("int main() { int cc; auto f = [&](){ return cc; }; }", matcher
));
4838 matches("int main() { int cc; auto f = [=](){ return cc; }; }", matcher
));
4839 EXPECT_FALSE(matches("int main() { int cc; auto f = [cc](){ return cc; }; }",
4843 } // namespace ast_matchers
4844 } // namespace clang