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//===----------------------------------------------------------------------===//
8
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"
17
18namespace clang {
19namespace ast_matchers {
20
21TEST_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"))));
27}
28
29TEST_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"))));
36}
37
38TEST_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"))));
46}
47
48TEST_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"))));
55}
56
57TEST_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);
63 }
64 )cc";
65 EXPECT_TRUE(matches(input, declRefExpr(isExpandedFromMacro("MY_MACRO"))));
66}
67
68// Like IsExpandedFromMacro_MatchesArgument, but the argument is itself a
69// macro.
70TEST_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));
76 }
77 )cc";
78 EXPECT_TRUE(matches(input, binaryOperator(isExpandedFromMacro("IDENTITY"))));
79}
80
81TEST_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));
87 }
88 )cc";
89 EXPECT_TRUE(matches(input, binaryOperator(isExpandedFromMacro("MY_MACRO"))));
90}
91
92TEST_P(ASTMatchersTest, IsExpandedFromMacro_MatchesObjectMacro) {
93 StringRef input = R"cc(
94#define PLUS (2 + 2)
95 void Test() {
96 PLUS;
97 }
98 )cc";
99 EXPECT_TRUE(matches(input, binaryOperator(isExpandedFromMacro("PLUS"))));
100}
101
102TEST(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"}));
109}
110
111TEST_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"))));
118}
119
120TEST_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"))));
127}
128
129TEST_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"))));
135}
136
137TEST_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"))));
143}
144
145TEST(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"))));
151}
152
153TEST(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"))));
159}
160
161TEST_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)))))));
187}
188
189TEST_P(ASTMatchersTest, Has) {
190 if (!GetParam().isCXX()) {
191 // FIXME: Add a test for `has()` that does not depend on C++.
192 return;
193 }
194
195 DeclarationMatcher HasClassX = recordDecl(has(recordDecl(hasName(Name: "X"))));
196 EXPECT_TRUE(matches("class Y { class X {}; };", HasClassX));
197 EXPECT_TRUE(matches("class X {};", HasClassX));
198
199 DeclarationMatcher YHasClassX =
200 recordDecl(hasName(Name: "Y"), has(recordDecl(hasName(Name: "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));
204}
205
206TEST_P(ASTMatchersTest, Has_RecursiveAllOf) {
207 if (!GetParam().isCXX()) {
208 return;
209 }
210
211 DeclarationMatcher Recursive =
212 recordDecl(has(recordDecl(has(recordDecl(hasName(Name: "X"))),
213 has(recordDecl(hasName(Name: "Y"))), hasName(Name: "Z"))),
214 has(recordDecl(has(recordDecl(hasName(Name: "A"))),
215 has(recordDecl(hasName(Name: "B"))), hasName(Name: "C"))),
216 hasName(Name: "F"));
217
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));
229
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));
243
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));
261}
262
263TEST_P(ASTMatchersTest, Has_RecursiveAnyOf) {
264 if (!GetParam().isCXX()) {
265 return;
266 }
267
268 DeclarationMatcher Recursive = recordDecl(
269 anyOf(has(recordDecl(anyOf(has(recordDecl(hasName(Name: "X"))),
270 has(recordDecl(hasName(Name: "Y"))), hasName(Name: "Z")))),
271 has(recordDecl(anyOf(hasName(Name: "C"), has(recordDecl(hasName(Name: "A"))),
272 has(recordDecl(hasName(Name: "B")))))),
273 hasName(Name: "F")));
274
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));
284}
285
286TEST_P(ASTMatchersTest, Unless) {
287 if (!GetParam().isCXX()) {
288 // FIXME: Add a test for `unless()` that does not depend on C++.
289 return;
290 }
291
292 DeclarationMatcher NotClassX =
293 cxxRecordDecl(isDerivedFrom(BaseName: "Y"), unless(hasName(Name: "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));
300
301 DeclarationMatcher ClassXHasNotClassY =
302 recordDecl(hasName(Name: "X"), has(recordDecl(hasName(Name: "Z"))),
303 unless(has(recordDecl(hasName(Name: "Y")))));
304 EXPECT_TRUE(matches("class X { class Z {}; };", ClassXHasNotClassY));
305 EXPECT_TRUE(
306 notMatches("class X { class Y {}; class Z {}; };", ClassXHasNotClassY));
307
308 DeclarationMatcher NamedNotRecord =
309 namedDecl(hasName(Name: "Foo"), unless(recordDecl()));
310 EXPECT_TRUE(matches("void Foo(){}", NamedNotRecord));
311 EXPECT_TRUE(notMatches("struct Foo {};", NamedNotRecord));
312}
313
314TEST_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)))))));
326}
327
328TEST_P(ASTMatchersTest, HasDescendant) {
329 if (!GetParam().isCXX()) {
330 // FIXME: Add a test for `hasDescendant()` that does not depend on C++.
331 return;
332 }
333
334 DeclarationMatcher ZDescendantClassX =
335 recordDecl(hasDescendant(recordDecl(hasName(Name: "X"))), hasName(Name: "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));
345
346 DeclarationMatcher ZDescendantClassXHasClassY = recordDecl(
347 hasDescendant(recordDecl(has(recordDecl(hasName(Name: "Y"))), hasName(Name: "X"))),
348 hasName(Name: "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));
366
367 DeclarationMatcher ZDescendantClassXDescendantClassY =
368 recordDecl(hasDescendant(recordDecl(
369 hasDescendant(recordDecl(hasName(Name: "Y"))), hasName(Name: "X"))),
370 hasName(Name: "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));
385}
386
387TEST_P(ASTMatchersTest, HasDescendant_Memoization) {
388 DeclarationMatcher CannotMemoize =
389 decl(hasDescendant(typeLoc().bind(ID: "x")), has(decl()));
390 EXPECT_TRUE(matches("void f() { int i; }", CannotMemoize));
391}
392
393TEST_P(ASTMatchersTest, HasDescendant_MemoizationUsesRestrictKind) {
394 auto Name = hasName(Name: "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)))));
405}
406
407TEST_P(ASTMatchersTest, HasAncestor_Memoization) {
408 if (!GetParam().isCXX()) {
409 return;
410 }
411
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(InnerMatcher: templateArgument().bind(ID: "targ")),
417 forEach(fieldDecl(hasAncestor(forStmt()))));
418
419 EXPECT_TRUE(notMatches("template <typename T> struct S;"
420 "template <> struct S<int>{ int i; int j; };",
421 CannotMemoize));
422}
423
424TEST_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))));
428}
429
430TEST_P(ASTMatchersTest, AnyOf) {
431 if (!GetParam().isCXX()) {
432 // FIXME: Add a test for `anyOf()` that does not depend on C++.
433 return;
434 }
435
436 DeclarationMatcher YOrZDerivedFromX = cxxRecordDecl(
437 anyOf(hasName(Name: "Y"), allOf(isDerivedFrom(BaseName: "X"), hasName(Name: "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));
443
444 DeclarationMatcher XOrYOrZOrU =
445 recordDecl(anyOf(hasName(Name: "X"), hasName(Name: "Y"), hasName(Name: "Z"), hasName(Name: "U")));
446 EXPECT_TRUE(matches("class X {};", XOrYOrZOrU));
447 EXPECT_TRUE(notMatches("class V {};", XOrYOrZOrU));
448
449 DeclarationMatcher XOrYOrZOrUOrV = recordDecl(anyOf(
450 hasName(Name: "X"), hasName(Name: "Y"), hasName(Name: "Z"), hasName(Name: "U"), hasName(Name: "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));
457
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));
462
463 EXPECT_TRUE(
464 matches("void f() try { } catch (int) { } catch (...) { }",
465 cxxCatchStmt(anyOf(hasDescendant(varDecl()), isCatchAll()))));
466}
467
468TEST_P(ASTMatchersTest, MapAnyOf) {
469 if (!GetParam().isCXX()) {
470 return;
471 }
472
473 if (GetParam().hasDelayedTemplateParsing()) {
474 return;
475 }
476
477 StringRef Code = R"cpp(
478void F() {
479 if (true) {}
480 for ( ; false; ) {}
481}
482)cpp";
483
484 auto trueExpr = cxxBoolLiteral(equals(Value: true));
485 auto falseExpr = cxxBoolLiteral(equals(Value: false));
486
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)))));
493
494 EXPECT_TRUE(
495 matches(Code, cxxBoolLiteral(equals(true),
496 hasAncestor(mapAnyOf(ifStmt, forStmt)))));
497
498 EXPECT_TRUE(
499 matches(Code, cxxBoolLiteral(equals(false),
500 hasAncestor(mapAnyOf(ifStmt, forStmt)))));
501
502 EXPECT_TRUE(
503 notMatches(Code, floatLiteral(hasAncestor(mapAnyOf(ifStmt, forStmt)))));
504
505 Code = R"cpp(
506void func(bool b) {}
507struct S {
508 S(bool b) {}
509};
510void F() {
511 func(false);
512 S s(true);
513}
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)))));
521
522 EXPECT_TRUE(
523 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
524 mapAnyOf(callExpr, cxxConstructExpr)
525 .with(hasArgument(0, expr()),
526 hasDeclaration(functionDecl())))));
527
528 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
529 mapAnyOf(callExpr, cxxConstructExpr))));
530
531 EXPECT_TRUE(matches(
532 Code, traverse(TK_IgnoreUnlessSpelledInSource,
533 mapAnyOf(callExpr, cxxConstructExpr).bind("call"))));
534
535 Code = R"cpp(
536struct HasOpNeqMem
537{
538 bool operator!=(const HasOpNeqMem& other) const
539 {
540 return true;
541 }
542};
543struct HasOpFree
544{
545};
546bool operator!=(const HasOpFree& lhs, const HasOpFree& rhs)
547{
548 return true;
549}
550
551void binop()
552{
553 int s1;
554 int s2;
555 if (s1 != s2)
556 return;
557}
558
559void opMem()
560{
561 HasOpNeqMem s1;
562 HasOpNeqMem s2;
563 if (s1 != s2)
564 return;
565}
566
567void opFree()
568{
569 HasOpFree s1;
570 HasOpFree s2;
571 if (s1 != s2)
572 return;
573}
574
575template<typename T>
576void templ()
577{
578 T s1;
579 T s2;
580 if (s1 != s2)
581 return;
582}
583)cpp";
584
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")))))))));
593
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")))))))));
602
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")))))))));
611
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")))))))));
621
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")))))))));
631
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")))))))));
641
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")))))))));
653
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")))))))));
665
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")))))))));
677
678 EXPECT_TRUE(matches(
679 Code, traverse(TK_IgnoreUnlessSpelledInSource,
680 mapAnyOf(binaryOperator, cxxOperatorCallExpr)
681 .with(hasAnyOperatorName("==", "!="),
682 forFunction(functionDecl(hasName("binop")))))));
683
684 EXPECT_TRUE(matches(
685 Code, traverse(TK_IgnoreUnlessSpelledInSource,
686 mapAnyOf(binaryOperator, cxxOperatorCallExpr)
687 .with(hasAnyOperatorName("==", "!="),
688 forFunction(functionDecl(hasName("opMem")))))));
689
690 EXPECT_TRUE(matches(
691 Code, traverse(TK_IgnoreUnlessSpelledInSource,
692 mapAnyOf(binaryOperator, cxxOperatorCallExpr)
693 .with(hasAnyOperatorName("==", "!="),
694 forFunction(functionDecl(hasName("opFree")))))));
695
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")))))))));
703
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")))))))));
711
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")))))))));
719
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")))))))));
727
728 Code = R"cpp(
729struct HasOpEq
730{
731 bool operator==(const HasOpEq &) const;
732};
733
734void inverse()
735{
736 HasOpEq s1;
737 HasOpEq s2;
738 if (s1 != s2)
739 return;
740}
741
742namespace std {
743struct strong_ordering {
744 int n;
745 constexpr operator int() const { return n; }
746 static const strong_ordering equal, greater, less;
747};
748constexpr strong_ordering strong_ordering::equal = {0};
749constexpr strong_ordering strong_ordering::greater = {1};
750constexpr strong_ordering strong_ordering::less = {-1};
751}
752
753struct HasSpaceshipMem {
754 int a;
755 constexpr auto operator<=>(const HasSpaceshipMem&) const = default;
756};
757
758void rewritten()
759{
760 HasSpaceshipMem s1;
761 HasSpaceshipMem s2;
762 if (s1 != s2)
763 return;
764}
765)cpp";
766
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"}));
776
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"}));
786
787 Code = R"cpp(
788struct HasOpBangMem
789{
790 bool operator!() const
791 {
792 return false;
793 }
794};
795struct HasOpBangFree
796{
797};
798bool operator!(HasOpBangFree const&)
799{
800 return false;
801}
802
803void unop()
804{
805 int s1;
806 if (!s1)
807 return;
808}
809
810void opMem()
811{
812 HasOpBangMem s1;
813 if (!s1)
814 return;
815}
816
817void opFree()
818{
819 HasOpBangFree s1;
820 if (!s1)
821 return;
822}
823)cpp";
824
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")))))))));
832
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")))))))));
840
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")))))))));
848
849 EXPECT_TRUE(matches(
850 Code, traverse(TK_IgnoreUnlessSpelledInSource,
851 mapAnyOf(unaryOperator, cxxOperatorCallExpr)
852 .with(hasAnyOperatorName("+", "!"),
853 forFunction(functionDecl(hasName("unop")))))));
854
855 EXPECT_TRUE(matches(
856 Code, traverse(TK_IgnoreUnlessSpelledInSource,
857 mapAnyOf(unaryOperator, cxxOperatorCallExpr)
858 .with(hasAnyOperatorName("+", "!"),
859 forFunction(functionDecl(hasName("opMem")))))));
860
861 EXPECT_TRUE(matches(
862 Code, traverse(TK_IgnoreUnlessSpelledInSource,
863 mapAnyOf(unaryOperator, cxxOperatorCallExpr)
864 .with(hasAnyOperatorName("+", "!"),
865 forFunction(functionDecl(hasName("opFree")))))));
866
867 Code = R"cpp(
868struct ConstructorTakesInt
869{
870 ConstructorTakesInt(int i) {}
871};
872
873void callTakesInt(int i)
874{
875
876}
877
878void doCall()
879{
880 callTakesInt(42);
881}
882
883void doConstruct()
884{
885 ConstructorTakesInt cti(42);
886}
887)cpp";
888
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")))))));
897
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")))))));
907}
908
909TEST_P(ASTMatchersTest, IsDerivedFrom) {
910 if (!GetParam().isCXX()) {
911 return;
912 }
913
914 DeclarationMatcher IsDerivedFromX = cxxRecordDecl(isDerivedFrom(BaseName: "X"));
915
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));
925
926 DeclarationMatcher IsZDerivedFromX =
927 cxxRecordDecl(hasName(Name: "Z"), isDerivedFrom(BaseName: "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));
933
934 DeclarationMatcher IsDirectlyDerivedFromX =
935 cxxRecordDecl(isDirectlyDerivedFrom(BaseName: "X"));
936
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));
943
944 DeclarationMatcher IsAX = cxxRecordDecl(isSameOrDerivedFrom(BaseName: "X"));
945
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));
951
952 DeclarationMatcher ZIsDerivedFromX =
953 cxxRecordDecl(hasName(Name: "Z"), isDerivedFrom(BaseName: "X"));
954 DeclarationMatcher ZIsDirectlyDerivedFromX =
955 cxxRecordDecl(hasName(Name: "Z"), isDirectlyDerivedFrom(BaseName: "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"))))));
1093
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")))))));
1119
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"))));
1148
1149 EXPECT_TRUE(matches(
1150 "class X {}; class Y : public X {};",
1151 cxxRecordDecl(isDerivedFrom(recordDecl(hasName("X")).bind("test")))));
1152
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"))))));
1157}
1158
1159TEST_P(ASTMatchersTest, IsDerivedFrom_EmptyName) {
1160 if (!GetParam().isCXX()) {
1161 return;
1162 }
1163
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(""))));
1168}
1169
1170TEST_P(ASTMatchersTest, IsDerivedFrom_ObjC) {
1171 DeclarationMatcher IsDerivedFromX = objcInterfaceDecl(isDerivedFrom(BaseName: "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));
1188
1189 DeclarationMatcher IsDirectlyDerivedFromX =
1190 objcInterfaceDecl(isDirectlyDerivedFrom(BaseName: "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));
1209
1210 DeclarationMatcher IsAX = objcInterfaceDecl(isSameOrDerivedFrom(BaseName: "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));
1216
1217 DeclarationMatcher ZIsDerivedFromX =
1218 objcInterfaceDecl(hasName(Name: "Z"), isDerivedFrom(BaseName: "X"));
1219 DeclarationMatcher ZIsDirectlyDerivedFromX =
1220 objcInterfaceDecl(hasName(Name: "Z"), isDirectlyDerivedFrom(BaseName: "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));
1279}
1280
1281TEST_P(ASTMatchersTest, IsLambda) {
1282 if (!GetParam().isCXX11OrLater()) {
1283 return;
1284 }
1285
1286 const auto IsLambda = cxxMethodDecl(ofClass(InnerMatcher: cxxRecordDecl(isLambda())));
1287 EXPECT_TRUE(matches("auto x = []{};", IsLambda));
1288 EXPECT_TRUE(notMatches("struct S { void operator()() const; };", IsLambda));
1289}
1290
1291TEST_P(ASTMatchersTest, Bind) {
1292 DeclarationMatcher ClassX = has(recordDecl(hasName(Name: "::X")).bind(ID: "x"));
1293
1294 EXPECT_TRUE(matchAndVerifyResultTrue(
1295 "class X {};", ClassX,
1296 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("x")));
1297
1298 EXPECT_TRUE(matchAndVerifyResultFalse(
1299 "class X {};", ClassX,
1300 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("other-id")));
1301
1302 TypeMatcher TypeAHasClassB = hasDeclaration(
1303 InnerMatcher: recordDecl(hasName(Name: "A"), has(recordDecl(hasName(Name: "B")).bind(ID: "b"))));
1304
1305 EXPECT_TRUE(matchAndVerifyResultTrue(
1306 "class A { public: A *a; class B {}; };", TypeAHasClassB,
1307 std::make_unique<VerifyIdIsBoundTo<Decl>>("b")));
1308
1309 StatementMatcher MethodX =
1310 callExpr(callee(InnerMatcher: cxxMethodDecl(hasName(Name: "x")))).bind(ID: "x");
1311
1312 EXPECT_TRUE(matchAndVerifyResultTrue(
1313 "class A { void x() { x(); } };", MethodX,
1314 std::make_unique<VerifyIdIsBoundTo<CXXMemberCallExpr>>("x")));
1315}
1316
1317TEST_P(ASTMatchersTest, Bind_SameNameInAlternatives) {
1318 StatementMatcher matcher = anyOf(
1319 binaryOperator(hasOperatorName(Name: "+"), hasLHS(InnerMatcher: expr().bind(ID: "x")),
1320 hasRHS(InnerMatcher: integerLiteral(equals(Value: 0)))),
1321 binaryOperator(hasOperatorName(Name: "+"), hasLHS(InnerMatcher: integerLiteral(equals(Value: 0))),
1322 hasRHS(InnerMatcher: expr().bind(ID: "x"))));
1323
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")));
1329}
1330
1331TEST_P(ASTMatchersTest, Bind_BindsIDForMemoizedResults) {
1332 // Using the same matcher in two match expressions will make memoization
1333 // kick in.
1334 DeclarationMatcher ClassX = recordDecl(hasName(Name: "X")).bind(ID: "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)));
1341}
1342
1343TEST_P(ASTMatchersTest, HasType_MatchesAsString) {
1344 if (!GetParam().isCXX()) {
1345 // FIXME: Add a test for `hasType()` that does not depend on C++.
1346 return;
1347 }
1348
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")))));
1359}
1360
1361TEST_P(ASTMatchersTest, HasOverloadedOperatorName) {
1362 if (!GetParam().isCXX()) {
1363 return;
1364 }
1365
1366 StatementMatcher OpCallAndAnd =
1367 cxxOperatorCallExpr(hasOverloadedOperatorName(Name: "&&"));
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(Name: "<<"));
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(Name: "*"));
1380 EXPECT_TRUE(
1381 matches("class Y; int operator*(Y &); void f(Y &y) { *y; }", OpStarCall));
1382 DeclarationMatcher ClassWithOpStar =
1383 cxxRecordDecl(hasMethod(InnerMatcher: hasOverloadedOperatorName(Name: "*")));
1384 EXPECT_TRUE(matches("class Y { int operator*(); };", ClassWithOpStar));
1385 EXPECT_TRUE(notMatches("class Y { void myOperator(); };", ClassWithOpStar));
1386 DeclarationMatcher AnyOpStar = functionDecl(hasOverloadedOperatorName(Name: "*"));
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));
1395}
1396
1397TEST_P(ASTMatchersTest, HasOverloadedOperatorName_MatchesNestedCalls) {
1398 if (!GetParam().isCXX()) {
1399 return;
1400 }
1401
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()))));
1417}
1418
1419TEST_P(ASTMatchersTest, HasLocalStorage) {
1420 auto M = varDecl(hasName(Name: "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));
1424}
1425
1426TEST_P(ASTMatchersTest, HasGlobalStorage) {
1427 auto M = varDecl(hasName(Name: "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));
1431}
1432
1433TEST_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));
1439}
1440
1441TEST_P(ASTMatchersTest, IsInitCapture) {
1442 if (!GetParam().isCXX11OrLater()) {
1443 return;
1444 }
1445 auto M = varDecl(hasName(Name: "vd"), isInitCapture());
1446 EXPECT_TRUE(notMatches(
1447 "int main() { int vd = 3; auto f = [vd]() { return vd; }; }", M));
1448
1449 if (!GetParam().isCXX14OrLater()) {
1450 return;
1451 }
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));
1455}
1456
1457TEST_P(ASTMatchersTest, StorageDuration) {
1458 StringRef T =
1459 "void f() { int x; static int y; } int a;static int b;extern int c;";
1460
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())));
1466
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())));
1472
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())));
1477}
1478
1479TEST_P(ASTMatchersTest, VarDecl_MatchesFunctionParameter) {
1480 EXPECT_TRUE(matches("void f(int i) {}", varDecl(hasName("i"))));
1481}
1482
1483TEST_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")))))));
1494}
1495
1496TEST_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()))))))));
1502}
1503
1504TEST_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;
1509 }
1510
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()))))))));
1516}
1517
1518TEST_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()))));
1522}
1523
1524TEST_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()))));
1528}
1529
1530TEST_P(ASTMatchersTest, IsAnyPointer_MatchesPointers) {
1531 if (!GetParam().isCXX11OrLater()) {
1532 // FIXME: Add a test for `isAnyPointer()` that does not depend on C++.
1533 return;
1534 }
1535
1536 EXPECT_TRUE(matches("int* i = nullptr;", varDecl(hasType(isAnyPointer()))));
1537}
1538
1539TEST_P(ASTMatchersTest, IsAnyPointer_MatchesObjcPointer) {
1540 EXPECT_TRUE(matchesObjC("@interface Foo @end Foo *f;",
1541 varDecl(hasType(isAnyPointer()))));
1542}
1543
1544TEST_P(ASTMatchersTest, IsAnyPointer_ReportsNoFalsePositives) {
1545 EXPECT_TRUE(notMatches("int i = 0;", varDecl(hasType(isAnyPointer()))));
1546}
1547
1548TEST_P(ASTMatchersTest, IsAnyCharacter_MatchesCharacters) {
1549 EXPECT_TRUE(matches("char i = 0;", varDecl(hasType(isAnyCharacter()))));
1550}
1551
1552TEST_P(ASTMatchersTest, IsAnyCharacter_ReportsNoFalsePositives) {
1553 EXPECT_TRUE(notMatches("int i;", varDecl(hasType(isAnyCharacter()))));
1554}
1555
1556TEST_P(ASTMatchersTest, IsArrow_MatchesMemberVariablesViaArrow) {
1557 if (!GetParam().isCXX()) {
1558 // FIXME: Add a test for `isArrow()` that does not depend on C++.
1559 return;
1560 }
1561 if (GetParam().hasDelayedTemplateParsing()) {
1562 // FIXME: Fix this test to work with delayed template parsing.
1563 return;
1564 }
1565
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(matches("template <class T> class Y { void x() { this->m; } };",
1573 cxxDependentScopeMemberExpr(isArrow())));
1574 EXPECT_TRUE(
1575 notMatches("template <class T> class Y { void x() { (*this).m; } };",
1576 cxxDependentScopeMemberExpr(isArrow())));
1577}
1578
1579TEST_P(ASTMatchersTest, IsArrow_MatchesStaticMemberVariablesViaArrow) {
1580 if (!GetParam().isCXX()) {
1581 // FIXME: Add a test for `isArrow()` that does not depend on C++.
1582 return;
1583 }
1584
1585 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
1586 memberExpr(isArrow())));
1587 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
1588 memberExpr(isArrow())));
1589 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } static int y; };",
1590 memberExpr(isArrow())));
1591}
1592
1593TEST_P(ASTMatchersTest, IsArrow_MatchesMemberCallsViaArrow) {
1594 if (!GetParam().isCXX()) {
1595 // FIXME: Add a test for `isArrow()` that does not depend on C++.
1596 return;
1597 }
1598 if (GetParam().hasDelayedTemplateParsing()) {
1599 // FIXME: Fix this test to work with delayed template parsing.
1600 return;
1601 }
1602
1603 EXPECT_TRUE(
1604 matches("class Y { void x() { this->x(); } };", memberExpr(isArrow())));
1605 EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpr(isArrow())));
1606 EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",
1607 memberExpr(isArrow())));
1608 EXPECT_TRUE(
1609 matches("class Y { template <class T> void x() { this->x<T>(); } };",
1610 unresolvedMemberExpr(isArrow())));
1611 EXPECT_TRUE(matches("class Y { template <class T> void x() { x<T>(); } };",
1612 unresolvedMemberExpr(isArrow())));
1613 EXPECT_TRUE(
1614 notMatches("class Y { template <class T> void x() { (*this).x<T>(); } };",
1615 unresolvedMemberExpr(isArrow())));
1616}
1617
1618TEST_P(ASTMatchersTest, IsExplicit_CXXConversionDecl) {
1619 if (!GetParam().isCXX11OrLater()) {
1620 return;
1621 }
1622
1623 EXPECT_TRUE(matches("struct S { explicit operator int(); };",
1624 cxxConversionDecl(isExplicit())));
1625 EXPECT_TRUE(notMatches("struct S { operator int(); };",
1626 cxxConversionDecl(isExplicit())));
1627}
1628
1629TEST_P(ASTMatchersTest, IsExplicit_CXXConversionDecl_CXX20) {
1630 if (!GetParam().isCXX20OrLater()) {
1631 return;
1632 }
1633
1634 EXPECT_TRUE(
1635 notMatches("template<bool b> struct S { explicit(b) operator int(); };",
1636 cxxConversionDecl(isExplicit())));
1637 EXPECT_TRUE(matches("struct S { explicit(true) operator int(); };",
1638 cxxConversionDecl(isExplicit())));
1639 EXPECT_TRUE(notMatches("struct S { explicit(false) operator int(); };",
1640 cxxConversionDecl(isExplicit())));
1641}
1642
1643TEST_P(ASTMatchersTest, ArgumentCountAtLeast_CallExpr) {
1644 StatementMatcher Call2PlusArgs = callExpr(argumentCountAtLeast(N: 2));
1645
1646 EXPECT_TRUE(notMatches("void x(void) { x(); }", Call2PlusArgs));
1647 EXPECT_TRUE(notMatches("void x(int) { x(0); }", Call2PlusArgs));
1648 EXPECT_TRUE(matches("void x(int, int) { x(0, 0); }", Call2PlusArgs));
1649 EXPECT_TRUE(matches("void x(int, int, int) { x(0, 0, 0); }", Call2PlusArgs));
1650
1651 if (!GetParam().isCXX()) {
1652 return;
1653 }
1654
1655 EXPECT_TRUE(
1656 notMatches("void x(int = 1) { x(); }", traverse(TK_AsIs, Call2PlusArgs)));
1657 EXPECT_TRUE(matches("void x(int, int = 1) { x(0); }",
1658 traverse(TK_AsIs, Call2PlusArgs)));
1659 EXPECT_TRUE(matches("void x(int, int = 1, int = 1) { x(0); }",
1660 traverse(TK_AsIs, Call2PlusArgs)));
1661 EXPECT_TRUE(matches("void x(int, int, int = 1) { x(0, 0); }",
1662 traverse(TK_AsIs, Call2PlusArgs)));
1663 EXPECT_TRUE(matches("void x(int, int, int, int = 1) { x(0, 0, 0); }",
1664 traverse(TK_AsIs, Call2PlusArgs)));
1665
1666 EXPECT_TRUE(
1667 notMatches("void x(int = 1) { x(); }",
1668 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));
1669 EXPECT_TRUE(
1670 notMatches("void x(int, int = 1) { x(0); }",
1671 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));
1672 EXPECT_TRUE(
1673 notMatches("void x(int, int = 1, int = 1) { x(0); }",
1674 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));
1675 EXPECT_TRUE(matches("void x(int, int, int = 1) { x(0, 0); }",
1676 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));
1677 EXPECT_TRUE(matches("void x(int, int, int, int = 1) { x(0, 0, 0); }",
1678 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));
1679}
1680
1681TEST_P(ASTMatchersTest, ArgumentCountAtLeast_CallExpr_CXX) {
1682 if (!GetParam().isCXX()) {
1683 return;
1684 }
1685
1686 StatementMatcher Call2PlusArgs = callExpr(argumentCountAtLeast(N: 2));
1687 EXPECT_TRUE(notMatches("class X { void x() { x(); } };", Call2PlusArgs));
1688 EXPECT_TRUE(notMatches("class X { void x(int) { x(0); } };", Call2PlusArgs));
1689 EXPECT_TRUE(
1690 matches("class X { void x(int, int) { x(0, 0); } };", Call2PlusArgs));
1691 EXPECT_TRUE(matches("class X { void x(int, int, int) { x(0, 0, 0); } };",
1692 Call2PlusArgs));
1693
1694 EXPECT_TRUE(notMatches("class X { void x(int = 1) { x(0); } };",
1695 traverse(TK_AsIs, Call2PlusArgs)));
1696 EXPECT_TRUE(matches("class X { void x(int, int = 1) { x(0); } };",
1697 traverse(TK_AsIs, Call2PlusArgs)));
1698 EXPECT_TRUE(matches("class X { void x(int, int = 1, int = 1) { x(0); } };",
1699 traverse(TK_AsIs, Call2PlusArgs)));
1700 EXPECT_TRUE(matches("class X { void x(int, int, int = 1) { x(0, 0); } };",
1701 traverse(TK_AsIs, Call2PlusArgs)));
1702 EXPECT_TRUE(
1703 matches("class X { void x(int, int, int, int = 1) { x(0, 0, 0); } };",
1704 traverse(TK_AsIs, Call2PlusArgs)));
1705
1706 EXPECT_TRUE(
1707 notMatches("class X { void x(int = 1) { x(0); } };",
1708 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));
1709 EXPECT_TRUE(
1710 notMatches("class X { void x(int, int = 1) { x(0); } };",
1711 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));
1712 EXPECT_TRUE(
1713 notMatches("class X { void x(int, int = 1, int = 1) { x(0); } };",
1714 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));
1715 EXPECT_TRUE(matches("class X { void x(int, int, int = 1) { x(0, 0); } };",
1716 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));
1717 EXPECT_TRUE(
1718 matches("class X { void x(int, int, int, int = 1) { x(0, 0, 0); } };",
1719 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));
1720
1721 EXPECT_TRUE(
1722 notMatches("class X { static void x() { x(); } };", Call2PlusArgs));
1723 EXPECT_TRUE(
1724 notMatches("class X { static void x(int) { x(0); } };", Call2PlusArgs));
1725 EXPECT_TRUE(matches("class X { static void x(int, int) { x(0, 0); } };",
1726 Call2PlusArgs));
1727 EXPECT_TRUE(
1728 matches("class X { static void x(int, int, int) { x(0, 0, 0); } };",
1729 Call2PlusArgs));
1730}
1731
1732TEST_P(ASTMatchersTest, ArgumentCountIs_CallExpr) {
1733 StatementMatcher Call1Arg = callExpr(argumentCountIs(N: 1));
1734
1735 EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg));
1736 EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg));
1737}
1738
1739TEST_P(ASTMatchersTest, ArgumentCountIs_CallExpr_CXX) {
1740 if (!GetParam().isCXX()) {
1741 return;
1742 }
1743
1744 StatementMatcher Call1Arg = callExpr(argumentCountIs(N: 1));
1745 EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg));
1746}
1747
1748TEST_P(ASTMatchersTest, ParameterCountIs) {
1749 DeclarationMatcher Function1Arg = functionDecl(parameterCountIs(N: 1));
1750 EXPECT_TRUE(matches("void f(int i) {}", Function1Arg));
1751 EXPECT_TRUE(notMatches("void f() {}", Function1Arg));
1752 EXPECT_TRUE(notMatches("void f(int i, int j, int k) {}", Function1Arg));
1753 EXPECT_TRUE(matches("void f(int i, ...) {};", Function1Arg));
1754}
1755
1756TEST_P(ASTMatchersTest, ParameterCountIs_CXX) {
1757 if (!GetParam().isCXX()) {
1758 return;
1759 }
1760
1761 DeclarationMatcher Function1Arg = functionDecl(parameterCountIs(N: 1));
1762 EXPECT_TRUE(matches("class X { void f(int i) {} };", Function1Arg));
1763}
1764
1765TEST_P(ASTMatchersTest, References) {
1766 if (!GetParam().isCXX()) {
1767 // FIXME: Add a test for `references()` that does not depend on C++.
1768 return;
1769 }
1770
1771 DeclarationMatcher ReferenceClassX =
1772 varDecl(hasType(InnerMatcher: references(InnerMatcher: recordDecl(hasName(Name: "X")))));
1773 EXPECT_TRUE(
1774 matches("class X {}; void y(X y) { X &x = y; }", ReferenceClassX));
1775 EXPECT_TRUE(
1776 matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
1777 // The match here is on the implicit copy constructor code for
1778 // class X, not on code 'X x = y'.
1779 EXPECT_TRUE(matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
1780 EXPECT_TRUE(notMatches("class X {}; extern X x;", ReferenceClassX));
1781 EXPECT_TRUE(
1782 notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
1783}
1784
1785TEST_P(ASTMatchersTest, HasLocalQualifiers) {
1786 if (!GetParam().isCXX11OrLater()) {
1787 // FIXME: Add a test for `hasLocalQualifiers()` that does not depend on C++.
1788 return;
1789 }
1790
1791 EXPECT_TRUE(notMatches("typedef const int const_int; const_int i = 1;",
1792 varDecl(hasType(hasLocalQualifiers()))));
1793 EXPECT_TRUE(matches("int *const j = nullptr;",
1794 varDecl(hasType(hasLocalQualifiers()))));
1795 EXPECT_TRUE(
1796 matches("int *volatile k;", varDecl(hasType(hasLocalQualifiers()))));
1797 EXPECT_TRUE(notMatches("int m;", varDecl(hasType(hasLocalQualifiers()))));
1798}
1799
1800TEST_P(ASTMatchersTest, IsExternC_MatchesExternCFunctionDeclarations) {
1801 if (!GetParam().isCXX()) {
1802 return;
1803 }
1804
1805 EXPECT_TRUE(matches("extern \"C\" void f() {}", functionDecl(isExternC())));
1806 EXPECT_TRUE(
1807 matches("extern \"C\" { void f() {} }", functionDecl(isExternC())));
1808 EXPECT_TRUE(notMatches("void f() {}", functionDecl(isExternC())));
1809}
1810
1811TEST_P(ASTMatchersTest, IsExternC_MatchesExternCVariableDeclarations) {
1812 if (!GetParam().isCXX()) {
1813 return;
1814 }
1815
1816 EXPECT_TRUE(matches("extern \"C\" int i;", varDecl(isExternC())));
1817 EXPECT_TRUE(matches("extern \"C\" { int i; }", varDecl(isExternC())));
1818 EXPECT_TRUE(notMatches("int i;", varDecl(isExternC())));
1819}
1820
1821TEST_P(ASTMatchersTest, IsStaticStorageClass) {
1822 EXPECT_TRUE(
1823 matches("static void f() {}", functionDecl(isStaticStorageClass())));
1824 EXPECT_TRUE(matches("static int i = 1;", varDecl(isStaticStorageClass())));
1825 EXPECT_TRUE(notMatches("int i = 1;", varDecl(isStaticStorageClass())));
1826 EXPECT_TRUE(notMatches("extern int i;", varDecl(isStaticStorageClass())));
1827 EXPECT_TRUE(notMatches("void f() {}", functionDecl(isStaticStorageClass())));
1828}
1829
1830TEST_P(ASTMatchersTest, IsDefaulted) {
1831 if (!GetParam().isCXX()) {
1832 return;
1833 }
1834
1835 EXPECT_TRUE(notMatches("class A { ~A(); };",
1836 functionDecl(hasName("~A"), isDefaulted())));
1837 EXPECT_TRUE(matches("class B { ~B() = default; };",
1838 functionDecl(hasName("~B"), isDefaulted())));
1839}
1840
1841TEST_P(ASTMatchersTest, IsDeleted) {
1842 if (!GetParam().isCXX()) {
1843 return;
1844 }
1845
1846 EXPECT_TRUE(
1847 notMatches("void Func();", functionDecl(hasName("Func"), isDeleted())));
1848 EXPECT_TRUE(matches("void Func() = delete;",
1849 functionDecl(hasName("Func"), isDeleted())));
1850}
1851
1852TEST_P(ASTMatchersTest, IsNoThrow_DynamicExceptionSpec) {
1853 if (!GetParam().supportsCXXDynamicExceptionSpecification()) {
1854 return;
1855 }
1856
1857 EXPECT_TRUE(notMatches("void f();", functionDecl(isNoThrow())));
1858 EXPECT_TRUE(notMatches("void f() throw(int);", functionDecl(isNoThrow())));
1859 EXPECT_TRUE(matches("void f() throw();", functionDecl(isNoThrow())));
1860
1861 EXPECT_TRUE(notMatches("void f();", functionProtoType(isNoThrow())));
1862 EXPECT_TRUE(
1863 notMatches("void f() throw(int);", functionProtoType(isNoThrow())));
1864 EXPECT_TRUE(matches("void f() throw();", functionProtoType(isNoThrow())));
1865}
1866
1867TEST_P(ASTMatchersTest, IsNoThrow_CXX11) {
1868 if (!GetParam().isCXX11OrLater()) {
1869 return;
1870 }
1871
1872 EXPECT_TRUE(
1873 notMatches("void f() noexcept(false);", functionDecl(isNoThrow())));
1874 EXPECT_TRUE(matches("void f() noexcept;", functionDecl(isNoThrow())));
1875
1876 EXPECT_TRUE(
1877 notMatches("void f() noexcept(false);", functionProtoType(isNoThrow())));
1878 EXPECT_TRUE(matches("void f() noexcept;", functionProtoType(isNoThrow())));
1879}
1880
1881TEST_P(ASTMatchersTest, IsConsteval) {
1882 if (!GetParam().isCXX20OrLater())
1883 return;
1884
1885 EXPECT_TRUE(matches("consteval int bar();",
1886 functionDecl(hasName("bar"), isConsteval())));
1887 EXPECT_TRUE(notMatches("constexpr int bar();",
1888 functionDecl(hasName("bar"), isConsteval())));
1889 EXPECT_TRUE(
1890 notMatches("int bar();", functionDecl(hasName("bar"), isConsteval())));
1891}
1892
1893TEST_P(ASTMatchersTest, IsConsteval_MatchesIfConsteval) {
1894 if (!GetParam().isCXX20OrLater())
1895 return;
1896
1897 EXPECT_TRUE(matches("void baz() { if consteval {} }", ifStmt(isConsteval())));
1898 EXPECT_TRUE(
1899 matches("void baz() { if ! consteval {} }", ifStmt(isConsteval())));
1900 EXPECT_TRUE(matches("void baz() { if ! consteval {} else {} }",
1901 ifStmt(isConsteval())));
1902 EXPECT_TRUE(
1903 matches("void baz() { if not consteval {} }", ifStmt(isConsteval())));
1904 EXPECT_TRUE(notMatches("void baz() { if constexpr(1 > 0) {} }",
1905 ifStmt(isConsteval())));
1906 EXPECT_TRUE(
1907 notMatches("void baz() { if (1 > 0) {} }", ifStmt(isConsteval())));
1908}
1909
1910TEST_P(ASTMatchersTest, IsConstexpr) {
1911 if (!GetParam().isCXX11OrLater()) {
1912 return;
1913 }
1914
1915 EXPECT_TRUE(matches("constexpr int foo = 42;",
1916 varDecl(hasName("foo"), isConstexpr())));
1917 EXPECT_TRUE(matches("constexpr int bar();",
1918 functionDecl(hasName("bar"), isConstexpr())));
1919}
1920
1921TEST_P(ASTMatchersTest, IsConstexpr_MatchesIfConstexpr) {
1922 if (!GetParam().isCXX17OrLater()) {
1923 return;
1924 }
1925
1926 EXPECT_TRUE(
1927 matches("void baz() { if constexpr(1 > 0) {} }", ifStmt(isConstexpr())));
1928 EXPECT_TRUE(
1929 notMatches("void baz() { if (1 > 0) {} }", ifStmt(isConstexpr())));
1930}
1931
1932TEST_P(ASTMatchersTest, IsConstinit) {
1933 if (!GetParam().isCXX20OrLater())
1934 return;
1935
1936 EXPECT_TRUE(matches("constinit int foo = 1;",
1937 varDecl(hasName("foo"), isConstinit())));
1938 EXPECT_TRUE(matches("extern constinit int foo;",
1939 varDecl(hasName("foo"), isConstinit())));
1940 EXPECT_TRUE(matches("constinit const char* foo = \"bar\";",
1941 varDecl(hasName("foo"), isConstinit())));
1942 EXPECT_TRUE(
1943 notMatches("[[clang::require_constant_initialization]] int foo = 1;",
1944 varDecl(hasName("foo"), isConstinit())));
1945 EXPECT_TRUE(notMatches("constexpr int foo = 1;",
1946 varDecl(hasName("foo"), isConstinit())));
1947 EXPECT_TRUE(notMatches("static inline int foo = 1;",
1948 varDecl(hasName("foo"), isConstinit())));
1949}
1950
1951TEST_P(ASTMatchersTest, HasInitStatement_MatchesSelectionInitializers) {
1952 EXPECT_TRUE(notMatches("void baz() { if (1 > 0) {} }",
1953 ifStmt(hasInitStatement(anything()))));
1954 EXPECT_TRUE(notMatches("void baz(int i) { switch (i) { default: break; } }",
1955 switchStmt(hasInitStatement(anything()))));
1956}
1957
1958TEST_P(ASTMatchersTest, HasInitStatement_MatchesSelectionInitializers_CXX) {
1959 if (!GetParam().isCXX()) {
1960 return;
1961 }
1962
1963 EXPECT_TRUE(notMatches("void baz() { if (int i = 1) {} }",
1964 ifStmt(hasInitStatement(anything()))));
1965}
1966
1967TEST_P(ASTMatchersTest, HasInitStatement_MatchesSelectionInitializers_CXX17) {
1968 if (!GetParam().isCXX17OrLater()) {
1969 return;
1970 }
1971
1972 EXPECT_TRUE(matches("void baz() { if (int i = 1; i > 0) {} }",
1973 ifStmt(hasInitStatement(anything()))));
1974 EXPECT_TRUE(
1975 matches("void baz(int i) { switch (int j = i; j) { default: break; } }",
1976 switchStmt(hasInitStatement(anything()))));
1977}
1978
1979TEST_P(ASTMatchersTest, HasInitStatement_MatchesRangeForInitializers) {
1980 if (!GetParam().isCXX20OrLater()) {
1981 return;
1982 }
1983
1984 EXPECT_TRUE(matches("void baz() {"
1985 "int items[] = {};"
1986 "for (auto &arr = items; auto &item : arr) {}"
1987 "}",
1988 cxxForRangeStmt(hasInitStatement(anything()))));
1989 EXPECT_TRUE(notMatches("void baz() {"
1990 "int items[] = {};"
1991 "for (auto &item : items) {}"
1992 "}",
1993 cxxForRangeStmt(hasInitStatement(anything()))));
1994}
1995
1996TEST_P(ASTMatchersTest, TemplateArgumentCountIs) {
1997 if (!GetParam().isCXX()) {
1998 return;
1999 }
2000
2001 EXPECT_TRUE(
2002 matches("template<typename T> struct C {}; C<int> c;",
2003 classTemplateSpecializationDecl(templateArgumentCountIs(1))));
2004 EXPECT_TRUE(
2005 notMatches("template<typename T> struct C {}; C<int> c;",
2006 classTemplateSpecializationDecl(templateArgumentCountIs(2))));
2007
2008 EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
2009 templateSpecializationType(templateArgumentCountIs(1))));
2010 EXPECT_TRUE(
2011 notMatches("template<typename T> struct C {}; C<int> c;",
2012 templateSpecializationType(templateArgumentCountIs(2))));
2013}
2014
2015TEST_P(ASTMatchersTest, IsIntegral) {
2016 if (!GetParam().isCXX()) {
2017 return;
2018 }
2019
2020 EXPECT_TRUE(matches(
2021 "template<int T> struct C {}; C<42> c;",
2022 classTemplateSpecializationDecl(hasAnyTemplateArgument(isIntegral()))));
2023 EXPECT_TRUE(notMatches("template<typename T> struct C {}; C<int> c;",
2024 classTemplateSpecializationDecl(hasAnyTemplateArgument(
2025 templateArgument(isIntegral())))));
2026}
2027
2028TEST_P(ASTMatchersTest, EqualsIntegralValue) {
2029 if (!GetParam().isCXX()) {
2030 return;
2031 }
2032
2033 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
2034 classTemplateSpecializationDecl(
2035 hasAnyTemplateArgument(equalsIntegralValue("42")))));
2036 EXPECT_TRUE(matches("template<int T> struct C {}; C<-42> c;",
2037 classTemplateSpecializationDecl(
2038 hasAnyTemplateArgument(equalsIntegralValue("-42")))));
2039 EXPECT_TRUE(matches("template<int T> struct C {}; C<-0042> c;",
2040 classTemplateSpecializationDecl(
2041 hasAnyTemplateArgument(equalsIntegralValue("-34")))));
2042 EXPECT_TRUE(notMatches("template<int T> struct C {}; C<42> c;",
2043 classTemplateSpecializationDecl(hasAnyTemplateArgument(
2044 equalsIntegralValue("0042")))));
2045}
2046
2047TEST_P(ASTMatchersTest, AccessSpecDecl) {
2048 if (!GetParam().isCXX()) {
2049 return;
2050 }
2051
2052 EXPECT_TRUE(matches("class C { public: int i; };", accessSpecDecl()));
2053 EXPECT_TRUE(
2054 matches("class C { public: int i; };", accessSpecDecl(isPublic())));
2055 EXPECT_TRUE(
2056 notMatches("class C { public: int i; };", accessSpecDecl(isProtected())));
2057 EXPECT_TRUE(
2058 notMatches("class C { public: int i; };", accessSpecDecl(isPrivate())));
2059
2060 EXPECT_TRUE(notMatches("class C { int i; };", accessSpecDecl()));
2061}
2062
2063TEST_P(ASTMatchersTest, IsFinal) {
2064 if (!GetParam().isCXX11OrLater()) {
2065 return;
2066 }
2067
2068 EXPECT_TRUE(matches("class X final {};", cxxRecordDecl(isFinal())));
2069 EXPECT_TRUE(matches("class X { virtual void f() final; };",
2070 cxxMethodDecl(isFinal())));
2071 EXPECT_TRUE(notMatches("class X {};", cxxRecordDecl(isFinal())));
2072 EXPECT_TRUE(
2073 notMatches("class X { virtual void f(); };", cxxMethodDecl(isFinal())));
2074}
2075
2076TEST_P(ASTMatchersTest, IsVirtual) {
2077 if (!GetParam().isCXX()) {
2078 return;
2079 }
2080
2081 EXPECT_TRUE(matches("class X { virtual int f(); };",
2082 cxxMethodDecl(isVirtual(), hasName("::X::f"))));
2083 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isVirtual())));
2084}
2085
2086TEST_P(ASTMatchersTest, IsVirtualAsWritten) {
2087 if (!GetParam().isCXX()) {
2088 return;
2089 }
2090
2091 EXPECT_TRUE(matches("class A { virtual int f(); };"
2092 "class B : public A { int f(); };",
2093 cxxMethodDecl(isVirtualAsWritten(), hasName("::A::f"))));
2094 EXPECT_TRUE(
2095 notMatches("class A { virtual int f(); };"
2096 "class B : public A { int f(); };",
2097 cxxMethodDecl(isVirtualAsWritten(), hasName("::B::f"))));
2098}
2099
2100TEST_P(ASTMatchersTest, IsPure) {
2101 if (!GetParam().isCXX()) {
2102 return;
2103 }
2104
2105 EXPECT_TRUE(matches("class X { virtual int f() = 0; };",
2106 cxxMethodDecl(isPure(), hasName("::X::f"))));
2107 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isPure())));
2108}
2109
2110TEST_P(ASTMatchersTest, IsExplicitObjectMemberFunction) {
2111 if (!GetParam().isCXX23OrLater()) {
2112 return;
2113 }
2114
2115 auto ExpObjParamFn = cxxMethodDecl(isExplicitObjectMemberFunction());
2116 EXPECT_TRUE(
2117 notMatches("struct A { static int operator()(int); };", ExpObjParamFn));
2118 EXPECT_TRUE(notMatches("struct A { int operator+(int); };", ExpObjParamFn));
2119 EXPECT_TRUE(
2120 matches("struct A { int operator-(this A, int); };", ExpObjParamFn));
2121 EXPECT_TRUE(matches("struct A { void fun(this A &&self); };", ExpObjParamFn));
2122}
2123
2124TEST_P(ASTMatchersTest, IsCopyAssignmentOperator) {
2125 if (!GetParam().isCXX()) {
2126 return;
2127 }
2128
2129 auto CopyAssignment =
2130 cxxMethodDecl(isCopyAssignmentOperator(), unless(isImplicit()));
2131 EXPECT_TRUE(matches("class X { X &operator=(X); };", CopyAssignment));
2132 EXPECT_TRUE(matches("class X { X &operator=(X &); };", CopyAssignment));
2133 EXPECT_TRUE(matches("class X { X &operator=(const X &); };", CopyAssignment));
2134 EXPECT_TRUE(matches("class X { X &operator=(volatile X &); };", //
2135 CopyAssignment));
2136 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &); };",
2137 CopyAssignment));
2138 EXPECT_TRUE(notMatches("class X { X &operator=(X &&); };", CopyAssignment));
2139}
2140
2141TEST_P(ASTMatchersTest, IsMoveAssignmentOperator) {
2142 if (!GetParam().isCXX()) {
2143 return;
2144 }
2145
2146 auto MoveAssignment =
2147 cxxMethodDecl(isMoveAssignmentOperator(), unless(isImplicit()));
2148 EXPECT_TRUE(notMatches("class X { X &operator=(X); };", MoveAssignment));
2149 EXPECT_TRUE(matches("class X { X &operator=(X &&); };", MoveAssignment));
2150 EXPECT_TRUE(matches("class X { X &operator=(const X &&); };", //
2151 MoveAssignment));
2152 EXPECT_TRUE(matches("class X { X &operator=(volatile X &&); };", //
2153 MoveAssignment));
2154 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &&); };",
2155 MoveAssignment));
2156 EXPECT_TRUE(notMatches("class X { X &operator=(X &); };", MoveAssignment));
2157}
2158
2159TEST_P(ASTMatchersTest, IsConst) {
2160 if (!GetParam().isCXX()) {
2161 return;
2162 }
2163
2164 EXPECT_TRUE(
2165 matches("struct A { void foo() const; };", cxxMethodDecl(isConst())));
2166 EXPECT_TRUE(
2167 notMatches("struct A { void foo(); };", cxxMethodDecl(isConst())));
2168}
2169
2170TEST_P(ASTMatchersTest, IsOverride) {
2171 if (!GetParam().isCXX()) {
2172 return;
2173 }
2174
2175 EXPECT_TRUE(matches("class X { virtual int f(); }; "
2176 "class Y : public X { int f(); };",
2177 cxxMethodDecl(isOverride(), hasName("::Y::f"))));
2178 EXPECT_TRUE(notMatches("class X { virtual int f(); }; "
2179 "class Y : public X { int f(); };",
2180 cxxMethodDecl(isOverride(), hasName("::X::f"))));
2181 EXPECT_TRUE(notMatches("class X { int f(); }; "
2182 "class Y : public X { int f(); };",
2183 cxxMethodDecl(isOverride())));
2184 EXPECT_TRUE(notMatches("class X { int f(); int f(int); }; ",
2185 cxxMethodDecl(isOverride())));
2186 EXPECT_TRUE(
2187 matches("template <typename Base> struct Y : Base { void f() override;};",
2188 cxxMethodDecl(isOverride(), hasName("::Y::f"))));
2189}
2190
2191TEST_P(ASTMatchersTest, HasArgument_CXXConstructorDecl) {
2192 if (!GetParam().isCXX()) {
2193 return;
2194 }
2195
2196 auto Constructor = traverse(
2197 TK: TK_AsIs,
2198 InnerMatcher: cxxConstructExpr(hasArgument(N: 0, InnerMatcher: declRefExpr(to(InnerMatcher: varDecl(hasName(Name: "y")))))));
2199
2200 EXPECT_TRUE(matches(
2201 "class X { public: X(int); }; void x() { int y; X x(y); }", Constructor));
2202 EXPECT_TRUE(
2203 matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
2204 Constructor));
2205 EXPECT_TRUE(
2206 matches("class X { public: X(int); }; void x() { int y; X x = y; }",
2207 Constructor));
2208 EXPECT_TRUE(notMatches(
2209 "class X { public: X(int); }; void x() { int z; X x(z); }", Constructor));
2210
2211 StatementMatcher WrongIndex =
2212 traverse(TK: TK_AsIs, InnerMatcher: cxxConstructExpr(hasArgument(
2213 N: 42, InnerMatcher: declRefExpr(to(InnerMatcher: varDecl(hasName(Name: "y")))))));
2214 EXPECT_TRUE(notMatches(
2215 "class X { public: X(int); }; void x() { int y; X x(y); }", WrongIndex));
2216}
2217
2218TEST_P(ASTMatchersTest, ArgumentCountIs_CXXConstructExpr) {
2219 if (!GetParam().isCXX()) {
2220 return;
2221 }
2222
2223 auto Constructor1Arg =
2224 traverse(TK: TK_AsIs, InnerMatcher: cxxConstructExpr(argumentCountIs(N: 1)));
2225
2226 EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x(0); }",
2227 Constructor1Arg));
2228 EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x = X(0); }",
2229 Constructor1Arg));
2230 EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x = 0; }",
2231 Constructor1Arg));
2232 EXPECT_TRUE(
2233 notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
2234 Constructor1Arg));
2235}
2236
2237TEST(ASTMatchersTest, NamesMember_CXXDependentScopeMemberExpr) {
2238
2239 // Member functions:
2240 {
2241 auto Code = "template <typename T> struct S{ void mem(); }; template "
2242 "<typename T> void x() { S<T> s; s.mem(); }";
2243
2244 EXPECT_TRUE(matches(
2245 Code,
2246 cxxDependentScopeMemberExpr(
2247 hasObjectExpression(declRefExpr(hasType(elaboratedType(namesType(
2248 templateSpecializationType(hasDeclaration(classTemplateDecl(
2249 has(cxxRecordDecl(has(cxxMethodDecl(hasName("mem"))
2250 .bind("templMem")))))))))))),
2251 memberHasSameNameAsBoundNode("templMem"))));
2252
2253 EXPECT_TRUE(
2254 matches(Code, cxxDependentScopeMemberExpr(hasMemberName("mem"))));
2255 }
2256
2257 // Member variables:
2258 {
2259 auto Code = "template <typename T> struct S{ int mem; }; template "
2260 "<typename T> void x() { S<T> s; s.mem; }";
2261
2262 EXPECT_TRUE(
2263 matches(Code, cxxDependentScopeMemberExpr(hasMemberName("mem"))));
2264
2265 EXPECT_TRUE(matches(
2266 Code,
2267 cxxDependentScopeMemberExpr(
2268 hasObjectExpression(declRefExpr(
2269 hasType(elaboratedType(namesType(templateSpecializationType(
2270 hasDeclaration(classTemplateDecl(has(cxxRecordDecl(has(
2271 fieldDecl(hasName("mem")).bind("templMem")))))))))))),
2272 memberHasSameNameAsBoundNode("templMem"))));
2273 }
2274
2275 // static member variables:
2276 {
2277 auto Code = "template <typename T> struct S{ static int mem; }; template "
2278 "<typename T> void x() { S<T> s; s.mem; }";
2279
2280 EXPECT_TRUE(
2281 matches(Code, cxxDependentScopeMemberExpr(hasMemberName("mem"))));
2282
2283 EXPECT_TRUE(matches(
2284 Code,
2285 cxxDependentScopeMemberExpr(
2286 hasObjectExpression(declRefExpr(
2287 hasType(elaboratedType(namesType(templateSpecializationType(
2288 hasDeclaration(classTemplateDecl(has(cxxRecordDecl(
2289 has(varDecl(hasName("mem")).bind("templMem")))))))))))),
2290 memberHasSameNameAsBoundNode("templMem"))));
2291 }
2292 {
2293 auto Code = R"cpp(
2294template <typename T>
2295struct S {
2296 bool operator==(int) const { return true; }
2297};
2298
2299template <typename T>
2300void func(T t) {
2301 S<T> s;
2302 s.operator==(1);
2303}
2304)cpp";
2305
2306 EXPECT_TRUE(matches(
2307 Code, cxxDependentScopeMemberExpr(hasMemberName("operator=="))));
2308 }
2309
2310 // other named decl:
2311 {
2312 auto Code = "template <typename T> struct S{ static int mem; }; struct "
2313 "mem{}; template "
2314 "<typename T> void x() { S<T> s; s.mem; }";
2315
2316 EXPECT_TRUE(matches(
2317 Code,
2318 translationUnitDecl(has(cxxRecordDecl(hasName("mem"))),
2319 hasDescendant(cxxDependentScopeMemberExpr()))));
2320
2321 EXPECT_FALSE(matches(
2322 Code,
2323 translationUnitDecl(has(cxxRecordDecl(hasName("mem")).bind("templMem")),
2324 hasDescendant(cxxDependentScopeMemberExpr(
2325 memberHasSameNameAsBoundNode("templMem"))))));
2326 }
2327}
2328
2329TEST(ASTMatchersTest, ArgumentCountIs_CXXUnresolvedConstructExpr) {
2330 const auto *Code =
2331 "template <typename T> struct S{}; template <typename T> void "
2332 "x() { auto s = S<T>(); }";
2333
2334 EXPECT_TRUE(matches(Code, cxxUnresolvedConstructExpr(argumentCountIs(0))));
2335 EXPECT_TRUE(notMatches(Code, cxxUnresolvedConstructExpr(argumentCountIs(1))));
2336}
2337
2338TEST(ASTMatchersTest, HasArgument_CXXUnresolvedConstructExpr) {
2339 const auto *Code =
2340 "template <typename T> struct S{ S(int){} }; template <typename "
2341 "T> void x() { int y; auto s = S<T>(y); }";
2342 EXPECT_TRUE(matches(Code, cxxUnresolvedConstructExpr(hasArgument(
2343 0, declRefExpr(to(varDecl(hasName("y"))))))));
2344 EXPECT_TRUE(
2345 notMatches(Code, cxxUnresolvedConstructExpr(hasArgument(
2346 0, declRefExpr(to(varDecl(hasName("x"))))))));
2347}
2348
2349TEST_P(ASTMatchersTest, IsListInitialization) {
2350 if (!GetParam().isCXX11OrLater()) {
2351 return;
2352 }
2353
2354 auto ConstructorListInit =
2355 traverse(TK: TK_AsIs, InnerMatcher: varDecl(has(cxxConstructExpr(isListInitialization()))));
2356
2357 EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x{0}; }",
2358 ConstructorListInit));
2359 EXPECT_FALSE(matches("class X { public: X(int); }; void x() { X x(0); }",
2360 ConstructorListInit));
2361}
2362
2363TEST_P(ASTMatchersTest, IsImplicit_CXXConstructorDecl) {
2364 if (!GetParam().isCXX()) {
2365 return;
2366 }
2367
2368 // This one doesn't match because the constructor is not added by the
2369 // compiler (it is not needed).
2370 EXPECT_TRUE(notMatches("class Foo { };", cxxConstructorDecl(isImplicit())));
2371 // The compiler added the implicit default constructor.
2372 EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
2373 cxxConstructorDecl(isImplicit())));
2374 EXPECT_TRUE(matches("class Foo { Foo(){} };",
2375 cxxConstructorDecl(unless(isImplicit()))));
2376 // The compiler added an implicit assignment operator.
2377 EXPECT_TRUE(matches("struct A { int x; } a = {0}, b = a; void f() { a = b; }",
2378 cxxMethodDecl(isImplicit(), hasName("operator="))));
2379}
2380
2381TEST_P(ASTMatchersTest, IsExplicit_CXXConstructorDecl) {
2382 if (!GetParam().isCXX()) {
2383 return;
2384 }
2385
2386 EXPECT_TRUE(matches("struct S { explicit S(int); };",
2387 cxxConstructorDecl(isExplicit())));
2388 EXPECT_TRUE(
2389 notMatches("struct S { S(int); };", cxxConstructorDecl(isExplicit())));
2390}
2391
2392TEST_P(ASTMatchersTest, IsExplicit_CXXConstructorDecl_CXX20) {
2393 if (!GetParam().isCXX20OrLater()) {
2394 return;
2395 }
2396
2397 EXPECT_TRUE(notMatches("template<bool b> struct S { explicit(b) S(int);};",
2398 cxxConstructorDecl(isExplicit())));
2399 EXPECT_TRUE(matches("struct S { explicit(true) S(int);};",
2400 cxxConstructorDecl(isExplicit())));
2401 EXPECT_TRUE(notMatches("struct S { explicit(false) S(int);};",
2402 cxxConstructorDecl(isExplicit())));
2403}
2404
2405TEST_P(ASTMatchersTest, IsExplicit_CXXDeductionGuideDecl) {
2406 if (!GetParam().isCXX17OrLater()) {
2407 return;
2408 }
2409
2410 EXPECT_TRUE(notMatches("template<typename T> struct S { S(int);};"
2411 "S(int) -> S<int>;",
2412 cxxDeductionGuideDecl(isExplicit())));
2413 EXPECT_TRUE(matches("template<typename T> struct S { S(int);};"
2414 "explicit S(int) -> S<int>;",
2415 cxxDeductionGuideDecl(isExplicit())));
2416}
2417
2418TEST_P(ASTMatchersTest, IsExplicit_CXXDeductionGuideDecl_CXX20) {
2419 if (!GetParam().isCXX20OrLater()) {
2420 return;
2421 }
2422
2423 EXPECT_TRUE(matches("template<typename T> struct S { S(int);};"
2424 "explicit(true) S(int) -> S<int>;",
2425 cxxDeductionGuideDecl(isExplicit())));
2426 EXPECT_TRUE(notMatches("template<typename T> struct S { S(int);};"
2427 "explicit(false) S(int) -> S<int>;",
2428 cxxDeductionGuideDecl(isExplicit())));
2429 EXPECT_TRUE(
2430 notMatches("template<typename T> struct S { S(int);};"
2431 "template<bool b = true> explicit(b) S(int) -> S<int>;",
2432 cxxDeductionGuideDecl(isExplicit())));
2433}
2434
2435TEST_P(ASTMatchersTest, CXXConstructorDecl_Kinds) {
2436 if (!GetParam().isCXX()) {
2437 return;
2438 }
2439
2440 EXPECT_TRUE(
2441 matches("struct S { S(); };", cxxConstructorDecl(isDefaultConstructor(),
2442 unless(isImplicit()))));
2443 EXPECT_TRUE(notMatches(
2444 "struct S { S(); };",
2445 cxxConstructorDecl(isCopyConstructor(), unless(isImplicit()))));
2446 EXPECT_TRUE(notMatches(
2447 "struct S { S(); };",
2448 cxxConstructorDecl(isMoveConstructor(), unless(isImplicit()))));
2449
2450 EXPECT_TRUE(notMatches(
2451 "struct S { S(const S&); };",
2452 cxxConstructorDecl(isDefaultConstructor(), unless(isImplicit()))));
2453 EXPECT_TRUE(
2454 matches("struct S { S(const S&); };",
2455 cxxConstructorDecl(isCopyConstructor(), unless(isImplicit()))));
2456 EXPECT_TRUE(notMatches(
2457 "struct S { S(const S&); };",
2458 cxxConstructorDecl(isMoveConstructor(), unless(isImplicit()))));
2459
2460 EXPECT_TRUE(notMatches(
2461 "struct S { S(S&&); };",
2462 cxxConstructorDecl(isDefaultConstructor(), unless(isImplicit()))));
2463 EXPECT_TRUE(notMatches(
2464 "struct S { S(S&&); };",
2465 cxxConstructorDecl(isCopyConstructor(), unless(isImplicit()))));
2466 EXPECT_TRUE(
2467 matches("struct S { S(S&&); };",
2468 cxxConstructorDecl(isMoveConstructor(), unless(isImplicit()))));
2469}
2470
2471TEST_P(ASTMatchersTest, IsUserProvided) {
2472 if (!GetParam().isCXX11OrLater()) {
2473 return;
2474 }
2475
2476 EXPECT_TRUE(notMatches("struct S { int X = 0; };",
2477 cxxConstructorDecl(isUserProvided())));
2478 EXPECT_TRUE(notMatches("struct S { S() = default; };",
2479 cxxConstructorDecl(isUserProvided())));
2480 EXPECT_TRUE(notMatches("struct S { S() = delete; };",
2481 cxxConstructorDecl(isUserProvided())));
2482 EXPECT_TRUE(
2483 matches("struct S { S(); };", cxxConstructorDecl(isUserProvided())));
2484 EXPECT_TRUE(matches("struct S { S(); }; S::S(){}",
2485 cxxConstructorDecl(isUserProvided())));
2486}
2487
2488TEST_P(ASTMatchersTest, IsDelegatingConstructor) {
2489 if (!GetParam().isCXX11OrLater()) {
2490 return;
2491 }
2492
2493 EXPECT_TRUE(notMatches("struct S { S(); S(int); int X; };",
2494 cxxConstructorDecl(isDelegatingConstructor())));
2495 EXPECT_TRUE(notMatches("struct S { S(){} S(int X) : X(X) {} int X; };",
2496 cxxConstructorDecl(isDelegatingConstructor())));
2497 EXPECT_TRUE(matches(
2498 "struct S { S() : S(0) {} S(int X) : X(X) {} int X; };",
2499 cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(0))));
2500 EXPECT_TRUE(matches(
2501 "struct S { S(); S(int X); int X; }; S::S(int X) : S() {}",
2502 cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(1))));
2503}
2504
2505TEST_P(ASTMatchersTest, HasSize) {
2506 StatementMatcher Literal = stringLiteral(hasSize(N: 4));
2507 EXPECT_TRUE(matches("const char *s = \"abcd\";", Literal));
2508 // with escaped characters
2509 EXPECT_TRUE(matches("const char *s = \"\x05\x06\x07\x08\";", Literal));
2510 // no matching, too small
2511 EXPECT_TRUE(notMatches("const char *s = \"ab\";", Literal));
2512}
2513
2514TEST_P(ASTMatchersTest, HasSize_CXX) {
2515 if (!GetParam().isCXX()) {
2516 // FIXME: Fix this test to also work in non-C++ language modes.
2517 return;
2518 }
2519
2520 StatementMatcher Literal = stringLiteral(hasSize(N: 4));
2521 // wide string
2522 EXPECT_TRUE(matches("const wchar_t *s = L\"abcd\";", Literal));
2523}
2524
2525TEST_P(ASTMatchersTest, HasName_MatchesNamespaces) {
2526 if (!GetParam().isCXX()) {
2527 return;
2528 }
2529
2530 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
2531 recordDecl(hasName("a::b::C"))));
2532 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
2533 recordDecl(hasName("::a::b::C"))));
2534 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
2535 recordDecl(hasName("b::C"))));
2536 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
2537 recordDecl(hasName("C"))));
2538 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2539 recordDecl(hasName("c::b::C"))));
2540 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2541 recordDecl(hasName("a::c::C"))));
2542 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2543 recordDecl(hasName("a::b::A"))));
2544 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2545 recordDecl(hasName("::C"))));
2546 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2547 recordDecl(hasName("::b::C"))));
2548 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2549 recordDecl(hasName("z::a::b::C"))));
2550 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2551 recordDecl(hasName("a+b::C"))));
2552 EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
2553 recordDecl(hasName("C"))));
2554}
2555
2556TEST_P(ASTMatchersTest, HasName_MatchesOuterClasses) {
2557 if (!GetParam().isCXX()) {
2558 return;
2559 }
2560
2561 EXPECT_TRUE(matches("class A { class B { class C; }; };",
2562 recordDecl(hasName("A::B::C"))));
2563 EXPECT_TRUE(matches("class A { class B { class C; }; };",
2564 recordDecl(hasName("::A::B::C"))));
2565 EXPECT_TRUE(matches("class A { class B { class C; }; };",
2566 recordDecl(hasName("B::C"))));
2567 EXPECT_TRUE(
2568 matches("class A { class B { class C; }; };", recordDecl(hasName("C"))));
2569 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2570 recordDecl(hasName("c::B::C"))));
2571 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2572 recordDecl(hasName("A::c::C"))));
2573 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2574 recordDecl(hasName("A::B::A"))));
2575 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2576 recordDecl(hasName("::C"))));
2577 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2578 recordDecl(hasName("::B::C"))));
2579 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2580 recordDecl(hasName("z::A::B::C"))));
2581 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2582 recordDecl(hasName("A+B::C"))));
2583}
2584
2585TEST_P(ASTMatchersTest, HasName_MatchesInlinedNamespaces) {
2586 if (!GetParam().isCXX()) {
2587 return;
2588 }
2589
2590 StringRef code = "namespace a { inline namespace b { class C; } }";
2591 EXPECT_TRUE(matches(code, recordDecl(hasName("a::b::C"))));
2592 EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
2593 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::b::C"))));
2594 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
2595}
2596
2597TEST_P(ASTMatchersTest, HasName_MatchesAnonymousNamespaces) {
2598 if (!GetParam().isCXX()) {
2599 return;
2600 }
2601
2602 StringRef code = "namespace a { namespace { class C; } }";
2603 EXPECT_TRUE(
2604 matches(code, recordDecl(hasName("a::(anonymous namespace)::C"))));
2605 EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
2606 EXPECT_TRUE(
2607 matches(code, recordDecl(hasName("::a::(anonymous namespace)::C"))));
2608 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
2609}
2610
2611TEST_P(ASTMatchersTest, HasName_MatchesAnonymousOuterClasses) {
2612 if (!GetParam().isCXX()) {
2613 return;
2614 }
2615
2616 EXPECT_TRUE(matches("class A { class { class C; } x; };",
2617 recordDecl(hasName("A::(anonymous class)::C"))));
2618 EXPECT_TRUE(matches("class A { class { class C; } x; };",
2619 recordDecl(hasName("::A::(anonymous class)::C"))));
2620 EXPECT_FALSE(matches("class A { class { class C; } x; };",
2621 recordDecl(hasName("::A::C"))));
2622 EXPECT_TRUE(matches("class A { struct { class C; } x; };",
2623 recordDecl(hasName("A::(anonymous struct)::C"))));
2624 EXPECT_TRUE(matches("class A { struct { class C; } x; };",
2625 recordDecl(hasName("::A::(anonymous struct)::C"))));
2626 EXPECT_FALSE(matches("class A { struct { class C; } x; };",
2627 recordDecl(hasName("::A::C"))));
2628}
2629
2630TEST_P(ASTMatchersTest, HasName_MatchesFunctionScope) {
2631 if (!GetParam().isCXX()) {
2632 return;
2633 }
2634
2635 StringRef code =
2636 "namespace a { void F(int a) { struct S { int m; }; int i; } }";
2637 EXPECT_TRUE(matches(code, varDecl(hasName("i"))));
2638 EXPECT_FALSE(matches(code, varDecl(hasName("F()::i"))));
2639
2640 EXPECT_TRUE(matches(code, fieldDecl(hasName("m"))));
2641 EXPECT_TRUE(matches(code, fieldDecl(hasName("S::m"))));
2642 EXPECT_TRUE(matches(code, fieldDecl(hasName("F(int)::S::m"))));
2643 EXPECT_TRUE(matches(code, fieldDecl(hasName("a::F(int)::S::m"))));
2644 EXPECT_TRUE(matches(code, fieldDecl(hasName("::a::F(int)::S::m"))));
2645}
2646
2647TEST_P(ASTMatchersTest, HasName_QualifiedStringMatchesThroughLinkage) {
2648 if (!GetParam().isCXX()) {
2649 return;
2650 }
2651
2652 // https://bugs.llvm.org/show_bug.cgi?id=42193
2653 StringRef code = R"cpp(namespace foo { extern "C" void test(); })cpp";
2654 EXPECT_TRUE(matches(code, functionDecl(hasName("test"))));
2655 EXPECT_TRUE(matches(code, functionDecl(hasName("foo::test"))));
2656 EXPECT_TRUE(matches(code, functionDecl(hasName("::foo::test"))));
2657 EXPECT_TRUE(notMatches(code, functionDecl(hasName("::test"))));
2658
2659 code = R"cpp(namespace foo { extern "C" { void test(); } })cpp";
2660 EXPECT_TRUE(matches(code, functionDecl(hasName("test"))));
2661 EXPECT_TRUE(matches(code, functionDecl(hasName("foo::test"))));
2662 EXPECT_TRUE(matches(code, functionDecl(hasName("::foo::test"))));
2663 EXPECT_TRUE(notMatches(code, functionDecl(hasName("::test"))));
2664}
2665
2666TEST_P(ASTMatchersTest, HasAnyName) {
2667 if (!GetParam().isCXX()) {
2668 // FIXME: Add a test for `hasAnyName()` that does not depend on C++.
2669 return;
2670 }
2671
2672 StringRef Code = "namespace a { namespace b { class C; } }";
2673
2674 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "a::b::C"))));
2675 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("a::b::C", "XX"))));
2676 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX::C", "a::b::C"))));
2677 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "C"))));
2678
2679 EXPECT_TRUE(notMatches(Code, recordDecl(hasAnyName("::C", "::b::C"))));
2680 EXPECT_TRUE(
2681 matches(Code, recordDecl(hasAnyName("::C", "::b::C", "::a::b::C"))));
2682
2683 std::vector<StringRef> Names = {"::C", "::b::C", "::a::b::C"};
2684 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName(Names))));
2685}
2686
2687TEST_P(ASTMatchersTest, IsDefinition) {
2688 DeclarationMatcher DefinitionOfClassA =
2689 recordDecl(hasName(Name: "A"), isDefinition());
2690 EXPECT_TRUE(matches("struct A {};", DefinitionOfClassA));
2691 EXPECT_TRUE(notMatches("struct A;", DefinitionOfClassA));
2692
2693 DeclarationMatcher DefinitionOfVariableA =
2694 varDecl(hasName(Name: "a"), isDefinition());
2695 EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));
2696 EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));
2697}
2698
2699TEST_P(ASTMatchersTest, IsDefinition_CXX) {
2700 if (!GetParam().isCXX()) {
2701 return;
2702 }
2703
2704 DeclarationMatcher DefinitionOfMethodA =
2705 cxxMethodDecl(hasName(Name: "a"), isDefinition());
2706 EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));
2707 EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));
2708
2709 DeclarationMatcher DefinitionOfObjCMethodA =
2710 objcMethodDecl(hasName(Name: "a"), isDefinition());
2711 EXPECT_TRUE(matchesObjC("@interface A @end "
2712 "@implementation A; -(void)a {} @end",
2713 DefinitionOfObjCMethodA));
2714 EXPECT_TRUE(
2715 notMatchesObjC("@interface A; - (void)a; @end", DefinitionOfObjCMethodA));
2716}
2717
2718TEST_P(ASTMatchersTest, HandlesNullQualTypes) {
2719 if (!GetParam().isCXX()) {
2720 // FIXME: Add an equivalent test that does not depend on C++.
2721 return;
2722 }
2723
2724 // FIXME: Add a Type matcher so we can replace uses of this
2725 // variable with Type(True())
2726 const TypeMatcher AnyType = anything();
2727
2728 // We don't really care whether this matcher succeeds; we're testing that
2729 // it completes without crashing.
2730 EXPECT_TRUE(matches(
2731 "struct A { };"
2732 "template <typename T>"
2733 "void f(T t) {"
2734 " T local_t(t /* this becomes a null QualType in the AST */);"
2735 "}"
2736 "void g() {"
2737 " f(0);"
2738 "}",
2739 expr(hasType(TypeMatcher(anyOf(TypeMatcher(hasDeclaration(anything())),
2740 pointsTo(AnyType), references(AnyType)
2741 // Other QualType matchers should go here.
2742 ))))));
2743}
2744
2745TEST_P(ASTMatchersTest, ObjCIvarRefExpr) {
2746 StringRef ObjCString =
2747 "@interface A @end "
2748 "@implementation A { A *x; } - (void) func { x = 0; } @end";
2749 EXPECT_TRUE(matchesObjC(ObjCString, objcIvarRefExpr()));
2750 EXPECT_TRUE(matchesObjC(
2751 ObjCString, objcIvarRefExpr(hasDeclaration(namedDecl(hasName("x"))))));
2752 EXPECT_FALSE(matchesObjC(
2753 ObjCString, objcIvarRefExpr(hasDeclaration(namedDecl(hasName("y"))))));
2754}
2755
2756TEST_P(ASTMatchersTest, BlockExpr) {
2757 EXPECT_TRUE(matchesObjC("void f() { ^{}(); }", blockExpr()));
2758}
2759
2760TEST_P(ASTMatchersTest,
2761 StatementCountIs_FindsNoStatementsInAnEmptyCompoundStatement) {
2762 EXPECT_TRUE(matches("void f() { }", compoundStmt(statementCountIs(0))));
2763 EXPECT_TRUE(notMatches("void f() {}", compoundStmt(statementCountIs(1))));
2764}
2765
2766TEST_P(ASTMatchersTest, StatementCountIs_AppearsToMatchOnlyOneCount) {
2767 EXPECT_TRUE(matches("void f() { 1; }", compoundStmt(statementCountIs(1))));
2768 EXPECT_TRUE(notMatches("void f() { 1; }", compoundStmt(statementCountIs(0))));
2769 EXPECT_TRUE(notMatches("void f() { 1; }", compoundStmt(statementCountIs(2))));
2770}
2771
2772TEST_P(ASTMatchersTest, StatementCountIs_WorksWithMultipleStatements) {
2773 EXPECT_TRUE(
2774 matches("void f() { 1; 2; 3; }", compoundStmt(statementCountIs(3))));
2775}
2776
2777TEST_P(ASTMatchersTest, StatementCountIs_WorksWithNestedCompoundStatements) {
2778 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
2779 compoundStmt(statementCountIs(1))));
2780 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
2781 compoundStmt(statementCountIs(2))));
2782 EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
2783 compoundStmt(statementCountIs(3))));
2784 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
2785 compoundStmt(statementCountIs(4))));
2786}
2787
2788TEST_P(ASTMatchersTest, Member_WorksInSimplestCase) {
2789 if (!GetParam().isCXX()) {
2790 // FIXME: Add a test for `member()` that does not depend on C++.
2791 return;
2792 }
2793 EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
2794 memberExpr(member(hasName("first")))));
2795}
2796
2797TEST_P(ASTMatchersTest, Member_DoesNotMatchTheBaseExpression) {
2798 if (!GetParam().isCXX()) {
2799 // FIXME: Add a test for `member()` that does not depend on C++.
2800 return;
2801 }
2802
2803 // Don't pick out the wrong part of the member expression, this should
2804 // be checking the member (name) only.
2805 EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
2806 memberExpr(member(hasName("first")))));
2807}
2808
2809TEST_P(ASTMatchersTest, Member_MatchesInMemberFunctionCall) {
2810 if (!GetParam().isCXX()) {
2811 return;
2812 }
2813
2814 EXPECT_TRUE(matches("void f() {"
2815 " struct { void first() {}; } s;"
2816 " s.first();"
2817 "};",
2818 memberExpr(member(hasName("first")))));
2819}
2820
2821TEST_P(ASTMatchersTest, FieldDecl) {
2822 EXPECT_TRUE(
2823 matches("struct A { int i; }; void f() { struct A a; a.i = 2; }",
2824 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
2825 EXPECT_TRUE(
2826 notMatches("struct A { float f; }; void f() { struct A a; a.f = 2.0f; }",
2827 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
2828}
2829
2830TEST_P(ASTMatchersTest, IsBitField) {
2831 EXPECT_TRUE(matches("struct C { int a : 2; int b; };",
2832 fieldDecl(isBitField(), hasName("a"))));
2833 EXPECT_TRUE(notMatches("struct C { int a : 2; int b; };",
2834 fieldDecl(isBitField(), hasName("b"))));
2835 EXPECT_TRUE(matches("struct C { int a : 2; int b : 4; };",
2836 fieldDecl(isBitField(), hasBitWidth(2), hasName("a"))));
2837}
2838
2839TEST_P(ASTMatchersTest, HasInClassInitializer) {
2840 if (!GetParam().isCXX()) {
2841 return;
2842 }
2843
2844 EXPECT_TRUE(
2845 matches("class C { int a = 2; int b; };",
2846 fieldDecl(hasInClassInitializer(integerLiteral(equals(2))),
2847 hasName("a"))));
2848 EXPECT_TRUE(
2849 notMatches("class C { int a = 2; int b; };",
2850 fieldDecl(hasInClassInitializer(anything()), hasName("b"))));
2851}
2852
2853TEST_P(ASTMatchersTest, IsPublic_IsProtected_IsPrivate) {
2854 if (!GetParam().isCXX()) {
2855 return;
2856 }
2857
2858 EXPECT_TRUE(
2859 matches("struct A { int i; };", fieldDecl(isPublic(), hasName("i"))));
2860 EXPECT_TRUE(notMatches("struct A { int i; };",
2861 fieldDecl(isProtected(), hasName("i"))));
2862 EXPECT_TRUE(
2863 notMatches("struct A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
2864
2865 EXPECT_TRUE(
2866 notMatches("class A { int i; };", fieldDecl(isPublic(), hasName("i"))));
2867 EXPECT_TRUE(notMatches("class A { int i; };",
2868 fieldDecl(isProtected(), hasName("i"))));
2869 EXPECT_TRUE(
2870 matches("class A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
2871
2872 EXPECT_TRUE(notMatches("class A { protected: int i; };",
2873 fieldDecl(isPublic(), hasName("i"))));
2874 EXPECT_TRUE(matches("class A { protected: int i; };",
2875 fieldDecl(isProtected(), hasName("i"))));
2876 EXPECT_TRUE(notMatches("class A { protected: int i; };",
2877 fieldDecl(isPrivate(), hasName("i"))));
2878
2879 // Non-member decls have the AccessSpecifier AS_none and thus aren't matched.
2880 EXPECT_TRUE(notMatches("int i;", varDecl(isPublic(), hasName("i"))));
2881 EXPECT_TRUE(notMatches("int i;", varDecl(isProtected(), hasName("i"))));
2882 EXPECT_TRUE(notMatches("int i;", varDecl(isPrivate(), hasName("i"))));
2883}
2884
2885TEST_P(ASTMatchersTest,
2886 HasDynamicExceptionSpec_MatchesDynamicExceptionSpecifications) {
2887 if (!GetParam().supportsCXXDynamicExceptionSpecification()) {
2888 return;
2889 }
2890
2891 EXPECT_TRUE(notMatches("void f();", functionDecl(hasDynamicExceptionSpec())));
2892 EXPECT_TRUE(
2893 matches("void j() throw();", functionDecl(hasDynamicExceptionSpec())));
2894 EXPECT_TRUE(
2895 matches("void k() throw(int);", functionDecl(hasDynamicExceptionSpec())));
2896 EXPECT_TRUE(
2897 matches("void l() throw(...);", functionDecl(hasDynamicExceptionSpec())));
2898
2899 EXPECT_TRUE(
2900 notMatches("void f();", functionProtoType(hasDynamicExceptionSpec())));
2901 EXPECT_TRUE(matches("void j() throw();",
2902 functionProtoType(hasDynamicExceptionSpec())));
2903 EXPECT_TRUE(matches("void k() throw(int);",
2904 functionProtoType(hasDynamicExceptionSpec())));
2905 EXPECT_TRUE(matches("void l() throw(...);",
2906 functionProtoType(hasDynamicExceptionSpec())));
2907}
2908
2909TEST_P(ASTMatchersTest,
2910 HasDynamicExceptionSpec_MatchesDynamicExceptionSpecifications_CXX11) {
2911 if (!GetParam().isCXX11OrLater()) {
2912 return;
2913 }
2914
2915 EXPECT_TRUE(notMatches("void g() noexcept;",
2916 functionDecl(hasDynamicExceptionSpec())));
2917 EXPECT_TRUE(notMatches("void h() noexcept(true);",
2918 functionDecl(hasDynamicExceptionSpec())));
2919 EXPECT_TRUE(notMatches("void i() noexcept(false);",
2920 functionDecl(hasDynamicExceptionSpec())));
2921
2922 EXPECT_TRUE(notMatches("void g() noexcept;",
2923 functionProtoType(hasDynamicExceptionSpec())));
2924 EXPECT_TRUE(notMatches("void h() noexcept(true);",
2925 functionProtoType(hasDynamicExceptionSpec())));
2926 EXPECT_TRUE(notMatches("void i() noexcept(false);",
2927 functionProtoType(hasDynamicExceptionSpec())));
2928}
2929
2930TEST_P(ASTMatchersTest, HasObjectExpression_DoesNotMatchMember) {
2931 if (!GetParam().isCXX()) {
2932 return;
2933 }
2934
2935 EXPECT_TRUE(notMatches(
2936 "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
2937 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
2938}
2939
2940TEST_P(ASTMatchersTest, HasObjectExpression_MatchesBaseOfVariable) {
2941 EXPECT_TRUE(matches(
2942 "struct X { int m; }; void f(struct X x) { x.m; }",
2943 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
2944 EXPECT_TRUE(matches("struct X { int m; }; void f(struct X* x) { x->m; }",
2945 memberExpr(hasObjectExpression(
2946 hasType(pointsTo(recordDecl(hasName("X"))))))));
2947}
2948
2949TEST_P(ASTMatchersTest, HasObjectExpression_MatchesBaseOfVariable_CXX) {
2950 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
2951 // FIXME: Fix this test to work with delayed template parsing.
2952 return;
2953 }
2954
2955 EXPECT_TRUE(matches("template <class T> struct X { void f() { T t; t.m; } };",
2956 cxxDependentScopeMemberExpr(hasObjectExpression(
2957 declRefExpr(to(namedDecl(hasName("t"))))))));
2958 EXPECT_TRUE(
2959 matches("template <class T> struct X { void f() { T t; t->m; } };",
2960 cxxDependentScopeMemberExpr(hasObjectExpression(
2961 declRefExpr(to(namedDecl(hasName("t"))))))));
2962}
2963
2964TEST_P(ASTMatchersTest, HasObjectExpression_MatchesBaseOfMemberFunc) {
2965 if (!GetParam().isCXX()) {
2966 return;
2967 }
2968
2969 EXPECT_TRUE(matches(
2970 "struct X { void f(); }; void g(X x) { x.f(); }",
2971 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
2972}
2973
2974TEST_P(ASTMatchersTest, HasObjectExpression_MatchesBaseOfMemberFunc_Template) {
2975 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
2976 // FIXME: Fix this test to work with delayed template parsing.
2977 return;
2978 }
2979
2980 EXPECT_TRUE(matches("struct X { template <class T> void f(); };"
2981 "template <class T> void g(X x) { x.f<T>(); }",
2982 unresolvedMemberExpr(hasObjectExpression(
2983 hasType(recordDecl(hasName("X")))))));
2984 EXPECT_TRUE(matches("template <class T> void f(T t) { t.g(); }",
2985 cxxDependentScopeMemberExpr(hasObjectExpression(
2986 declRefExpr(to(namedDecl(hasName("t"))))))));
2987}
2988
2989TEST_P(ASTMatchersTest, HasObjectExpression_ImplicitlyFormedMemberExpression) {
2990 if (!GetParam().isCXX()) {
2991 return;
2992 }
2993
2994 EXPECT_TRUE(matches("class X {}; struct S { X m; void f() { this->m; } };",
2995 memberExpr(hasObjectExpression(
2996 hasType(pointsTo(recordDecl(hasName("S"))))))));
2997 EXPECT_TRUE(matches("class X {}; struct S { X m; void f() { m; } };",
2998 memberExpr(hasObjectExpression(
2999 hasType(pointsTo(recordDecl(hasName("S"))))))));
3000}
3001
3002TEST_P(ASTMatchersTest, FieldDecl_DoesNotMatchNonFieldMembers) {
3003 if (!GetParam().isCXX()) {
3004 return;
3005 }
3006
3007 EXPECT_TRUE(notMatches("class X { void m(); };", fieldDecl(hasName("m"))));
3008 EXPECT_TRUE(notMatches("class X { class m {}; };", fieldDecl(hasName("m"))));
3009 EXPECT_TRUE(notMatches("class X { enum { m }; };", fieldDecl(hasName("m"))));
3010 EXPECT_TRUE(notMatches("class X { enum m {}; };", fieldDecl(hasName("m"))));
3011}
3012
3013TEST_P(ASTMatchersTest, FieldDecl_MatchesField) {
3014 EXPECT_TRUE(matches("struct X { int m; };", fieldDecl(hasName("m"))));
3015}
3016
3017TEST_P(ASTMatchersTest, IsVolatileQualified) {
3018 EXPECT_TRUE(
3019 matches("volatile int i = 42;", varDecl(hasType(isVolatileQualified()))));
3020 EXPECT_TRUE(
3021 notMatches("volatile int *i;", varDecl(hasType(isVolatileQualified()))));
3022 EXPECT_TRUE(matches("typedef volatile int v_int; v_int i = 42;",
3023 varDecl(hasType(isVolatileQualified()))));
3024}
3025
3026TEST_P(ASTMatchersTest, IsConstQualified_MatchesConstInt) {
3027 EXPECT_TRUE(
3028 matches("const int i = 42;", varDecl(hasType(isConstQualified()))));
3029}
3030
3031TEST_P(ASTMatchersTest, IsConstQualified_MatchesConstPointer) {
3032 EXPECT_TRUE(matches("int i = 42; int* const p = &i;",
3033 varDecl(hasType(isConstQualified()))));
3034}
3035
3036TEST_P(ASTMatchersTest, IsConstQualified_MatchesThroughTypedef) {
3037 EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
3038 varDecl(hasType(isConstQualified()))));
3039 EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p = ((int*)0);",
3040 varDecl(hasType(isConstQualified()))));
3041}
3042
3043TEST_P(ASTMatchersTest, IsConstQualified_DoesNotMatchInappropriately) {
3044 EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
3045 varDecl(hasType(isConstQualified()))));
3046 EXPECT_TRUE(
3047 notMatches("int const* p;", varDecl(hasType(isConstQualified()))));
3048}
3049
3050TEST_P(ASTMatchersTest, DeclCountIs_DeclCountIsCorrect) {
3051 EXPECT_TRUE(matches("void f() {int i,j;}", declStmt(declCountIs(2))));
3052 EXPECT_TRUE(
3053 notMatches("void f() {int i,j; int k;}", declStmt(declCountIs(3))));
3054 EXPECT_TRUE(
3055 notMatches("void f() {int i,j, k, l;}", declStmt(declCountIs(3))));
3056}
3057
3058TEST_P(ASTMatchersTest, EachOf_TriggersForEachMatch) {
3059 EXPECT_TRUE(matchAndVerifyResultTrue(
3060 "class A { int a; int b; };",
3061 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
3062 has(fieldDecl(hasName("b")).bind("v")))),
3063 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 2)));
3064}
3065
3066TEST_P(ASTMatchersTest, EachOf_BehavesLikeAnyOfUnlessBothMatch) {
3067 EXPECT_TRUE(matchAndVerifyResultTrue(
3068 "struct A { int a; int c; };",
3069 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
3070 has(fieldDecl(hasName("b")).bind("v")))),
3071 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 1)));
3072 EXPECT_TRUE(matchAndVerifyResultTrue(
3073 "struct A { int c; int b; };",
3074 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
3075 has(fieldDecl(hasName("b")).bind("v")))),
3076 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 1)));
3077 EXPECT_TRUE(
3078 notMatches("struct A { int c; int d; };",
3079 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
3080 has(fieldDecl(hasName("b")).bind("v"))))));
3081}
3082
3083TEST_P(ASTMatchersTest, Optionally_SubmatchersDoNotMatch) {
3084 EXPECT_TRUE(matchAndVerifyResultFalse(
3085 "class A { int a; int b; };",
3086 recordDecl(optionally(has(fieldDecl(hasName("c")).bind("c")))),
3087 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("c")));
3088}
3089
3090// Regression test.
3091TEST_P(ASTMatchersTest, Optionally_SubmatchersDoNotMatchButPreserveBindings) {
3092 StringRef Code = "class A { int a; int b; };";
3093 auto Matcher = recordDecl(decl().bind(ID: "decl"),
3094 optionally(has(fieldDecl(hasName(Name: "c")).bind(ID: "v"))));
3095 // "decl" is still bound.
3096 EXPECT_TRUE(matchAndVerifyResultTrue(
3097 Code, Matcher, std::make_unique<VerifyIdIsBoundTo<RecordDecl>>("decl")));
3098 // "v" is not bound, but the match still suceeded.
3099 EXPECT_TRUE(matchAndVerifyResultFalse(
3100 Code, Matcher, std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v")));
3101}
3102
3103TEST_P(ASTMatchersTest, Optionally_SubmatchersMatch) {
3104 EXPECT_TRUE(matchAndVerifyResultTrue(
3105 "class A { int a; int c; };",
3106 recordDecl(optionally(has(fieldDecl(hasName("a")).bind("v")))),
3107 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v")));
3108}
3109
3110TEST_P(ASTMatchersTest,
3111 IsTemplateInstantiation_MatchesImplicitClassTemplateInstantiation) {
3112 if (!GetParam().isCXX()) {
3113 return;
3114 }
3115
3116 // Make sure that we can both match the class by name (::X) and by the type
3117 // the template was instantiated with (via a field).
3118
3119 EXPECT_TRUE(
3120 matches("template <typename T> class X {}; class A {}; X<A> x;",
3121 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
3122
3123 EXPECT_TRUE(matches(
3124 "template <typename T> class X { T t; }; class A {}; X<A> x;",
3125 cxxRecordDecl(
3126 isTemplateInstantiation(),
3127 hasDescendant(fieldDecl(hasType(recordDecl(hasName("A"))))))));
3128}
3129
3130TEST_P(ASTMatchersTest,
3131 IsTemplateInstantiation_MatchesImplicitFunctionTemplateInstantiation) {
3132 if (!GetParam().isCXX()) {
3133 return;
3134 }
3135
3136 EXPECT_TRUE(matches(
3137 "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
3138 functionDecl(hasParameter(0, hasType(recordDecl(hasName("A")))),
3139 isTemplateInstantiation())));
3140}
3141
3142TEST_P(ASTMatchersTest,
3143 IsTemplateInstantiation_MatchesExplicitClassTemplateInstantiation) {
3144 if (!GetParam().isCXX()) {
3145 return;
3146 }
3147
3148 EXPECT_TRUE(matches("template <typename T> class X { T t; }; class A {};"
3149 "template class X<A>;",
3150 cxxRecordDecl(isTemplateInstantiation(),
3151 hasDescendant(fieldDecl(
3152 hasType(recordDecl(hasName("A"))))))));
3153
3154 // Make sure that we match the instantiation instead of the template
3155 // definition by checking whether the member function is present.
3156 EXPECT_TRUE(
3157 matches("template <typename T> class X { void f() { T t; } };"
3158 "extern template class X<int>;",
3159 cxxRecordDecl(isTemplateInstantiation(),
3160 unless(hasDescendant(varDecl(hasName("t")))))));
3161}
3162
3163TEST_P(
3164 ASTMatchersTest,
3165 IsTemplateInstantiation_MatchesInstantiationOfPartiallySpecializedClassTemplate) {
3166 if (!GetParam().isCXX()) {
3167 return;
3168 }
3169
3170 EXPECT_TRUE(
3171 matches("template <typename T> class X {};"
3172 "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
3173 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
3174}
3175
3176TEST_P(
3177 ASTMatchersTest,
3178 IsTemplateInstantiation_MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
3179 if (!GetParam().isCXX()) {
3180 return;
3181 }
3182
3183 EXPECT_TRUE(
3184 matches("class A {};"
3185 "class X {"
3186 " template <typename U> class Y { U u; };"
3187 " Y<A> y;"
3188 "};",
3189 cxxRecordDecl(hasName("::X::Y"), isTemplateInstantiation())));
3190}
3191
3192TEST_P(
3193 ASTMatchersTest,
3194 IsTemplateInstantiation_DoesNotMatchInstantiationsInsideOfInstantiation) {
3195 if (!GetParam().isCXX()) {
3196 return;
3197 }
3198
3199 // FIXME: Figure out whether this makes sense. It doesn't affect the
3200 // normal use case as long as the uppermost instantiation always is marked
3201 // as template instantiation, but it might be confusing as a predicate.
3202 EXPECT_TRUE(matches(
3203 "class A {};"
3204 "template <typename T> class X {"
3205 " template <typename U> class Y { U u; };"
3206 " Y<T> y;"
3207 "}; X<A> x;",
3208 cxxRecordDecl(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
3209}
3210
3211TEST_P(
3212 ASTMatchersTest,
3213 IsTemplateInstantiation_DoesNotMatchExplicitClassTemplateSpecialization) {
3214 if (!GetParam().isCXX()) {
3215 return;
3216 }
3217
3218 EXPECT_TRUE(
3219 notMatches("template <typename T> class X {}; class A {};"
3220 "template <> class X<A> {}; X<A> x;",
3221 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
3222}
3223
3224TEST_P(ASTMatchersTest, IsTemplateInstantiation_DoesNotMatchNonTemplate) {
3225 if (!GetParam().isCXX()) {
3226 return;
3227 }
3228
3229 EXPECT_TRUE(notMatches("class A {}; class Y { A a; };",
3230 cxxRecordDecl(isTemplateInstantiation())));
3231}
3232
3233TEST_P(ASTMatchersTest, IsInstantiated_MatchesInstantiation) {
3234 if (!GetParam().isCXX()) {
3235 return;
3236 }
3237
3238 EXPECT_TRUE(
3239 matches("template<typename T> class A { T i; }; class Y { A<int> a; };",
3240 cxxRecordDecl(isInstantiated())));
3241}
3242
3243TEST_P(ASTMatchersTest, IsInstantiated_NotMatchesDefinition) {
3244 if (!GetParam().isCXX()) {
3245 return;
3246 }
3247
3248 EXPECT_TRUE(notMatches("template<typename T> class A { T i; };",
3249 cxxRecordDecl(isInstantiated())));
3250}
3251
3252TEST_P(ASTMatchersTest, IsInTemplateInstantiation_MatchesInstantiationStmt) {
3253 if (!GetParam().isCXX()) {
3254 return;
3255 }
3256
3257 EXPECT_TRUE(matches("template<typename T> struct A { A() { T i; } };"
3258 "class Y { A<int> a; }; Y y;",
3259 declStmt(isInTemplateInstantiation())));
3260}
3261
3262TEST_P(ASTMatchersTest, IsInTemplateInstantiation_NotMatchesDefinitionStmt) {
3263 if (!GetParam().isCXX()) {
3264 return;
3265 }
3266
3267 EXPECT_TRUE(notMatches("template<typename T> struct A { void x() { T i; } };",
3268 declStmt(isInTemplateInstantiation())));
3269}
3270
3271TEST_P(ASTMatchersTest, IsInstantiated_MatchesFunctionInstantiation) {
3272 if (!GetParam().isCXX()) {
3273 return;
3274 }
3275
3276 EXPECT_TRUE(
3277 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
3278 functionDecl(isInstantiated())));
3279}
3280
3281TEST_P(ASTMatchersTest, IsInstantiated_NotMatchesFunctionDefinition) {
3282 if (!GetParam().isCXX()) {
3283 return;
3284 }
3285
3286 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
3287 varDecl(isInstantiated())));
3288}
3289
3290TEST_P(ASTMatchersTest,
3291 IsInTemplateInstantiation_MatchesFunctionInstantiationStmt) {
3292 if (!GetParam().isCXX()) {
3293 return;
3294 }
3295
3296 EXPECT_TRUE(
3297 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
3298 declStmt(isInTemplateInstantiation())));
3299}
3300
3301TEST_P(ASTMatchersTest,
3302 IsInTemplateInstantiation_NotMatchesFunctionDefinitionStmt) {
3303 if (!GetParam().isCXX()) {
3304 return;
3305 }
3306
3307 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
3308 declStmt(isInTemplateInstantiation())));
3309}
3310
3311TEST_P(ASTMatchersTest, IsInTemplateInstantiation_Sharing) {
3312 if (!GetParam().isCXX()) {
3313 return;
3314 }
3315
3316 auto Matcher = binaryOperator(unless(isInTemplateInstantiation()));
3317 // FIXME: Node sharing is an implementation detail, exposing it is ugly
3318 // and makes the matcher behave in non-obvious ways.
3319 EXPECT_TRUE(notMatches(
3320 "int j; template<typename T> void A(T t) { j += 42; } void x() { A(0); }",
3321 Matcher));
3322 EXPECT_TRUE(matches(
3323 "int j; template<typename T> void A(T t) { j += t; } void x() { A(0); }",
3324 Matcher));
3325}
3326
3327TEST_P(ASTMatchersTest, IsInstantiationDependent_MatchesNonValueTypeDependent) {
3328 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3329 // FIXME: Fix this test to work with delayed template parsing.
3330 return;
3331 }
3332
3333 EXPECT_TRUE(matches(
3334 "template<typename T> void f() { (void) sizeof(sizeof(T() + T())); }",
3335 expr(isInstantiationDependent())));
3336}
3337
3338TEST_P(ASTMatchersTest, IsInstantiationDependent_MatchesValueDependent) {
3339 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3340 // FIXME: Fix this test to work with delayed template parsing.
3341 return;
3342 }
3343
3344 EXPECT_TRUE(matches("template<int T> int f() { return T; }",
3345 expr(isInstantiationDependent())));
3346}
3347
3348TEST_P(ASTMatchersTest, IsInstantiationDependent_MatchesTypeDependent) {
3349 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3350 // FIXME: Fix this test to work with delayed template parsing.
3351 return;
3352 }
3353
3354 EXPECT_TRUE(matches("template<typename T> T f() { return T(); }",
3355 expr(isInstantiationDependent())));
3356}
3357
3358TEST_P(ASTMatchersTest, IsTypeDependent_MatchesTypeDependent) {
3359 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3360 // FIXME: Fix this test to work with delayed template parsing.
3361 return;
3362 }
3363
3364 EXPECT_TRUE(matches("template<typename T> T f() { return T(); }",
3365 expr(isTypeDependent())));
3366}
3367
3368TEST_P(ASTMatchersTest, IsTypeDependent_NotMatchesValueDependent) {
3369 if (!GetParam().isCXX()) {
3370 return;
3371 }
3372
3373 EXPECT_TRUE(notMatches("template<int T> int f() { return T; }",
3374 expr(isTypeDependent())));
3375}
3376
3377TEST_P(ASTMatchersTest, IsValueDependent_MatchesValueDependent) {
3378 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3379 // FIXME: Fix this test to work with delayed template parsing.
3380 return;
3381 }
3382
3383 EXPECT_TRUE(matches("template<int T> int f() { return T; }",
3384 expr(isValueDependent())));
3385}
3386
3387TEST_P(ASTMatchersTest, IsValueDependent_MatchesTypeDependent) {
3388 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3389 // FIXME: Fix this test to work with delayed template parsing.
3390 return;
3391 }
3392
3393 EXPECT_TRUE(matches("template<typename T> T f() { return T(); }",
3394 expr(isValueDependent())));
3395}
3396
3397TEST_P(ASTMatchersTest, IsValueDependent_MatchesInstantiationDependent) {
3398 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3399 // FIXME: Fix this test to work with delayed template parsing.
3400 return;
3401 }
3402
3403 EXPECT_TRUE(matches(
3404 "template<typename T> void f() { (void) sizeof(sizeof(T() + T())); }",
3405 expr(isValueDependent())));
3406}
3407
3408TEST_P(ASTMatchersTest,
3409 IsExplicitTemplateSpecialization_DoesNotMatchPrimaryTemplate) {
3410 if (!GetParam().isCXX()) {
3411 return;
3412 }
3413
3414 EXPECT_TRUE(notMatches("template <typename T> class X {};",
3415 cxxRecordDecl(isExplicitTemplateSpecialization())));
3416 EXPECT_TRUE(notMatches("template <typename T> void f(T t);",
3417 functionDecl(isExplicitTemplateSpecialization())));
3418}
3419
3420TEST_P(
3421 ASTMatchersTest,
3422 IsExplicitTemplateSpecialization_DoesNotMatchExplicitTemplateInstantiations) {
3423 if (!GetParam().isCXX()) {
3424 return;
3425 }
3426
3427 EXPECT_TRUE(
3428 notMatches("template <typename T> class X {};"
3429 "template class X<int>; extern template class X<long>;",
3430 cxxRecordDecl(isExplicitTemplateSpecialization())));
3431 EXPECT_TRUE(
3432 notMatches("template <typename T> void f(T t) {}"
3433 "template void f(int t); extern template void f(long t);",
3434 functionDecl(isExplicitTemplateSpecialization())));
3435}
3436
3437TEST_P(
3438 ASTMatchersTest,
3439 IsExplicitTemplateSpecialization_DoesNotMatchImplicitTemplateInstantiations) {
3440 if (!GetParam().isCXX()) {
3441 return;
3442 }
3443
3444 EXPECT_TRUE(notMatches("template <typename T> class X {}; X<int> x;",
3445 cxxRecordDecl(isExplicitTemplateSpecialization())));
3446 EXPECT_TRUE(
3447 notMatches("template <typename T> void f(T t); void g() { f(10); }",
3448 functionDecl(isExplicitTemplateSpecialization())));
3449}
3450
3451TEST_P(
3452 ASTMatchersTest,
3453 IsExplicitTemplateSpecialization_MatchesExplicitTemplateSpecializations) {
3454 if (!GetParam().isCXX()) {
3455 return;
3456 }
3457
3458 EXPECT_TRUE(matches("template <typename T> class X {};"
3459 "template<> class X<int> {};",
3460 cxxRecordDecl(isExplicitTemplateSpecialization())));
3461 EXPECT_TRUE(matches("template <typename T> void f(T t) {}"
3462 "template<> void f(int t) {}",
3463 functionDecl(isExplicitTemplateSpecialization())));
3464}
3465
3466TEST_P(ASTMatchersTest, IsNoReturn) {
3467 EXPECT_TRUE(notMatches("void func();", functionDecl(isNoReturn())));
3468 EXPECT_TRUE(notMatches("void func() {}", functionDecl(isNoReturn())));
3469
3470 EXPECT_TRUE(matches("__attribute__((noreturn)) void func();",
3471 functionDecl(isNoReturn())));
3472 EXPECT_TRUE(matches("__attribute__((noreturn)) void func() {}",
3473 functionDecl(isNoReturn())));
3474
3475 EXPECT_TRUE(matches("_Noreturn void func();", functionDecl(isNoReturn())));
3476 EXPECT_TRUE(matches("_Noreturn void func() {}", functionDecl(isNoReturn())));
3477}
3478
3479TEST_P(ASTMatchersTest, IsNoReturn_CXX) {
3480 if (!GetParam().isCXX()) {
3481 return;
3482 }
3483
3484 EXPECT_TRUE(
3485 notMatches("struct S { void func(); };", functionDecl(isNoReturn())));
3486 EXPECT_TRUE(
3487 notMatches("struct S { void func() {} };", functionDecl(isNoReturn())));
3488
3489 EXPECT_TRUE(notMatches("struct S { static void func(); };",
3490 functionDecl(isNoReturn())));
3491 EXPECT_TRUE(notMatches("struct S { static void func() {} };",
3492 functionDecl(isNoReturn())));
3493
3494 EXPECT_TRUE(notMatches("struct S { S(); };", functionDecl(isNoReturn())));
3495 EXPECT_TRUE(notMatches("struct S { S() {} };", functionDecl(isNoReturn())));
3496
3497 // ---
3498
3499 EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) void func(); };",
3500 functionDecl(isNoReturn())));
3501 EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) void func() {} };",
3502 functionDecl(isNoReturn())));
3503
3504 EXPECT_TRUE(
3505 matches("struct S { __attribute__((noreturn)) static void func(); };",
3506 functionDecl(isNoReturn())));
3507 EXPECT_TRUE(
3508 matches("struct S { __attribute__((noreturn)) static void func() {} };",
3509 functionDecl(isNoReturn())));
3510
3511 EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) S(); };",
3512 functionDecl(isNoReturn())));
3513 EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) S() {} };",
3514 functionDecl(isNoReturn())));
3515}
3516
3517TEST_P(ASTMatchersTest, IsNoReturn_CXX11Attribute) {
3518 if (!GetParam().isCXX11OrLater()) {
3519 return;
3520 }
3521
3522 EXPECT_TRUE(matches("[[noreturn]] void func();", functionDecl(isNoReturn())));
3523 EXPECT_TRUE(
3524 matches("[[noreturn]] void func() {}", functionDecl(isNoReturn())));
3525
3526 EXPECT_TRUE(matches("struct S { [[noreturn]] void func(); };",
3527 functionDecl(isNoReturn())));
3528 EXPECT_TRUE(matches("struct S { [[noreturn]] void func() {} };",
3529 functionDecl(isNoReturn())));
3530
3531 EXPECT_TRUE(matches("struct S { [[noreturn]] static void func(); };",
3532 functionDecl(isNoReturn())));
3533 EXPECT_TRUE(matches("struct S { [[noreturn]] static void func() {} };",
3534 functionDecl(isNoReturn())));
3535
3536 EXPECT_TRUE(
3537 matches("struct S { [[noreturn]] S(); };", functionDecl(isNoReturn())));
3538 EXPECT_TRUE(
3539 matches("struct S { [[noreturn]] S() {} };", functionDecl(isNoReturn())));
3540}
3541
3542TEST_P(ASTMatchersTest, BooleanType) {
3543 if (!GetParam().isCXX()) {
3544 // FIXME: Add a test for `booleanType()` that does not depend on C++.
3545 return;
3546 }
3547
3548 EXPECT_TRUE(matches("struct S { bool func(); };",
3549 cxxMethodDecl(returns(booleanType()))));
3550 EXPECT_TRUE(notMatches("struct S { void func(); };",
3551 cxxMethodDecl(returns(booleanType()))));
3552}
3553
3554TEST_P(ASTMatchersTest, VoidType) {
3555 if (!GetParam().isCXX()) {
3556 // FIXME: Add a test for `voidType()` that does not depend on C++.
3557 return;
3558 }
3559
3560 EXPECT_TRUE(matches("struct S { void func(); };",
3561 cxxMethodDecl(returns(voidType()))));
3562}
3563
3564TEST_P(ASTMatchersTest, RealFloatingPointType) {
3565 if (!GetParam().isCXX()) {
3566 // FIXME: Add a test for `realFloatingPointType()` that does not depend on
3567 // C++.
3568 return;
3569 }
3570
3571 EXPECT_TRUE(matches("struct S { float func(); };",
3572 cxxMethodDecl(returns(realFloatingPointType()))));
3573 EXPECT_TRUE(notMatches("struct S { int func(); };",
3574 cxxMethodDecl(returns(realFloatingPointType()))));
3575 EXPECT_TRUE(matches("struct S { long double func(); };",
3576 cxxMethodDecl(returns(realFloatingPointType()))));
3577}
3578
3579TEST_P(ASTMatchersTest, ArrayType) {
3580 EXPECT_TRUE(matches("int a[] = {2,3};", arrayType()));
3581 EXPECT_TRUE(matches("int a[42];", arrayType()));
3582 EXPECT_TRUE(matches("void f(int b) { int a[b]; }", arrayType()));
3583
3584 EXPECT_TRUE(notMatches("struct A {}; struct A a[7];",
3585 arrayType(hasElementType(builtinType()))));
3586
3587 EXPECT_TRUE(matches("int const a[] = { 2, 3 };",
3588 qualType(arrayType(hasElementType(builtinType())))));
3589 EXPECT_TRUE(matches(
3590 "int const a[] = { 2, 3 };",
3591 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
3592 EXPECT_TRUE(matches("typedef const int T; T x[] = { 1, 2 };",
3593 qualType(isConstQualified(), arrayType())));
3594
3595 EXPECT_TRUE(notMatches(
3596 "int a[] = { 2, 3 };",
3597 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
3598 EXPECT_TRUE(notMatches(
3599 "int a[] = { 2, 3 };",
3600 qualType(arrayType(hasElementType(isConstQualified(), builtinType())))));
3601 EXPECT_TRUE(notMatches("int const a[] = { 2, 3 };",
3602 qualType(arrayType(hasElementType(builtinType())),
3603 unless(isConstQualified()))));
3604
3605 EXPECT_TRUE(
3606 matches("int a[2];", constantArrayType(hasElementType(builtinType()))));
3607 EXPECT_TRUE(matches("const int a = 0;", qualType(isInteger())));
3608}
3609
3610TEST_P(ASTMatchersTest, DecayedType) {
3611 EXPECT_TRUE(
3612 matches("void f(int i[]);",
3613 valueDecl(hasType(decayedType(hasDecayedType(pointerType()))))));
3614 EXPECT_TRUE(notMatches("int i[7];", decayedType()));
3615}
3616
3617TEST_P(ASTMatchersTest, ComplexType) {
3618 EXPECT_TRUE(matches("_Complex float f;", complexType()));
3619 EXPECT_TRUE(
3620 matches("_Complex float f;", complexType(hasElementType(builtinType()))));
3621 EXPECT_TRUE(notMatches("_Complex float f;",
3622 complexType(hasElementType(isInteger()))));
3623}
3624
3625TEST_P(ASTMatchersTest, IsAnonymous) {
3626 if (!GetParam().isCXX()) {
3627 return;
3628 }
3629
3630 EXPECT_TRUE(notMatches("namespace N {}", namespaceDecl(isAnonymous())));
3631 EXPECT_TRUE(matches("namespace {}", namespaceDecl(isAnonymous())));
3632}
3633
3634TEST_P(ASTMatchersTest, InStdNamespace) {
3635 if (!GetParam().isCXX()) {
3636 return;
3637 }
3638
3639 EXPECT_TRUE(notMatches("class vector {};"
3640 "namespace foo {"
3641 " class vector {};"
3642 "}"
3643 "namespace foo {"
3644 " namespace std {"
3645 " class vector {};"
3646 " }"
3647 "}",
3648 cxxRecordDecl(hasName("vector"), isInStdNamespace())));
3649
3650 EXPECT_TRUE(matches("namespace std {"
3651 " class vector {};"
3652 "}",
3653 cxxRecordDecl(hasName("vector"), isInStdNamespace())));
3654
3655 EXPECT_TRUE(matches("namespace std {"
3656 " extern \"C++\" class vector {};"
3657 "}",
3658 cxxRecordDecl(hasName("vector"), isInStdNamespace())));
3659}
3660
3661TEST_P(ASTMatchersTest, InAnonymousNamespace) {
3662 if (!GetParam().isCXX()) {
3663 return;
3664 }
3665
3666 EXPECT_TRUE(
3667 notMatches("class vector {};"
3668 "namespace foo {"
3669 " class vector {};"
3670 "}",
3671 cxxRecordDecl(hasName("vector"), isInAnonymousNamespace())));
3672
3673 EXPECT_TRUE(
3674 matches("namespace {"
3675 " class vector {};"
3676 "}",
3677 cxxRecordDecl(hasName("vector"), isInAnonymousNamespace())));
3678
3679 EXPECT_TRUE(
3680 matches("namespace foo {"
3681 " namespace {"
3682 " class vector {};"
3683 " }"
3684 "}",
3685 cxxRecordDecl(hasName("vector"), isInAnonymousNamespace())));
3686
3687 EXPECT_TRUE(
3688 matches("namespace {"
3689 " namespace foo {"
3690 " class vector {};"
3691 " }"
3692 "}",
3693 cxxRecordDecl(hasName("vector"), isInAnonymousNamespace())));
3694}
3695
3696TEST_P(ASTMatchersTest, InStdNamespace_CXX11) {
3697 if (!GetParam().isCXX11OrLater()) {
3698 return;
3699 }
3700
3701 EXPECT_TRUE(matches("namespace std {"
3702 " inline namespace __1 {"
3703 " class vector {};"
3704 " }"
3705 "}",
3706 cxxRecordDecl(hasName("vector"), isInStdNamespace())));
3707 EXPECT_TRUE(notMatches("namespace std {"
3708 " inline namespace __1 {"
3709 " inline namespace __fs {"
3710 " namespace filesystem {"
3711 " inline namespace v1 {"
3712 " class path {};"
3713 " }"
3714 " }"
3715 " }"
3716 " }"
3717 "}",
3718 cxxRecordDecl(hasName("path"), isInStdNamespace())));
3719 EXPECT_TRUE(
3720 matches("namespace std {"
3721 " inline namespace __1 {"
3722 " inline namespace __fs {"
3723 " namespace filesystem {"
3724 " inline namespace v1 {"
3725 " class path {};"
3726 " }"
3727 " }"
3728 " }"
3729 " }"
3730 "}",
3731 cxxRecordDecl(hasName("path"),
3732 hasAncestor(namespaceDecl(hasName("filesystem"),
3733 isInStdNamespace())))));
3734}
3735
3736TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_QualType) {
3737 EXPECT_TRUE(matches(
3738 "int i = 1;", varDecl(hasType(qualType().bind("type")),
3739 hasInitializer(ignoringParenImpCasts(
3740 hasType(qualType(equalsBoundNode("type"))))))));
3741 EXPECT_TRUE(notMatches("int i = 1.f;",
3742 varDecl(hasType(qualType().bind("type")),
3743 hasInitializer(ignoringParenImpCasts(hasType(
3744 qualType(equalsBoundNode("type"))))))));
3745}
3746
3747TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_NonMatchingTypes) {
3748 EXPECT_TRUE(notMatches(
3749 "int i = 1;", varDecl(namedDecl(hasName("i")).bind("name"),
3750 hasInitializer(ignoringParenImpCasts(
3751 hasType(qualType(equalsBoundNode("type"))))))));
3752}
3753
3754TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_Stmt) {
3755 EXPECT_TRUE(
3756 matches("void f() { if(1) {} }",
3757 stmt(allOf(ifStmt().bind("if"),
3758 hasParent(stmt(has(stmt(equalsBoundNode("if")))))))));
3759
3760 EXPECT_TRUE(notMatches(
3761 "void f() { if(1) { if (1) {} } }",
3762 stmt(allOf(ifStmt().bind("if"), has(stmt(equalsBoundNode("if")))))));
3763}
3764
3765TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_Decl) {
3766 if (!GetParam().isCXX()) {
3767 // FIXME: Add a test for `equalsBoundNode()` for declarations that does not
3768 // depend on C++.
3769 return;
3770 }
3771
3772 EXPECT_TRUE(matches(
3773 "class X { class Y {}; };",
3774 decl(allOf(recordDecl(hasName("::X::Y")).bind("record"),
3775 hasParent(decl(has(decl(equalsBoundNode("record")))))))));
3776
3777 EXPECT_TRUE(notMatches("class X { class Y {}; };",
3778 decl(allOf(recordDecl(hasName("::X")).bind("record"),
3779 has(decl(equalsBoundNode("record")))))));
3780}
3781
3782TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_Type) {
3783 if (!GetParam().isCXX()) {
3784 // FIXME: Add a test for `equalsBoundNode()` for types that does not depend
3785 // on C++.
3786 return;
3787 }
3788 EXPECT_TRUE(matches(
3789 "class X { int a; int b; };",
3790 recordDecl(
3791 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
3792 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
3793
3794 EXPECT_TRUE(notMatches(
3795 "class X { int a; double b; };",
3796 recordDecl(
3797 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
3798 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
3799}
3800
3801TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_UsingForEachDescendant) {
3802 EXPECT_TRUE(matchAndVerifyResultTrue(
3803 "int f() {"
3804 " if (1) {"
3805 " int i = 9;"
3806 " }"
3807 " int j = 10;"
3808 " {"
3809 " float k = 9.0;"
3810 " }"
3811 " return 0;"
3812 "}",
3813 // Look for variable declarations within functions whose type is the same
3814 // as the function return type.
3815 functionDecl(
3816 returns(qualType().bind("type")),
3817 forEachDescendant(varDecl(hasType(qualType(equalsBoundNode("type"))))
3818 .bind("decl"))),
3819 // Only i and j should match, not k.
3820 std::make_unique<VerifyIdIsBoundTo<VarDecl>>("decl", 2)));
3821}
3822
3823TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_FiltersMatchedCombinations) {
3824 EXPECT_TRUE(matchAndVerifyResultTrue(
3825 "void f() {"
3826 " int x;"
3827 " double d;"
3828 " x = d + x - d + x;"
3829 "}",
3830 functionDecl(
3831 hasName("f"), forEachDescendant(varDecl().bind("d")),
3832 forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d")))))),
3833 std::make_unique<VerifyIdIsBoundTo<VarDecl>>("d", 5)));
3834}
3835
3836TEST_P(ASTMatchersTest,
3837 EqualsBoundNodeMatcher_UnlessDescendantsOfAncestorsMatch) {
3838 EXPECT_TRUE(matchAndVerifyResultTrue(
3839 "struct StringRef { int size() const; const char* data() const; };"
3840 "void f(StringRef v) {"
3841 " v.data();"
3842 "}",
3843 cxxMemberCallExpr(
3844 callee(cxxMethodDecl(hasName("data"))),
3845 on(declRefExpr(to(
3846 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
3847 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
3848 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
3849 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
3850 .bind("data"),
3851 std::make_unique<VerifyIdIsBoundTo<Expr>>("data", 1)));
3852
3853 EXPECT_FALSE(matches(
3854 "struct StringRef { int size() const; const char* data() const; };"
3855 "void f(StringRef v) {"
3856 " v.data();"
3857 " v.size();"
3858 "}",
3859 cxxMemberCallExpr(
3860 callee(cxxMethodDecl(hasName("data"))),
3861 on(declRefExpr(to(
3862 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
3863 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
3864 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
3865 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
3866 .bind("data")));
3867}
3868
3869TEST_P(ASTMatchersTest, NullPointerConstant) {
3870 EXPECT_TRUE(matches("#define NULL ((void *)0)\n"
3871 "void *v1 = NULL;",
3872 expr(nullPointerConstant())));
3873 EXPECT_TRUE(matches("char *cp = (char *)0;", expr(nullPointerConstant())));
3874 EXPECT_TRUE(matches("int *ip = 0;", expr(nullPointerConstant())));
3875 EXPECT_FALSE(matches("int i = 0;", expr(nullPointerConstant())));
3876}
3877
3878TEST_P(ASTMatchersTest, NullPointerConstant_GNUNull) {
3879 if (!GetParam().isCXX()) {
3880 return;
3881 }
3882
3883 EXPECT_TRUE(matches("void *p = __null;", expr(nullPointerConstant())));
3884}
3885
3886TEST_P(ASTMatchersTest, NullPointerConstant_GNUNullInTemplate) {
3887 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3888 // FIXME: Fix this test to work with delayed template parsing.
3889 return;
3890 }
3891
3892 const char kTest[] = R"(
3893 template <typename T>
3894 struct MyTemplate {
3895 MyTemplate() : field_(__null) {}
3896 T* field_;
3897 };
3898 )";
3899 EXPECT_TRUE(matches(kTest, expr(nullPointerConstant())));
3900}
3901
3902TEST_P(ASTMatchersTest, NullPointerConstant_CXX11Nullptr) {
3903 if (!GetParam().isCXX11OrLater()) {
3904 return;
3905 }
3906
3907 EXPECT_TRUE(matches("void *p = nullptr;", expr(nullPointerConstant())));
3908}
3909
3910TEST_P(ASTMatchersTest, HasExternalFormalLinkage) {
3911 EXPECT_TRUE(matches("int a = 0;",
3912 namedDecl(hasName("a"), hasExternalFormalLinkage())));
3913 EXPECT_TRUE(notMatches("static int a = 0;",
3914 namedDecl(hasName("a"), hasExternalFormalLinkage())));
3915 EXPECT_TRUE(notMatches("static void f(void) { int a = 0; }",
3916 namedDecl(hasName("a"), hasExternalFormalLinkage())));
3917 EXPECT_TRUE(notMatches("void f(void) { int a = 0; }",
3918 namedDecl(hasName("a"), hasExternalFormalLinkage())));
3919}
3920
3921TEST_P(ASTMatchersTest, HasExternalFormalLinkage_CXX) {
3922 if (!GetParam().isCXX()) {
3923 return;
3924 }
3925
3926 EXPECT_TRUE(notMatches("namespace { int a = 0; }",
3927 namedDecl(hasName("a"), hasExternalFormalLinkage())));
3928}
3929
3930TEST_P(ASTMatchersTest, HasDefaultArgument) {
3931 if (!GetParam().isCXX()) {
3932 return;
3933 }
3934
3935 EXPECT_TRUE(
3936 matches("void x(int val = 0) {}", parmVarDecl(hasDefaultArgument())));
3937 EXPECT_TRUE(
3938 notMatches("void x(int val) {}", parmVarDecl(hasDefaultArgument())));
3939}
3940
3941TEST_P(ASTMatchersTest, IsAtPosition) {
3942 EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1))));
3943 EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(0))));
3944 EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1))));
3945 EXPECT_TRUE(notMatches("void x(int val) {}", parmVarDecl(isAtPosition(1))));
3946}
3947
3948TEST_P(ASTMatchersTest, IsAtPosition_FunctionDecl) {
3949 EXPECT_TRUE(matches("void x(int a);", parmVarDecl(isAtPosition(0))));
3950 EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(0))));
3951 EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(1))));
3952 EXPECT_TRUE(notMatches("void x(int val);", parmVarDecl(isAtPosition(1))));
3953}
3954
3955TEST_P(ASTMatchersTest, IsAtPosition_Lambda) {
3956 if (!GetParam().isCXX11OrLater()) {
3957 return;
3958 }
3959
3960 EXPECT_TRUE(
3961 matches("void x() { [](int a) {}; }", parmVarDecl(isAtPosition(0))));
3962 EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",
3963 parmVarDecl(isAtPosition(0))));
3964 EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",
3965 parmVarDecl(isAtPosition(1))));
3966 EXPECT_TRUE(
3967 notMatches("void x() { [](int val) {}; }", parmVarDecl(isAtPosition(1))));
3968}
3969
3970TEST_P(ASTMatchersTest, IsAtPosition_BlockDecl) {
3971 EXPECT_TRUE(matchesObjC(
3972 "void func() { void (^my_block)(int arg) = ^void(int arg) {}; } ",
3973 parmVarDecl(isAtPosition(0))));
3974
3975 EXPECT_TRUE(matchesObjC("void func() { void (^my_block)(int x, int y) = "
3976 "^void(int x, int y) {}; } ",
3977 parmVarDecl(isAtPosition(1))));
3978
3979 EXPECT_TRUE(notMatchesObjC(
3980 "void func() { void (^my_block)(int arg) = ^void(int arg) {}; } ",
3981 parmVarDecl(isAtPosition(1))));
3982}
3983
3984TEST_P(ASTMatchersTest, IsArray) {
3985 if (!GetParam().isCXX()) {
3986 return;
3987 }
3988
3989 EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",
3990 cxxNewExpr(isArray())));
3991}
3992
3993TEST_P(ASTMatchersTest, HasArraySize) {
3994 if (!GetParam().isCXX()) {
3995 return;
3996 }
3997
3998 EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",
3999 cxxNewExpr(hasArraySize(
4000 ignoringParenImpCasts(integerLiteral(equals(10)))))));
4001}
4002
4003TEST_P(ASTMatchersTest, HasDefinition_MatchesStructDefinition) {
4004 if (!GetParam().isCXX()) {
4005 return;
4006 }
4007
4008 EXPECT_TRUE(matches("struct x {};", cxxRecordDecl(hasDefinition())));
4009 EXPECT_TRUE(notMatches("struct x;", cxxRecordDecl(hasDefinition())));
4010}
4011
4012TEST_P(ASTMatchersTest, HasDefinition_MatchesClassDefinition) {
4013 if (!GetParam().isCXX()) {
4014 return;
4015 }
4016
4017 EXPECT_TRUE(matches("class x {};", cxxRecordDecl(hasDefinition())));
4018 EXPECT_TRUE(notMatches("class x;", cxxRecordDecl(hasDefinition())));
4019}
4020
4021TEST_P(ASTMatchersTest, HasDefinition_MatchesUnionDefinition) {
4022 if (!GetParam().isCXX()) {
4023 return;
4024 }
4025
4026 EXPECT_TRUE(matches("union x {};", cxxRecordDecl(hasDefinition())));
4027 EXPECT_TRUE(notMatches("union x;", cxxRecordDecl(hasDefinition())));
4028}
4029
4030TEST_P(ASTMatchersTest, IsScoped_MatchesScopedEnum) {
4031 if (!GetParam().isCXX11OrLater()) {
4032 return;
4033 }
4034 EXPECT_TRUE(matches("enum class X {};", enumDecl(isScoped())));
4035}
4036
4037TEST_P(ASTMatchersTest, IsScoped_NotMatchesRegularEnum) {
4038 EXPECT_TRUE(notMatches("enum E { E1 };", enumDecl(isScoped())));
4039}
4040
4041TEST_P(ASTMatchersTest, IsStruct) {
4042 EXPECT_TRUE(matches("struct S {};", tagDecl(isStruct())));
4043}
4044
4045TEST_P(ASTMatchersTest, IsUnion) {
4046 EXPECT_TRUE(matches("union U {};", tagDecl(isUnion())));
4047}
4048
4049TEST_P(ASTMatchersTest, IsEnum) {
4050 EXPECT_TRUE(matches("enum E { E1 };", tagDecl(isEnum())));
4051}
4052
4053TEST_P(ASTMatchersTest, IsClass) {
4054 if (!GetParam().isCXX()) {
4055 return;
4056 }
4057
4058 EXPECT_TRUE(matches("class C {};", tagDecl(isClass())));
4059}
4060
4061TEST_P(ASTMatchersTest, HasTrailingReturn_MatchesTrailingReturn) {
4062 if (!GetParam().isCXX11OrLater()) {
4063 return;
4064 }
4065
4066 EXPECT_TRUE(matches("auto Y() -> int { return 0; }",
4067 functionDecl(hasTrailingReturn())));
4068 EXPECT_TRUE(matches("auto X() -> int;", functionDecl(hasTrailingReturn())));
4069 EXPECT_TRUE(
4070 notMatches("int X() { return 0; }", functionDecl(hasTrailingReturn())));
4071 EXPECT_TRUE(notMatches("int X();", functionDecl(hasTrailingReturn())));
4072 EXPECT_TRUE(notMatches("void X();", functionDecl(hasTrailingReturn())));
4073}
4074
4075TEST_P(ASTMatchersTest, HasTrailingReturn_MatchesLambdaTrailingReturn) {
4076 if (!GetParam().isCXX11OrLater()) {
4077 return;
4078 }
4079
4080 EXPECT_TRUE(matches(
4081 "auto lambda2 = [](double x, double y) -> double {return x + y;};",
4082 functionDecl(hasTrailingReturn())));
4083 EXPECT_TRUE(
4084 notMatches("auto lambda2 = [](double x, double y) {return x + y;};",
4085 functionDecl(hasTrailingReturn())));
4086}
4087
4088TEST_P(ASTMatchersTest, IsAssignmentOperator) {
4089 if (!GetParam().isCXX()) {
4090 return;
4091 }
4092
4093 StatementMatcher BinAsgmtOperator = binaryOperator(isAssignmentOperator());
4094 StatementMatcher CXXAsgmtOperator =
4095 cxxOperatorCallExpr(isAssignmentOperator());
4096
4097 EXPECT_TRUE(matches("void x() { int a; a += 1; }", BinAsgmtOperator));
4098 EXPECT_TRUE(matches("void x() { int a; a = 2; }", BinAsgmtOperator));
4099 EXPECT_TRUE(matches("void x() { int a; a &= 3; }", BinAsgmtOperator));
4100 EXPECT_TRUE(matches("struct S { S& operator=(const S&); };"
4101 "void x() { S s1, s2; s1 = s2; }",
4102 CXXAsgmtOperator));
4103 EXPECT_TRUE(
4104 notMatches("void x() { int a; if(a == 0) return; }", BinAsgmtOperator));
4105}
4106
4107TEST_P(ASTMatchersTest, IsComparisonOperator) {
4108 if (!GetParam().isCXX()) {
4109 return;
4110 }
4111
4112 StatementMatcher BinCompOperator = binaryOperator(isComparisonOperator());
4113 StatementMatcher CXXCompOperator =
4114 cxxOperatorCallExpr(isComparisonOperator());
4115
4116 EXPECT_TRUE(matches("void x() { int a; a == 1; }", BinCompOperator));
4117 EXPECT_TRUE(matches("void x() { int a; a > 2; }", BinCompOperator));
4118 EXPECT_TRUE(matches("struct S { bool operator==(const S&); };"
4119 "void x() { S s1, s2; bool b1 = s1 == s2; }",
4120 CXXCompOperator));
4121 EXPECT_TRUE(
4122 notMatches("void x() { int a; if(a = 0) return; }", BinCompOperator));
4123}
4124
4125TEST_P(ASTMatchersTest, isRightFold) {
4126 if (!GetParam().isCXX17OrLater()) {
4127 return;
4128 }
4129
4130 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4131 "return (0 + ... + args); }",
4132 cxxFoldExpr(isRightFold())));
4133 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4134 "return (args + ... + 0); }",
4135 cxxFoldExpr(isRightFold())));
4136 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4137 "return (... + args); };",
4138 cxxFoldExpr(isRightFold())));
4139 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4140 "return (args + ...); };",
4141 cxxFoldExpr(isRightFold())));
4142}
4143
4144TEST_P(ASTMatchersTest, isLeftFold) {
4145 if (!GetParam().isCXX17OrLater()) {
4146 return;
4147 }
4148
4149 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4150 "return (0 + ... + args); }",
4151 cxxFoldExpr(isLeftFold())));
4152 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4153 "return (args + ... + 0); }",
4154 cxxFoldExpr(isLeftFold())));
4155 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4156 "return (... + args); };",
4157 cxxFoldExpr(isLeftFold())));
4158 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4159 "return (args + ...); };",
4160 cxxFoldExpr(isLeftFold())));
4161}
4162
4163TEST_P(ASTMatchersTest, isUnaryFold) {
4164 if (!GetParam().isCXX17OrLater()) {
4165 return;
4166 }
4167
4168 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4169 "return (0 + ... + args); }",
4170 cxxFoldExpr(isUnaryFold())));
4171 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4172 "return (args + ... + 0); }",
4173 cxxFoldExpr(isUnaryFold())));
4174 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4175 "return (... + args); };",
4176 cxxFoldExpr(isUnaryFold())));
4177 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4178 "return (args + ...); };",
4179 cxxFoldExpr(isUnaryFold())));
4180}
4181
4182TEST_P(ASTMatchersTest, isBinaryFold) {
4183 if (!GetParam().isCXX17OrLater()) {
4184 return;
4185 }
4186
4187 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4188 "return (0 + ... + args); }",
4189 cxxFoldExpr(isBinaryFold())));
4190 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4191 "return (args + ... + 0); }",
4192 cxxFoldExpr(isBinaryFold())));
4193 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4194 "return (... + args); };",
4195 cxxFoldExpr(isBinaryFold())));
4196 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "
4197 "return (args + ...); };",
4198 cxxFoldExpr(isBinaryFold())));
4199}
4200
4201TEST_P(ASTMatchersTest, hasOperator) {
4202 if (!GetParam().isCXX17OrLater()) {
4203 return;
4204 }
4205
4206 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4207 "return (0 + ... + args); }",
4208 cxxFoldExpr(hasOperatorName("+"))));
4209 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
4210 "return (... + args); };",
4211 cxxFoldExpr(hasOperatorName("+"))));
4212
4213 EXPECT_FALSE(
4214 matches("template <typename... Args> auto multiply(Args... args) { "
4215 "return (0 * ... * args); }",
4216 cxxFoldExpr(hasOperatorName("+"))));
4217 EXPECT_FALSE(
4218 matches("template <typename... Args> auto multiply(Args... args) { "
4219 "return (... * args); };",
4220 cxxFoldExpr(hasOperatorName("+"))));
4221}
4222
4223TEST_P(ASTMatchersTest, IsMain) {
4224 EXPECT_TRUE(matches("int main() {}", functionDecl(isMain())));
4225
4226 EXPECT_TRUE(notMatches("int main2() {}", functionDecl(isMain())));
4227}
4228
4229TEST_P(ASTMatchersTest, OMPExecutableDirective_IsStandaloneDirective) {
4230 auto Matcher = ompExecutableDirective(isStandaloneDirective());
4231
4232 StringRef Source0 = R"(
4233void x() {
4234#pragma omp parallel
4235;
4236})";
4237 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
4238
4239 StringRef Source1 = R"(
4240void x() {
4241#pragma omp taskyield
4242})";
4243 EXPECT_TRUE(matchesWithOpenMP(Source1, Matcher));
4244}
4245
4246TEST_P(ASTMatchersTest, OMPExecutableDirective_HasStructuredBlock) {
4247 StringRef Source0 = R"(
4248void x() {
4249#pragma omp parallel
4250;
4251})";
4252 EXPECT_TRUE(matchesWithOpenMP(
4253 Source0, ompExecutableDirective(hasStructuredBlock(nullStmt()))));
4254
4255 StringRef Source1 = R"(
4256void x() {
4257#pragma omp parallel
4258{;}
4259})";
4260 EXPECT_TRUE(notMatchesWithOpenMP(
4261 Source1, ompExecutableDirective(hasStructuredBlock(nullStmt()))));
4262 EXPECT_TRUE(matchesWithOpenMP(
4263 Source1, ompExecutableDirective(hasStructuredBlock(compoundStmt()))));
4264
4265 StringRef Source2 = R"(
4266void x() {
4267#pragma omp taskyield
4268{;}
4269})";
4270 EXPECT_TRUE(notMatchesWithOpenMP(
4271 Source2, ompExecutableDirective(hasStructuredBlock(anything()))));
4272}
4273
4274TEST_P(ASTMatchersTest, OMPExecutableDirective_HasClause) {
4275 auto Matcher = ompExecutableDirective(hasAnyClause(InnerMatcher: anything()));
4276
4277 StringRef Source0 = R"(
4278void x() {
4279;
4280})";
4281 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
4282
4283 StringRef Source1 = R"(
4284void x() {
4285#pragma omp parallel
4286;
4287})";
4288 EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));
4289
4290 StringRef Source2 = R"(
4291void x() {
4292#pragma omp parallel default(none)
4293;
4294})";
4295 EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher));
4296
4297 StringRef Source3 = R"(
4298void x() {
4299#pragma omp parallel default(shared)
4300;
4301})";
4302 EXPECT_TRUE(matchesWithOpenMP(Source3, Matcher));
4303
4304 StringRef Source4 = R"(
4305void x() {
4306#pragma omp parallel default(firstprivate)
4307;
4308})";
4309 EXPECT_TRUE(matchesWithOpenMP51(Source4, Matcher));
4310
4311 StringRef Source5 = R"(
4312void x(int x) {
4313#pragma omp parallel num_threads(x)
4314;
4315})";
4316 EXPECT_TRUE(matchesWithOpenMP(Source5, Matcher));
4317}
4318
4319TEST_P(ASTMatchersTest, OMPDefaultClause_IsNoneKind) {
4320 auto Matcher =
4321 ompExecutableDirective(hasAnyClause(InnerMatcher: ompDefaultClause(isNoneKind())));
4322
4323 StringRef Source0 = R"(
4324void x() {
4325;
4326})";
4327 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
4328
4329 StringRef Source1 = R"(
4330void x() {
4331#pragma omp parallel
4332;
4333})";
4334 EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));
4335
4336 StringRef Source2 = R"(
4337void x() {
4338#pragma omp parallel default(none)
4339;
4340})";
4341 EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher));
4342
4343 StringRef Source3 = R"(
4344void x() {
4345#pragma omp parallel default(shared)
4346;
4347})";
4348 EXPECT_TRUE(notMatchesWithOpenMP(Source3, Matcher));
4349
4350 StringRef Source4 = R"(
4351void x(int x) {
4352#pragma omp parallel default(firstprivate)
4353;
4354})";
4355 EXPECT_TRUE(notMatchesWithOpenMP51(Source4, Matcher));
4356
4357 StringRef Source5 = R"(
4358void x(int x) {
4359#pragma omp parallel default(private)
4360;
4361})";
4362 EXPECT_TRUE(notMatchesWithOpenMP51(Source5, Matcher));
4363
4364 const std::string Source6 = R"(
4365void x(int x) {
4366#pragma omp parallel num_threads(x)
4367;
4368})";
4369 EXPECT_TRUE(notMatchesWithOpenMP(Source6, Matcher));
4370}
4371
4372TEST_P(ASTMatchersTest, OMPDefaultClause_IsSharedKind) {
4373 auto Matcher =
4374 ompExecutableDirective(hasAnyClause(InnerMatcher: ompDefaultClause(isSharedKind())));
4375
4376 StringRef Source0 = R"(
4377void x() {
4378;
4379})";
4380 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
4381
4382 StringRef Source1 = R"(
4383void x() {
4384#pragma omp parallel
4385;
4386})";
4387 EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));
4388
4389 StringRef Source2 = R"(
4390void x() {
4391#pragma omp parallel default(shared)
4392;
4393})";
4394 EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher));
4395
4396 StringRef Source3 = R"(
4397void x() {
4398#pragma omp parallel default(none)
4399;
4400})";
4401 EXPECT_TRUE(notMatchesWithOpenMP(Source3, Matcher));
4402
4403 StringRef Source4 = R"(
4404void x(int x) {
4405#pragma omp parallel default(firstprivate)
4406;
4407})";
4408 EXPECT_TRUE(notMatchesWithOpenMP51(Source4, Matcher));
4409
4410 StringRef Source5 = R"(
4411void x(int x) {
4412#pragma omp parallel default(private)
4413;
4414})";
4415 EXPECT_TRUE(notMatchesWithOpenMP51(Source5, Matcher));
4416
4417 const std::string Source6 = R"(
4418void x(int x) {
4419#pragma omp parallel num_threads(x)
4420;
4421})";
4422 EXPECT_TRUE(notMatchesWithOpenMP(Source6, Matcher));
4423}
4424
4425TEST(OMPDefaultClause, isFirstPrivateKind) {
4426 auto Matcher = ompExecutableDirective(
4427 hasAnyClause(InnerMatcher: ompDefaultClause(isFirstPrivateKind())));
4428
4429 const std::string Source0 = R"(
4430void x() {
4431;
4432})";
4433 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
4434
4435 const std::string Source1 = R"(
4436void x() {
4437#pragma omp parallel
4438;
4439})";
4440 EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));
4441
4442 const std::string Source2 = R"(
4443void x() {
4444#pragma omp parallel default(shared)
4445;
4446})";
4447 EXPECT_TRUE(notMatchesWithOpenMP(Source2, Matcher));
4448
4449 const std::string Source3 = R"(
4450void x() {
4451#pragma omp parallel default(none)
4452;
4453})";
4454 EXPECT_TRUE(notMatchesWithOpenMP(Source3, Matcher));
4455
4456 const std::string Source4 = R"(
4457void x(int x) {
4458#pragma omp parallel default(firstprivate)
4459;
4460})";
4461 EXPECT_TRUE(matchesWithOpenMP51(Source4, Matcher));
4462
4463 const std::string Source5 = R"(
4464void x(int x) {
4465#pragma omp parallel default(private)
4466;
4467})";
4468 EXPECT_TRUE(notMatchesWithOpenMP51(Source5, Matcher));
4469
4470 const std::string Source6 = R"(
4471void x(int x) {
4472#pragma omp parallel num_threads(x)
4473;
4474})";
4475 EXPECT_TRUE(notMatchesWithOpenMP(Source6, Matcher));
4476}
4477
4478TEST(OMPDefaultClause, istPrivateKind) {
4479 auto Matcher =
4480 ompExecutableDirective(hasAnyClause(InnerMatcher: ompDefaultClause(isPrivateKind())));
4481
4482 const std::string Source0 = R"(
4483void x() {
4484;
4485})";
4486 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
4487
4488 const std::string Source1 = R"(
4489void x() {
4490#pragma omp parallel
4491;
4492})";
4493 EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));
4494
4495 const std::string Source2 = R"(
4496void x() {
4497#pragma omp parallel default(shared)
4498;
4499})";
4500 EXPECT_TRUE(notMatchesWithOpenMP(Source2, Matcher));
4501
4502 const std::string Source3 = R"(
4503void x() {
4504#pragma omp parallel default(none)
4505;
4506})";
4507 EXPECT_TRUE(notMatchesWithOpenMP(Source3, Matcher));
4508
4509 const std::string Source4 = R"(
4510void x(int x) {
4511#pragma omp parallel default(firstprivate)
4512;
4513})";
4514 EXPECT_TRUE(notMatchesWithOpenMP51(Source4, Matcher));
4515
4516 const std::string Source5 = R"(
4517void x(int x) {
4518#pragma omp parallel default(private)
4519;
4520})";
4521 EXPECT_TRUE(matchesWithOpenMP51(Source5, Matcher));
4522
4523 const std::string Source6 = R"(
4524void x(int x) {
4525#pragma omp parallel num_threads(x)
4526;
4527})";
4528 EXPECT_TRUE(notMatchesWithOpenMP(Source6, Matcher));
4529}
4530
4531TEST_P(ASTMatchersTest, OMPExecutableDirective_IsAllowedToContainClauseKind) {
4532 auto Matcher = ompExecutableDirective(
4533 isAllowedToContainClauseKind(llvm::omp::OMPC_default));
4534
4535 StringRef Source0 = R"(
4536void x() {
4537;
4538})";
4539 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
4540
4541 StringRef Source1 = R"(
4542void x() {
4543#pragma omp parallel
4544;
4545})";
4546 EXPECT_TRUE(matchesWithOpenMP(Source1, Matcher));
4547
4548 StringRef Source2 = R"(
4549void x() {
4550#pragma omp parallel default(none)
4551;
4552})";
4553 EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher));
4554
4555 StringRef Source3 = R"(
4556void x() {
4557#pragma omp parallel default(shared)
4558;
4559})";
4560 EXPECT_TRUE(matchesWithOpenMP(Source3, Matcher));
4561
4562 StringRef Source4 = R"(
4563void x() {
4564#pragma omp parallel default(firstprivate)
4565;
4566})";
4567 EXPECT_TRUE(matchesWithOpenMP51(Source4, Matcher));
4568
4569 StringRef Source5 = R"(
4570void x() {
4571#pragma omp parallel default(private)
4572;
4573})";
4574 EXPECT_TRUE(matchesWithOpenMP51(Source5, Matcher));
4575
4576 StringRef Source6 = R"(
4577void x(int x) {
4578#pragma omp parallel num_threads(x)
4579;
4580})";
4581 EXPECT_TRUE(matchesWithOpenMP(Source6, Matcher));
4582
4583 StringRef Source7 = R"(
4584void x() {
4585#pragma omp taskyield
4586})";
4587 EXPECT_TRUE(notMatchesWithOpenMP(Source7, Matcher));
4588
4589 StringRef Source8 = R"(
4590void x() {
4591#pragma omp task
4592;
4593})";
4594 EXPECT_TRUE(matchesWithOpenMP(Source8, Matcher));
4595}
4596
4597TEST_P(ASTMatchersTest, HasAnyBase_DirectBase) {
4598 if (!GetParam().isCXX()) {
4599 return;
4600 }
4601 EXPECT_TRUE(matches(
4602 "struct Base {};"
4603 "struct ExpectedMatch : Base {};",
4604 cxxRecordDecl(hasName("ExpectedMatch"),
4605 hasAnyBase(hasType(cxxRecordDecl(hasName("Base")))))));
4606}
4607
4608TEST_P(ASTMatchersTest, HasAnyBase_IndirectBase) {
4609 if (!GetParam().isCXX()) {
4610 return;
4611 }
4612 EXPECT_TRUE(matches(
4613 "struct Base {};"
4614 "struct Intermediate : Base {};"
4615 "struct ExpectedMatch : Intermediate {};",
4616 cxxRecordDecl(hasName("ExpectedMatch"),
4617 hasAnyBase(hasType(cxxRecordDecl(hasName("Base")))))));
4618}
4619
4620TEST_P(ASTMatchersTest, HasAnyBase_NoBase) {
4621 if (!GetParam().isCXX()) {
4622 return;
4623 }
4624 EXPECT_TRUE(notMatches("struct Foo {};"
4625 "struct Bar {};",
4626 cxxRecordDecl(hasAnyBase(hasType(cxxRecordDecl())))));
4627}
4628
4629TEST_P(ASTMatchersTest, HasAnyBase_IsPublic_Public) {
4630 if (!GetParam().isCXX()) {
4631 return;
4632 }
4633 EXPECT_TRUE(matches("class Base {};"
4634 "class Derived : public Base {};",
4635 cxxRecordDecl(hasAnyBase(isPublic()))));
4636}
4637
4638TEST_P(ASTMatchersTest, HasAnyBase_IsPublic_DefaultAccessSpecifierPublic) {
4639 if (!GetParam().isCXX()) {
4640 return;
4641 }
4642 EXPECT_TRUE(matches("class Base {};"
4643 "struct Derived : Base {};",
4644 cxxRecordDecl(hasAnyBase(isPublic()))));
4645}
4646
4647TEST_P(ASTMatchersTest, HasAnyBase_IsPublic_Private) {
4648 if (!GetParam().isCXX()) {
4649 return;
4650 }
4651 EXPECT_TRUE(notMatches("class Base {};"
4652 "class Derived : private Base {};",
4653 cxxRecordDecl(hasAnyBase(isPublic()))));
4654}
4655
4656TEST_P(ASTMatchersTest, HasAnyBase_IsPublic_DefaultAccessSpecifierPrivate) {
4657 if (!GetParam().isCXX()) {
4658 return;
4659 }
4660 EXPECT_TRUE(notMatches("class Base {};"
4661 "class Derived : Base {};",
4662 cxxRecordDecl(hasAnyBase(isPublic()))));
4663}
4664
4665TEST_P(ASTMatchersTest, HasAnyBase_IsPublic_Protected) {
4666 if (!GetParam().isCXX()) {
4667 return;
4668 }
4669 EXPECT_TRUE(notMatches("class Base {};"
4670 "class Derived : protected Base {};",
4671 cxxRecordDecl(hasAnyBase(isPublic()))));
4672}
4673
4674TEST_P(ASTMatchersTest, HasAnyBase_IsPrivate_Private) {
4675 if (!GetParam().isCXX()) {
4676 return;
4677 }
4678 EXPECT_TRUE(matches("class Base {};"
4679 "class Derived : private Base {};",
4680 cxxRecordDecl(hasAnyBase(isPrivate()))));
4681}
4682
4683TEST_P(ASTMatchersTest, HasAnyBase_IsPrivate_DefaultAccessSpecifierPrivate) {
4684 if (!GetParam().isCXX()) {
4685 return;
4686 }
4687 EXPECT_TRUE(matches("struct Base {};"
4688 "class Derived : Base {};",
4689 cxxRecordDecl(hasAnyBase(isPrivate()))));
4690}
4691
4692TEST_P(ASTMatchersTest, HasAnyBase_IsPrivate_Public) {
4693 if (!GetParam().isCXX()) {
4694 return;
4695 }
4696 EXPECT_TRUE(notMatches("class Base {};"
4697 "class Derived : public Base {};",
4698 cxxRecordDecl(hasAnyBase(isPrivate()))));
4699}
4700
4701TEST_P(ASTMatchersTest, HasAnyBase_IsPrivate_DefaultAccessSpecifierPublic) {
4702 if (!GetParam().isCXX()) {
4703 return;
4704 }
4705 EXPECT_TRUE(notMatches("class Base {};"
4706 "struct Derived : Base {};",
4707 cxxRecordDecl(hasAnyBase(isPrivate()))));
4708}
4709
4710TEST_P(ASTMatchersTest, HasAnyBase_IsPrivate_Protected) {
4711 if (!GetParam().isCXX()) {
4712 return;
4713 }
4714 EXPECT_TRUE(notMatches("class Base {};"
4715 "class Derived : protected Base {};",
4716 cxxRecordDecl(hasAnyBase(isPrivate()))));
4717}
4718
4719TEST_P(ASTMatchersTest, HasAnyBase_IsProtected_Protected) {
4720 if (!GetParam().isCXX()) {
4721 return;
4722 }
4723 EXPECT_TRUE(matches("class Base {};"
4724 "class Derived : protected Base {};",
4725 cxxRecordDecl(hasAnyBase(isProtected()))));
4726}
4727
4728TEST_P(ASTMatchersTest, HasAnyBase_IsProtected_Public) {
4729 if (!GetParam().isCXX()) {
4730 return;
4731 }
4732 EXPECT_TRUE(notMatches("class Base {};"
4733 "class Derived : public Base {};",
4734 cxxRecordDecl(hasAnyBase(isProtected()))));
4735}
4736
4737TEST_P(ASTMatchersTest, HasAnyBase_IsProtected_Private) {
4738 if (!GetParam().isCXX()) {
4739 return;
4740 }
4741 EXPECT_TRUE(notMatches("class Base {};"
4742 "class Derived : private Base {};",
4743 cxxRecordDecl(hasAnyBase(isProtected()))));
4744}
4745
4746TEST_P(ASTMatchersTest, HasAnyBase_IsVirtual_Directly) {
4747 if (!GetParam().isCXX()) {
4748 return;
4749 }
4750 EXPECT_TRUE(matches("class Base {};"
4751 "class Derived : virtual Base {};",
4752 cxxRecordDecl(hasAnyBase(isVirtual()))));
4753}
4754
4755TEST_P(ASTMatchersTest, HasAnyBase_IsVirtual_Indirectly) {
4756 if (!GetParam().isCXX()) {
4757 return;
4758 }
4759 EXPECT_TRUE(
4760 matches("class Base {};"
4761 "class Intermediate : virtual Base {};"
4762 "class Derived : Intermediate {};",
4763 cxxRecordDecl(hasName("Derived"), hasAnyBase(isVirtual()))));
4764}
4765
4766TEST_P(ASTMatchersTest, HasAnyBase_IsVirtual_NoVirtualBase) {
4767 if (!GetParam().isCXX()) {
4768 return;
4769 }
4770 EXPECT_TRUE(notMatches("class Base {};"
4771 "class Derived : Base {};",
4772 cxxRecordDecl(hasAnyBase(isVirtual()))));
4773}
4774
4775TEST_P(ASTMatchersTest, HasDirectBase) {
4776 if (!GetParam().isCXX()) {
4777 return;
4778 }
4779
4780 DeclarationMatcher ClassHasAnyDirectBase =
4781 cxxRecordDecl(hasDirectBase(BaseSpecMatcher: cxxBaseSpecifier()));
4782 EXPECT_TRUE(notMatches("class X {};", ClassHasAnyDirectBase));
4783 EXPECT_TRUE(matches("class X {}; class Y : X {};", ClassHasAnyDirectBase));
4784 EXPECT_TRUE(matches("class X {}; class Y : public virtual X {};",
4785 ClassHasAnyDirectBase));
4786
4787 EXPECT_TRUE(matches(
4788 R"cc(
4789 class Base {};
4790 class Derived : Base{};
4791 )cc",
4792 cxxRecordDecl(hasName("Derived"),
4793 hasDirectBase(hasType(cxxRecordDecl(hasName("Base")))))));
4794
4795 StringRef MultiDerived = R"cc(
4796 class Base {};
4797 class Base2 {};
4798 class Derived : Base, Base2{};
4799 )cc";
4800
4801 EXPECT_TRUE(matches(
4802 MultiDerived,
4803 cxxRecordDecl(hasName("Derived"),
4804 hasDirectBase(hasType(cxxRecordDecl(hasName("Base")))))));
4805 EXPECT_TRUE(matches(
4806 MultiDerived,
4807 cxxRecordDecl(hasName("Derived"),
4808 hasDirectBase(hasType(cxxRecordDecl(hasName("Base2")))))));
4809
4810 StringRef Indirect = R"cc(
4811 class Base {};
4812 class Intermediate : Base {};
4813 class Derived : Intermediate{};
4814 )cc";
4815
4816 EXPECT_TRUE(
4817 matches(Indirect, cxxRecordDecl(hasName("Derived"),
4818 hasDirectBase(hasType(cxxRecordDecl(
4819 hasName("Intermediate")))))));
4820 EXPECT_TRUE(notMatches(
4821 Indirect,
4822 cxxRecordDecl(hasName("Derived"),
4823 hasDirectBase(hasType(cxxRecordDecl(hasName("Base")))))));
4824}
4825
4826TEST_P(ASTMatchersTest, CapturesThis) {
4827 if (!GetParam().isCXX11OrLater()) {
4828 return;
4829 }
4830 auto matcher = lambdaExpr(hasAnyCapture(InnerMatcher: lambdaCapture(capturesThis())));
4831 EXPECT_TRUE(matches("class C { int cc; int f() { auto l = [this](){ return "
4832 "cc; }; return l(); } };",
4833 matcher));
4834 EXPECT_TRUE(matches("class C { int cc; int f() { auto l = [=](){ return cc; "
4835 "}; return l(); } };",
4836 matcher));
4837 EXPECT_TRUE(matches("class C { int cc; int f() { auto l = [&](){ return cc; "
4838 "}; return l(); } };",
4839 matcher));
4840 EXPECT_FALSE(matches("class C { int cc; int f() { auto l = [cc](){ return "
4841 "cc; }; return l(); } };",
4842 matcher));
4843 EXPECT_FALSE(matches("class C { int this; int f() { auto l = [this](){ "
4844 "return this; }; return l(); } };",
4845 matcher));
4846}
4847
4848TEST_P(ASTMatchersTest, IsImplicit_LambdaCapture) {
4849 if (!GetParam().isCXX11OrLater()) {
4850 return;
4851 }
4852 auto matcher = lambdaExpr(hasAnyCapture(
4853 InnerMatcher: lambdaCapture(isImplicit(), capturesVar(InnerMatcher: varDecl(hasName(Name: "cc"))))));
4854 EXPECT_TRUE(
4855 matches("int main() { int cc; auto f = [&](){ return cc; }; }", matcher));
4856 EXPECT_TRUE(
4857 matches("int main() { int cc; auto f = [=](){ return cc; }; }", matcher));
4858 EXPECT_FALSE(matches("int main() { int cc; auto f = [cc](){ return cc; }; }",
4859 matcher));
4860}
4861
4862} // namespace ast_matchers
4863} // namespace clang
4864

source code of clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp