[NFC][Coroutines] Use structured binding with llvm::enumerate in CoroSplit (#116879)
[llvm-project.git] / clang / unittests / ASTMatchers / ASTMatchersNarrowingTest.cpp
blob056b7c7b571ef46780ea79353c161a44303b843e
1 // unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp - AST matcher unit tests//
2 //
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
6 //
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"
18 namespace clang {
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); }
25 )cc";
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); }
34 )cc";
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); }
44 )cc";
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); }
53 )cc";
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))
60 void Test() {
61 int x = 5;
62 MY_MACRO(x);
64 )cc";
65 EXPECT_TRUE(matches(input, declRefExpr(isExpandedFromMacro("MY_MACRO"))));
68 // Like IsExpandedFromMacro_MatchesArgument, but the argument is itself a
69 // macro.
70 TEST_P(ASTMatchersTest, IsExpandedFromMacro_MatchesArgumentMacroExpansion) {
71 StringRef input = R"cc(
72 #define MY_MACRO(a) (4 + (a))
73 #define IDENTITY(a) (a)
74 void Test() {
75 IDENTITY(MY_MACRO(2));
77 )cc";
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)
85 void Test() {
86 IDENTITY(MY_MACRO(2));
88 )cc";
89 EXPECT_TRUE(matches(input, binaryOperator(isExpandedFromMacro("MY_MACRO"))));
92 TEST_P(ASTMatchersTest, IsExpandedFromMacro_MatchesObjectMacro) {
93 StringRef input = R"cc(
94 #define PLUS (2 + 2)
95 void Test() {
96 PLUS;
98 )cc";
99 EXPECT_TRUE(matches(input, binaryOperator(isExpandedFromMacro("PLUS"))));
102 TEST(IsExpandedFromMacro, MatchesFromCommandLine) {
103 StringRef input = R"cc(
104 void Test() { FOUR_PLUS_FOUR; }
105 )cc";
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(
113 #define ONE_PLUS 1+
114 void Test() { ONE_PLUS 4; }
115 )cc";
116 EXPECT_TRUE(
117 notMatches(input, binaryOperator(isExpandedFromMacro("ONE_PLUS"))));
120 TEST_P(ASTMatchersTest, IsExpandedFromMacro_NotMatchesEndOnly) {
121 StringRef input = R"cc(
122 #define PLUS_ONE +1
123 void Test() { 4 PLUS_ONE; }
124 )cc";
125 EXPECT_TRUE(
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); }
133 )cc";
134 EXPECT_TRUE(notMatches(input, binaryOperator(isExpandedFromMacro("OTHER"))));
137 TEST_P(ASTMatchersTest, IsExpandedFromMacro_NotMatchesDifferentInstances) {
138 StringRef input = R"cc(
139 #define FOUR 4
140 void Test() { FOUR + FOUR; }
141 )cc";
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); }
149 )cc";
150 EXPECT_TRUE(matches(input, varDecl(isExpandedFromMacro("MY_MACRO"))));
153 TEST(IsExpandedFromMacro, IsExpandedFromMacro_MatchesTypelocs) {
154 StringRef input = R"cc(
155 #define MY_TYPE int
156 void Test() { MY_TYPE i = 4; }
157 )cc";
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); }";
165 EXPECT_TRUE(matches(
166 Program, callExpr(allOf(callee(functionDecl(hasName("f"))),
167 hasArgument(0, declRefExpr(to(varDecl())))))));
168 EXPECT_TRUE(matches(
169 Program,
170 callExpr(
171 allOf(callee(functionDecl(hasName("f"))),
172 hasArgument(0, declRefExpr(to(varDecl()))),
173 hasArgument(1, hasType(pointsTo(recordDecl(hasName("T")))))))));
174 EXPECT_TRUE(matches(
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)))))));
180 EXPECT_TRUE(matches(
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++.
192 return;
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()) {
208 return;
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"))),
216 hasName("F"));
218 EXPECT_TRUE(matches("class F {"
219 " class Z {"
220 " class X {};"
221 " class Y {};"
222 " };"
223 " class C {"
224 " class A {};"
225 " class B {};"
226 " };"
227 "};",
228 Recursive));
230 EXPECT_TRUE(matches("class F {"
231 " class Z {"
232 " class A {};"
233 " class X {};"
234 " class Y {};"
235 " };"
236 " class C {"
237 " class X {};"
238 " class A {};"
239 " class B {};"
240 " };"
241 "};",
242 Recursive));
244 EXPECT_TRUE(matches("class O1 {"
245 " class O2 {"
246 " class F {"
247 " class Z {"
248 " class A {};"
249 " class X {};"
250 " class Y {};"
251 " };"
252 " class C {"
253 " class X {};"
254 " class A {};"
255 " class B {};"
256 " };"
257 " };"
258 " };"
259 "};",
260 Recursive));
263 TEST_P(ASTMatchersTest, Has_RecursiveAnyOf) {
264 if (!GetParam().isCXX()) {
265 return;
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")))))),
273 hasName("F")));
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 {}; }; }; "
282 "}; };",
283 Recursive));
286 TEST_P(ASTMatchersTest, Unless) {
287 if (!GetParam().isCXX()) {
288 // FIXME: Add a test for `unless()` that does not depend on C++.
289 return;
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));
298 EXPECT_TRUE(
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));
305 EXPECT_TRUE(
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) {
315 EXPECT_TRUE(
316 matches("char *p = 0;",
317 traverse(TK_AsIs,
318 varDecl(has(castExpr(hasCastKind(CK_NullToPointer)))))));
319 EXPECT_TRUE(notMatches(
320 "char *p = 0;",
321 traverse(TK_AsIs,
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++.
331 return;
334 DeclarationMatcher ZDescendantClassX =
335 recordDecl(hasDescendant(recordDecl(hasName("X"))), hasName("Z"));
336 EXPECT_TRUE(matches("class Z { class X {}; };", ZDescendantClassX));
337 EXPECT_TRUE(
338 matches("class Z { class Y { class X {}; }; };", ZDescendantClassX));
339 EXPECT_TRUE(matches("class Z { class A { class Y { class X {}; }; }; };",
340 ZDescendantClassX));
341 EXPECT_TRUE(
342 matches("class Z { class A { class B { class Y { class X {}; }; }; }; };",
343 ZDescendantClassX));
344 EXPECT_TRUE(notMatches("class Z {};", ZDescendantClassX));
346 DeclarationMatcher ZDescendantClassXHasClassY = recordDecl(
347 hasDescendant(recordDecl(has(recordDecl(hasName("Y"))), hasName("X"))),
348 hasName("Z"));
349 EXPECT_TRUE(matches("class Z { class X { class Y {}; }; };",
350 ZDescendantClassXHasClassY));
351 EXPECT_TRUE(
352 matches("class Z { class A { class B { class X { class Y {}; }; }; }; };",
353 ZDescendantClassXHasClassY));
354 EXPECT_TRUE(notMatches("class Z {"
355 " class A {"
356 " class B {"
357 " class X {"
358 " class C {"
359 " class Y {};"
360 " };"
361 " };"
362 " }; "
363 " };"
364 "};",
365 ZDescendantClassXHasClassY));
367 DeclarationMatcher ZDescendantClassXDescendantClassY =
368 recordDecl(hasDescendant(recordDecl(
369 hasDescendant(recordDecl(hasName("Y"))), hasName("X"))),
370 hasName("Z"));
371 EXPECT_TRUE(
372 matches("class Z { class A { class X { class B { class Y {}; }; }; }; };",
373 ZDescendantClassXDescendantClassY));
374 EXPECT_TRUE(matches("class Z {"
375 " class A {"
376 " class X {"
377 " class B {"
378 " class Y {};"
379 " };"
380 " class Y {};"
381 " };"
382 " };"
383 "};",
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()) {
409 return;
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
414 // it on the cache.
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; };",
421 CannotMemoize));
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++.
433 return;
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));
440 EXPECT_TRUE(
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));
463 EXPECT_TRUE(
464 matches("void f() try { } catch (int) { } catch (...) { }",
465 cxxCatchStmt(anyOf(hasDescendant(varDecl()), isCatchAll()))));
468 TEST_P(ASTMatchersTest, MapAnyOf) {
469 if (!GetParam().isCXX()) {
470 return;
473 if (GetParam().hasDelayedTemplateParsing()) {
474 return;
477 StringRef Code = R"cpp(
478 void F() {
479 if (true) {}
480 for ( ; false; ) {}
482 )cpp";
484 auto trueExpr = cxxBoolLiteral(equals(true));
485 auto falseExpr = cxxBoolLiteral(equals(false));
487 EXPECT_TRUE(matches(
488 Code, traverse(TK_IgnoreUnlessSpelledInSource,
489 mapAnyOf(ifStmt, forStmt).with(hasCondition(trueExpr)))));
490 EXPECT_TRUE(matches(
491 Code, traverse(TK_IgnoreUnlessSpelledInSource,
492 mapAnyOf(ifStmt, forStmt).with(hasCondition(falseExpr)))));
494 EXPECT_TRUE(
495 matches(Code, cxxBoolLiteral(equals(true),
496 hasAncestor(mapAnyOf(ifStmt, forStmt)))));
498 EXPECT_TRUE(
499 matches(Code, cxxBoolLiteral(equals(false),
500 hasAncestor(mapAnyOf(ifStmt, forStmt)))));
502 EXPECT_TRUE(
503 notMatches(Code, floatLiteral(hasAncestor(mapAnyOf(ifStmt, forStmt)))));
505 Code = R"cpp(
506 void func(bool b) {}
507 struct S {
508 S(bool b) {}
510 void F() {
511 func(false);
512 S s(true);
514 )cpp";
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)))));
522 EXPECT_TRUE(
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))));
531 EXPECT_TRUE(matches(
532 Code, traverse(TK_IgnoreUnlessSpelledInSource,
533 mapAnyOf(callExpr, cxxConstructExpr).bind("call"))));
535 Code = R"cpp(
536 struct HasOpNeqMem
538 bool operator!=(const HasOpNeqMem& other) const
540 return true;
543 struct HasOpFree
546 bool operator!=(const HasOpFree& lhs, const HasOpFree& rhs)
548 return true;
551 void binop()
553 int s1;
554 int s2;
555 if (s1 != s2)
556 return;
559 void opMem()
561 HasOpNeqMem s1;
562 HasOpNeqMem s2;
563 if (s1 != s2)
564 return;
567 void opFree()
569 HasOpFree s1;
570 HasOpFree s2;
571 if (s1 != s2)
572 return;
575 template<typename T>
576 void templ()
578 T s1;
579 T s2;
580 if (s1 != s2)
581 return;
583 )cpp";
585 EXPECT_TRUE(matches(
586 Code,
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")))))))));
594 EXPECT_TRUE(matches(
595 Code,
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")))))))));
603 EXPECT_TRUE(matches(
604 Code,
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")))))))));
612 EXPECT_TRUE(matches(
613 Code, traverse(TK_IgnoreUnlessSpelledInSource,
614 mapAnyOf(binaryOperator, cxxOperatorCallExpr)
615 .with(hasOperatorName("!="),
616 forFunction(functionDecl(hasName("binop"))),
617 hasEitherOperand(
618 declRefExpr(to(varDecl(hasName("s1"))))),
619 hasEitherOperand(
620 declRefExpr(to(varDecl(hasName("s2")))))))));
622 EXPECT_TRUE(matches(
623 Code, traverse(TK_IgnoreUnlessSpelledInSource,
624 mapAnyOf(binaryOperator, cxxOperatorCallExpr)
625 .with(hasOperatorName("!="),
626 forFunction(functionDecl(hasName("opMem"))),
627 hasEitherOperand(
628 declRefExpr(to(varDecl(hasName("s1"))))),
629 hasEitherOperand(
630 declRefExpr(to(varDecl(hasName("s2")))))))));
632 EXPECT_TRUE(matches(
633 Code, traverse(TK_IgnoreUnlessSpelledInSource,
634 mapAnyOf(binaryOperator, cxxOperatorCallExpr)
635 .with(hasOperatorName("!="),
636 forFunction(functionDecl(hasName("opFree"))),
637 hasEitherOperand(
638 declRefExpr(to(varDecl(hasName("s1"))))),
639 hasEitherOperand(
640 declRefExpr(to(varDecl(hasName("s2")))))))));
642 EXPECT_TRUE(matches(
643 Code,
644 traverse(
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")))))))));
654 EXPECT_TRUE(matches(
655 Code,
656 traverse(
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")))))))));
666 EXPECT_TRUE(matches(
667 Code,
668 traverse(
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")))))))));
678 EXPECT_TRUE(matches(
679 Code, traverse(TK_IgnoreUnlessSpelledInSource,
680 mapAnyOf(binaryOperator, cxxOperatorCallExpr)
681 .with(hasAnyOperatorName("==", "!="),
682 forFunction(functionDecl(hasName("binop")))))));
684 EXPECT_TRUE(matches(
685 Code, traverse(TK_IgnoreUnlessSpelledInSource,
686 mapAnyOf(binaryOperator, cxxOperatorCallExpr)
687 .with(hasAnyOperatorName("==", "!="),
688 forFunction(functionDecl(hasName("opMem")))))));
690 EXPECT_TRUE(matches(
691 Code, traverse(TK_IgnoreUnlessSpelledInSource,
692 mapAnyOf(binaryOperator, cxxOperatorCallExpr)
693 .with(hasAnyOperatorName("==", "!="),
694 forFunction(functionDecl(hasName("opFree")))))));
696 EXPECT_TRUE(matches(
697 Code, traverse(TK_IgnoreUnlessSpelledInSource,
698 binaryOperation(
699 hasOperatorName("!="),
700 forFunction(functionDecl(hasName("binop"))),
701 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
702 hasRHS(declRefExpr(to(varDecl(hasName("s2")))))))));
704 EXPECT_TRUE(matches(
705 Code, traverse(TK_IgnoreUnlessSpelledInSource,
706 binaryOperation(
707 hasOperatorName("!="),
708 forFunction(functionDecl(hasName("opMem"))),
709 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
710 hasRHS(declRefExpr(to(varDecl(hasName("s2")))))))));
712 EXPECT_TRUE(matches(
713 Code, traverse(TK_IgnoreUnlessSpelledInSource,
714 binaryOperation(
715 hasOperatorName("!="),
716 forFunction(functionDecl(hasName("opFree"))),
717 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
718 hasRHS(declRefExpr(to(varDecl(hasName("s2")))))))));
720 EXPECT_TRUE(matches(
721 Code, traverse(TK_IgnoreUnlessSpelledInSource,
722 binaryOperation(
723 hasOperatorName("!="),
724 forFunction(functionDecl(hasName("templ"))),
725 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),
726 hasRHS(declRefExpr(to(varDecl(hasName("s2")))))))));
728 Code = R"cpp(
729 struct HasOpEq
731 bool operator==(const HasOpEq &) const;
734 void inverse()
736 HasOpEq s1;
737 HasOpEq s2;
738 if (s1 != s2)
739 return;
742 namespace std {
743 struct strong_ordering {
744 int n;
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 {
754 int a;
755 constexpr auto operator<=>(const HasSpaceshipMem&) const = default;
758 void rewritten()
760 HasSpaceshipMem s1;
761 HasSpaceshipMem s2;
762 if (s1 != s2)
763 return;
765 )cpp";
767 EXPECT_TRUE(matchesConditionally(
768 Code,
769 traverse(
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(
778 Code,
779 traverse(
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"}));
787 Code = R"cpp(
788 struct HasOpBangMem
790 bool operator!() const
792 return false;
795 struct HasOpBangFree
798 bool operator!(HasOpBangFree const&)
800 return false;
803 void unop()
805 int s1;
806 if (!s1)
807 return;
810 void opMem()
812 HasOpBangMem s1;
813 if (!s1)
814 return;
817 void opFree()
819 HasOpBangFree s1;
820 if (!s1)
821 return;
823 )cpp";
825 EXPECT_TRUE(matches(
826 Code, traverse(TK_IgnoreUnlessSpelledInSource,
827 mapAnyOf(unaryOperator, cxxOperatorCallExpr)
828 .with(hasOperatorName("!"),
829 forFunction(functionDecl(hasName("unop"))),
830 hasUnaryOperand(
831 declRefExpr(to(varDecl(hasName("s1")))))))));
833 EXPECT_TRUE(matches(
834 Code, traverse(TK_IgnoreUnlessSpelledInSource,
835 mapAnyOf(unaryOperator, cxxOperatorCallExpr)
836 .with(hasOperatorName("!"),
837 forFunction(functionDecl(hasName("opMem"))),
838 hasUnaryOperand(
839 declRefExpr(to(varDecl(hasName("s1")))))))));
841 EXPECT_TRUE(matches(
842 Code, traverse(TK_IgnoreUnlessSpelledInSource,
843 mapAnyOf(unaryOperator, cxxOperatorCallExpr)
844 .with(hasOperatorName("!"),
845 forFunction(functionDecl(hasName("opFree"))),
846 hasUnaryOperand(
847 declRefExpr(to(varDecl(hasName("s1")))))))));
849 EXPECT_TRUE(matches(
850 Code, traverse(TK_IgnoreUnlessSpelledInSource,
851 mapAnyOf(unaryOperator, cxxOperatorCallExpr)
852 .with(hasAnyOperatorName("+", "!"),
853 forFunction(functionDecl(hasName("unop")))))));
855 EXPECT_TRUE(matches(
856 Code, traverse(TK_IgnoreUnlessSpelledInSource,
857 mapAnyOf(unaryOperator, cxxOperatorCallExpr)
858 .with(hasAnyOperatorName("+", "!"),
859 forFunction(functionDecl(hasName("opMem")))))));
861 EXPECT_TRUE(matches(
862 Code, traverse(TK_IgnoreUnlessSpelledInSource,
863 mapAnyOf(unaryOperator, cxxOperatorCallExpr)
864 .with(hasAnyOperatorName("+", "!"),
865 forFunction(functionDecl(hasName("opFree")))))));
867 Code = R"cpp(
868 struct ConstructorTakesInt
870 ConstructorTakesInt(int i) {}
873 void callTakesInt(int i)
878 void doCall()
880 callTakesInt(42);
883 void doConstruct()
885 ConstructorTakesInt cti(42);
887 )cpp";
889 EXPECT_TRUE(matches(
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")))))));
898 EXPECT_TRUE(matches(
899 Code,
900 traverse(
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()) {
911 return;
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 {};",
922 IsDerivedFromX));
923 EXPECT_TRUE(matches("class X {}; template<int N> class Y : X, Y<N-1> {};",
924 IsDerivedFromX));
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> {};",
932 IsZDerivedFromX));
934 DeclarationMatcher IsDirectlyDerivedFromX =
935 cxxRecordDecl(isDirectlyDerivedFrom("X"));
937 EXPECT_TRUE(
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"));
956 EXPECT_TRUE(
957 matches("class X {}; class Y : public X {}; class Z : public Y {};",
958 ZIsDerivedFromX));
959 EXPECT_TRUE(
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> {};",
965 ZIsDerivedFromX));
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 {};",
971 ZIsDerivedFromX));
972 EXPECT_TRUE(matches("template<class T> class X {}; "
973 "template<class T> class Z : public X<T> {};",
974 ZIsDerivedFromX));
975 EXPECT_TRUE(matches("template<class T, class U=T> class X {}; "
976 "template<class T> class Z : public X<T> {};",
977 ZIsDerivedFromX));
978 EXPECT_TRUE(
979 notMatches("template<class X> class A { class Z : public X {}; };",
980 ZIsDerivedFromX));
981 EXPECT_TRUE(
982 matches("template<class X> class A { public: class Z : public X {}; }; "
983 "class X{}; void y() { A<X>::Z z; }",
984 ZIsDerivedFromX));
985 EXPECT_TRUE(
986 matches("template <class T> class X {}; "
987 "template<class Y> class A { class Z : public X<Y> {}; };",
988 ZIsDerivedFromX));
989 EXPECT_TRUE(notMatches("template<template<class T> class X> class A { "
990 " class Z : public X<int> {}; };",
991 ZIsDerivedFromX));
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; }",
995 ZIsDerivedFromX));
996 EXPECT_TRUE(
997 notMatches("template<class X> class A { class Z : public X::D {}; };",
998 ZIsDerivedFromX));
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; }",
1003 ZIsDerivedFromX));
1004 EXPECT_TRUE(matches("class X {}; typedef X Y; class Z : public Y {};",
1005 ZIsDerivedFromX));
1006 EXPECT_TRUE(matches("template<class T> class Y { typedef typename T::U X; "
1007 " class Z : public X {}; };",
1008 ZIsDerivedFromX));
1009 EXPECT_TRUE(matches("class X {}; class Z : public ::X {};", ZIsDerivedFromX));
1010 EXPECT_TRUE(
1011 notMatches("template<class T> class X {}; "
1012 "template<class T> class A { class Z : public X<T>::D {}; };",
1013 ZIsDerivedFromX));
1014 EXPECT_TRUE(
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; }",
1018 ZIsDerivedFromX));
1019 EXPECT_TRUE(
1020 notMatches("template<class X> class A { class Z : public X::D::E {}; };",
1021 ZIsDerivedFromX));
1022 EXPECT_TRUE(
1023 matches("class X {}; typedef X V; typedef V W; class Z : public W {};",
1024 ZIsDerivedFromX));
1025 EXPECT_TRUE(matches("class X {}; class Y : public X {}; "
1026 "typedef Y V; typedef V W; class Z : public W {};",
1027 ZIsDerivedFromX));
1028 EXPECT_TRUE(notMatches("class X {}; class Y : public X {}; "
1029 "typedef Y V; typedef V W; class Z : public W {};",
1030 ZIsDirectlyDerivedFromX));
1031 EXPECT_TRUE(
1032 matches("template<class T, class U> class X {}; "
1033 "template<class T> class A { class Z : public X<T, int> {}; };",
1034 ZIsDerivedFromX));
1035 EXPECT_TRUE(
1036 notMatches("template<class X> class D { typedef X A; typedef A B; "
1037 " typedef B C; class Z : public C {}; };",
1038 ZIsDerivedFromX));
1039 EXPECT_TRUE(matches("class X {}; typedef X A; typedef A B; "
1040 "class Z : public B {};",
1041 ZIsDerivedFromX));
1042 EXPECT_TRUE(matches("class X {}; typedef X A; typedef A B; typedef B C; "
1043 "class Z : public C {};",
1044 ZIsDerivedFromX));
1045 EXPECT_TRUE(matches("class U {}; typedef U X; typedef X V; "
1046 "class Z : public V {};",
1047 ZIsDerivedFromX));
1048 EXPECT_TRUE(matches("class Base {}; typedef Base X; "
1049 "class Z : public Base {};",
1050 ZIsDerivedFromX));
1051 EXPECT_TRUE(matches("class Base {}; typedef Base Base2; typedef Base2 X; "
1052 "class Z : public Base {};",
1053 ZIsDerivedFromX));
1054 EXPECT_TRUE(notMatches("class Base {}; class Base2 {}; typedef Base2 X; "
1055 "class Z : public Base {};",
1056 ZIsDerivedFromX));
1057 EXPECT_TRUE(matches("class A {}; typedef A X; typedef A Y; "
1058 "class Z : public Y {};",
1059 ZIsDerivedFromX));
1060 EXPECT_TRUE(notMatches("template <typename T> class Z;"
1061 "template <> class Z<void> {};"
1062 "template <typename T> class Z : public Z<void> {};",
1063 IsDerivedFromX));
1064 EXPECT_TRUE(matches("template <typename T> class X;"
1065 "template <> class X<void> {};"
1066 "template <typename T> class X : public X<void> {};",
1067 IsDerivedFromX));
1068 EXPECT_TRUE(
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 {};",
1073 ZIsDerivedFromX));
1074 EXPECT_TRUE(
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(
1079 "struct A {};"
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(
1086 "struct A {};"
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")))))));
1114 EXPECT_TRUE(
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")))))));
1139 EXPECT_TRUE(
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()) {
1161 return;
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"));
1172 EXPECT_TRUE(
1173 matchesObjC("@interface X @end @interface Y : X @end", IsDerivedFromX));
1174 EXPECT_TRUE(matchesObjC(
1175 "@interface X @end @interface Y<__covariant ObjectType> : X @end",
1176 IsDerivedFromX));
1177 EXPECT_TRUE(matchesObjC(
1178 "@interface X @end @compatibility_alias Y X; @interface Z : Y @end",
1179 IsDerivedFromX));
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;",
1186 IsDerivedFromX));
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));
1199 EXPECT_TRUE(
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));
1207 EXPECT_TRUE(
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",
1223 ZIsDerivedFromX));
1224 EXPECT_TRUE(matchesObjC("@interface X @end @interface Y : X @end typedef Y "
1225 "V; typedef V W; @interface Z : W @end",
1226 ZIsDerivedFromX));
1227 EXPECT_TRUE(matchesObjC(
1228 "@interface X @end typedef X Y; @interface Z : Y @end", ZIsDerivedFromX));
1229 EXPECT_TRUE(
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",
1234 ZIsDerivedFromX));
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",
1240 ZIsDerivedFromX));
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",
1246 ZIsDerivedFromX));
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",
1253 ZIsDerivedFromX));
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));
1260 EXPECT_TRUE(
1261 matchesObjC("@interface Y @end typedef Y X; @interface Z : X @end",
1262 ZIsDirectlyDerivedFromX));
1263 EXPECT_TRUE(
1264 matchesObjC("@interface A @end @compatibility_alias Y A; typedef Y X;"
1265 "@interface Z : A @end",
1266 ZIsDerivedFromX));
1267 EXPECT_TRUE(
1268 matchesObjC("@interface A @end @compatibility_alias Y A; typedef Y X;"
1269 "@interface Z : A @end",
1270 ZIsDirectlyDerivedFromX));
1271 EXPECT_TRUE(
1272 matchesObjC("@interface A @end typedef A Y; @compatibility_alias X Y;"
1273 "@interface Z : A @end",
1274 ZIsDerivedFromX));
1275 EXPECT_TRUE(
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()) {
1283 return;
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
1333 // kick in.
1334 DeclarationMatcher ClassX = recordDecl(hasName("X")).bind("x");
1335 EXPECT_TRUE(matchAndVerifyResultTrue(
1336 "class A { class B { class X {}; }; };",
1337 DeclarationMatcher(
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++.
1346 return;
1349 EXPECT_TRUE(
1350 matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }",
1351 cxxMemberCallExpr(on(hasType(asString("Y *"))))));
1352 EXPECT_TRUE(
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()) {
1363 return;
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;",
1371 OpCallAndAnd));
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;",
1377 OpCallLessLess));
1378 StatementMatcher OpStarCall =
1379 cxxOperatorCallExpr(hasOverloadedOperatorName("*"));
1380 EXPECT_TRUE(
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()) {
1399 return;
1402 EXPECT_TRUE(matchAndVerifyResultTrue(
1403 "class Y { }; "
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()))));
1412 EXPECT_TRUE(
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()) {
1443 return;
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()) {
1450 return;
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) {
1458 StringRef T =
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())));
1462 EXPECT_TRUE(
1463 notMatches(T, varDecl(hasName("y"), hasAutomaticStorageDuration())));
1464 EXPECT_TRUE(
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()))));
1498 EXPECT_TRUE(
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
1507 // on C++.
1508 return;
1511 EXPECT_TRUE(notMatches("int *i;", varDecl(hasType(isInteger()))));
1512 EXPECT_TRUE(
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()))));
1520 EXPECT_TRUE(
1521 notMatches("unsigned i = 0;", varDecl(hasType(isSignedInteger()))));
1524 TEST_P(ASTMatchersTest, IsUnsignedInteger_MatchesUnsignedIntegers) {
1525 EXPECT_TRUE(notMatches("int i = 0;", varDecl(hasType(isUnsignedInteger()))));
1526 EXPECT_TRUE(
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++.
1533 return;
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++.
1559 return;
1561 if (GetParam().hasDelayedTemplateParsing()) {
1562 // FIXME: Fix this test to work with delayed template parsing.
1563 return;
1566 EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };",
1567 memberExpr(isArrow())));
1568 EXPECT_TRUE(
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(
1573 matches("template <class T> class Y { void x() { this->m; } int m; };",
1574 memberExpr(isArrow())));
1575 EXPECT_TRUE(notMatches(
1576 "template <class T> class Y { void x() { (*this).m; } int m; };",
1577 memberExpr(isArrow())));
1580 TEST_P(ASTMatchersTest, IsArrow_MatchesStaticMemberVariablesViaArrow) {
1581 if (!GetParam().isCXX()) {
1582 // FIXME: Add a test for `isArrow()` that does not depend on C++.
1583 return;
1586 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
1587 memberExpr(isArrow())));
1588 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
1589 memberExpr(isArrow())));
1590 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } static int y; };",
1591 memberExpr(isArrow())));
1594 TEST_P(ASTMatchersTest, IsArrow_MatchesMemberCallsViaArrow) {
1595 if (!GetParam().isCXX()) {
1596 // FIXME: Add a test for `isArrow()` that does not depend on C++.
1597 return;
1599 if (GetParam().hasDelayedTemplateParsing()) {
1600 // FIXME: Fix this test to work with delayed template parsing.
1601 return;
1604 EXPECT_TRUE(
1605 matches("class Y { void x() { this->x(); } };", memberExpr(isArrow())));
1606 EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpr(isArrow())));
1607 EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",
1608 memberExpr(isArrow())));
1609 EXPECT_TRUE(
1610 matches("class Y { template <class T> void x() { this->x<T>(); } };",
1611 unresolvedMemberExpr(isArrow())));
1612 EXPECT_TRUE(matches("class Y { template <class T> void x() { x<T>(); } };",
1613 unresolvedMemberExpr(isArrow())));
1614 EXPECT_TRUE(
1615 notMatches("class Y { template <class T> void x() { (*this).x<T>(); } };",
1616 unresolvedMemberExpr(isArrow())));
1619 TEST_P(ASTMatchersTest, IsExplicit_CXXConversionDecl) {
1620 if (!GetParam().isCXX11OrLater()) {
1621 return;
1624 EXPECT_TRUE(matches("struct S { explicit operator int(); };",
1625 cxxConversionDecl(isExplicit())));
1626 EXPECT_TRUE(notMatches("struct S { operator int(); };",
1627 cxxConversionDecl(isExplicit())));
1630 TEST_P(ASTMatchersTest, IsExplicit_CXXConversionDecl_CXX20) {
1631 if (!GetParam().isCXX20OrLater()) {
1632 return;
1635 EXPECT_TRUE(
1636 notMatches("template<bool b> struct S { explicit(b) operator int(); };",
1637 cxxConversionDecl(isExplicit())));
1638 EXPECT_TRUE(matches("struct S { explicit(true) operator int(); };",
1639 cxxConversionDecl(isExplicit())));
1640 EXPECT_TRUE(notMatches("struct S { explicit(false) operator int(); };",
1641 cxxConversionDecl(isExplicit())));
1644 TEST_P(ASTMatchersTest, ArgumentCountAtLeast_CallExpr) {
1645 StatementMatcher Call2PlusArgs = callExpr(argumentCountAtLeast(2));
1647 EXPECT_TRUE(notMatches("void x(void) { x(); }", Call2PlusArgs));
1648 EXPECT_TRUE(notMatches("void x(int) { x(0); }", Call2PlusArgs));
1649 EXPECT_TRUE(matches("void x(int, int) { x(0, 0); }", Call2PlusArgs));
1650 EXPECT_TRUE(matches("void x(int, int, int) { x(0, 0, 0); }", Call2PlusArgs));
1652 if (!GetParam().isCXX()) {
1653 return;
1656 EXPECT_TRUE(
1657 notMatches("void x(int = 1) { x(); }", traverse(TK_AsIs, Call2PlusArgs)));
1658 EXPECT_TRUE(matches("void x(int, int = 1) { x(0); }",
1659 traverse(TK_AsIs, Call2PlusArgs)));
1660 EXPECT_TRUE(matches("void x(int, int = 1, int = 1) { x(0); }",
1661 traverse(TK_AsIs, Call2PlusArgs)));
1662 EXPECT_TRUE(matches("void x(int, int, int = 1) { x(0, 0); }",
1663 traverse(TK_AsIs, Call2PlusArgs)));
1664 EXPECT_TRUE(matches("void x(int, int, int, int = 1) { x(0, 0, 0); }",
1665 traverse(TK_AsIs, Call2PlusArgs)));
1667 EXPECT_TRUE(
1668 notMatches("void x(int = 1) { x(); }",
1669 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));
1670 EXPECT_TRUE(
1671 notMatches("void x(int, int = 1) { x(0); }",
1672 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));
1673 EXPECT_TRUE(
1674 notMatches("void x(int, int = 1, int = 1) { x(0); }",
1675 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));
1676 EXPECT_TRUE(matches("void x(int, int, int = 1) { x(0, 0); }",
1677 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));
1678 EXPECT_TRUE(matches("void x(int, int, int, int = 1) { x(0, 0, 0); }",
1679 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));
1682 TEST_P(ASTMatchersTest, ArgumentCountAtLeast_CallExpr_CXX) {
1683 if (!GetParam().isCXX()) {
1684 return;
1687 StatementMatcher Call2PlusArgs = callExpr(argumentCountAtLeast(2));
1688 EXPECT_TRUE(notMatches("class X { void x() { x(); } };", Call2PlusArgs));
1689 EXPECT_TRUE(notMatches("class X { void x(int) { x(0); } };", Call2PlusArgs));
1690 EXPECT_TRUE(
1691 matches("class X { void x(int, int) { x(0, 0); } };", Call2PlusArgs));
1692 EXPECT_TRUE(matches("class X { void x(int, int, int) { x(0, 0, 0); } };",
1693 Call2PlusArgs));
1695 EXPECT_TRUE(notMatches("class X { void x(int = 1) { x(0); } };",
1696 traverse(TK_AsIs, Call2PlusArgs)));
1697 EXPECT_TRUE(matches("class X { void x(int, int = 1) { x(0); } };",
1698 traverse(TK_AsIs, Call2PlusArgs)));
1699 EXPECT_TRUE(matches("class X { void x(int, int = 1, int = 1) { x(0); } };",
1700 traverse(TK_AsIs, Call2PlusArgs)));
1701 EXPECT_TRUE(matches("class X { void x(int, int, int = 1) { x(0, 0); } };",
1702 traverse(TK_AsIs, Call2PlusArgs)));
1703 EXPECT_TRUE(
1704 matches("class X { void x(int, int, int, int = 1) { x(0, 0, 0); } };",
1705 traverse(TK_AsIs, Call2PlusArgs)));
1707 EXPECT_TRUE(
1708 notMatches("class X { void x(int = 1) { x(0); } };",
1709 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));
1710 EXPECT_TRUE(
1711 notMatches("class X { void x(int, int = 1) { x(0); } };",
1712 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));
1713 EXPECT_TRUE(
1714 notMatches("class X { void x(int, int = 1, int = 1) { x(0); } };",
1715 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));
1716 EXPECT_TRUE(matches("class X { void x(int, int, int = 1) { x(0, 0); } };",
1717 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));
1718 EXPECT_TRUE(
1719 matches("class X { void x(int, int, int, int = 1) { x(0, 0, 0); } };",
1720 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));
1722 EXPECT_TRUE(
1723 notMatches("class X { static void x() { x(); } };", Call2PlusArgs));
1724 EXPECT_TRUE(
1725 notMatches("class X { static void x(int) { x(0); } };", Call2PlusArgs));
1726 EXPECT_TRUE(matches("class X { static void x(int, int) { x(0, 0); } };",
1727 Call2PlusArgs));
1728 EXPECT_TRUE(
1729 matches("class X { static void x(int, int, int) { x(0, 0, 0); } };",
1730 Call2PlusArgs));
1733 TEST_P(ASTMatchersTest, ArgumentCountIs_CallExpr) {
1734 StatementMatcher Call1Arg = callExpr(argumentCountIs(1));
1736 EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg));
1737 EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg));
1740 TEST_P(ASTMatchersTest, ArgumentCountIs_CallExpr_CXX) {
1741 if (!GetParam().isCXX()) {
1742 return;
1745 StatementMatcher Call1Arg = callExpr(argumentCountIs(1));
1746 EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg));
1749 TEST_P(ASTMatchersTest, ParameterCountIs) {
1750 DeclarationMatcher Function1Arg = functionDecl(parameterCountIs(1));
1751 EXPECT_TRUE(matches("void f(int i) {}", Function1Arg));
1752 EXPECT_TRUE(notMatches("void f() {}", Function1Arg));
1753 EXPECT_TRUE(notMatches("void f(int i, int j, int k) {}", Function1Arg));
1754 EXPECT_TRUE(matches("void f(int i, ...) {};", Function1Arg));
1757 TEST_P(ASTMatchersTest, ParameterCountIs_CXX) {
1758 if (!GetParam().isCXX()) {
1759 return;
1762 DeclarationMatcher Function1Arg = functionDecl(parameterCountIs(1));
1763 EXPECT_TRUE(matches("class X { void f(int i) {} };", Function1Arg));
1766 TEST_P(ASTMatchersTest, References) {
1767 if (!GetParam().isCXX()) {
1768 // FIXME: Add a test for `references()` that does not depend on C++.
1769 return;
1772 DeclarationMatcher ReferenceClassX =
1773 varDecl(hasType(references(recordDecl(hasName("X")))));
1774 EXPECT_TRUE(
1775 matches("class X {}; void y(X y) { X &x = y; }", ReferenceClassX));
1776 EXPECT_TRUE(
1777 matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
1778 // The match here is on the implicit copy constructor code for
1779 // class X, not on code 'X x = y'.
1780 EXPECT_TRUE(matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
1781 EXPECT_TRUE(notMatches("class X {}; extern X x;", ReferenceClassX));
1782 EXPECT_TRUE(
1783 notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
1786 TEST_P(ASTMatchersTest, HasLocalQualifiers) {
1787 if (!GetParam().isCXX11OrLater()) {
1788 // FIXME: Add a test for `hasLocalQualifiers()` that does not depend on C++.
1789 return;
1792 EXPECT_TRUE(notMatches("typedef const int const_int; const_int i = 1;",
1793 varDecl(hasType(hasLocalQualifiers()))));
1794 EXPECT_TRUE(matches("int *const j = nullptr;",
1795 varDecl(hasType(hasLocalQualifiers()))));
1796 EXPECT_TRUE(
1797 matches("int *volatile k;", varDecl(hasType(hasLocalQualifiers()))));
1798 EXPECT_TRUE(notMatches("int m;", varDecl(hasType(hasLocalQualifiers()))));
1801 TEST_P(ASTMatchersTest, IsExternC_MatchesExternCFunctionDeclarations) {
1802 if (!GetParam().isCXX()) {
1803 return;
1806 EXPECT_TRUE(matches("extern \"C\" void f() {}", functionDecl(isExternC())));
1807 EXPECT_TRUE(
1808 matches("extern \"C\" { void f() {} }", functionDecl(isExternC())));
1809 EXPECT_TRUE(notMatches("void f() {}", functionDecl(isExternC())));
1812 TEST_P(ASTMatchersTest, IsExternC_MatchesExternCVariableDeclarations) {
1813 if (!GetParam().isCXX()) {
1814 return;
1817 EXPECT_TRUE(matches("extern \"C\" int i;", varDecl(isExternC())));
1818 EXPECT_TRUE(matches("extern \"C\" { int i; }", varDecl(isExternC())));
1819 EXPECT_TRUE(notMatches("int i;", varDecl(isExternC())));
1822 TEST_P(ASTMatchersTest, IsStaticStorageClass) {
1823 EXPECT_TRUE(
1824 matches("static void f() {}", functionDecl(isStaticStorageClass())));
1825 EXPECT_TRUE(matches("static int i = 1;", varDecl(isStaticStorageClass())));
1826 EXPECT_TRUE(notMatches("int i = 1;", varDecl(isStaticStorageClass())));
1827 EXPECT_TRUE(notMatches("extern int i;", varDecl(isStaticStorageClass())));
1828 EXPECT_TRUE(notMatches("void f() {}", functionDecl(isStaticStorageClass())));
1831 TEST_P(ASTMatchersTest, IsDefaulted) {
1832 if (!GetParam().isCXX()) {
1833 return;
1836 EXPECT_TRUE(notMatches("class A { ~A(); };",
1837 functionDecl(hasName("~A"), isDefaulted())));
1838 EXPECT_TRUE(matches("class B { ~B() = default; };",
1839 functionDecl(hasName("~B"), isDefaulted())));
1842 TEST_P(ASTMatchersTest, IsDeleted) {
1843 if (!GetParam().isCXX()) {
1844 return;
1847 EXPECT_TRUE(
1848 notMatches("void Func();", functionDecl(hasName("Func"), isDeleted())));
1849 EXPECT_TRUE(matches("void Func() = delete;",
1850 functionDecl(hasName("Func"), isDeleted())));
1853 TEST_P(ASTMatchersTest, IsNoThrow_DynamicExceptionSpec) {
1854 if (!GetParam().supportsCXXDynamicExceptionSpecification()) {
1855 return;
1858 EXPECT_TRUE(notMatches("void f();", functionDecl(isNoThrow())));
1859 EXPECT_TRUE(notMatches("void f() throw(int);", functionDecl(isNoThrow())));
1860 EXPECT_TRUE(matches("void f() throw();", functionDecl(isNoThrow())));
1862 EXPECT_TRUE(notMatches("void f();", functionProtoType(isNoThrow())));
1863 EXPECT_TRUE(
1864 notMatches("void f() throw(int);", functionProtoType(isNoThrow())));
1865 EXPECT_TRUE(matches("void f() throw();", functionProtoType(isNoThrow())));
1868 TEST_P(ASTMatchersTest, IsNoThrow_CXX11) {
1869 if (!GetParam().isCXX11OrLater()) {
1870 return;
1873 EXPECT_TRUE(
1874 notMatches("void f() noexcept(false);", functionDecl(isNoThrow())));
1875 EXPECT_TRUE(matches("void f() noexcept;", functionDecl(isNoThrow())));
1877 EXPECT_TRUE(
1878 notMatches("void f() noexcept(false);", functionProtoType(isNoThrow())));
1879 EXPECT_TRUE(matches("void f() noexcept;", functionProtoType(isNoThrow())));
1882 TEST_P(ASTMatchersTest, IsConsteval) {
1883 if (!GetParam().isCXX20OrLater())
1884 return;
1886 EXPECT_TRUE(matches("consteval int bar();",
1887 functionDecl(hasName("bar"), isConsteval())));
1888 EXPECT_TRUE(notMatches("constexpr int bar();",
1889 functionDecl(hasName("bar"), isConsteval())));
1890 EXPECT_TRUE(
1891 notMatches("int bar();", functionDecl(hasName("bar"), isConsteval())));
1894 TEST_P(ASTMatchersTest, IsConsteval_MatchesIfConsteval) {
1895 if (!GetParam().isCXX20OrLater())
1896 return;
1898 EXPECT_TRUE(matches("void baz() { if consteval {} }", ifStmt(isConsteval())));
1899 EXPECT_TRUE(
1900 matches("void baz() { if ! consteval {} }", ifStmt(isConsteval())));
1901 EXPECT_TRUE(matches("void baz() { if ! consteval {} else {} }",
1902 ifStmt(isConsteval())));
1903 EXPECT_TRUE(
1904 matches("void baz() { if not consteval {} }", ifStmt(isConsteval())));
1905 EXPECT_TRUE(notMatches("void baz() { if constexpr(1 > 0) {} }",
1906 ifStmt(isConsteval())));
1907 EXPECT_TRUE(
1908 notMatches("void baz() { if (1 > 0) {} }", ifStmt(isConsteval())));
1911 TEST_P(ASTMatchersTest, IsConstexpr) {
1912 if (!GetParam().isCXX11OrLater()) {
1913 return;
1916 EXPECT_TRUE(matches("constexpr int foo = 42;",
1917 varDecl(hasName("foo"), isConstexpr())));
1918 EXPECT_TRUE(matches("constexpr int bar();",
1919 functionDecl(hasName("bar"), isConstexpr())));
1922 TEST_P(ASTMatchersTest, IsConstexpr_MatchesIfConstexpr) {
1923 if (!GetParam().isCXX17OrLater()) {
1924 return;
1927 EXPECT_TRUE(
1928 matches("void baz() { if constexpr(1 > 0) {} }", ifStmt(isConstexpr())));
1929 EXPECT_TRUE(
1930 notMatches("void baz() { if (1 > 0) {} }", ifStmt(isConstexpr())));
1933 TEST_P(ASTMatchersTest, IsConstinit) {
1934 if (!GetParam().isCXX20OrLater())
1935 return;
1937 EXPECT_TRUE(matches("constinit int foo = 1;",
1938 varDecl(hasName("foo"), isConstinit())));
1939 EXPECT_TRUE(matches("extern constinit int foo;",
1940 varDecl(hasName("foo"), isConstinit())));
1941 EXPECT_TRUE(matches("constinit const char* foo = \"bar\";",
1942 varDecl(hasName("foo"), isConstinit())));
1943 EXPECT_TRUE(
1944 notMatches("[[clang::require_constant_initialization]] int foo = 1;",
1945 varDecl(hasName("foo"), isConstinit())));
1946 EXPECT_TRUE(notMatches("constexpr int foo = 1;",
1947 varDecl(hasName("foo"), isConstinit())));
1948 EXPECT_TRUE(notMatches("static inline int foo = 1;",
1949 varDecl(hasName("foo"), isConstinit())));
1952 TEST_P(ASTMatchersTest, HasInitStatement_MatchesSelectionInitializers) {
1953 EXPECT_TRUE(notMatches("void baz() { if (1 > 0) {} }",
1954 ifStmt(hasInitStatement(anything()))));
1955 EXPECT_TRUE(notMatches("void baz(int i) { switch (i) { default: break; } }",
1956 switchStmt(hasInitStatement(anything()))));
1959 TEST_P(ASTMatchersTest, HasInitStatement_MatchesSelectionInitializers_CXX) {
1960 if (!GetParam().isCXX()) {
1961 return;
1964 EXPECT_TRUE(notMatches("void baz() { if (int i = 1) {} }",
1965 ifStmt(hasInitStatement(anything()))));
1968 TEST_P(ASTMatchersTest, HasInitStatement_MatchesSelectionInitializers_CXX17) {
1969 if (!GetParam().isCXX17OrLater()) {
1970 return;
1973 EXPECT_TRUE(matches("void baz() { if (int i = 1; i > 0) {} }",
1974 ifStmt(hasInitStatement(anything()))));
1975 EXPECT_TRUE(
1976 matches("void baz(int i) { switch (int j = i; j) { default: break; } }",
1977 switchStmt(hasInitStatement(anything()))));
1980 TEST_P(ASTMatchersTest, HasInitStatement_MatchesRangeForInitializers) {
1981 if (!GetParam().isCXX20OrLater()) {
1982 return;
1985 EXPECT_TRUE(matches("void baz() {"
1986 "int items[] = {};"
1987 "for (auto &arr = items; auto &item : arr) {}"
1988 "}",
1989 cxxForRangeStmt(hasInitStatement(anything()))));
1990 EXPECT_TRUE(notMatches("void baz() {"
1991 "int items[] = {};"
1992 "for (auto &item : items) {}"
1993 "}",
1994 cxxForRangeStmt(hasInitStatement(anything()))));
1997 TEST_P(ASTMatchersTest, TemplateArgumentCountIs) {
1998 if (!GetParam().isCXX()) {
1999 return;
2002 EXPECT_TRUE(
2003 matches("template<typename T> struct C {}; C<int> c;",
2004 classTemplateSpecializationDecl(templateArgumentCountIs(1))));
2005 EXPECT_TRUE(
2006 notMatches("template<typename T> struct C {}; C<int> c;",
2007 classTemplateSpecializationDecl(templateArgumentCountIs(2))));
2009 EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
2010 templateSpecializationType(templateArgumentCountIs(1))));
2011 EXPECT_TRUE(
2012 notMatches("template<typename T> struct C {}; C<int> c;",
2013 templateSpecializationType(templateArgumentCountIs(2))));
2016 TEST_P(ASTMatchersTest, IsIntegral) {
2017 if (!GetParam().isCXX()) {
2018 return;
2021 EXPECT_TRUE(matches(
2022 "template<int T> struct C {}; C<42> c;",
2023 classTemplateSpecializationDecl(hasAnyTemplateArgument(isIntegral()))));
2024 EXPECT_TRUE(notMatches("template<typename T> struct C {}; C<int> c;",
2025 classTemplateSpecializationDecl(hasAnyTemplateArgument(
2026 templateArgument(isIntegral())))));
2029 TEST_P(ASTMatchersTest, EqualsIntegralValue) {
2030 if (!GetParam().isCXX()) {
2031 return;
2034 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
2035 classTemplateSpecializationDecl(
2036 hasAnyTemplateArgument(equalsIntegralValue("42")))));
2037 EXPECT_TRUE(matches("template<int T> struct C {}; C<-42> c;",
2038 classTemplateSpecializationDecl(
2039 hasAnyTemplateArgument(equalsIntegralValue("-42")))));
2040 EXPECT_TRUE(matches("template<int T> struct C {}; C<-0042> c;",
2041 classTemplateSpecializationDecl(
2042 hasAnyTemplateArgument(equalsIntegralValue("-34")))));
2043 EXPECT_TRUE(notMatches("template<int T> struct C {}; C<42> c;",
2044 classTemplateSpecializationDecl(hasAnyTemplateArgument(
2045 equalsIntegralValue("0042")))));
2048 TEST_P(ASTMatchersTest, AccessSpecDecl) {
2049 if (!GetParam().isCXX()) {
2050 return;
2053 EXPECT_TRUE(matches("class C { public: int i; };", accessSpecDecl()));
2054 EXPECT_TRUE(
2055 matches("class C { public: int i; };", accessSpecDecl(isPublic())));
2056 EXPECT_TRUE(
2057 notMatches("class C { public: int i; };", accessSpecDecl(isProtected())));
2058 EXPECT_TRUE(
2059 notMatches("class C { public: int i; };", accessSpecDecl(isPrivate())));
2061 EXPECT_TRUE(notMatches("class C { int i; };", accessSpecDecl()));
2064 TEST_P(ASTMatchersTest, IsFinal) {
2065 if (!GetParam().isCXX11OrLater()) {
2066 return;
2069 EXPECT_TRUE(matches("class X final {};", cxxRecordDecl(isFinal())));
2070 EXPECT_TRUE(matches("class X { virtual void f() final; };",
2071 cxxMethodDecl(isFinal())));
2072 EXPECT_TRUE(notMatches("class X {};", cxxRecordDecl(isFinal())));
2073 EXPECT_TRUE(
2074 notMatches("class X { virtual void f(); };", cxxMethodDecl(isFinal())));
2077 TEST_P(ASTMatchersTest, IsVirtual) {
2078 if (!GetParam().isCXX()) {
2079 return;
2082 EXPECT_TRUE(matches("class X { virtual int f(); };",
2083 cxxMethodDecl(isVirtual(), hasName("::X::f"))));
2084 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isVirtual())));
2087 TEST_P(ASTMatchersTest, IsVirtualAsWritten) {
2088 if (!GetParam().isCXX()) {
2089 return;
2092 EXPECT_TRUE(matches("class A { virtual int f(); };"
2093 "class B : public A { int f(); };",
2094 cxxMethodDecl(isVirtualAsWritten(), hasName("::A::f"))));
2095 EXPECT_TRUE(
2096 notMatches("class A { virtual int f(); };"
2097 "class B : public A { int f(); };",
2098 cxxMethodDecl(isVirtualAsWritten(), hasName("::B::f"))));
2101 TEST_P(ASTMatchersTest, IsPure) {
2102 if (!GetParam().isCXX()) {
2103 return;
2106 EXPECT_TRUE(matches("class X { virtual int f() = 0; };",
2107 cxxMethodDecl(isPure(), hasName("::X::f"))));
2108 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isPure())));
2111 TEST_P(ASTMatchersTest, IsExplicitObjectMemberFunction) {
2112 if (!GetParam().isCXX23OrLater()) {
2113 return;
2116 auto ExpObjParamFn = cxxMethodDecl(isExplicitObjectMemberFunction());
2117 EXPECT_TRUE(
2118 notMatches("struct A { static int operator()(int); };", ExpObjParamFn));
2119 EXPECT_TRUE(notMatches("struct A { int operator+(int); };", ExpObjParamFn));
2120 EXPECT_TRUE(
2121 matches("struct A { int operator-(this A, int); };", ExpObjParamFn));
2122 EXPECT_TRUE(matches("struct A { void fun(this A &&self); };", ExpObjParamFn));
2125 TEST_P(ASTMatchersTest, IsCopyAssignmentOperator) {
2126 if (!GetParam().isCXX()) {
2127 return;
2130 auto CopyAssignment =
2131 cxxMethodDecl(isCopyAssignmentOperator(), unless(isImplicit()));
2132 EXPECT_TRUE(matches("class X { X &operator=(X); };", CopyAssignment));
2133 EXPECT_TRUE(matches("class X { X &operator=(X &); };", CopyAssignment));
2134 EXPECT_TRUE(matches("class X { X &operator=(const X &); };", CopyAssignment));
2135 EXPECT_TRUE(matches("class X { X &operator=(volatile X &); };", //
2136 CopyAssignment));
2137 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &); };",
2138 CopyAssignment));
2139 EXPECT_TRUE(notMatches("class X { X &operator=(X &&); };", CopyAssignment));
2142 TEST_P(ASTMatchersTest, IsMoveAssignmentOperator) {
2143 if (!GetParam().isCXX()) {
2144 return;
2147 auto MoveAssignment =
2148 cxxMethodDecl(isMoveAssignmentOperator(), unless(isImplicit()));
2149 EXPECT_TRUE(notMatches("class X { X &operator=(X); };", MoveAssignment));
2150 EXPECT_TRUE(matches("class X { X &operator=(X &&); };", MoveAssignment));
2151 EXPECT_TRUE(matches("class X { X &operator=(const X &&); };", //
2152 MoveAssignment));
2153 EXPECT_TRUE(matches("class X { X &operator=(volatile X &&); };", //
2154 MoveAssignment));
2155 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &&); };",
2156 MoveAssignment));
2157 EXPECT_TRUE(notMatches("class X { X &operator=(X &); };", MoveAssignment));
2160 TEST_P(ASTMatchersTest, IsConst) {
2161 if (!GetParam().isCXX()) {
2162 return;
2165 EXPECT_TRUE(
2166 matches("struct A { void foo() const; };", cxxMethodDecl(isConst())));
2167 EXPECT_TRUE(
2168 notMatches("struct A { void foo(); };", cxxMethodDecl(isConst())));
2171 TEST_P(ASTMatchersTest, IsOverride) {
2172 if (!GetParam().isCXX()) {
2173 return;
2176 EXPECT_TRUE(matches("class X { virtual int f(); }; "
2177 "class Y : public X { int f(); };",
2178 cxxMethodDecl(isOverride(), hasName("::Y::f"))));
2179 EXPECT_TRUE(notMatches("class X { virtual int f(); }; "
2180 "class Y : public X { int f(); };",
2181 cxxMethodDecl(isOverride(), hasName("::X::f"))));
2182 EXPECT_TRUE(notMatches("class X { int f(); }; "
2183 "class Y : public X { int f(); };",
2184 cxxMethodDecl(isOverride())));
2185 EXPECT_TRUE(notMatches("class X { int f(); int f(int); }; ",
2186 cxxMethodDecl(isOverride())));
2187 EXPECT_TRUE(
2188 matches("template <typename Base> struct Y : Base { void f() override;};",
2189 cxxMethodDecl(isOverride(), hasName("::Y::f"))));
2192 TEST_P(ASTMatchersTest, HasArgument_CXXConstructorDecl) {
2193 if (!GetParam().isCXX()) {
2194 return;
2197 auto Constructor = traverse(
2198 TK_AsIs,
2199 cxxConstructExpr(hasArgument(0, declRefExpr(to(varDecl(hasName("y")))))));
2201 EXPECT_TRUE(matches(
2202 "class X { public: X(int); }; void x() { int y; X x(y); }", Constructor));
2203 EXPECT_TRUE(
2204 matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
2205 Constructor));
2206 EXPECT_TRUE(
2207 matches("class X { public: X(int); }; void x() { int y; X x = y; }",
2208 Constructor));
2209 EXPECT_TRUE(notMatches(
2210 "class X { public: X(int); }; void x() { int z; X x(z); }", Constructor));
2212 StatementMatcher WrongIndex =
2213 traverse(TK_AsIs, cxxConstructExpr(hasArgument(
2214 42, declRefExpr(to(varDecl(hasName("y")))))));
2215 EXPECT_TRUE(notMatches(
2216 "class X { public: X(int); }; void x() { int y; X x(y); }", WrongIndex));
2219 TEST_P(ASTMatchersTest, ArgumentCountIs_CXXConstructExpr) {
2220 if (!GetParam().isCXX()) {
2221 return;
2224 auto Constructor1Arg =
2225 traverse(TK_AsIs, cxxConstructExpr(argumentCountIs(1)));
2227 EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x(0); }",
2228 Constructor1Arg));
2229 EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x = X(0); }",
2230 Constructor1Arg));
2231 EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x = 0; }",
2232 Constructor1Arg));
2233 EXPECT_TRUE(
2234 notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
2235 Constructor1Arg));
2238 TEST(ASTMatchersTest, NamesMember_CXXDependentScopeMemberExpr) {
2240 // Member functions:
2242 auto Code = "template <typename T> struct S{ void mem(); }; template "
2243 "<typename T> void x() { S<T> s; s.mem(); }";
2245 EXPECT_TRUE(matches(
2246 Code,
2247 cxxDependentScopeMemberExpr(
2248 hasObjectExpression(declRefExpr(hasType(elaboratedType(namesType(
2249 templateSpecializationType(hasDeclaration(classTemplateDecl(
2250 has(cxxRecordDecl(has(cxxMethodDecl(hasName("mem"))
2251 .bind("templMem")))))))))))),
2252 memberHasSameNameAsBoundNode("templMem"))));
2254 EXPECT_TRUE(
2255 matches(Code, cxxDependentScopeMemberExpr(hasMemberName("mem"))));
2258 // Member variables:
2260 auto Code = "template <typename T> struct S{ int mem; }; template "
2261 "<typename T> void x() { S<T> s; s.mem; }";
2263 EXPECT_TRUE(
2264 matches(Code, cxxDependentScopeMemberExpr(hasMemberName("mem"))));
2266 EXPECT_TRUE(matches(
2267 Code,
2268 cxxDependentScopeMemberExpr(
2269 hasObjectExpression(declRefExpr(
2270 hasType(elaboratedType(namesType(templateSpecializationType(
2271 hasDeclaration(classTemplateDecl(has(cxxRecordDecl(has(
2272 fieldDecl(hasName("mem")).bind("templMem")))))))))))),
2273 memberHasSameNameAsBoundNode("templMem"))));
2276 // static member variables:
2278 auto Code = "template <typename T> struct S{ static int mem; }; template "
2279 "<typename T> void x() { S<T> s; s.mem; }";
2281 EXPECT_TRUE(
2282 matches(Code, cxxDependentScopeMemberExpr(hasMemberName("mem"))));
2284 EXPECT_TRUE(matches(
2285 Code,
2286 cxxDependentScopeMemberExpr(
2287 hasObjectExpression(declRefExpr(
2288 hasType(elaboratedType(namesType(templateSpecializationType(
2289 hasDeclaration(classTemplateDecl(has(cxxRecordDecl(
2290 has(varDecl(hasName("mem")).bind("templMem")))))))))))),
2291 memberHasSameNameAsBoundNode("templMem"))));
2294 auto Code = R"cpp(
2295 template <typename T>
2296 struct S {
2297 bool operator==(int) const { return true; }
2300 template <typename T>
2301 void func(T t) {
2302 S<T> s;
2303 s.operator==(1);
2305 )cpp";
2307 EXPECT_TRUE(matches(
2308 Code, cxxDependentScopeMemberExpr(hasMemberName("operator=="))));
2311 // other named decl:
2313 auto Code = "template <typename T> struct S{ static int mem; }; struct "
2314 "mem{}; template "
2315 "<typename T> void x() { S<T> s; s.mem; }";
2317 EXPECT_TRUE(matches(
2318 Code,
2319 translationUnitDecl(has(cxxRecordDecl(hasName("mem"))),
2320 hasDescendant(cxxDependentScopeMemberExpr()))));
2322 EXPECT_FALSE(matches(
2323 Code,
2324 translationUnitDecl(has(cxxRecordDecl(hasName("mem")).bind("templMem")),
2325 hasDescendant(cxxDependentScopeMemberExpr(
2326 memberHasSameNameAsBoundNode("templMem"))))));
2330 TEST(ASTMatchersTest, ArgumentCountIs_CXXUnresolvedConstructExpr) {
2331 const auto *Code =
2332 "template <typename T> struct S{}; template <typename T> void "
2333 "x() { auto s = S<T>(); }";
2335 EXPECT_TRUE(matches(Code, cxxUnresolvedConstructExpr(argumentCountIs(0))));
2336 EXPECT_TRUE(notMatches(Code, cxxUnresolvedConstructExpr(argumentCountIs(1))));
2339 TEST(ASTMatchersTest, HasArgument_CXXUnresolvedConstructExpr) {
2340 const auto *Code =
2341 "template <typename T> struct S{ S(int){} }; template <typename "
2342 "T> void x() { int y; auto s = S<T>(y); }";
2343 EXPECT_TRUE(matches(Code, cxxUnresolvedConstructExpr(hasArgument(
2344 0, declRefExpr(to(varDecl(hasName("y"))))))));
2345 EXPECT_TRUE(
2346 notMatches(Code, cxxUnresolvedConstructExpr(hasArgument(
2347 0, declRefExpr(to(varDecl(hasName("x"))))))));
2350 TEST_P(ASTMatchersTest, IsListInitialization) {
2351 if (!GetParam().isCXX11OrLater()) {
2352 return;
2355 auto ConstructorListInit =
2356 traverse(TK_AsIs, varDecl(has(cxxConstructExpr(isListInitialization()))));
2358 EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x{0}; }",
2359 ConstructorListInit));
2360 EXPECT_FALSE(matches("class X { public: X(int); }; void x() { X x(0); }",
2361 ConstructorListInit));
2364 TEST_P(ASTMatchersTest, IsImplicit_CXXConstructorDecl) {
2365 if (!GetParam().isCXX()) {
2366 return;
2369 // This one doesn't match because the constructor is not added by the
2370 // compiler (it is not needed).
2371 EXPECT_TRUE(notMatches("class Foo { };", cxxConstructorDecl(isImplicit())));
2372 // The compiler added the implicit default constructor.
2373 EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
2374 cxxConstructorDecl(isImplicit())));
2375 EXPECT_TRUE(matches("class Foo { Foo(){} };",
2376 cxxConstructorDecl(unless(isImplicit()))));
2377 // The compiler added an implicit assignment operator.
2378 EXPECT_TRUE(matches("struct A { int x; } a = {0}, b = a; void f() { a = b; }",
2379 cxxMethodDecl(isImplicit(), hasName("operator="))));
2382 TEST_P(ASTMatchersTest, IsExplicit_CXXConstructorDecl) {
2383 if (!GetParam().isCXX()) {
2384 return;
2387 EXPECT_TRUE(matches("struct S { explicit S(int); };",
2388 cxxConstructorDecl(isExplicit())));
2389 EXPECT_TRUE(
2390 notMatches("struct S { S(int); };", cxxConstructorDecl(isExplicit())));
2393 TEST_P(ASTMatchersTest, IsExplicit_CXXConstructorDecl_CXX20) {
2394 if (!GetParam().isCXX20OrLater()) {
2395 return;
2398 EXPECT_TRUE(notMatches("template<bool b> struct S { explicit(b) S(int);};",
2399 cxxConstructorDecl(isExplicit())));
2400 EXPECT_TRUE(matches("struct S { explicit(true) S(int);};",
2401 cxxConstructorDecl(isExplicit())));
2402 EXPECT_TRUE(notMatches("struct S { explicit(false) S(int);};",
2403 cxxConstructorDecl(isExplicit())));
2406 TEST_P(ASTMatchersTest, IsExplicit_CXXDeductionGuideDecl) {
2407 if (!GetParam().isCXX17OrLater()) {
2408 return;
2411 EXPECT_TRUE(notMatches("template<typename T> struct S { S(int);};"
2412 "S(int) -> S<int>;",
2413 cxxDeductionGuideDecl(isExplicit())));
2414 EXPECT_TRUE(matches("template<typename T> struct S { S(int);};"
2415 "explicit S(int) -> S<int>;",
2416 cxxDeductionGuideDecl(isExplicit())));
2419 TEST_P(ASTMatchersTest, IsExplicit_CXXDeductionGuideDecl_CXX20) {
2420 if (!GetParam().isCXX20OrLater()) {
2421 return;
2424 EXPECT_TRUE(matches("template<typename T> struct S { S(int);};"
2425 "explicit(true) S(int) -> S<int>;",
2426 cxxDeductionGuideDecl(isExplicit())));
2427 EXPECT_TRUE(notMatches("template<typename T> struct S { S(int);};"
2428 "explicit(false) S(int) -> S<int>;",
2429 cxxDeductionGuideDecl(isExplicit())));
2430 EXPECT_TRUE(
2431 notMatches("template<typename T> struct S { S(int);};"
2432 "template<bool b = true> explicit(b) S(int) -> S<int>;",
2433 cxxDeductionGuideDecl(isExplicit())));
2436 TEST_P(ASTMatchersTest, CXXConstructorDecl_Kinds) {
2437 if (!GetParam().isCXX()) {
2438 return;
2441 EXPECT_TRUE(
2442 matches("struct S { S(); };", cxxConstructorDecl(isDefaultConstructor(),
2443 unless(isImplicit()))));
2444 EXPECT_TRUE(notMatches(
2445 "struct S { S(); };",
2446 cxxConstructorDecl(isCopyConstructor(), unless(isImplicit()))));
2447 EXPECT_TRUE(notMatches(
2448 "struct S { S(); };",
2449 cxxConstructorDecl(isMoveConstructor(), unless(isImplicit()))));
2451 EXPECT_TRUE(notMatches(
2452 "struct S { S(const S&); };",
2453 cxxConstructorDecl(isDefaultConstructor(), unless(isImplicit()))));
2454 EXPECT_TRUE(
2455 matches("struct S { S(const S&); };",
2456 cxxConstructorDecl(isCopyConstructor(), unless(isImplicit()))));
2457 EXPECT_TRUE(notMatches(
2458 "struct S { S(const S&); };",
2459 cxxConstructorDecl(isMoveConstructor(), unless(isImplicit()))));
2461 EXPECT_TRUE(notMatches(
2462 "struct S { S(S&&); };",
2463 cxxConstructorDecl(isDefaultConstructor(), unless(isImplicit()))));
2464 EXPECT_TRUE(notMatches(
2465 "struct S { S(S&&); };",
2466 cxxConstructorDecl(isCopyConstructor(), unless(isImplicit()))));
2467 EXPECT_TRUE(
2468 matches("struct S { S(S&&); };",
2469 cxxConstructorDecl(isMoveConstructor(), unless(isImplicit()))));
2472 TEST_P(ASTMatchersTest, IsUserProvided) {
2473 if (!GetParam().isCXX11OrLater()) {
2474 return;
2477 EXPECT_TRUE(notMatches("struct S { int X = 0; };",
2478 cxxConstructorDecl(isUserProvided())));
2479 EXPECT_TRUE(notMatches("struct S { S() = default; };",
2480 cxxConstructorDecl(isUserProvided())));
2481 EXPECT_TRUE(notMatches("struct S { S() = delete; };",
2482 cxxConstructorDecl(isUserProvided())));
2483 EXPECT_TRUE(
2484 matches("struct S { S(); };", cxxConstructorDecl(isUserProvided())));
2485 EXPECT_TRUE(matches("struct S { S(); }; S::S(){}",
2486 cxxConstructorDecl(isUserProvided())));
2489 TEST_P(ASTMatchersTest, IsDelegatingConstructor) {
2490 if (!GetParam().isCXX11OrLater()) {
2491 return;
2494 EXPECT_TRUE(notMatches("struct S { S(); S(int); int X; };",
2495 cxxConstructorDecl(isDelegatingConstructor())));
2496 EXPECT_TRUE(notMatches("struct S { S(){} S(int X) : X(X) {} int X; };",
2497 cxxConstructorDecl(isDelegatingConstructor())));
2498 EXPECT_TRUE(matches(
2499 "struct S { S() : S(0) {} S(int X) : X(X) {} int X; };",
2500 cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(0))));
2501 EXPECT_TRUE(matches(
2502 "struct S { S(); S(int X); int X; }; S::S(int X) : S() {}",
2503 cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(1))));
2506 TEST_P(ASTMatchersTest, HasSize) {
2507 StatementMatcher Literal = stringLiteral(hasSize(4));
2508 EXPECT_TRUE(matches("const char *s = \"abcd\";", Literal));
2509 // with escaped characters
2510 EXPECT_TRUE(matches("const char *s = \"\x05\x06\x07\x08\";", Literal));
2511 // no matching, too small
2512 EXPECT_TRUE(notMatches("const char *s = \"ab\";", Literal));
2515 TEST_P(ASTMatchersTest, HasSize_CXX) {
2516 if (!GetParam().isCXX()) {
2517 // FIXME: Fix this test to also work in non-C++ language modes.
2518 return;
2521 StatementMatcher Literal = stringLiteral(hasSize(4));
2522 // wide string
2523 EXPECT_TRUE(matches("const wchar_t *s = L\"abcd\";", Literal));
2526 TEST_P(ASTMatchersTest, HasName_MatchesNamespaces) {
2527 if (!GetParam().isCXX()) {
2528 return;
2531 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
2532 recordDecl(hasName("a::b::C"))));
2533 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
2534 recordDecl(hasName("::a::b::C"))));
2535 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
2536 recordDecl(hasName("b::C"))));
2537 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
2538 recordDecl(hasName("C"))));
2539 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2540 recordDecl(hasName("c::b::C"))));
2541 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2542 recordDecl(hasName("a::c::C"))));
2543 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2544 recordDecl(hasName("a::b::A"))));
2545 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2546 recordDecl(hasName("::C"))));
2547 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2548 recordDecl(hasName("::b::C"))));
2549 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2550 recordDecl(hasName("z::a::b::C"))));
2551 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2552 recordDecl(hasName("a+b::C"))));
2553 EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
2554 recordDecl(hasName("C"))));
2555 EXPECT_TRUE(matches("namespace a { inline namespace a { class C; } }",
2556 recordDecl(hasName("::a::C"))));
2557 EXPECT_TRUE(matches("namespace a { inline namespace a { class C; } }",
2558 recordDecl(hasName("::a::a::C"))));
2561 TEST_P(ASTMatchersTest, HasName_MatchesOuterClasses) {
2562 if (!GetParam().isCXX()) {
2563 return;
2566 EXPECT_TRUE(matches("class A { class B { class C; }; };",
2567 recordDecl(hasName("A::B::C"))));
2568 EXPECT_TRUE(matches("class A { class B { class C; }; };",
2569 recordDecl(hasName("::A::B::C"))));
2570 EXPECT_TRUE(matches("class A { class B { class C; }; };",
2571 recordDecl(hasName("B::C"))));
2572 EXPECT_TRUE(
2573 matches("class A { class B { class C; }; };", recordDecl(hasName("C"))));
2574 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2575 recordDecl(hasName("c::B::C"))));
2576 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2577 recordDecl(hasName("A::c::C"))));
2578 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2579 recordDecl(hasName("A::B::A"))));
2580 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2581 recordDecl(hasName("::C"))));
2582 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2583 recordDecl(hasName("::B::C"))));
2584 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2585 recordDecl(hasName("z::A::B::C"))));
2586 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2587 recordDecl(hasName("A+B::C"))));
2590 TEST_P(ASTMatchersTest, HasName_MatchesInlinedNamespaces) {
2591 if (!GetParam().isCXX()) {
2592 return;
2595 StringRef code = "namespace a { inline namespace b { class C; } }";
2596 EXPECT_TRUE(matches(code, recordDecl(hasName("a::b::C"))));
2597 EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
2598 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::b::C"))));
2599 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
2602 TEST_P(ASTMatchersTest, HasName_MatchesSpecializedInlinedNamespace) {
2603 if (!GetParam().isCXX11OrLater()) {
2604 return;
2607 StringRef code = R"(
2608 namespace a {
2609 inline namespace v1 {
2610 template<typename T> T foo(T);
2614 namespace a {
2615 enum Tag{T1, T2};
2617 template <Tag, typename T> T foo(T);
2620 auto v1 = a::foo(1);
2621 auto v2 = a::foo<a::T1>(1);
2623 EXPECT_TRUE(matches(
2624 code, varDecl(hasName("v1"), hasDescendant(callExpr(callee(
2625 functionDecl(hasName("::a::foo"))))))));
2626 EXPECT_TRUE(matches(
2627 code, varDecl(hasName("v2"), hasDescendant(callExpr(callee(
2628 functionDecl(hasName("::a::foo"))))))));
2631 TEST_P(ASTMatchersTest, HasName_MatchesAnonymousNamespaces) {
2632 if (!GetParam().isCXX()) {
2633 return;
2636 StringRef code = "namespace a { namespace { class C; } }";
2637 EXPECT_TRUE(
2638 matches(code, recordDecl(hasName("a::(anonymous namespace)::C"))));
2639 EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
2640 EXPECT_TRUE(
2641 matches(code, recordDecl(hasName("::a::(anonymous namespace)::C"))));
2642 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
2645 TEST_P(ASTMatchersTest, HasName_MatchesAnonymousOuterClasses) {
2646 if (!GetParam().isCXX()) {
2647 return;
2650 EXPECT_TRUE(matches("class A { class { class C; } x; };",
2651 recordDecl(hasName("A::(anonymous class)::C"))));
2652 EXPECT_TRUE(matches("class A { class { class C; } x; };",
2653 recordDecl(hasName("::A::(anonymous class)::C"))));
2654 EXPECT_FALSE(matches("class A { class { class C; } x; };",
2655 recordDecl(hasName("::A::C"))));
2656 EXPECT_TRUE(matches("class A { struct { class C; } x; };",
2657 recordDecl(hasName("A::(anonymous struct)::C"))));
2658 EXPECT_TRUE(matches("class A { struct { class C; } x; };",
2659 recordDecl(hasName("::A::(anonymous struct)::C"))));
2660 EXPECT_FALSE(matches("class A { struct { class C; } x; };",
2661 recordDecl(hasName("::A::C"))));
2664 TEST_P(ASTMatchersTest, HasName_MatchesFunctionScope) {
2665 if (!GetParam().isCXX()) {
2666 return;
2669 StringRef code =
2670 "namespace a { void F(int a) { struct S { int m; }; int i; } }";
2671 EXPECT_TRUE(matches(code, varDecl(hasName("i"))));
2672 EXPECT_FALSE(matches(code, varDecl(hasName("F()::i"))));
2674 EXPECT_TRUE(matches(code, fieldDecl(hasName("m"))));
2675 EXPECT_TRUE(matches(code, fieldDecl(hasName("S::m"))));
2676 EXPECT_TRUE(matches(code, fieldDecl(hasName("F(int)::S::m"))));
2677 EXPECT_TRUE(matches(code, fieldDecl(hasName("a::F(int)::S::m"))));
2678 EXPECT_TRUE(matches(code, fieldDecl(hasName("::a::F(int)::S::m"))));
2681 TEST_P(ASTMatchersTest, HasName_QualifiedStringMatchesThroughLinkage) {
2682 if (!GetParam().isCXX()) {
2683 return;
2686 // https://bugs.llvm.org/show_bug.cgi?id=42193
2687 StringRef code = R"cpp(namespace foo { extern "C" void test(); })cpp";
2688 EXPECT_TRUE(matches(code, functionDecl(hasName("test"))));
2689 EXPECT_TRUE(matches(code, functionDecl(hasName("foo::test"))));
2690 EXPECT_TRUE(matches(code, functionDecl(hasName("::foo::test"))));
2691 EXPECT_TRUE(notMatches(code, functionDecl(hasName("::test"))));
2693 code = R"cpp(namespace foo { extern "C" { void test(); } })cpp";
2694 EXPECT_TRUE(matches(code, functionDecl(hasName("test"))));
2695 EXPECT_TRUE(matches(code, functionDecl(hasName("foo::test"))));
2696 EXPECT_TRUE(matches(code, functionDecl(hasName("::foo::test"))));
2697 EXPECT_TRUE(notMatches(code, functionDecl(hasName("::test"))));
2700 TEST_P(ASTMatchersTest, HasAnyName) {
2701 if (!GetParam().isCXX()) {
2702 // FIXME: Add a test for `hasAnyName()` that does not depend on C++.
2703 return;
2706 StringRef Code = "namespace a { namespace b { class C; } }";
2708 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "a::b::C"))));
2709 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("a::b::C", "XX"))));
2710 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX::C", "a::b::C"))));
2711 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "C"))));
2713 EXPECT_TRUE(notMatches(Code, recordDecl(hasAnyName("::C", "::b::C"))));
2714 EXPECT_TRUE(
2715 matches(Code, recordDecl(hasAnyName("::C", "::b::C", "::a::b::C"))));
2717 std::vector<StringRef> Names = {"::C", "::b::C", "::a::b::C"};
2718 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName(Names))));
2721 TEST_P(ASTMatchersTest, IsDefinition) {
2722 DeclarationMatcher DefinitionOfClassA =
2723 recordDecl(hasName("A"), isDefinition());
2724 EXPECT_TRUE(matches("struct A {};", DefinitionOfClassA));
2725 EXPECT_TRUE(notMatches("struct A;", DefinitionOfClassA));
2727 DeclarationMatcher DefinitionOfVariableA =
2728 varDecl(hasName("a"), isDefinition());
2729 EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));
2730 EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));
2733 TEST_P(ASTMatchersTest, IsDefinition_CXX) {
2734 if (!GetParam().isCXX()) {
2735 return;
2738 DeclarationMatcher DefinitionOfMethodA =
2739 cxxMethodDecl(hasName("a"), isDefinition());
2740 EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));
2741 EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));
2743 DeclarationMatcher DefinitionOfObjCMethodA =
2744 objcMethodDecl(hasName("a"), isDefinition());
2745 EXPECT_TRUE(matchesObjC("@interface A @end "
2746 "@implementation A; -(void)a {} @end",
2747 DefinitionOfObjCMethodA));
2748 EXPECT_TRUE(
2749 notMatchesObjC("@interface A; - (void)a; @end", DefinitionOfObjCMethodA));
2752 TEST_P(ASTMatchersTest, HandlesNullQualTypes) {
2753 if (!GetParam().isCXX()) {
2754 // FIXME: Add an equivalent test that does not depend on C++.
2755 return;
2758 // FIXME: Add a Type matcher so we can replace uses of this
2759 // variable with Type(True())
2760 const TypeMatcher AnyType = anything();
2762 // We don't really care whether this matcher succeeds; we're testing that
2763 // it completes without crashing.
2764 EXPECT_TRUE(matches(
2765 "struct A { };"
2766 "template <typename T>"
2767 "void f(T t) {"
2768 " T local_t(t /* this becomes a null QualType in the AST */);"
2770 "void g() {"
2771 " f(0);"
2772 "}",
2773 expr(hasType(TypeMatcher(anyOf(TypeMatcher(hasDeclaration(anything())),
2774 pointsTo(AnyType), references(AnyType)
2775 // Other QualType matchers should go here.
2776 ))))));
2779 TEST_P(ASTMatchersTest, ObjCIvarRefExpr) {
2780 StringRef ObjCString =
2781 "@interface A @end "
2782 "@implementation A { A *x; } - (void) func { x = 0; } @end";
2783 EXPECT_TRUE(matchesObjC(ObjCString, objcIvarRefExpr()));
2784 EXPECT_TRUE(matchesObjC(
2785 ObjCString, objcIvarRefExpr(hasDeclaration(namedDecl(hasName("x"))))));
2786 EXPECT_FALSE(matchesObjC(
2787 ObjCString, objcIvarRefExpr(hasDeclaration(namedDecl(hasName("y"))))));
2790 TEST_P(ASTMatchersTest, BlockExpr) {
2791 EXPECT_TRUE(matchesObjC("void f() { ^{}(); }", blockExpr()));
2794 TEST_P(ASTMatchersTest,
2795 StatementCountIs_FindsNoStatementsInAnEmptyCompoundStatement) {
2796 EXPECT_TRUE(matches("void f() { }", compoundStmt(statementCountIs(0))));
2797 EXPECT_TRUE(notMatches("void f() {}", compoundStmt(statementCountIs(1))));
2800 TEST_P(ASTMatchersTest, StatementCountIs_AppearsToMatchOnlyOneCount) {
2801 EXPECT_TRUE(matches("void f() { 1; }", compoundStmt(statementCountIs(1))));
2802 EXPECT_TRUE(notMatches("void f() { 1; }", compoundStmt(statementCountIs(0))));
2803 EXPECT_TRUE(notMatches("void f() { 1; }", compoundStmt(statementCountIs(2))));
2806 TEST_P(ASTMatchersTest, StatementCountIs_WorksWithMultipleStatements) {
2807 EXPECT_TRUE(
2808 matches("void f() { 1; 2; 3; }", compoundStmt(statementCountIs(3))));
2811 TEST_P(ASTMatchersTest, StatementCountIs_WorksWithNestedCompoundStatements) {
2812 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
2813 compoundStmt(statementCountIs(1))));
2814 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
2815 compoundStmt(statementCountIs(2))));
2816 EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
2817 compoundStmt(statementCountIs(3))));
2818 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
2819 compoundStmt(statementCountIs(4))));
2822 TEST_P(ASTMatchersTest, Member_WorksInSimplestCase) {
2823 if (!GetParam().isCXX()) {
2824 // FIXME: Add a test for `member()` that does not depend on C++.
2825 return;
2827 EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
2828 memberExpr(member(hasName("first")))));
2831 TEST_P(ASTMatchersTest, Member_DoesNotMatchTheBaseExpression) {
2832 if (!GetParam().isCXX()) {
2833 // FIXME: Add a test for `member()` that does not depend on C++.
2834 return;
2837 // Don't pick out the wrong part of the member expression, this should
2838 // be checking the member (name) only.
2839 EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
2840 memberExpr(member(hasName("first")))));
2843 TEST_P(ASTMatchersTest, Member_MatchesInMemberFunctionCall) {
2844 if (!GetParam().isCXX()) {
2845 return;
2848 EXPECT_TRUE(matches("void f() {"
2849 " struct { void first() {}; } s;"
2850 " s.first();"
2851 "};",
2852 memberExpr(member(hasName("first")))));
2855 TEST_P(ASTMatchersTest, FieldDecl) {
2856 EXPECT_TRUE(
2857 matches("struct A { int i; }; void f() { struct A a; a.i = 2; }",
2858 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
2859 EXPECT_TRUE(
2860 notMatches("struct A { float f; }; void f() { struct A a; a.f = 2.0f; }",
2861 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
2864 TEST_P(ASTMatchersTest, IsBitField) {
2865 EXPECT_TRUE(matches("struct C { int a : 2; int b; };",
2866 fieldDecl(isBitField(), hasName("a"))));
2867 EXPECT_TRUE(notMatches("struct C { int a : 2; int b; };",
2868 fieldDecl(isBitField(), hasName("b"))));
2869 EXPECT_TRUE(matches("struct C { int a : 2; int b : 4; };",
2870 fieldDecl(isBitField(), hasBitWidth(2), hasName("a"))));
2873 TEST_P(ASTMatchersTest, HasInClassInitializer) {
2874 if (!GetParam().isCXX()) {
2875 return;
2878 EXPECT_TRUE(
2879 matches("class C { int a = 2; int b; };",
2880 fieldDecl(hasInClassInitializer(integerLiteral(equals(2))),
2881 hasName("a"))));
2882 EXPECT_TRUE(
2883 notMatches("class C { int a = 2; int b; };",
2884 fieldDecl(hasInClassInitializer(anything()), hasName("b"))));
2887 TEST_P(ASTMatchersTest, IsPublic_IsProtected_IsPrivate) {
2888 if (!GetParam().isCXX()) {
2889 return;
2892 EXPECT_TRUE(
2893 matches("struct A { int i; };", fieldDecl(isPublic(), hasName("i"))));
2894 EXPECT_TRUE(notMatches("struct A { int i; };",
2895 fieldDecl(isProtected(), hasName("i"))));
2896 EXPECT_TRUE(
2897 notMatches("struct A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
2899 EXPECT_TRUE(
2900 notMatches("class A { int i; };", fieldDecl(isPublic(), hasName("i"))));
2901 EXPECT_TRUE(notMatches("class A { int i; };",
2902 fieldDecl(isProtected(), hasName("i"))));
2903 EXPECT_TRUE(
2904 matches("class A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
2906 EXPECT_TRUE(notMatches("class A { protected: int i; };",
2907 fieldDecl(isPublic(), hasName("i"))));
2908 EXPECT_TRUE(matches("class A { protected: int i; };",
2909 fieldDecl(isProtected(), hasName("i"))));
2910 EXPECT_TRUE(notMatches("class A { protected: int i; };",
2911 fieldDecl(isPrivate(), hasName("i"))));
2913 // Non-member decls have the AccessSpecifier AS_none and thus aren't matched.
2914 EXPECT_TRUE(notMatches("int i;", varDecl(isPublic(), hasName("i"))));
2915 EXPECT_TRUE(notMatches("int i;", varDecl(isProtected(), hasName("i"))));
2916 EXPECT_TRUE(notMatches("int i;", varDecl(isPrivate(), hasName("i"))));
2919 TEST_P(ASTMatchersTest,
2920 HasDynamicExceptionSpec_MatchesDynamicExceptionSpecifications) {
2921 if (!GetParam().supportsCXXDynamicExceptionSpecification()) {
2922 return;
2925 EXPECT_TRUE(notMatches("void f();", functionDecl(hasDynamicExceptionSpec())));
2926 EXPECT_TRUE(
2927 matches("void j() throw();", functionDecl(hasDynamicExceptionSpec())));
2928 EXPECT_TRUE(
2929 matches("void k() throw(int);", functionDecl(hasDynamicExceptionSpec())));
2930 EXPECT_TRUE(
2931 matches("void l() throw(...);", functionDecl(hasDynamicExceptionSpec())));
2933 EXPECT_TRUE(
2934 notMatches("void f();", functionProtoType(hasDynamicExceptionSpec())));
2935 EXPECT_TRUE(matches("void j() throw();",
2936 functionProtoType(hasDynamicExceptionSpec())));
2937 EXPECT_TRUE(matches("void k() throw(int);",
2938 functionProtoType(hasDynamicExceptionSpec())));
2939 EXPECT_TRUE(matches("void l() throw(...);",
2940 functionProtoType(hasDynamicExceptionSpec())));
2943 TEST_P(ASTMatchersTest,
2944 HasDynamicExceptionSpec_MatchesDynamicExceptionSpecifications_CXX11) {
2945 if (!GetParam().isCXX11OrLater()) {
2946 return;
2949 EXPECT_TRUE(notMatches("void g() noexcept;",
2950 functionDecl(hasDynamicExceptionSpec())));
2951 EXPECT_TRUE(notMatches("void h() noexcept(true);",
2952 functionDecl(hasDynamicExceptionSpec())));
2953 EXPECT_TRUE(notMatches("void i() noexcept(false);",
2954 functionDecl(hasDynamicExceptionSpec())));
2956 EXPECT_TRUE(notMatches("void g() noexcept;",
2957 functionProtoType(hasDynamicExceptionSpec())));
2958 EXPECT_TRUE(notMatches("void h() noexcept(true);",
2959 functionProtoType(hasDynamicExceptionSpec())));
2960 EXPECT_TRUE(notMatches("void i() noexcept(false);",
2961 functionProtoType(hasDynamicExceptionSpec())));
2964 TEST_P(ASTMatchersTest, HasObjectExpression_DoesNotMatchMember) {
2965 if (!GetParam().isCXX()) {
2966 return;
2969 EXPECT_TRUE(notMatches(
2970 "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
2971 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
2974 TEST_P(ASTMatchersTest, HasObjectExpression_MatchesBaseOfVariable) {
2975 EXPECT_TRUE(matches(
2976 "struct X { int m; }; void f(struct X x) { x.m; }",
2977 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
2978 EXPECT_TRUE(matches("struct X { int m; }; void f(struct X* x) { x->m; }",
2979 memberExpr(hasObjectExpression(
2980 hasType(pointsTo(recordDecl(hasName("X"))))))));
2983 TEST_P(ASTMatchersTest, HasObjectExpression_MatchesBaseOfVariable_CXX) {
2984 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
2985 // FIXME: Fix this test to work with delayed template parsing.
2986 return;
2989 EXPECT_TRUE(matches("template <class T> struct X { void f() { T t; t.m; } };",
2990 cxxDependentScopeMemberExpr(hasObjectExpression(
2991 declRefExpr(to(namedDecl(hasName("t"))))))));
2992 EXPECT_TRUE(
2993 matches("template <class T> struct X { void f() { T t; t->m; } };",
2994 cxxDependentScopeMemberExpr(hasObjectExpression(
2995 declRefExpr(to(namedDecl(hasName("t"))))))));
2998 TEST_P(ASTMatchersTest, HasObjectExpression_MatchesBaseOfMemberFunc) {
2999 if (!GetParam().isCXX()) {
3000 return;
3003 EXPECT_TRUE(matches(
3004 "struct X { void f(); }; void g(X x) { x.f(); }",
3005 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
3008 TEST_P(ASTMatchersTest, HasObjectExpression_MatchesBaseOfMemberFunc_Template) {
3009 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3010 // FIXME: Fix this test to work with delayed template parsing.
3011 return;
3014 EXPECT_TRUE(matches("struct X { template <class T> void f(); };"
3015 "template <class T> void g(X x) { x.f<T>(); }",
3016 unresolvedMemberExpr(hasObjectExpression(
3017 hasType(recordDecl(hasName("X")))))));
3018 EXPECT_TRUE(matches("template <class T> void f(T t) { t.g(); }",
3019 cxxDependentScopeMemberExpr(hasObjectExpression(
3020 declRefExpr(to(namedDecl(hasName("t"))))))));
3023 TEST_P(ASTMatchersTest, HasObjectExpression_ImplicitlyFormedMemberExpression) {
3024 if (!GetParam().isCXX()) {
3025 return;
3028 EXPECT_TRUE(matches("class X {}; struct S { X m; void f() { this->m; } };",
3029 memberExpr(hasObjectExpression(
3030 hasType(pointsTo(recordDecl(hasName("S"))))))));
3031 EXPECT_TRUE(matches("class X {}; struct S { X m; void f() { m; } };",
3032 memberExpr(hasObjectExpression(
3033 hasType(pointsTo(recordDecl(hasName("S"))))))));
3036 TEST_P(ASTMatchersTest, FieldDecl_DoesNotMatchNonFieldMembers) {
3037 if (!GetParam().isCXX()) {
3038 return;
3041 EXPECT_TRUE(notMatches("class X { void m(); };", fieldDecl(hasName("m"))));
3042 EXPECT_TRUE(notMatches("class X { class m {}; };", fieldDecl(hasName("m"))));
3043 EXPECT_TRUE(notMatches("class X { enum { m }; };", fieldDecl(hasName("m"))));
3044 EXPECT_TRUE(notMatches("class X { enum m {}; };", fieldDecl(hasName("m"))));
3047 TEST_P(ASTMatchersTest, FieldDecl_MatchesField) {
3048 EXPECT_TRUE(matches("struct X { int m; };", fieldDecl(hasName("m"))));
3051 TEST_P(ASTMatchersTest, IsVolatileQualified) {
3052 EXPECT_TRUE(
3053 matches("volatile int i = 42;", varDecl(hasType(isVolatileQualified()))));
3054 EXPECT_TRUE(
3055 notMatches("volatile int *i;", varDecl(hasType(isVolatileQualified()))));
3056 EXPECT_TRUE(matches("typedef volatile int v_int; v_int i = 42;",
3057 varDecl(hasType(isVolatileQualified()))));
3060 TEST_P(ASTMatchersTest, IsConstQualified_MatchesConstInt) {
3061 EXPECT_TRUE(
3062 matches("const int i = 42;", varDecl(hasType(isConstQualified()))));
3065 TEST_P(ASTMatchersTest, IsConstQualified_MatchesConstPointer) {
3066 EXPECT_TRUE(matches("int i = 42; int* const p = &i;",
3067 varDecl(hasType(isConstQualified()))));
3070 TEST_P(ASTMatchersTest, IsConstQualified_MatchesThroughTypedef) {
3071 EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
3072 varDecl(hasType(isConstQualified()))));
3073 EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p = ((int*)0);",
3074 varDecl(hasType(isConstQualified()))));
3077 TEST_P(ASTMatchersTest, IsConstQualified_DoesNotMatchInappropriately) {
3078 EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
3079 varDecl(hasType(isConstQualified()))));
3080 EXPECT_TRUE(
3081 notMatches("int const* p;", varDecl(hasType(isConstQualified()))));
3084 TEST_P(ASTMatchersTest, DeclCountIs_DeclCountIsCorrect) {
3085 EXPECT_TRUE(matches("void f() {int i,j;}", declStmt(declCountIs(2))));
3086 EXPECT_TRUE(
3087 notMatches("void f() {int i,j; int k;}", declStmt(declCountIs(3))));
3088 EXPECT_TRUE(
3089 notMatches("void f() {int i,j, k, l;}", declStmt(declCountIs(3))));
3092 TEST_P(ASTMatchersTest, EachOf_TriggersForEachMatch) {
3093 EXPECT_TRUE(matchAndVerifyResultTrue(
3094 "class A { int a; int b; };",
3095 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
3096 has(fieldDecl(hasName("b")).bind("v")))),
3097 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 2)));
3100 TEST_P(ASTMatchersTest, EachOf_BehavesLikeAnyOfUnlessBothMatch) {
3101 EXPECT_TRUE(matchAndVerifyResultTrue(
3102 "struct A { int a; int c; };",
3103 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
3104 has(fieldDecl(hasName("b")).bind("v")))),
3105 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 1)));
3106 EXPECT_TRUE(matchAndVerifyResultTrue(
3107 "struct A { int c; int b; };",
3108 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
3109 has(fieldDecl(hasName("b")).bind("v")))),
3110 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 1)));
3111 EXPECT_TRUE(
3112 notMatches("struct A { int c; int d; };",
3113 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
3114 has(fieldDecl(hasName("b")).bind("v"))))));
3117 TEST_P(ASTMatchersTest, Optionally_SubmatchersDoNotMatch) {
3118 EXPECT_TRUE(matchAndVerifyResultFalse(
3119 "class A { int a; int b; };",
3120 recordDecl(optionally(has(fieldDecl(hasName("c")).bind("c")))),
3121 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("c")));
3124 // Regression test.
3125 TEST_P(ASTMatchersTest, Optionally_SubmatchersDoNotMatchButPreserveBindings) {
3126 StringRef Code = "class A { int a; int b; };";
3127 auto Matcher = recordDecl(decl().bind("decl"),
3128 optionally(has(fieldDecl(hasName("c")).bind("v"))));
3129 // "decl" is still bound.
3130 EXPECT_TRUE(matchAndVerifyResultTrue(
3131 Code, Matcher, std::make_unique<VerifyIdIsBoundTo<RecordDecl>>("decl")));
3132 // "v" is not bound, but the match still suceeded.
3133 EXPECT_TRUE(matchAndVerifyResultFalse(
3134 Code, Matcher, std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v")));
3137 TEST_P(ASTMatchersTest, Optionally_SubmatchersMatch) {
3138 EXPECT_TRUE(matchAndVerifyResultTrue(
3139 "class A { int a; int c; };",
3140 recordDecl(optionally(has(fieldDecl(hasName("a")).bind("v")))),
3141 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v")));
3144 TEST_P(ASTMatchersTest,
3145 IsTemplateInstantiation_MatchesImplicitClassTemplateInstantiation) {
3146 if (!GetParam().isCXX()) {
3147 return;
3150 // Make sure that we can both match the class by name (::X) and by the type
3151 // the template was instantiated with (via a field).
3153 EXPECT_TRUE(
3154 matches("template <typename T> class X {}; class A {}; X<A> x;",
3155 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
3157 EXPECT_TRUE(matches(
3158 "template <typename T> class X { T t; }; class A {}; X<A> x;",
3159 cxxRecordDecl(
3160 isTemplateInstantiation(),
3161 hasDescendant(fieldDecl(hasType(recordDecl(hasName("A"))))))));
3164 TEST_P(ASTMatchersTest,
3165 IsTemplateInstantiation_MatchesImplicitFunctionTemplateInstantiation) {
3166 if (!GetParam().isCXX()) {
3167 return;
3170 EXPECT_TRUE(matches(
3171 "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
3172 functionDecl(hasParameter(0, hasType(recordDecl(hasName("A")))),
3173 isTemplateInstantiation())));
3176 TEST_P(ASTMatchersTest,
3177 IsTemplateInstantiation_MatchesExplicitClassTemplateInstantiation) {
3178 if (!GetParam().isCXX()) {
3179 return;
3182 EXPECT_TRUE(matches("template <typename T> class X { T t; }; class A {};"
3183 "template class X<A>;",
3184 cxxRecordDecl(isTemplateInstantiation(),
3185 hasDescendant(fieldDecl(
3186 hasType(recordDecl(hasName("A"))))))));
3188 // Make sure that we match the instantiation instead of the template
3189 // definition by checking whether the member function is present.
3190 EXPECT_TRUE(
3191 matches("template <typename T> class X { void f() { T t; } };"
3192 "extern template class X<int>;",
3193 cxxRecordDecl(isTemplateInstantiation(),
3194 unless(hasDescendant(varDecl(hasName("t")))))));
3197 TEST_P(
3198 ASTMatchersTest,
3199 IsTemplateInstantiation_MatchesInstantiationOfPartiallySpecializedClassTemplate) {
3200 if (!GetParam().isCXX()) {
3201 return;
3204 EXPECT_TRUE(
3205 matches("template <typename T> class X {};"
3206 "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
3207 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
3210 TEST_P(
3211 ASTMatchersTest,
3212 IsTemplateInstantiation_MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
3213 if (!GetParam().isCXX()) {
3214 return;
3217 EXPECT_TRUE(
3218 matches("class A {};"
3219 "class X {"
3220 " template <typename U> class Y { U u; };"
3221 " Y<A> y;"
3222 "};",
3223 cxxRecordDecl(hasName("::X::Y"), isTemplateInstantiation())));
3226 TEST_P(
3227 ASTMatchersTest,
3228 IsTemplateInstantiation_DoesNotMatchInstantiationsInsideOfInstantiation) {
3229 if (!GetParam().isCXX()) {
3230 return;
3233 // FIXME: Figure out whether this makes sense. It doesn't affect the
3234 // normal use case as long as the uppermost instantiation always is marked
3235 // as template instantiation, but it might be confusing as a predicate.
3236 EXPECT_TRUE(matches(
3237 "class A {};"
3238 "template <typename T> class X {"
3239 " template <typename U> class Y { U u; };"
3240 " Y<T> y;"
3241 "}; X<A> x;",
3242 cxxRecordDecl(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
3245 TEST_P(
3246 ASTMatchersTest,
3247 IsTemplateInstantiation_DoesNotMatchExplicitClassTemplateSpecialization) {
3248 if (!GetParam().isCXX()) {
3249 return;
3252 EXPECT_TRUE(
3253 notMatches("template <typename T> class X {}; class A {};"
3254 "template <> class X<A> {}; X<A> x;",
3255 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
3258 TEST_P(ASTMatchersTest, IsTemplateInstantiation_DoesNotMatchNonTemplate) {
3259 if (!GetParam().isCXX()) {
3260 return;
3263 EXPECT_TRUE(notMatches("class A {}; class Y { A a; };",
3264 cxxRecordDecl(isTemplateInstantiation())));
3267 TEST_P(ASTMatchersTest, IsInstantiated_MatchesInstantiation) {
3268 if (!GetParam().isCXX()) {
3269 return;
3272 EXPECT_TRUE(
3273 matches("template<typename T> class A { T i; }; class Y { A<int> a; };",
3274 cxxRecordDecl(isInstantiated())));
3277 TEST_P(ASTMatchersTest, IsInstantiated_NotMatchesDefinition) {
3278 if (!GetParam().isCXX()) {
3279 return;
3282 EXPECT_TRUE(notMatches("template<typename T> class A { T i; };",
3283 cxxRecordDecl(isInstantiated())));
3286 TEST_P(ASTMatchersTest, IsInTemplateInstantiation_MatchesInstantiationStmt) {
3287 if (!GetParam().isCXX()) {
3288 return;
3291 EXPECT_TRUE(matches("template<typename T> struct A { A() { T i; } };"
3292 "class Y { A<int> a; }; Y y;",
3293 declStmt(isInTemplateInstantiation())));
3296 TEST_P(ASTMatchersTest, IsInTemplateInstantiation_NotMatchesDefinitionStmt) {
3297 if (!GetParam().isCXX()) {
3298 return;
3301 EXPECT_TRUE(notMatches("template<typename T> struct A { void x() { T i; } };",
3302 declStmt(isInTemplateInstantiation())));
3305 TEST_P(ASTMatchersTest, IsInstantiated_MatchesFunctionInstantiation) {
3306 if (!GetParam().isCXX()) {
3307 return;
3310 EXPECT_TRUE(
3311 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
3312 functionDecl(isInstantiated())));
3315 TEST_P(ASTMatchersTest, IsInstantiated_NotMatchesFunctionDefinition) {
3316 if (!GetParam().isCXX()) {
3317 return;
3320 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
3321 varDecl(isInstantiated())));
3324 TEST_P(ASTMatchersTest,
3325 IsInTemplateInstantiation_MatchesFunctionInstantiationStmt) {
3326 if (!GetParam().isCXX()) {
3327 return;
3330 EXPECT_TRUE(
3331 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
3332 declStmt(isInTemplateInstantiation())));
3335 TEST_P(ASTMatchersTest,
3336 IsInTemplateInstantiation_NotMatchesFunctionDefinitionStmt) {
3337 if (!GetParam().isCXX()) {
3338 return;
3341 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
3342 declStmt(isInTemplateInstantiation())));
3345 TEST_P(ASTMatchersTest, IsInstantiated_MatchesVariableInstantiation) {
3346 if (!GetParam().isCXX14OrLater()) {
3347 return;
3350 EXPECT_TRUE(matches("template<typename T> int V = 10; void x() { V<int>; }",
3351 varDecl(isInstantiated())));
3354 TEST_P(ASTMatchersTest, IsInstantiated_NotMatchesVariableDefinition) {
3355 if (!GetParam().isCXX14OrLater()) {
3356 return;
3359 EXPECT_TRUE(notMatches("template<typename T> int V = 10;",
3360 varDecl(isInstantiated())));
3363 TEST_P(ASTMatchersTest,
3364 IsInTemplateInstantiation_MatchesVariableInstantiationStmt) {
3365 if (!GetParam().isCXX14OrLater()) {
3366 return;
3369 EXPECT_TRUE(matches(
3370 "template<typename T> auto V = []() { T i; }; void x() { V<int>(); }",
3371 declStmt(isInTemplateInstantiation())));
3374 TEST_P(ASTMatchersTest,
3375 IsInTemplateInstantiation_NotMatchesVariableDefinitionStmt) {
3376 if (!GetParam().isCXX14OrLater()) {
3377 return;
3380 EXPECT_TRUE(notMatches("template<typename T> auto V = []() { T i; };",
3381 declStmt(isInTemplateInstantiation())));
3384 TEST_P(ASTMatchersTest, IsInTemplateInstantiation_Sharing) {
3385 if (!GetParam().isCXX()) {
3386 return;
3389 auto Matcher = binaryOperator(unless(isInTemplateInstantiation()));
3390 // FIXME: Node sharing is an implementation detail, exposing it is ugly
3391 // and makes the matcher behave in non-obvious ways.
3392 EXPECT_TRUE(notMatches(
3393 "int j; template<typename T> void A(T t) { j += 42; } void x() { A(0); }",
3394 Matcher));
3395 EXPECT_TRUE(matches(
3396 "int j; template<typename T> void A(T t) { j += t; } void x() { A(0); }",
3397 Matcher));
3400 TEST_P(ASTMatchersTest, IsInstantiationDependent_MatchesNonValueTypeDependent) {
3401 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3402 // FIXME: Fix this test to work with delayed template parsing.
3403 return;
3406 EXPECT_TRUE(matches(
3407 "template<typename T> void f() { (void) sizeof(sizeof(T() + T())); }",
3408 expr(isInstantiationDependent())));
3411 TEST_P(ASTMatchersTest, IsInstantiationDependent_MatchesValueDependent) {
3412 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3413 // FIXME: Fix this test to work with delayed template parsing.
3414 return;
3417 EXPECT_TRUE(matches("template<int T> int f() { return T; }",
3418 expr(isInstantiationDependent())));
3421 TEST_P(ASTMatchersTest, IsInstantiationDependent_MatchesTypeDependent) {
3422 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3423 // FIXME: Fix this test to work with delayed template parsing.
3424 return;
3427 EXPECT_TRUE(matches("template<typename T> T f() { return T(); }",
3428 expr(isInstantiationDependent())));
3431 TEST_P(ASTMatchersTest, IsTypeDependent_MatchesTypeDependent) {
3432 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3433 // FIXME: Fix this test to work with delayed template parsing.
3434 return;
3437 EXPECT_TRUE(matches("template<typename T> T f() { return T(); }",
3438 expr(isTypeDependent())));
3441 TEST_P(ASTMatchersTest, IsTypeDependent_NotMatchesValueDependent) {
3442 if (!GetParam().isCXX()) {
3443 return;
3446 EXPECT_TRUE(notMatches("template<int T> int f() { return T; }",
3447 expr(isTypeDependent())));
3450 TEST_P(ASTMatchersTest, IsValueDependent_MatchesValueDependent) {
3451 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3452 // FIXME: Fix this test to work with delayed template parsing.
3453 return;
3456 EXPECT_TRUE(matches("template<int T> int f() { return T; }",
3457 expr(isValueDependent())));
3460 TEST_P(ASTMatchersTest, IsValueDependent_MatchesTypeDependent) {
3461 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3462 // FIXME: Fix this test to work with delayed template parsing.
3463 return;
3466 EXPECT_TRUE(matches("template<typename T> T f() { return T(); }",
3467 expr(isValueDependent())));
3470 TEST_P(ASTMatchersTest, IsValueDependent_MatchesInstantiationDependent) {
3471 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3472 // FIXME: Fix this test to work with delayed template parsing.
3473 return;
3476 EXPECT_TRUE(matches(
3477 "template<typename T> void f() { (void) sizeof(sizeof(T() + T())); }",
3478 expr(isValueDependent())));
3481 TEST_P(ASTMatchersTest,
3482 IsExplicitTemplateSpecialization_DoesNotMatchPrimaryTemplate) {
3483 if (!GetParam().isCXX()) {
3484 return;
3487 EXPECT_TRUE(notMatches("template <typename T> class X {};",
3488 cxxRecordDecl(isExplicitTemplateSpecialization())));
3489 EXPECT_TRUE(notMatches("template <typename T> void f(T t);",
3490 functionDecl(isExplicitTemplateSpecialization())));
3493 TEST_P(
3494 ASTMatchersTest,
3495 IsExplicitTemplateSpecialization_DoesNotMatchExplicitTemplateInstantiations) {
3496 if (!GetParam().isCXX()) {
3497 return;
3500 EXPECT_TRUE(
3501 notMatches("template <typename T> class X {};"
3502 "template class X<int>; extern template class X<long>;",
3503 cxxRecordDecl(isExplicitTemplateSpecialization())));
3504 EXPECT_TRUE(
3505 notMatches("template <typename T> void f(T t) {}"
3506 "template void f(int t); extern template void f(long t);",
3507 functionDecl(isExplicitTemplateSpecialization())));
3510 TEST_P(
3511 ASTMatchersTest,
3512 IsExplicitTemplateSpecialization_DoesNotMatchImplicitTemplateInstantiations) {
3513 if (!GetParam().isCXX()) {
3514 return;
3517 EXPECT_TRUE(notMatches("template <typename T> class X {}; X<int> x;",
3518 cxxRecordDecl(isExplicitTemplateSpecialization())));
3519 EXPECT_TRUE(
3520 notMatches("template <typename T> void f(T t); void g() { f(10); }",
3521 functionDecl(isExplicitTemplateSpecialization())));
3524 TEST_P(
3525 ASTMatchersTest,
3526 IsExplicitTemplateSpecialization_MatchesExplicitTemplateSpecializations) {
3527 if (!GetParam().isCXX()) {
3528 return;
3531 EXPECT_TRUE(matches("template <typename T> class X {};"
3532 "template<> class X<int> {};",
3533 cxxRecordDecl(isExplicitTemplateSpecialization())));
3534 EXPECT_TRUE(matches("template <typename T> void f(T t) {}"
3535 "template<> void f(int t) {}",
3536 functionDecl(isExplicitTemplateSpecialization())));
3539 TEST_P(ASTMatchersTest, IsNoReturn) {
3540 EXPECT_TRUE(notMatches("void func();", functionDecl(isNoReturn())));
3541 EXPECT_TRUE(notMatches("void func() {}", functionDecl(isNoReturn())));
3543 EXPECT_TRUE(matches("__attribute__((noreturn)) void func();",
3544 functionDecl(isNoReturn())));
3545 EXPECT_TRUE(matches("__attribute__((noreturn)) void func() {}",
3546 functionDecl(isNoReturn())));
3548 EXPECT_TRUE(matches("_Noreturn void func();", functionDecl(isNoReturn())));
3549 EXPECT_TRUE(matches("_Noreturn void func() {}", functionDecl(isNoReturn())));
3552 TEST_P(ASTMatchersTest, IsNoReturn_CXX) {
3553 if (!GetParam().isCXX()) {
3554 return;
3557 EXPECT_TRUE(
3558 notMatches("struct S { void func(); };", functionDecl(isNoReturn())));
3559 EXPECT_TRUE(
3560 notMatches("struct S { void func() {} };", functionDecl(isNoReturn())));
3562 EXPECT_TRUE(notMatches("struct S { static void func(); };",
3563 functionDecl(isNoReturn())));
3564 EXPECT_TRUE(notMatches("struct S { static void func() {} };",
3565 functionDecl(isNoReturn())));
3567 EXPECT_TRUE(notMatches("struct S { S(); };", functionDecl(isNoReturn())));
3568 EXPECT_TRUE(notMatches("struct S { S() {} };", functionDecl(isNoReturn())));
3570 // ---
3572 EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) void func(); };",
3573 functionDecl(isNoReturn())));
3574 EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) void func() {} };",
3575 functionDecl(isNoReturn())));
3577 EXPECT_TRUE(
3578 matches("struct S { __attribute__((noreturn)) static void func(); };",
3579 functionDecl(isNoReturn())));
3580 EXPECT_TRUE(
3581 matches("struct S { __attribute__((noreturn)) static void func() {} };",
3582 functionDecl(isNoReturn())));
3584 EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) S(); };",
3585 functionDecl(isNoReturn())));
3586 EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) S() {} };",
3587 functionDecl(isNoReturn())));
3590 TEST_P(ASTMatchersTest, IsNoReturn_CXX11Attribute) {
3591 if (!GetParam().isCXX11OrLater()) {
3592 return;
3595 EXPECT_TRUE(matches("[[noreturn]] void func();", functionDecl(isNoReturn())));
3596 EXPECT_TRUE(
3597 matches("[[noreturn]] void func() {}", functionDecl(isNoReturn())));
3599 EXPECT_TRUE(matches("struct S { [[noreturn]] void func(); };",
3600 functionDecl(isNoReturn())));
3601 EXPECT_TRUE(matches("struct S { [[noreturn]] void func() {} };",
3602 functionDecl(isNoReturn())));
3604 EXPECT_TRUE(matches("struct S { [[noreturn]] static void func(); };",
3605 functionDecl(isNoReturn())));
3606 EXPECT_TRUE(matches("struct S { [[noreturn]] static void func() {} };",
3607 functionDecl(isNoReturn())));
3609 EXPECT_TRUE(
3610 matches("struct S { [[noreturn]] S(); };", functionDecl(isNoReturn())));
3611 EXPECT_TRUE(
3612 matches("struct S { [[noreturn]] S() {} };", functionDecl(isNoReturn())));
3615 TEST_P(ASTMatchersTest, BooleanType) {
3616 if (!GetParam().isCXX()) {
3617 // FIXME: Add a test for `booleanType()` that does not depend on C++.
3618 return;
3621 EXPECT_TRUE(matches("struct S { bool func(); };",
3622 cxxMethodDecl(returns(booleanType()))));
3623 EXPECT_TRUE(notMatches("struct S { void func(); };",
3624 cxxMethodDecl(returns(booleanType()))));
3627 TEST_P(ASTMatchersTest, VoidType) {
3628 if (!GetParam().isCXX()) {
3629 // FIXME: Add a test for `voidType()` that does not depend on C++.
3630 return;
3633 EXPECT_TRUE(matches("struct S { void func(); };",
3634 cxxMethodDecl(returns(voidType()))));
3637 TEST_P(ASTMatchersTest, RealFloatingPointType) {
3638 if (!GetParam().isCXX()) {
3639 // FIXME: Add a test for `realFloatingPointType()` that does not depend on
3640 // C++.
3641 return;
3644 EXPECT_TRUE(matches("struct S { float func(); };",
3645 cxxMethodDecl(returns(realFloatingPointType()))));
3646 EXPECT_TRUE(notMatches("struct S { int func(); };",
3647 cxxMethodDecl(returns(realFloatingPointType()))));
3648 EXPECT_TRUE(matches("struct S { long double func(); };",
3649 cxxMethodDecl(returns(realFloatingPointType()))));
3652 TEST_P(ASTMatchersTest, ArrayType) {
3653 EXPECT_TRUE(matches("int a[] = {2,3};", arrayType()));
3654 EXPECT_TRUE(matches("int a[42];", arrayType()));
3655 EXPECT_TRUE(matches("void f(int b) { int a[b]; }", arrayType()));
3657 EXPECT_TRUE(notMatches("struct A {}; struct A a[7];",
3658 arrayType(hasElementType(builtinType()))));
3660 EXPECT_TRUE(matches("int const a[] = { 2, 3 };",
3661 qualType(arrayType(hasElementType(builtinType())))));
3662 EXPECT_TRUE(matches(
3663 "int const a[] = { 2, 3 };",
3664 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
3665 EXPECT_TRUE(matches("typedef const int T; T x[] = { 1, 2 };",
3666 qualType(isConstQualified(), arrayType())));
3668 EXPECT_TRUE(notMatches(
3669 "int a[] = { 2, 3 };",
3670 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
3671 EXPECT_TRUE(notMatches(
3672 "int a[] = { 2, 3 };",
3673 qualType(arrayType(hasElementType(isConstQualified(), builtinType())))));
3674 EXPECT_TRUE(notMatches("int const a[] = { 2, 3 };",
3675 qualType(arrayType(hasElementType(builtinType())),
3676 unless(isConstQualified()))));
3678 EXPECT_TRUE(
3679 matches("int a[2];", constantArrayType(hasElementType(builtinType()))));
3680 EXPECT_TRUE(matches("const int a = 0;", qualType(isInteger())));
3683 TEST_P(ASTMatchersTest, DecayedType) {
3684 EXPECT_TRUE(
3685 matches("void f(int i[]);",
3686 valueDecl(hasType(decayedType(hasDecayedType(pointerType()))))));
3687 EXPECT_TRUE(notMatches("int i[7];", decayedType()));
3690 TEST_P(ASTMatchersTest, ComplexType) {
3691 EXPECT_TRUE(matches("_Complex float f;", complexType()));
3692 EXPECT_TRUE(
3693 matches("_Complex float f;", complexType(hasElementType(builtinType()))));
3694 EXPECT_TRUE(notMatches("_Complex float f;",
3695 complexType(hasElementType(isInteger()))));
3698 TEST_P(ASTMatchersTest, IsAnonymous) {
3699 if (!GetParam().isCXX()) {
3700 return;
3703 EXPECT_TRUE(notMatches("namespace N {}", namespaceDecl(isAnonymous())));
3704 EXPECT_TRUE(matches("namespace {}", namespaceDecl(isAnonymous())));
3707 TEST_P(ASTMatchersTest, InStdNamespace) {
3708 if (!GetParam().isCXX()) {
3709 return;
3712 EXPECT_TRUE(notMatches("class vector {};"
3713 "namespace foo {"
3714 " class vector {};"
3716 "namespace foo {"
3717 " namespace std {"
3718 " class vector {};"
3719 " }"
3720 "}",
3721 cxxRecordDecl(hasName("vector"), isInStdNamespace())));
3723 EXPECT_TRUE(matches("namespace std {"
3724 " class vector {};"
3725 "}",
3726 cxxRecordDecl(hasName("vector"), isInStdNamespace())));
3728 EXPECT_TRUE(matches("namespace std {"
3729 " extern \"C++\" class vector {};"
3730 "}",
3731 cxxRecordDecl(hasName("vector"), isInStdNamespace())));
3734 TEST_P(ASTMatchersTest, InAnonymousNamespace) {
3735 if (!GetParam().isCXX()) {
3736 return;
3739 EXPECT_TRUE(
3740 notMatches("class vector {};"
3741 "namespace foo {"
3742 " class vector {};"
3743 "}",
3744 cxxRecordDecl(hasName("vector"), isInAnonymousNamespace())));
3746 EXPECT_TRUE(
3747 matches("namespace {"
3748 " class vector {};"
3749 "}",
3750 cxxRecordDecl(hasName("vector"), isInAnonymousNamespace())));
3752 EXPECT_TRUE(
3753 matches("namespace foo {"
3754 " namespace {"
3755 " class vector {};"
3756 " }"
3757 "}",
3758 cxxRecordDecl(hasName("vector"), isInAnonymousNamespace())));
3760 EXPECT_TRUE(
3761 matches("namespace {"
3762 " namespace foo {"
3763 " class vector {};"
3764 " }"
3765 "}",
3766 cxxRecordDecl(hasName("vector"), isInAnonymousNamespace())));
3769 TEST_P(ASTMatchersTest, InStdNamespace_CXX11) {
3770 if (!GetParam().isCXX11OrLater()) {
3771 return;
3774 EXPECT_TRUE(matches("namespace std {"
3775 " inline namespace __1 {"
3776 " class vector {};"
3777 " }"
3778 "}",
3779 cxxRecordDecl(hasName("vector"), isInStdNamespace())));
3780 EXPECT_TRUE(notMatches("namespace std {"
3781 " inline namespace __1 {"
3782 " inline namespace __fs {"
3783 " namespace filesystem {"
3784 " inline namespace v1 {"
3785 " class path {};"
3786 " }"
3787 " }"
3788 " }"
3789 " }"
3790 "}",
3791 cxxRecordDecl(hasName("path"), isInStdNamespace())));
3792 EXPECT_TRUE(
3793 matches("namespace std {"
3794 " inline namespace __1 {"
3795 " inline namespace __fs {"
3796 " namespace filesystem {"
3797 " inline namespace v1 {"
3798 " class path {};"
3799 " }"
3800 " }"
3801 " }"
3802 " }"
3803 "}",
3804 cxxRecordDecl(hasName("path"),
3805 hasAncestor(namespaceDecl(hasName("filesystem"),
3806 isInStdNamespace())))));
3809 TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_QualType) {
3810 EXPECT_TRUE(matches(
3811 "int i = 1;", varDecl(hasType(qualType().bind("type")),
3812 hasInitializer(ignoringParenImpCasts(
3813 hasType(qualType(equalsBoundNode("type"))))))));
3814 EXPECT_TRUE(notMatches("int i = 1.f;",
3815 varDecl(hasType(qualType().bind("type")),
3816 hasInitializer(ignoringParenImpCasts(hasType(
3817 qualType(equalsBoundNode("type"))))))));
3820 TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_NonMatchingTypes) {
3821 EXPECT_TRUE(notMatches(
3822 "int i = 1;", varDecl(namedDecl(hasName("i")).bind("name"),
3823 hasInitializer(ignoringParenImpCasts(
3824 hasType(qualType(equalsBoundNode("type"))))))));
3827 TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_Stmt) {
3828 EXPECT_TRUE(
3829 matches("void f() { if(1) {} }",
3830 stmt(allOf(ifStmt().bind("if"),
3831 hasParent(stmt(has(stmt(equalsBoundNode("if")))))))));
3833 EXPECT_TRUE(notMatches(
3834 "void f() { if(1) { if (1) {} } }",
3835 stmt(allOf(ifStmt().bind("if"), has(stmt(equalsBoundNode("if")))))));
3838 TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_Decl) {
3839 if (!GetParam().isCXX()) {
3840 // FIXME: Add a test for `equalsBoundNode()` for declarations that does not
3841 // depend on C++.
3842 return;
3845 EXPECT_TRUE(matches(
3846 "class X { class Y {}; };",
3847 decl(allOf(recordDecl(hasName("::X::Y")).bind("record"),
3848 hasParent(decl(has(decl(equalsBoundNode("record")))))))));
3850 EXPECT_TRUE(notMatches("class X { class Y {}; };",
3851 decl(allOf(recordDecl(hasName("::X")).bind("record"),
3852 has(decl(equalsBoundNode("record")))))));
3855 TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_Type) {
3856 if (!GetParam().isCXX()) {
3857 // FIXME: Add a test for `equalsBoundNode()` for types that does not depend
3858 // on C++.
3859 return;
3861 EXPECT_TRUE(matches(
3862 "class X { int a; int b; };",
3863 recordDecl(
3864 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
3865 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
3867 EXPECT_TRUE(notMatches(
3868 "class X { int a; double b; };",
3869 recordDecl(
3870 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
3871 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
3874 TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_UsingForEachDescendant) {
3875 EXPECT_TRUE(matchAndVerifyResultTrue(
3876 "int f() {"
3877 " if (1) {"
3878 " int i = 9;"
3879 " }"
3880 " int j = 10;"
3881 " {"
3882 " float k = 9.0;"
3883 " }"
3884 " return 0;"
3885 "}",
3886 // Look for variable declarations within functions whose type is the same
3887 // as the function return type.
3888 functionDecl(
3889 returns(qualType().bind("type")),
3890 forEachDescendant(varDecl(hasType(qualType(equalsBoundNode("type"))))
3891 .bind("decl"))),
3892 // Only i and j should match, not k.
3893 std::make_unique<VerifyIdIsBoundTo<VarDecl>>("decl", 2)));
3896 TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_FiltersMatchedCombinations) {
3897 EXPECT_TRUE(matchAndVerifyResultTrue(
3898 "void f() {"
3899 " int x;"
3900 " double d;"
3901 " x = d + x - d + x;"
3902 "}",
3903 functionDecl(
3904 hasName("f"), forEachDescendant(varDecl().bind("d")),
3905 forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d")))))),
3906 std::make_unique<VerifyIdIsBoundTo<VarDecl>>("d", 5)));
3909 TEST_P(ASTMatchersTest,
3910 EqualsBoundNodeMatcher_UnlessDescendantsOfAncestorsMatch) {
3911 EXPECT_TRUE(matchAndVerifyResultTrue(
3912 "struct StringRef { int size() const; const char* data() const; };"
3913 "void f(StringRef v) {"
3914 " v.data();"
3915 "}",
3916 cxxMemberCallExpr(
3917 callee(cxxMethodDecl(hasName("data"))),
3918 on(declRefExpr(to(
3919 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
3920 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
3921 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
3922 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
3923 .bind("data"),
3924 std::make_unique<VerifyIdIsBoundTo<Expr>>("data", 1)));
3926 EXPECT_FALSE(matches(
3927 "struct StringRef { int size() const; const char* data() const; };"
3928 "void f(StringRef v) {"
3929 " v.data();"
3930 " v.size();"
3931 "}",
3932 cxxMemberCallExpr(
3933 callee(cxxMethodDecl(hasName("data"))),
3934 on(declRefExpr(to(
3935 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
3936 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
3937 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
3938 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
3939 .bind("data")));
3942 TEST_P(ASTMatchersTest, NullPointerConstant) {
3943 EXPECT_TRUE(matches("#define NULL ((void *)0)\n"
3944 "void *v1 = NULL;",
3945 expr(nullPointerConstant())));
3946 EXPECT_TRUE(matches("char *cp = (char *)0;", expr(nullPointerConstant())));
3947 EXPECT_TRUE(matches("int *ip = 0;", expr(nullPointerConstant())));
3948 EXPECT_FALSE(matches("int i = 0;", expr(nullPointerConstant())));
3951 TEST_P(ASTMatchersTest, NullPointerConstant_GNUNull) {
3952 if (!GetParam().isCXX()) {
3953 return;
3956 EXPECT_TRUE(matches("void *p = __null;", expr(nullPointerConstant())));
3959 TEST_P(ASTMatchersTest, NullPointerConstant_GNUNullInTemplate) {
3960 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3961 // FIXME: Fix this test to work with delayed template parsing.
3962 return;
3965 const char kTest[] = R"(
3966 template <typename T>
3967 struct MyTemplate {
3968 MyTemplate() : field_(__null) {}
3969 T* field_;
3972 EXPECT_TRUE(matches(kTest, expr(nullPointerConstant())));
3975 TEST_P(ASTMatchersTest, NullPointerConstant_CXX11Nullptr) {
3976 if (!GetParam().isCXX11OrLater()) {
3977 return;
3980 EXPECT_TRUE(matches("void *p = nullptr;", expr(nullPointerConstant())));
3983 TEST_P(ASTMatchersTest, HasExternalFormalLinkage) {
3984 EXPECT_TRUE(matches("int a = 0;",
3985 namedDecl(hasName("a"), hasExternalFormalLinkage())));
3986 EXPECT_TRUE(notMatches("static int a = 0;",
3987 namedDecl(hasName("a"), hasExternalFormalLinkage())));
3988 EXPECT_TRUE(notMatches("static void f(void) { int a = 0; }",
3989 namedDecl(hasName("a"), hasExternalFormalLinkage())));
3990 EXPECT_TRUE(notMatches("void f(void) { int a = 0; }",
3991 namedDecl(hasName("a"), hasExternalFormalLinkage())));
3994 TEST_P(ASTMatchersTest, HasExternalFormalLinkage_CXX) {
3995 if (!GetParam().isCXX()) {
3996 return;
3999 EXPECT_TRUE(notMatches("namespace { int a = 0; }",
4000 namedDecl(hasName("a"), hasExternalFormalLinkage())));
4003 TEST_P(ASTMatchersTest, HasDefaultArgument) {
4004 if (!GetParam().isCXX()) {
4005 return;
4008 EXPECT_TRUE(
4009 matches("void x(int val = 0) {}", parmVarDecl(hasDefaultArgument())));
4010 EXPECT_TRUE(
4011 notMatches("void x(int val) {}", parmVarDecl(hasDefaultArgument())));
4014 TEST_P(ASTMatchersTest, IsAtPosition) {
4015 EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1))));
4016 EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(0))));
4017 EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1))));
4018 EXPECT_TRUE(notMatches("void x(int val) {}", parmVarDecl(isAtPosition(1))));
4021 TEST_P(ASTMatchersTest, IsAtPosition_FunctionDecl) {
4022 EXPECT_TRUE(matches("void x(int a);", parmVarDecl(isAtPosition(0))));
4023 EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(0))));
4024 EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(1))));
4025 EXPECT_TRUE(notMatches("void x(int val);", parmVarDecl(isAtPosition(1))));
4028 TEST_P(ASTMatchersTest, IsAtPosition_Lambda) {
4029 if (!GetParam().isCXX11OrLater()) {
4030 return;
4033 EXPECT_TRUE(
4034 matches("void x() { [](int a) {}; }", parmVarDecl(isAtPosition(0))));
4035 EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",
4036 parmVarDecl(isAtPosition(0))));
4037 EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",
4038 parmVarDecl(isAtPosition(1))));
4039 EXPECT_TRUE(
4040 notMatches("void x() { [](int val) {}; }", parmVarDecl(isAtPosition(1))));
4043 TEST_P(ASTMatchersTest, IsAtPosition_BlockDecl) {
4044 EXPECT_TRUE(matchesObjC(
4045 "void func() { void (^my_block)(int arg) = ^void(int arg) {}; } ",
4046 parmVarDecl(isAtPosition(0))));
4048 EXPECT_TRUE(matchesObjC("void func() { void (^my_block)(int x, int y) = "
4049 "^void(int x, int y) {}; } ",
4050 parmVarDecl(isAtPosition(1))));
4052 EXPECT_TRUE(notMatchesObjC(
4053 "void func() { void (^my_block)(int arg) = ^void(int arg) {}; } ",
4054 parmVarDecl(isAtPosition(1))));
4057 TEST_P(ASTMatchersTest, IsArray) {
4058 if (!GetParam().isCXX()) {
4059 return;
4062 EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",
4063 cxxNewExpr(isArray())));
4066 TEST_P(ASTMatchersTest, HasArraySize) {
4067 if (!GetParam().isCXX()) {
4068 return;
4071 EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",
4072 cxxNewExpr(hasArraySize(
4073 ignoringParenImpCasts(integerLiteral(equals(10)))))));
4076 TEST_P(ASTMatchersTest, HasDefinition_MatchesStructDefinition) {
4077 if (!GetParam().isCXX()) {
4078 return;
4081 EXPECT_TRUE(matches("struct x {};", cxxRecordDecl(hasDefinition())));
4082 EXPECT_TRUE(notMatches("struct x;", cxxRecordDecl(hasDefinition())));
4085 TEST_P(ASTMatchersTest, HasDefinition_MatchesClassDefinition) {
4086 if (!GetParam().isCXX()) {
4087 return;
4090 EXPECT_TRUE(matches("class x {};", cxxRecordDecl(hasDefinition())));
4091 EXPECT_TRUE(notMatches("class x;", cxxRecordDecl(hasDefinition())));
4094 TEST_P(ASTMatchersTest, HasDefinition_MatchesUnionDefinition) {
4095 if (!GetParam().isCXX()) {
4096 return;
4099 EXPECT_TRUE(matches("union x {};", cxxRecordDecl(hasDefinition())));
4100 EXPECT_TRUE(notMatches("union x;", cxxRecordDecl(hasDefinition())));
4103 TEST_P(ASTMatchersTest, IsScoped_MatchesScopedEnum) {
4104 if (!GetParam().isCXX11OrLater()) {
4105 return;
4107 EXPECT_TRUE(matches("enum class X {};", enumDecl(isScoped())));
4110 TEST_P(ASTMatchersTest, IsScoped_NotMatchesRegularEnum) {
4111 EXPECT_TRUE(notMatches("enum E { E1 };", enumDecl(isScoped())));
4114 TEST_P(ASTMatchersTest, IsStruct) {
4115 EXPECT_TRUE(matches("struct S {};", tagDecl(isStruct())));
4118 TEST_P(ASTMatchersTest, IsUnion) {
4119 EXPECT_TRUE(matches("union U {};", tagDecl(isUnion())));
4122 TEST_P(ASTMatchersTest, IsEnum) {
4123 EXPECT_TRUE(matches("enum E { E1 };", tagDecl(isEnum())));
4126 TEST_P(ASTMatchersTest, IsClass) {
4127 if (!GetParam().isCXX()) {
4128 return;
4131 EXPECT_TRUE(matches("class C {};", tagDecl(isClass())));
4134 TEST_P(ASTMatchersTest, HasTrailingReturn_MatchesTrailingReturn) {
4135 if (!GetParam().isCXX11OrLater()) {
4136 return;
4139 EXPECT_TRUE(matches("auto Y() -> int { return 0; }",
4140 functionDecl(hasTrailingReturn())));
4141 EXPECT_TRUE(matches("auto X() -> int;", functionDecl(hasTrailingReturn())));
4142 EXPECT_TRUE(
4143 notMatches("int X() { return 0; }", functionDecl(hasTrailingReturn())));
4144 EXPECT_TRUE(notMatches("int X();", functionDecl(hasTrailingReturn())));
4145 EXPECT_TRUE(notMatches("void X();", functionDecl(hasTrailingReturn())));
4148 TEST_P(ASTMatchersTest, HasTrailingReturn_MatchesLambdaTrailingReturn) {
4149 if (!GetParam().isCXX11OrLater()) {
4150 return;
4153 EXPECT_TRUE(matches(
4154 "auto lambda2 = [](double x, double y) -> double {return x + y;};",
4155 functionDecl(hasTrailingReturn())));
4156 EXPECT_TRUE(
4157 notMatches("auto lambda2 = [](double x, double y) {return x + y;};",
4158 functionDecl(hasTrailingReturn())));
4161 TEST_P(ASTMatchersTest, IsAssignmentOperator) {
4162 if (!GetParam().isCXX()) {
4163 return;
4166 StatementMatcher BinAsgmtOperator = binaryOperator(isAssignmentOperator());
4167 StatementMatcher CXXAsgmtOperator =
4168 cxxOperatorCallExpr(isAssignmentOperator());
4170 EXPECT_TRUE(matches("void x() { int a; a += 1; }", BinAsgmtOperator));
4171 EXPECT_TRUE(matches("void x() { int a; a = 2; }", BinAsgmtOperator));
4172 EXPECT_TRUE(matches("void x() { int a; a &= 3; }", BinAsgmtOperator));
4173 EXPECT_TRUE(matches("struct S { S& operator=(const S&); };"
4174 "void x() { S s1, s2; s1 = s2; }",
4175 CXXAsgmtOperator));
4176 EXPECT_TRUE(
4177 notMatches("void x() { int a; if(a == 0) return; }", BinAsgmtOperator));
4180 TEST_P(ASTMatchersTest, IsComparisonOperator) {
4181 if (!GetParam().isCXX()) {
4182 return;
4185 StatementMatcher BinCompOperator = binaryOperator(isComparisonOperator());
4186 StatementMatcher CXXCompOperator =
4187 cxxOperatorCallExpr(isComparisonOperator());
4189 EXPECT_TRUE(matches("void x() { int a; a == 1; }", BinCompOperator));
4190 EXPECT_TRUE(matches("void x() { int a; a > 2; }", BinCompOperator));
4191 EXPECT_TRUE(matches("struct S { bool operator==(const S&); };"
4192 "void x() { S s1, s2; bool b1 = s1 == s2; }",
4193 CXXCompOperator));
4194 EXPECT_TRUE(
4195 notMatches("void x() { int a; if(a = 0) return; }", BinCompOperator));
4198 TEST_P(ASTMatchersTest, isRightFold) {
4199 if (!GetParam().isCXX17OrLater()) {
4200 return;
4203 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4204 "return (0 + ... + args); }",
4205 cxxFoldExpr(isRightFold())));
4206 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4207 "return (args + ... + 0); }",
4208 cxxFoldExpr(isRightFold())));
4209 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4210 "return (... + args); };",
4211 cxxFoldExpr(isRightFold())));
4212 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4213 "return (args + ...); };",
4214 cxxFoldExpr(isRightFold())));
4217 TEST_P(ASTMatchersTest, isLeftFold) {
4218 if (!GetParam().isCXX17OrLater()) {
4219 return;
4222 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4223 "return (0 + ... + args); }",
4224 cxxFoldExpr(isLeftFold())));
4225 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4226 "return (args + ... + 0); }",
4227 cxxFoldExpr(isLeftFold())));
4228 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4229 "return (... + args); };",
4230 cxxFoldExpr(isLeftFold())));
4231 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4232 "return (args + ...); };",
4233 cxxFoldExpr(isLeftFold())));
4236 TEST_P(ASTMatchersTest, isUnaryFold) {
4237 if (!GetParam().isCXX17OrLater()) {
4238 return;
4241 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4242 "return (0 + ... + args); }",
4243 cxxFoldExpr(isUnaryFold())));
4244 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4245 "return (args + ... + 0); }",
4246 cxxFoldExpr(isUnaryFold())));
4247 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4248 "return (... + args); };",
4249 cxxFoldExpr(isUnaryFold())));
4250 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4251 "return (args + ...); };",
4252 cxxFoldExpr(isUnaryFold())));
4255 TEST_P(ASTMatchersTest, isBinaryFold) {
4256 if (!GetParam().isCXX17OrLater()) {
4257 return;
4260 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4261 "return (0 + ... + args); }",
4262 cxxFoldExpr(isBinaryFold())));
4263 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4264 "return (args + ... + 0); }",
4265 cxxFoldExpr(isBinaryFold())));
4266 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4267 "return (... + args); };",
4268 cxxFoldExpr(isBinaryFold())));
4269 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4270 "return (args + ...); };",
4271 cxxFoldExpr(isBinaryFold())));
4274 TEST_P(ASTMatchersTest, hasOperator) {
4275 if (!GetParam().isCXX17OrLater()) {
4276 return;
4279 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4280 "return (0 + ... + args); }",
4281 cxxFoldExpr(hasOperatorName("+"))));
4282 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4283 "return (... + args); };",
4284 cxxFoldExpr(hasOperatorName("+"))));
4286 EXPECT_FALSE(
4287 matches("template <typename... Args> auto multiply(Args... args) { "
4288 "return (0 * ... * args); }",
4289 cxxFoldExpr(hasOperatorName("+"))));
4290 EXPECT_FALSE(
4291 matches("template <typename... Args> auto multiply(Args... args) { "
4292 "return (... * args); };",
4293 cxxFoldExpr(hasOperatorName("+"))));
4296 TEST_P(ASTMatchersTest, IsMain) {
4297 EXPECT_TRUE(matches("int main() {}", functionDecl(isMain())));
4299 EXPECT_TRUE(notMatches("int main2() {}", functionDecl(isMain())));
4302 TEST_P(ASTMatchersTest, OMPExecutableDirective_IsStandaloneDirective) {
4303 auto Matcher = ompExecutableDirective(isStandaloneDirective());
4305 StringRef Source0 = R"(
4306 void x() {
4307 #pragma omp parallel
4309 })";
4310 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
4312 StringRef Source1 = R"(
4313 void x() {
4314 #pragma omp taskyield
4315 })";
4316 EXPECT_TRUE(matchesWithOpenMP(Source1, Matcher));
4319 TEST_P(ASTMatchersTest, OMPExecutableDirective_HasStructuredBlock) {
4320 StringRef Source0 = R"(
4321 void x() {
4322 #pragma omp parallel
4324 })";
4325 EXPECT_TRUE(matchesWithOpenMP(
4326 Source0, ompExecutableDirective(hasStructuredBlock(nullStmt()))));
4328 StringRef Source1 = R"(
4329 void x() {
4330 #pragma omp parallel
4332 })";
4333 EXPECT_TRUE(notMatchesWithOpenMP(
4334 Source1, ompExecutableDirective(hasStructuredBlock(nullStmt()))));
4335 EXPECT_TRUE(matchesWithOpenMP(
4336 Source1, ompExecutableDirective(hasStructuredBlock(compoundStmt()))));
4338 StringRef Source2 = R"(
4339 void x() {
4340 #pragma omp taskyield
4342 })";
4343 EXPECT_TRUE(notMatchesWithOpenMP(
4344 Source2, ompExecutableDirective(hasStructuredBlock(anything()))));
4347 TEST_P(ASTMatchersTest, OMPExecutableDirective_HasClause) {
4348 auto Matcher = ompExecutableDirective(hasAnyClause(anything()));
4350 StringRef Source0 = R"(
4351 void x() {
4353 })";
4354 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
4356 StringRef Source1 = R"(
4357 void x() {
4358 #pragma omp parallel
4360 })";
4361 EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));
4363 StringRef Source2 = R"(
4364 void x() {
4365 #pragma omp parallel default(none)
4367 })";
4368 EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher));
4370 StringRef Source3 = R"(
4371 void x() {
4372 #pragma omp parallel default(shared)
4374 })";
4375 EXPECT_TRUE(matchesWithOpenMP(Source3, Matcher));
4377 StringRef Source4 = R"(
4378 void x() {
4379 #pragma omp parallel default(firstprivate)
4381 })";
4382 EXPECT_TRUE(matchesWithOpenMP51(Source4, Matcher));
4384 StringRef Source5 = R"(
4385 void x(int x) {
4386 #pragma omp parallel num_threads(x)
4388 })";
4389 EXPECT_TRUE(matchesWithOpenMP(Source5, Matcher));
4392 TEST_P(ASTMatchersTest, OMPDefaultClause_IsNoneKind) {
4393 auto Matcher =
4394 ompExecutableDirective(hasAnyClause(ompDefaultClause(isNoneKind())));
4396 StringRef Source0 = R"(
4397 void x() {
4399 })";
4400 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
4402 StringRef Source1 = R"(
4403 void x() {
4404 #pragma omp parallel
4406 })";
4407 EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));
4409 StringRef Source2 = R"(
4410 void x() {
4411 #pragma omp parallel default(none)
4413 })";
4414 EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher));
4416 StringRef Source3 = R"(
4417 void x() {
4418 #pragma omp parallel default(shared)
4420 })";
4421 EXPECT_TRUE(notMatchesWithOpenMP(Source3, Matcher));
4423 StringRef Source4 = R"(
4424 void x(int x) {
4425 #pragma omp parallel default(firstprivate)
4427 })";
4428 EXPECT_TRUE(notMatchesWithOpenMP51(Source4, Matcher));
4430 StringRef Source5 = R"(
4431 void x(int x) {
4432 #pragma omp parallel default(private)
4434 })";
4435 EXPECT_TRUE(notMatchesWithOpenMP51(Source5, Matcher));
4437 const std::string Source6 = R"(
4438 void x(int x) {
4439 #pragma omp parallel num_threads(x)
4441 })";
4442 EXPECT_TRUE(notMatchesWithOpenMP(Source6, Matcher));
4445 TEST_P(ASTMatchersTest, OMPDefaultClause_IsSharedKind) {
4446 auto Matcher =
4447 ompExecutableDirective(hasAnyClause(ompDefaultClause(isSharedKind())));
4449 StringRef Source0 = R"(
4450 void x() {
4452 })";
4453 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
4455 StringRef Source1 = R"(
4456 void x() {
4457 #pragma omp parallel
4459 })";
4460 EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));
4462 StringRef Source2 = R"(
4463 void x() {
4464 #pragma omp parallel default(shared)
4466 })";
4467 EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher));
4469 StringRef Source3 = R"(
4470 void x() {
4471 #pragma omp parallel default(none)
4473 })";
4474 EXPECT_TRUE(notMatchesWithOpenMP(Source3, Matcher));
4476 StringRef Source4 = R"(
4477 void x(int x) {
4478 #pragma omp parallel default(firstprivate)
4480 })";
4481 EXPECT_TRUE(notMatchesWithOpenMP51(Source4, Matcher));
4483 StringRef Source5 = R"(
4484 void x(int x) {
4485 #pragma omp parallel default(private)
4487 })";
4488 EXPECT_TRUE(notMatchesWithOpenMP51(Source5, Matcher));
4490 const std::string Source6 = R"(
4491 void x(int x) {
4492 #pragma omp parallel num_threads(x)
4494 })";
4495 EXPECT_TRUE(notMatchesWithOpenMP(Source6, Matcher));
4498 TEST(OMPDefaultClause, isFirstPrivateKind) {
4499 auto Matcher = ompExecutableDirective(
4500 hasAnyClause(ompDefaultClause(isFirstPrivateKind())));
4502 const std::string Source0 = R"(
4503 void x() {
4505 })";
4506 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
4508 const std::string Source1 = R"(
4509 void x() {
4510 #pragma omp parallel
4512 })";
4513 EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));
4515 const std::string Source2 = R"(
4516 void x() {
4517 #pragma omp parallel default(shared)
4519 })";
4520 EXPECT_TRUE(notMatchesWithOpenMP(Source2, Matcher));
4522 const std::string Source3 = R"(
4523 void x() {
4524 #pragma omp parallel default(none)
4526 })";
4527 EXPECT_TRUE(notMatchesWithOpenMP(Source3, Matcher));
4529 const std::string Source4 = R"(
4530 void x(int x) {
4531 #pragma omp parallel default(firstprivate)
4533 })";
4534 EXPECT_TRUE(matchesWithOpenMP51(Source4, Matcher));
4536 const std::string Source5 = R"(
4537 void x(int x) {
4538 #pragma omp parallel default(private)
4540 })";
4541 EXPECT_TRUE(notMatchesWithOpenMP51(Source5, Matcher));
4543 const std::string Source6 = R"(
4544 void x(int x) {
4545 #pragma omp parallel num_threads(x)
4547 })";
4548 EXPECT_TRUE(notMatchesWithOpenMP(Source6, Matcher));
4551 TEST(OMPDefaultClause, istPrivateKind) {
4552 auto Matcher =
4553 ompExecutableDirective(hasAnyClause(ompDefaultClause(isPrivateKind())));
4555 const std::string Source0 = R"(
4556 void x() {
4558 })";
4559 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
4561 const std::string Source1 = R"(
4562 void x() {
4563 #pragma omp parallel
4565 })";
4566 EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));
4568 const std::string Source2 = R"(
4569 void x() {
4570 #pragma omp parallel default(shared)
4572 })";
4573 EXPECT_TRUE(notMatchesWithOpenMP(Source2, Matcher));
4575 const std::string Source3 = R"(
4576 void x() {
4577 #pragma omp parallel default(none)
4579 })";
4580 EXPECT_TRUE(notMatchesWithOpenMP(Source3, Matcher));
4582 const std::string Source4 = R"(
4583 void x(int x) {
4584 #pragma omp parallel default(firstprivate)
4586 })";
4587 EXPECT_TRUE(notMatchesWithOpenMP51(Source4, Matcher));
4589 const std::string Source5 = R"(
4590 void x(int x) {
4591 #pragma omp parallel default(private)
4593 })";
4594 EXPECT_TRUE(matchesWithOpenMP51(Source5, Matcher));
4596 const std::string Source6 = R"(
4597 void x(int x) {
4598 #pragma omp parallel num_threads(x)
4600 })";
4601 EXPECT_TRUE(notMatchesWithOpenMP(Source6, Matcher));
4604 TEST_P(ASTMatchersTest, OMPExecutableDirective_IsAllowedToContainClauseKind) {
4605 auto Matcher = ompExecutableDirective(
4606 isAllowedToContainClauseKind(llvm::omp::OMPC_default));
4608 StringRef Source0 = R"(
4609 void x() {
4611 })";
4612 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
4614 StringRef Source1 = R"(
4615 void x() {
4616 #pragma omp parallel
4618 })";
4619 EXPECT_TRUE(matchesWithOpenMP(Source1, Matcher));
4621 StringRef Source2 = R"(
4622 void x() {
4623 #pragma omp parallel default(none)
4625 })";
4626 EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher));
4628 StringRef Source3 = R"(
4629 void x() {
4630 #pragma omp parallel default(shared)
4632 })";
4633 EXPECT_TRUE(matchesWithOpenMP(Source3, Matcher));
4635 StringRef Source4 = R"(
4636 void x() {
4637 #pragma omp parallel default(firstprivate)
4639 })";
4640 EXPECT_TRUE(matchesWithOpenMP51(Source4, Matcher));
4642 StringRef Source5 = R"(
4643 void x() {
4644 #pragma omp parallel default(private)
4646 })";
4647 EXPECT_TRUE(matchesWithOpenMP51(Source5, Matcher));
4649 StringRef Source6 = R"(
4650 void x(int x) {
4651 #pragma omp parallel num_threads(x)
4653 })";
4654 EXPECT_TRUE(matchesWithOpenMP(Source6, Matcher));
4656 StringRef Source7 = R"(
4657 void x() {
4658 #pragma omp taskyield
4659 })";
4660 EXPECT_TRUE(notMatchesWithOpenMP(Source7, Matcher));
4662 StringRef Source8 = R"(
4663 void x() {
4664 #pragma omp task
4666 })";
4667 EXPECT_TRUE(matchesWithOpenMP(Source8, Matcher));
4670 TEST_P(ASTMatchersTest, HasAnyBase_DirectBase) {
4671 if (!GetParam().isCXX()) {
4672 return;
4674 EXPECT_TRUE(matches(
4675 "struct Base {};"
4676 "struct ExpectedMatch : Base {};",
4677 cxxRecordDecl(hasName("ExpectedMatch"),
4678 hasAnyBase(hasType(cxxRecordDecl(hasName("Base")))))));
4681 TEST_P(ASTMatchersTest, HasAnyBase_IndirectBase) {
4682 if (!GetParam().isCXX()) {
4683 return;
4685 EXPECT_TRUE(matches(
4686 "struct Base {};"
4687 "struct Intermediate : Base {};"
4688 "struct ExpectedMatch : Intermediate {};",
4689 cxxRecordDecl(hasName("ExpectedMatch"),
4690 hasAnyBase(hasType(cxxRecordDecl(hasName("Base")))))));
4693 TEST_P(ASTMatchersTest, HasAnyBase_NoBase) {
4694 if (!GetParam().isCXX()) {
4695 return;
4697 EXPECT_TRUE(notMatches("struct Foo {};"
4698 "struct Bar {};",
4699 cxxRecordDecl(hasAnyBase(hasType(cxxRecordDecl())))));
4702 TEST_P(ASTMatchersTest, HasAnyBase_IsPublic_Public) {
4703 if (!GetParam().isCXX()) {
4704 return;
4706 EXPECT_TRUE(matches("class Base {};"
4707 "class Derived : public Base {};",
4708 cxxRecordDecl(hasAnyBase(isPublic()))));
4711 TEST_P(ASTMatchersTest, HasAnyBase_IsPublic_DefaultAccessSpecifierPublic) {
4712 if (!GetParam().isCXX()) {
4713 return;
4715 EXPECT_TRUE(matches("class Base {};"
4716 "struct Derived : Base {};",
4717 cxxRecordDecl(hasAnyBase(isPublic()))));
4720 TEST_P(ASTMatchersTest, HasAnyBase_IsPublic_Private) {
4721 if (!GetParam().isCXX()) {
4722 return;
4724 EXPECT_TRUE(notMatches("class Base {};"
4725 "class Derived : private Base {};",
4726 cxxRecordDecl(hasAnyBase(isPublic()))));
4729 TEST_P(ASTMatchersTest, HasAnyBase_IsPublic_DefaultAccessSpecifierPrivate) {
4730 if (!GetParam().isCXX()) {
4731 return;
4733 EXPECT_TRUE(notMatches("class Base {};"
4734 "class Derived : Base {};",
4735 cxxRecordDecl(hasAnyBase(isPublic()))));
4738 TEST_P(ASTMatchersTest, HasAnyBase_IsPublic_Protected) {
4739 if (!GetParam().isCXX()) {
4740 return;
4742 EXPECT_TRUE(notMatches("class Base {};"
4743 "class Derived : protected Base {};",
4744 cxxRecordDecl(hasAnyBase(isPublic()))));
4747 TEST_P(ASTMatchersTest, HasAnyBase_IsPrivate_Private) {
4748 if (!GetParam().isCXX()) {
4749 return;
4751 EXPECT_TRUE(matches("class Base {};"
4752 "class Derived : private Base {};",
4753 cxxRecordDecl(hasAnyBase(isPrivate()))));
4756 TEST_P(ASTMatchersTest, HasAnyBase_IsPrivate_DefaultAccessSpecifierPrivate) {
4757 if (!GetParam().isCXX()) {
4758 return;
4760 EXPECT_TRUE(matches("struct Base {};"
4761 "class Derived : Base {};",
4762 cxxRecordDecl(hasAnyBase(isPrivate()))));
4765 TEST_P(ASTMatchersTest, HasAnyBase_IsPrivate_Public) {
4766 if (!GetParam().isCXX()) {
4767 return;
4769 EXPECT_TRUE(notMatches("class Base {};"
4770 "class Derived : public Base {};",
4771 cxxRecordDecl(hasAnyBase(isPrivate()))));
4774 TEST_P(ASTMatchersTest, HasAnyBase_IsPrivate_DefaultAccessSpecifierPublic) {
4775 if (!GetParam().isCXX()) {
4776 return;
4778 EXPECT_TRUE(notMatches("class Base {};"
4779 "struct Derived : Base {};",
4780 cxxRecordDecl(hasAnyBase(isPrivate()))));
4783 TEST_P(ASTMatchersTest, HasAnyBase_IsPrivate_Protected) {
4784 if (!GetParam().isCXX()) {
4785 return;
4787 EXPECT_TRUE(notMatches("class Base {};"
4788 "class Derived : protected Base {};",
4789 cxxRecordDecl(hasAnyBase(isPrivate()))));
4792 TEST_P(ASTMatchersTest, HasAnyBase_IsProtected_Protected) {
4793 if (!GetParam().isCXX()) {
4794 return;
4796 EXPECT_TRUE(matches("class Base {};"
4797 "class Derived : protected Base {};",
4798 cxxRecordDecl(hasAnyBase(isProtected()))));
4801 TEST_P(ASTMatchersTest, HasAnyBase_IsProtected_Public) {
4802 if (!GetParam().isCXX()) {
4803 return;
4805 EXPECT_TRUE(notMatches("class Base {};"
4806 "class Derived : public Base {};",
4807 cxxRecordDecl(hasAnyBase(isProtected()))));
4810 TEST_P(ASTMatchersTest, HasAnyBase_IsProtected_Private) {
4811 if (!GetParam().isCXX()) {
4812 return;
4814 EXPECT_TRUE(notMatches("class Base {};"
4815 "class Derived : private Base {};",
4816 cxxRecordDecl(hasAnyBase(isProtected()))));
4819 TEST_P(ASTMatchersTest, HasAnyBase_IsVirtual_Directly) {
4820 if (!GetParam().isCXX()) {
4821 return;
4823 EXPECT_TRUE(matches("class Base {};"
4824 "class Derived : virtual Base {};",
4825 cxxRecordDecl(hasAnyBase(isVirtual()))));
4828 TEST_P(ASTMatchersTest, HasAnyBase_IsVirtual_Indirectly) {
4829 if (!GetParam().isCXX()) {
4830 return;
4832 EXPECT_TRUE(
4833 matches("class Base {};"
4834 "class Intermediate : virtual Base {};"
4835 "class Derived : Intermediate {};",
4836 cxxRecordDecl(hasName("Derived"), hasAnyBase(isVirtual()))));
4839 TEST_P(ASTMatchersTest, HasAnyBase_IsVirtual_NoVirtualBase) {
4840 if (!GetParam().isCXX()) {
4841 return;
4843 EXPECT_TRUE(notMatches("class Base {};"
4844 "class Derived : Base {};",
4845 cxxRecordDecl(hasAnyBase(isVirtual()))));
4848 TEST_P(ASTMatchersTest, HasDirectBase) {
4849 if (!GetParam().isCXX()) {
4850 return;
4853 DeclarationMatcher ClassHasAnyDirectBase =
4854 cxxRecordDecl(hasDirectBase(cxxBaseSpecifier()));
4855 EXPECT_TRUE(notMatches("class X {};", ClassHasAnyDirectBase));
4856 EXPECT_TRUE(matches("class X {}; class Y : X {};", ClassHasAnyDirectBase));
4857 EXPECT_TRUE(matches("class X {}; class Y : public virtual X {};",
4858 ClassHasAnyDirectBase));
4860 EXPECT_TRUE(matches(
4861 R"cc(
4862 class Base {};
4863 class Derived : Base{};
4864 )cc",
4865 cxxRecordDecl(hasName("Derived"),
4866 hasDirectBase(hasType(cxxRecordDecl(hasName("Base")))))));
4868 StringRef MultiDerived = R"cc(
4869 class Base {};
4870 class Base2 {};
4871 class Derived : Base, Base2{};
4872 )cc";
4874 EXPECT_TRUE(matches(
4875 MultiDerived,
4876 cxxRecordDecl(hasName("Derived"),
4877 hasDirectBase(hasType(cxxRecordDecl(hasName("Base")))))));
4878 EXPECT_TRUE(matches(
4879 MultiDerived,
4880 cxxRecordDecl(hasName("Derived"),
4881 hasDirectBase(hasType(cxxRecordDecl(hasName("Base2")))))));
4883 StringRef Indirect = R"cc(
4884 class Base {};
4885 class Intermediate : Base {};
4886 class Derived : Intermediate{};
4887 )cc";
4889 EXPECT_TRUE(
4890 matches(Indirect, cxxRecordDecl(hasName("Derived"),
4891 hasDirectBase(hasType(cxxRecordDecl(
4892 hasName("Intermediate")))))));
4893 EXPECT_TRUE(notMatches(
4894 Indirect,
4895 cxxRecordDecl(hasName("Derived"),
4896 hasDirectBase(hasType(cxxRecordDecl(hasName("Base")))))));
4899 TEST_P(ASTMatchersTest, CapturesThis) {
4900 if (!GetParam().isCXX11OrLater()) {
4901 return;
4903 auto matcher = lambdaExpr(hasAnyCapture(lambdaCapture(capturesThis())));
4904 EXPECT_TRUE(matches("class C { int cc; int f() { auto l = [this](){ return "
4905 "cc; }; return l(); } };",
4906 matcher));
4907 EXPECT_TRUE(matches("class C { int cc; int f() { auto l = [=](){ return cc; "
4908 "}; return l(); } };",
4909 matcher));
4910 EXPECT_TRUE(matches("class C { int cc; int f() { auto l = [&](){ return cc; "
4911 "}; return l(); } };",
4912 matcher));
4913 EXPECT_FALSE(matches("class C { int cc; int f() { auto l = [cc](){ return "
4914 "cc; }; return l(); } };",
4915 matcher));
4916 EXPECT_FALSE(matches("class C { int this; int f() { auto l = [this](){ "
4917 "return this; }; return l(); } };",
4918 matcher));
4921 TEST_P(ASTMatchersTest, IsImplicit_LambdaCapture) {
4922 if (!GetParam().isCXX11OrLater()) {
4923 return;
4925 auto matcher = lambdaExpr(hasAnyCapture(
4926 lambdaCapture(isImplicit(), capturesVar(varDecl(hasName("cc"))))));
4927 EXPECT_TRUE(
4928 matches("int main() { int cc; auto f = [&](){ return cc; }; }", matcher));
4929 EXPECT_TRUE(
4930 matches("int main() { int cc; auto f = [=](){ return cc; }; }", matcher));
4931 EXPECT_FALSE(matches("int main() { int cc; auto f = [cc](){ return cc; }; }",
4932 matcher));
4935 } // namespace ast_matchers
4936 } // namespace clang