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/ADT/Triple.h"
15 #include "llvm/Support/Host.h"
16 #include "gtest/gtest.h"
17
18 namespace clang {
19 namespace ast_matchers {
20
TEST_P(ASTMatchersTest,IsExpandedFromMacro_MatchesInFile)21 TEST_P(ASTMatchersTest, IsExpandedFromMacro_MatchesInFile) {
22 StringRef input = R"cc(
23 #define MY_MACRO(a) (4 + (a))
24 void Test() { MY_MACRO(4); }
25 )cc";
26 EXPECT_TRUE(matches(input, binaryOperator(isExpandedFromMacro("MY_MACRO"))));
27 }
28
TEST_P(ASTMatchersTest,IsExpandedFromMacro_MatchesNested)29 TEST_P(ASTMatchersTest, IsExpandedFromMacro_MatchesNested) {
30 StringRef input = R"cc(
31 #define MY_MACRO(a) (4 + (a))
32 #define WRAPPER(a) MY_MACRO(a)
33 void Test() { WRAPPER(4); }
34 )cc";
35 EXPECT_TRUE(matches(input, binaryOperator(isExpandedFromMacro("MY_MACRO"))));
36 }
37
TEST_P(ASTMatchersTest,IsExpandedFromMacro_MatchesIntermediate)38 TEST_P(ASTMatchersTest, IsExpandedFromMacro_MatchesIntermediate) {
39 StringRef input = R"cc(
40 #define IMPL(a) (4 + (a))
41 #define MY_MACRO(a) IMPL(a)
42 #define WRAPPER(a) MY_MACRO(a)
43 void Test() { WRAPPER(4); }
44 )cc";
45 EXPECT_TRUE(matches(input, binaryOperator(isExpandedFromMacro("MY_MACRO"))));
46 }
47
TEST_P(ASTMatchersTest,IsExpandedFromMacro_MatchesTransitive)48 TEST_P(ASTMatchersTest, IsExpandedFromMacro_MatchesTransitive) {
49 StringRef input = R"cc(
50 #define MY_MACRO(a) (4 + (a))
51 #define WRAPPER(a) MY_MACRO(a)
52 void Test() { WRAPPER(4); }
53 )cc";
54 EXPECT_TRUE(matches(input, binaryOperator(isExpandedFromMacro("WRAPPER"))));
55 }
56
TEST_P(ASTMatchersTest,IsExpandedFromMacro_MatchesArgument)57 TEST_P(ASTMatchersTest, IsExpandedFromMacro_MatchesArgument) {
58 StringRef input = R"cc(
59 #define MY_MACRO(a) (4 + (a))
60 void Test() {
61 int x = 5;
62 MY_MACRO(x);
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.
TEST_P(ASTMatchersTest,IsExpandedFromMacro_MatchesArgumentMacroExpansion)70 TEST_P(ASTMatchersTest, IsExpandedFromMacro_MatchesArgumentMacroExpansion) {
71 StringRef input = R"cc(
72 #define MY_MACRO(a) (4 + (a))
73 #define IDENTITY(a) (a)
74 void Test() {
75 IDENTITY(MY_MACRO(2));
76 }
77 )cc";
78 EXPECT_TRUE(matches(input, binaryOperator(isExpandedFromMacro("IDENTITY"))));
79 }
80
TEST_P(ASTMatchersTest,IsExpandedFromMacro_MatchesWhenInArgument)81 TEST_P(ASTMatchersTest, IsExpandedFromMacro_MatchesWhenInArgument) {
82 StringRef input = R"cc(
83 #define MY_MACRO(a) (4 + (a))
84 #define IDENTITY(a) (a)
85 void Test() {
86 IDENTITY(MY_MACRO(2));
87 }
88 )cc";
89 EXPECT_TRUE(matches(input, binaryOperator(isExpandedFromMacro("MY_MACRO"))));
90 }
91
TEST_P(ASTMatchersTest,IsExpandedFromMacro_MatchesObjectMacro)92 TEST_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
TEST(IsExpandedFromMacro,MatchesFromCommandLine)102 TEST(IsExpandedFromMacro, MatchesFromCommandLine) {
103 StringRef input = R"cc(
104 void Test() { FOUR_PLUS_FOUR; }
105 )cc";
106 EXPECT_TRUE(matchesConditionally(
107 input, binaryOperator(isExpandedFromMacro("FOUR_PLUS_FOUR")), true,
108 {"-std=c++11", "-DFOUR_PLUS_FOUR=4+4"}));
109 }
110
TEST_P(ASTMatchersTest,IsExpandedFromMacro_NotMatchesBeginOnly)111 TEST_P(ASTMatchersTest, IsExpandedFromMacro_NotMatchesBeginOnly) {
112 StringRef input = R"cc(
113 #define ONE_PLUS 1+
114 void Test() { ONE_PLUS 4; }
115 )cc";
116 EXPECT_TRUE(
117 notMatches(input, binaryOperator(isExpandedFromMacro("ONE_PLUS"))));
118 }
119
TEST_P(ASTMatchersTest,IsExpandedFromMacro_NotMatchesEndOnly)120 TEST_P(ASTMatchersTest, IsExpandedFromMacro_NotMatchesEndOnly) {
121 StringRef input = R"cc(
122 #define PLUS_ONE +1
123 void Test() { 4 PLUS_ONE; }
124 )cc";
125 EXPECT_TRUE(
126 notMatches(input, binaryOperator(isExpandedFromMacro("PLUS_ONE"))));
127 }
128
TEST_P(ASTMatchersTest,IsExpandedFromMacro_NotMatchesDifferentMacro)129 TEST_P(ASTMatchersTest, IsExpandedFromMacro_NotMatchesDifferentMacro) {
130 StringRef input = R"cc(
131 #define MY_MACRO(a) (4 + (a))
132 void Test() { MY_MACRO(4); }
133 )cc";
134 EXPECT_TRUE(notMatches(input, binaryOperator(isExpandedFromMacro("OTHER"))));
135 }
136
TEST_P(ASTMatchersTest,IsExpandedFromMacro_NotMatchesDifferentInstances)137 TEST_P(ASTMatchersTest, IsExpandedFromMacro_NotMatchesDifferentInstances) {
138 StringRef input = R"cc(
139 #define FOUR 4
140 void Test() { FOUR + FOUR; }
141 )cc";
142 EXPECT_TRUE(notMatches(input, binaryOperator(isExpandedFromMacro("FOUR"))));
143 }
144
TEST(IsExpandedFromMacro,IsExpandedFromMacro_MatchesDecls)145 TEST(IsExpandedFromMacro, IsExpandedFromMacro_MatchesDecls) {
146 StringRef input = R"cc(
147 #define MY_MACRO(a) int i = a;
148 void Test() { MY_MACRO(4); }
149 )cc";
150 EXPECT_TRUE(matches(input, varDecl(isExpandedFromMacro("MY_MACRO"))));
151 }
152
TEST(IsExpandedFromMacro,IsExpandedFromMacro_MatchesTypelocs)153 TEST(IsExpandedFromMacro, IsExpandedFromMacro_MatchesTypelocs) {
154 StringRef input = R"cc(
155 #define MY_TYPE int
156 void Test() { MY_TYPE i = 4; }
157 )cc";
158 EXPECT_TRUE(matches(input, typeLoc(isExpandedFromMacro("MY_TYPE"))));
159 }
160
TEST_P(ASTMatchersTest,AllOf)161 TEST_P(ASTMatchersTest, AllOf) {
162 const char Program[] = "struct T { };"
163 "int f(int, struct T*, int, int);"
164 "void g(int x) { struct T t; f(x, &t, 3, 4); }";
165 EXPECT_TRUE(matches(
166 Program, callExpr(allOf(callee(functionDecl(hasName("f"))),
167 hasArgument(0, declRefExpr(to(varDecl())))))));
168 EXPECT_TRUE(matches(
169 Program,
170 callExpr(
171 allOf(callee(functionDecl(hasName("f"))),
172 hasArgument(0, declRefExpr(to(varDecl()))),
173 hasArgument(1, hasType(pointsTo(recordDecl(hasName("T")))))))));
174 EXPECT_TRUE(matches(
175 Program, callExpr(allOf(
176 callee(functionDecl(hasName("f"))),
177 hasArgument(0, declRefExpr(to(varDecl()))),
178 hasArgument(1, hasType(pointsTo(recordDecl(hasName("T"))))),
179 hasArgument(2, integerLiteral(equals(3)))))));
180 EXPECT_TRUE(matches(
181 Program, callExpr(allOf(
182 callee(functionDecl(hasName("f"))),
183 hasArgument(0, declRefExpr(to(varDecl()))),
184 hasArgument(1, hasType(pointsTo(recordDecl(hasName("T"))))),
185 hasArgument(2, integerLiteral(equals(3))),
186 hasArgument(3, integerLiteral(equals(4)))))));
187 }
188
TEST_P(ASTMatchersTest,Has)189 TEST_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("X"))));
196 EXPECT_TRUE(matches("class Y { class X {}; };", HasClassX));
197 EXPECT_TRUE(matches("class X {};", HasClassX));
198
199 DeclarationMatcher YHasClassX =
200 recordDecl(hasName("Y"), has(recordDecl(hasName("X"))));
201 EXPECT_TRUE(matches("class Y { class X {}; };", YHasClassX));
202 EXPECT_TRUE(notMatches("class X {};", YHasClassX));
203 EXPECT_TRUE(notMatches("class Y { class Z { class X {}; }; };", YHasClassX));
204 }
205
TEST_P(ASTMatchersTest,Has_RecursiveAllOf)206 TEST_P(ASTMatchersTest, Has_RecursiveAllOf) {
207 if (!GetParam().isCXX()) {
208 return;
209 }
210
211 DeclarationMatcher Recursive =
212 recordDecl(has(recordDecl(has(recordDecl(hasName("X"))),
213 has(recordDecl(hasName("Y"))), hasName("Z"))),
214 has(recordDecl(has(recordDecl(hasName("A"))),
215 has(recordDecl(hasName("B"))), hasName("C"))),
216 hasName("F"));
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
TEST_P(ASTMatchersTest,Has_RecursiveAnyOf)263 TEST_P(ASTMatchersTest, Has_RecursiveAnyOf) {
264 if (!GetParam().isCXX()) {
265 return;
266 }
267
268 DeclarationMatcher Recursive = recordDecl(
269 anyOf(has(recordDecl(anyOf(has(recordDecl(hasName("X"))),
270 has(recordDecl(hasName("Y"))), hasName("Z")))),
271 has(recordDecl(anyOf(hasName("C"), has(recordDecl(hasName("A"))),
272 has(recordDecl(hasName("B")))))),
273 hasName("F")));
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
TEST_P(ASTMatchersTest,Unless)286 TEST_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("Y"), unless(hasName("X")));
294 EXPECT_TRUE(notMatches("", NotClassX));
295 EXPECT_TRUE(notMatches("class Y {};", NotClassX));
296 EXPECT_TRUE(matches("class Y {}; class Z : public Y {};", NotClassX));
297 EXPECT_TRUE(notMatches("class Y {}; class X : public Y {};", NotClassX));
298 EXPECT_TRUE(
299 notMatches("class Y {}; class Z {}; class X : public Y {};", NotClassX));
300
301 DeclarationMatcher ClassXHasNotClassY =
302 recordDecl(hasName("X"), has(recordDecl(hasName("Z"))),
303 unless(has(recordDecl(hasName("Y")))));
304 EXPECT_TRUE(matches("class X { class Z {}; };", ClassXHasNotClassY));
305 EXPECT_TRUE(
306 notMatches("class X { class Y {}; class Z {}; };", ClassXHasNotClassY));
307
308 DeclarationMatcher NamedNotRecord =
309 namedDecl(hasName("Foo"), unless(recordDecl()));
310 EXPECT_TRUE(matches("void Foo(){}", NamedNotRecord));
311 EXPECT_TRUE(notMatches("struct Foo {};", NamedNotRecord));
312 }
313
TEST_P(ASTMatchersTest,HasCastKind)314 TEST_P(ASTMatchersTest, HasCastKind) {
315 EXPECT_TRUE(
316 matches("char *p = 0;",
317 traverse(TK_AsIs,
318 varDecl(has(castExpr(hasCastKind(CK_NullToPointer)))))));
319 EXPECT_TRUE(notMatches(
320 "char *p = 0;",
321 traverse(TK_AsIs,
322 varDecl(has(castExpr(hasCastKind(CK_DerivedToBase)))))));
323 EXPECT_TRUE(matches("char *p = 0;",
324 traverse(TK_AsIs, varDecl(has(implicitCastExpr(
325 hasCastKind(CK_NullToPointer)))))));
326 }
327
TEST_P(ASTMatchersTest,HasDescendant)328 TEST_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("X"))), hasName("Z"));
336 EXPECT_TRUE(matches("class Z { class X {}; };", ZDescendantClassX));
337 EXPECT_TRUE(
338 matches("class Z { class Y { class X {}; }; };", ZDescendantClassX));
339 EXPECT_TRUE(matches("class Z { class A { class Y { class X {}; }; }; };",
340 ZDescendantClassX));
341 EXPECT_TRUE(
342 matches("class Z { class A { class B { class Y { class X {}; }; }; }; };",
343 ZDescendantClassX));
344 EXPECT_TRUE(notMatches("class Z {};", ZDescendantClassX));
345
346 DeclarationMatcher ZDescendantClassXHasClassY = recordDecl(
347 hasDescendant(recordDecl(has(recordDecl(hasName("Y"))), hasName("X"))),
348 hasName("Z"));
349 EXPECT_TRUE(matches("class Z { class X { class Y {}; }; };",
350 ZDescendantClassXHasClassY));
351 EXPECT_TRUE(
352 matches("class Z { class A { class B { class X { class Y {}; }; }; }; };",
353 ZDescendantClassXHasClassY));
354 EXPECT_TRUE(notMatches("class Z {"
355 " class A {"
356 " class B {"
357 " class X {"
358 " class C {"
359 " class Y {};"
360 " };"
361 " };"
362 " }; "
363 " };"
364 "};",
365 ZDescendantClassXHasClassY));
366
367 DeclarationMatcher ZDescendantClassXDescendantClassY =
368 recordDecl(hasDescendant(recordDecl(
369 hasDescendant(recordDecl(hasName("Y"))), hasName("X"))),
370 hasName("Z"));
371 EXPECT_TRUE(
372 matches("class Z { class A { class X { class B { class Y {}; }; }; }; };",
373 ZDescendantClassXDescendantClassY));
374 EXPECT_TRUE(matches("class Z {"
375 " class A {"
376 " class X {"
377 " class B {"
378 " class Y {};"
379 " };"
380 " class Y {};"
381 " };"
382 " };"
383 "};",
384 ZDescendantClassXDescendantClassY));
385 }
386
TEST_P(ASTMatchersTest,HasDescendant_Memoization)387 TEST_P(ASTMatchersTest, HasDescendant_Memoization) {
388 DeclarationMatcher CannotMemoize =
389 decl(hasDescendant(typeLoc().bind("x")), has(decl()));
390 EXPECT_TRUE(matches("void f() { int i; }", CannotMemoize));
391 }
392
TEST_P(ASTMatchersTest,HasDescendant_MemoizationUsesRestrictKind)393 TEST_P(ASTMatchersTest, HasDescendant_MemoizationUsesRestrictKind) {
394 auto Name = hasName("i");
395 auto VD = internal::Matcher<VarDecl>(Name).dynCastTo<Decl>();
396 auto RD = internal::Matcher<RecordDecl>(Name).dynCastTo<Decl>();
397 // Matching VD first should not make a cache hit for RD.
398 EXPECT_TRUE(notMatches("void f() { int i; }",
399 decl(hasDescendant(VD), hasDescendant(RD))));
400 EXPECT_TRUE(notMatches("void f() { int i; }",
401 decl(hasDescendant(RD), hasDescendant(VD))));
402 // Not matching RD first should not make a cache hit for VD either.
403 EXPECT_TRUE(matches("void f() { int i; }",
404 decl(anyOf(hasDescendant(RD), hasDescendant(VD)))));
405 }
406
TEST_P(ASTMatchersTest,HasAncestor_Memoization)407 TEST_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(templateArgument().bind("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
TEST_P(ASTMatchersTest,HasAttr)424 TEST_P(ASTMatchersTest, HasAttr) {
425 EXPECT_TRUE(matches("struct __attribute__((warn_unused)) X {};",
426 decl(hasAttr(clang::attr::WarnUnused))));
427 EXPECT_FALSE(matches("struct X {};", decl(hasAttr(clang::attr::WarnUnused))));
428 }
429
TEST_P(ASTMatchersTest,AnyOf)430 TEST_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("Y"), allOf(isDerivedFrom("X"), hasName("Z"))));
438 EXPECT_TRUE(matches("class X {}; class Z : public X {};", YOrZDerivedFromX));
439 EXPECT_TRUE(matches("class Y {};", YOrZDerivedFromX));
440 EXPECT_TRUE(
441 notMatches("class X {}; class W : public X {};", YOrZDerivedFromX));
442 EXPECT_TRUE(notMatches("class Z {};", YOrZDerivedFromX));
443
444 DeclarationMatcher XOrYOrZOrU =
445 recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U")));
446 EXPECT_TRUE(matches("class X {};", XOrYOrZOrU));
447 EXPECT_TRUE(notMatches("class V {};", XOrYOrZOrU));
448
449 DeclarationMatcher XOrYOrZOrUOrV = recordDecl(anyOf(
450 hasName("X"), hasName("Y"), hasName("Z"), hasName("U"), hasName("V")));
451 EXPECT_TRUE(matches("class X {};", XOrYOrZOrUOrV));
452 EXPECT_TRUE(matches("class Y {};", XOrYOrZOrUOrV));
453 EXPECT_TRUE(matches("class Z {};", XOrYOrZOrUOrV));
454 EXPECT_TRUE(matches("class U {};", XOrYOrZOrUOrV));
455 EXPECT_TRUE(matches("class V {};", XOrYOrZOrUOrV));
456 EXPECT_TRUE(notMatches("class A {};", XOrYOrZOrUOrV));
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
TEST_P(ASTMatchersTest,MapAnyOf)468 TEST_P(ASTMatchersTest, MapAnyOf) {
469 if (!GetParam().isCXX()) {
470 return;
471 }
472
473 if (GetParam().hasDelayedTemplateParsing()) {
474 return;
475 }
476
477 StringRef Code = R"cpp(
478 void F() {
479 if (true) {}
480 for ( ; false; ) {}
481 }
482 )cpp";
483
484 auto trueExpr = cxxBoolLiteral(equals(true));
485 auto falseExpr = cxxBoolLiteral(equals(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(
506 void func(bool b) {}
507 struct S {
508 S(bool b) {}
509 };
510 void 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(
536 struct HasOpNeqMem
537 {
538 bool operator!=(const HasOpNeqMem& other) const
539 {
540 return true;
541 }
542 };
543 struct HasOpFree
544 {
545 };
546 bool operator!=(const HasOpFree& lhs, const HasOpFree& rhs)
547 {
548 return true;
549 }
550
551 void binop()
552 {
553 int s1;
554 int s2;
555 if (s1 != s2)
556 return;
557 }
558
559 void opMem()
560 {
561 HasOpNeqMem s1;
562 HasOpNeqMem s2;
563 if (s1 != s2)
564 return;
565 }
566
567 void opFree()
568 {
569 HasOpFree s1;
570 HasOpFree s2;
571 if (s1 != s2)
572 return;
573 }
574
575 template<typename T>
576 void 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(
729 struct HasOpEq
730 {
731 bool operator==(const HasOpEq &) const;
732 };
733
734 void inverse()
735 {
736 HasOpEq s1;
737 HasOpEq s2;
738 if (s1 != s2)
739 return;
740 }
741
742 namespace std {
743 struct strong_ordering {
744 int n;
745 constexpr operator int() const { return n; }
746 static const strong_ordering equal, greater, less;
747 };
748 constexpr strong_ordering strong_ordering::equal = {0};
749 constexpr strong_ordering strong_ordering::greater = {1};
750 constexpr strong_ordering strong_ordering::less = {-1};
751 }
752
753 struct HasSpaceshipMem {
754 int a;
755 constexpr auto operator<=>(const HasSpaceshipMem&) const = default;
756 };
757
758 void 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(
788 struct HasOpBangMem
789 {
790 bool operator!() const
791 {
792 return false;
793 }
794 };
795 struct HasOpBangFree
796 {
797 };
798 bool operator!(HasOpBangFree const&)
799 {
800 return false;
801 }
802
803 void unop()
804 {
805 int s1;
806 if (!s1)
807 return;
808 }
809
810 void opMem()
811 {
812 HasOpBangMem s1;
813 if (!s1)
814 return;
815 }
816
817 void 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
TEST_P(ASTMatchersTest,IsDerivedFrom)868 TEST_P(ASTMatchersTest, IsDerivedFrom) {
869 if (!GetParam().isCXX()) {
870 return;
871 }
872
873 DeclarationMatcher IsDerivedFromX = cxxRecordDecl(isDerivedFrom("X"));
874
875 EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsDerivedFromX));
876 EXPECT_TRUE(notMatches("class X {};", IsDerivedFromX));
877 EXPECT_TRUE(notMatches("class X;", IsDerivedFromX));
878 EXPECT_TRUE(notMatches("class Y;", IsDerivedFromX));
879 EXPECT_TRUE(notMatches("", IsDerivedFromX));
880 EXPECT_TRUE(matches("class X {}; template<int N> class Y : Y<N-1>, X {};",
881 IsDerivedFromX));
882 EXPECT_TRUE(matches("class X {}; template<int N> class Y : X, Y<N-1> {};",
883 IsDerivedFromX));
884
885 DeclarationMatcher IsZDerivedFromX =
886 cxxRecordDecl(hasName("Z"), isDerivedFrom("X"));
887 EXPECT_TRUE(matches("class X {};"
888 "template<int N> class Y : Y<N-1> {};"
889 "template<> class Y<0> : X {};"
890 "class Z : Y<1> {};",
891 IsZDerivedFromX));
892
893 DeclarationMatcher IsDirectlyDerivedFromX =
894 cxxRecordDecl(isDirectlyDerivedFrom("X"));
895
896 EXPECT_TRUE(
897 matches("class X {}; class Y : public X {};", IsDirectlyDerivedFromX));
898 EXPECT_TRUE(notMatches("class X {};", IsDirectlyDerivedFromX));
899 EXPECT_TRUE(notMatches("class X;", IsDirectlyDerivedFromX));
900 EXPECT_TRUE(notMatches("class Y;", IsDirectlyDerivedFromX));
901 EXPECT_TRUE(notMatches("", IsDirectlyDerivedFromX));
902
903 DeclarationMatcher IsAX = cxxRecordDecl(isSameOrDerivedFrom("X"));
904
905 EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsAX));
906 EXPECT_TRUE(matches("class X {};", IsAX));
907 EXPECT_TRUE(matches("class X;", IsAX));
908 EXPECT_TRUE(notMatches("class Y;", IsAX));
909 EXPECT_TRUE(notMatches("", IsAX));
910
911 DeclarationMatcher ZIsDerivedFromX =
912 cxxRecordDecl(hasName("Z"), isDerivedFrom("X"));
913 DeclarationMatcher ZIsDirectlyDerivedFromX =
914 cxxRecordDecl(hasName("Z"), isDirectlyDerivedFrom("X"));
915 EXPECT_TRUE(
916 matches("class X {}; class Y : public X {}; class Z : public Y {};",
917 ZIsDerivedFromX));
918 EXPECT_TRUE(
919 notMatches("class X {}; class Y : public X {}; class Z : public Y {};",
920 ZIsDirectlyDerivedFromX));
921 EXPECT_TRUE(matches("class X {};"
922 "template<class T> class Y : public X {};"
923 "class Z : public Y<int> {};",
924 ZIsDerivedFromX));
925 EXPECT_TRUE(notMatches("class X {};"
926 "template<class T> class Y : public X {};"
927 "class Z : public Y<int> {};",
928 ZIsDirectlyDerivedFromX));
929 EXPECT_TRUE(matches("class X {}; template<class T> class Z : public X {};",
930 ZIsDerivedFromX));
931 EXPECT_TRUE(matches("template<class T> class X {}; "
932 "template<class T> class Z : public X<T> {};",
933 ZIsDerivedFromX));
934 EXPECT_TRUE(matches("template<class T, class U=T> class X {}; "
935 "template<class T> class Z : public X<T> {};",
936 ZIsDerivedFromX));
937 EXPECT_TRUE(
938 notMatches("template<class X> class A { class Z : public X {}; };",
939 ZIsDerivedFromX));
940 EXPECT_TRUE(
941 matches("template<class X> class A { public: class Z : public X {}; }; "
942 "class X{}; void y() { A<X>::Z z; }",
943 ZIsDerivedFromX));
944 EXPECT_TRUE(
945 matches("template <class T> class X {}; "
946 "template<class Y> class A { class Z : public X<Y> {}; };",
947 ZIsDerivedFromX));
948 EXPECT_TRUE(notMatches("template<template<class T> class X> class A { "
949 " class Z : public X<int> {}; };",
950 ZIsDerivedFromX));
951 EXPECT_TRUE(matches("template<template<class T> class X> class A { "
952 " public: class Z : public X<int> {}; }; "
953 "template<class T> class X {}; void y() { A<X>::Z z; }",
954 ZIsDerivedFromX));
955 EXPECT_TRUE(
956 notMatches("template<class X> class A { class Z : public X::D {}; };",
957 ZIsDerivedFromX));
958 EXPECT_TRUE(matches("template<class X> class A { public: "
959 " class Z : public X::D {}; }; "
960 "class Y { public: class X {}; typedef X D; }; "
961 "void y() { A<Y>::Z z; }",
962 ZIsDerivedFromX));
963 EXPECT_TRUE(matches("class X {}; typedef X Y; class Z : public Y {};",
964 ZIsDerivedFromX));
965 EXPECT_TRUE(matches("template<class T> class Y { typedef typename T::U X; "
966 " class Z : public X {}; };",
967 ZIsDerivedFromX));
968 EXPECT_TRUE(matches("class X {}; class Z : public ::X {};", ZIsDerivedFromX));
969 EXPECT_TRUE(
970 notMatches("template<class T> class X {}; "
971 "template<class T> class A { class Z : public X<T>::D {}; };",
972 ZIsDerivedFromX));
973 EXPECT_TRUE(
974 matches("template<class T> class X { public: typedef X<T> D; }; "
975 "template<class T> class A { public: "
976 " class Z : public X<T>::D {}; }; void y() { A<int>::Z z; }",
977 ZIsDerivedFromX));
978 EXPECT_TRUE(
979 notMatches("template<class X> class A { class Z : public X::D::E {}; };",
980 ZIsDerivedFromX));
981 EXPECT_TRUE(
982 matches("class X {}; typedef X V; typedef V W; class Z : public W {};",
983 ZIsDerivedFromX));
984 EXPECT_TRUE(matches("class X {}; class Y : public X {}; "
985 "typedef Y V; typedef V W; class Z : public W {};",
986 ZIsDerivedFromX));
987 EXPECT_TRUE(notMatches("class X {}; class Y : public X {}; "
988 "typedef Y V; typedef V W; class Z : public W {};",
989 ZIsDirectlyDerivedFromX));
990 EXPECT_TRUE(
991 matches("template<class T, class U> class X {}; "
992 "template<class T> class A { class Z : public X<T, int> {}; };",
993 ZIsDerivedFromX));
994 EXPECT_TRUE(
995 notMatches("template<class X> class D { typedef X A; typedef A B; "
996 " typedef B C; class Z : public C {}; };",
997 ZIsDerivedFromX));
998 EXPECT_TRUE(matches("class X {}; typedef X A; typedef A B; "
999 "class Z : public B {};",
1000 ZIsDerivedFromX));
1001 EXPECT_TRUE(matches("class X {}; typedef X A; typedef A B; typedef B C; "
1002 "class Z : public C {};",
1003 ZIsDerivedFromX));
1004 EXPECT_TRUE(matches("class U {}; typedef U X; typedef X V; "
1005 "class Z : public V {};",
1006 ZIsDerivedFromX));
1007 EXPECT_TRUE(matches("class Base {}; typedef Base X; "
1008 "class Z : public Base {};",
1009 ZIsDerivedFromX));
1010 EXPECT_TRUE(matches("class Base {}; typedef Base Base2; typedef Base2 X; "
1011 "class Z : public Base {};",
1012 ZIsDerivedFromX));
1013 EXPECT_TRUE(notMatches("class Base {}; class Base2 {}; typedef Base2 X; "
1014 "class Z : public Base {};",
1015 ZIsDerivedFromX));
1016 EXPECT_TRUE(matches("class A {}; typedef A X; typedef A Y; "
1017 "class Z : public Y {};",
1018 ZIsDerivedFromX));
1019 EXPECT_TRUE(notMatches("template <typename T> class Z;"
1020 "template <> class Z<void> {};"
1021 "template <typename T> class Z : public Z<void> {};",
1022 IsDerivedFromX));
1023 EXPECT_TRUE(matches("template <typename T> class X;"
1024 "template <> class X<void> {};"
1025 "template <typename T> class X : public X<void> {};",
1026 IsDerivedFromX));
1027 EXPECT_TRUE(
1028 matches("class X {};"
1029 "template <typename T> class Z;"
1030 "template <> class Z<void> {};"
1031 "template <typename T> class Z : public Z<void>, public X {};",
1032 ZIsDerivedFromX));
1033 EXPECT_TRUE(
1034 notMatches("template<int> struct X;"
1035 "template<int i> struct X : public X<i-1> {};",
1036 cxxRecordDecl(isDerivedFrom(recordDecl(hasName("Some"))))));
1037 EXPECT_TRUE(matches(
1038 "struct A {};"
1039 "template<int> struct X;"
1040 "template<int i> struct X : public X<i-1> {};"
1041 "template<> struct X<0> : public A {};"
1042 "struct B : public X<42> {};",
1043 cxxRecordDecl(hasName("B"), isDerivedFrom(recordDecl(hasName("A"))))));
1044 EXPECT_TRUE(notMatches(
1045 "struct A {};"
1046 "template<int> struct X;"
1047 "template<int i> struct X : public X<i-1> {};"
1048 "template<> struct X<0> : public A {};"
1049 "struct B : public X<42> {};",
1050 cxxRecordDecl(hasName("B"),
1051 isDirectlyDerivedFrom(recordDecl(hasName("A"))))));
1052
1053 // FIXME: Once we have better matchers for template type matching,
1054 // get rid of the Variable(...) matching and match the right template
1055 // declarations directly.
1056 const char *RecursiveTemplateOneParameter =
1057 "class Base1 {}; class Base2 {};"
1058 "template <typename T> class Z;"
1059 "template <> class Z<void> : public Base1 {};"
1060 "template <> class Z<int> : public Base2 {};"
1061 "template <> class Z<float> : public Z<void> {};"
1062 "template <> class Z<double> : public Z<int> {};"
1063 "template <typename T> class Z : public Z<float>, public Z<double> {};"
1064 "void f() { Z<float> z_float; Z<double> z_double; Z<char> z_char; }";
1065 EXPECT_TRUE(matches(
1066 RecursiveTemplateOneParameter,
1067 varDecl(hasName("z_float"),
1068 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1")))))));
1069 EXPECT_TRUE(notMatches(
1070 RecursiveTemplateOneParameter,
1071 varDecl(hasName("z_float"),
1072 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2")))))));
1073 EXPECT_TRUE(
1074 matches(RecursiveTemplateOneParameter,
1075 varDecl(hasName("z_char"),
1076 hasInitializer(hasType(cxxRecordDecl(
1077 isDerivedFrom("Base1"), isDerivedFrom("Base2")))))));
1078
1079 const char *RecursiveTemplateTwoParameters =
1080 "class Base1 {}; class Base2 {};"
1081 "template <typename T1, typename T2> class Z;"
1082 "template <typename T> class Z<void, T> : public Base1 {};"
1083 "template <typename T> class Z<int, T> : public Base2 {};"
1084 "template <typename T> class Z<float, T> : public Z<void, T> {};"
1085 "template <typename T> class Z<double, T> : public Z<int, T> {};"
1086 "template <typename T1, typename T2> class Z : "
1087 " public Z<float, T2>, public Z<double, T2> {};"
1088 "void f() { Z<float, void> z_float; Z<double, void> z_double; "
1089 " Z<char, void> z_char; }";
1090 EXPECT_TRUE(matches(
1091 RecursiveTemplateTwoParameters,
1092 varDecl(hasName("z_float"),
1093 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1")))))));
1094 EXPECT_TRUE(notMatches(
1095 RecursiveTemplateTwoParameters,
1096 varDecl(hasName("z_float"),
1097 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2")))))));
1098 EXPECT_TRUE(
1099 matches(RecursiveTemplateTwoParameters,
1100 varDecl(hasName("z_char"),
1101 hasInitializer(hasType(cxxRecordDecl(
1102 isDerivedFrom("Base1"), isDerivedFrom("Base2")))))));
1103 EXPECT_TRUE(matches("namespace ns { class X {}; class Y : public X {}; }",
1104 cxxRecordDecl(isDerivedFrom("::ns::X"))));
1105 EXPECT_TRUE(notMatches("class X {}; class Y : public X {};",
1106 cxxRecordDecl(isDerivedFrom("::ns::X"))));
1107
1108 EXPECT_TRUE(matches(
1109 "class X {}; class Y : public X {};",
1110 cxxRecordDecl(isDerivedFrom(recordDecl(hasName("X")).bind("test")))));
1111
1112 EXPECT_TRUE(matches("template<typename T> class X {};"
1113 "template<typename T> using Z = X<T>;"
1114 "template <typename T> class Y : Z<T> {};",
1115 cxxRecordDecl(isDerivedFrom(namedDecl(hasName("X"))))));
1116 }
1117
TEST_P(ASTMatchersTest,IsDerivedFrom_EmptyName)1118 TEST_P(ASTMatchersTest, IsDerivedFrom_EmptyName) {
1119 if (!GetParam().isCXX()) {
1120 return;
1121 }
1122
1123 const char *const Code = "class X {}; class Y : public X {};";
1124 EXPECT_TRUE(notMatches(Code, cxxRecordDecl(isDerivedFrom(""))));
1125 EXPECT_TRUE(notMatches(Code, cxxRecordDecl(isDirectlyDerivedFrom(""))));
1126 EXPECT_TRUE(notMatches(Code, cxxRecordDecl(isSameOrDerivedFrom(""))));
1127 }
1128
TEST_P(ASTMatchersTest,IsDerivedFrom_ObjC)1129 TEST_P(ASTMatchersTest, IsDerivedFrom_ObjC) {
1130 DeclarationMatcher IsDerivedFromX = objcInterfaceDecl(isDerivedFrom("X"));
1131 EXPECT_TRUE(
1132 matchesObjC("@interface X @end @interface Y : X @end", IsDerivedFromX));
1133 EXPECT_TRUE(matchesObjC(
1134 "@interface X @end @interface Y<__covariant ObjectType> : X @end",
1135 IsDerivedFromX));
1136 EXPECT_TRUE(matchesObjC(
1137 "@interface X @end @compatibility_alias Y X; @interface Z : Y @end",
1138 IsDerivedFromX));
1139 EXPECT_TRUE(matchesObjC(
1140 "@interface X @end typedef X Y; @interface Z : Y @end", IsDerivedFromX));
1141 EXPECT_TRUE(notMatchesObjC("@interface X @end", IsDerivedFromX));
1142 EXPECT_TRUE(notMatchesObjC("@class X;", IsDerivedFromX));
1143 EXPECT_TRUE(notMatchesObjC("@class Y;", IsDerivedFromX));
1144 EXPECT_TRUE(notMatchesObjC("@interface X @end @compatibility_alias Y X;",
1145 IsDerivedFromX));
1146 EXPECT_TRUE(notMatchesObjC("@interface X @end typedef X Y;", IsDerivedFromX));
1147
1148 DeclarationMatcher IsDirectlyDerivedFromX =
1149 objcInterfaceDecl(isDirectlyDerivedFrom("X"));
1150 EXPECT_TRUE(matchesObjC("@interface X @end @interface Y : X @end",
1151 IsDirectlyDerivedFromX));
1152 EXPECT_TRUE(matchesObjC(
1153 "@interface X @end @interface Y<__covariant ObjectType> : X @end",
1154 IsDirectlyDerivedFromX));
1155 EXPECT_TRUE(matchesObjC(
1156 "@interface X @end @compatibility_alias Y X; @interface Z : Y @end",
1157 IsDirectlyDerivedFromX));
1158 EXPECT_TRUE(
1159 matchesObjC("@interface X @end typedef X Y; @interface Z : Y @end",
1160 IsDirectlyDerivedFromX));
1161 EXPECT_TRUE(notMatchesObjC("@interface X @end", IsDirectlyDerivedFromX));
1162 EXPECT_TRUE(notMatchesObjC("@class X;", IsDirectlyDerivedFromX));
1163 EXPECT_TRUE(notMatchesObjC("@class Y;", IsDirectlyDerivedFromX));
1164 EXPECT_TRUE(notMatchesObjC("@interface X @end @compatibility_alias Y X;",
1165 IsDirectlyDerivedFromX));
1166 EXPECT_TRUE(
1167 notMatchesObjC("@interface X @end typedef X Y;", IsDirectlyDerivedFromX));
1168
1169 DeclarationMatcher IsAX = objcInterfaceDecl(isSameOrDerivedFrom("X"));
1170 EXPECT_TRUE(matchesObjC("@interface X @end @interface Y : X @end", IsAX));
1171 EXPECT_TRUE(matchesObjC("@interface X @end", IsAX));
1172 EXPECT_TRUE(matchesObjC("@class X;", IsAX));
1173 EXPECT_TRUE(notMatchesObjC("@interface Y @end", IsAX));
1174 EXPECT_TRUE(notMatchesObjC("@class Y;", IsAX));
1175
1176 DeclarationMatcher ZIsDerivedFromX =
1177 objcInterfaceDecl(hasName("Z"), isDerivedFrom("X"));
1178 DeclarationMatcher ZIsDirectlyDerivedFromX =
1179 objcInterfaceDecl(hasName("Z"), isDirectlyDerivedFrom("X"));
1180 EXPECT_TRUE(matchesObjC(
1181 "@interface X @end @interface Y : X @end @interface Z : Y @end",
1182 ZIsDerivedFromX));
1183 EXPECT_TRUE(matchesObjC("@interface X @end @interface Y : X @end typedef Y "
1184 "V; typedef V W; @interface Z : W @end",
1185 ZIsDerivedFromX));
1186 EXPECT_TRUE(matchesObjC(
1187 "@interface X @end typedef X Y; @interface Z : Y @end", ZIsDerivedFromX));
1188 EXPECT_TRUE(
1189 matchesObjC("@interface X @end typedef X Y; @interface Z : Y @end",
1190 ZIsDirectlyDerivedFromX));
1191 EXPECT_TRUE(matchesObjC(
1192 "@interface A @end typedef A X; typedef A Y; @interface Z : Y @end",
1193 ZIsDerivedFromX));
1194 EXPECT_TRUE(matchesObjC(
1195 "@interface A @end typedef A X; typedef A Y; @interface Z : Y @end",
1196 ZIsDirectlyDerivedFromX));
1197 EXPECT_TRUE(matchesObjC(
1198 "@interface X @end @compatibility_alias Y X; @interface Z : Y @end",
1199 ZIsDerivedFromX));
1200 EXPECT_TRUE(matchesObjC(
1201 "@interface X @end @compatibility_alias Y X; @interface Z : Y @end",
1202 ZIsDirectlyDerivedFromX));
1203 EXPECT_TRUE(matchesObjC(
1204 "@interface Y @end @compatibility_alias X Y; @interface Z : Y @end",
1205 ZIsDerivedFromX));
1206 EXPECT_TRUE(matchesObjC(
1207 "@interface Y @end @compatibility_alias X Y; @interface Z : Y @end",
1208 ZIsDirectlyDerivedFromX));
1209 EXPECT_TRUE(matchesObjC(
1210 "@interface A @end @compatibility_alias X A; @compatibility_alias Y A;"
1211 "@interface Z : Y @end",
1212 ZIsDerivedFromX));
1213 EXPECT_TRUE(matchesObjC(
1214 "@interface A @end @compatibility_alias X A; @compatibility_alias Y A;"
1215 "@interface Z : Y @end",
1216 ZIsDirectlyDerivedFromX));
1217 EXPECT_TRUE(matchesObjC(
1218 "@interface Y @end typedef Y X; @interface Z : X @end", ZIsDerivedFromX));
1219 EXPECT_TRUE(
1220 matchesObjC("@interface Y @end typedef Y X; @interface Z : X @end",
1221 ZIsDirectlyDerivedFromX));
1222 EXPECT_TRUE(
1223 matchesObjC("@interface A @end @compatibility_alias Y A; typedef Y X;"
1224 "@interface Z : A @end",
1225 ZIsDerivedFromX));
1226 EXPECT_TRUE(
1227 matchesObjC("@interface A @end @compatibility_alias Y A; typedef Y X;"
1228 "@interface Z : A @end",
1229 ZIsDirectlyDerivedFromX));
1230 EXPECT_TRUE(
1231 matchesObjC("@interface A @end typedef A Y; @compatibility_alias X Y;"
1232 "@interface Z : A @end",
1233 ZIsDerivedFromX));
1234 EXPECT_TRUE(
1235 matchesObjC("@interface A @end typedef A Y; @compatibility_alias X Y;"
1236 "@interface Z : A @end",
1237 ZIsDirectlyDerivedFromX));
1238 }
1239
TEST_P(ASTMatchersTest,IsLambda)1240 TEST_P(ASTMatchersTest, IsLambda) {
1241 if (!GetParam().isCXX11OrLater()) {
1242 return;
1243 }
1244
1245 const auto IsLambda = cxxMethodDecl(ofClass(cxxRecordDecl(isLambda())));
1246 EXPECT_TRUE(matches("auto x = []{};", IsLambda));
1247 EXPECT_TRUE(notMatches("struct S { void operator()() const; };", IsLambda));
1248 }
1249
TEST_P(ASTMatchersTest,Bind)1250 TEST_P(ASTMatchersTest, Bind) {
1251 DeclarationMatcher ClassX = has(recordDecl(hasName("::X")).bind("x"));
1252
1253 EXPECT_TRUE(matchAndVerifyResultTrue(
1254 "class X {};", ClassX,
1255 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("x")));
1256
1257 EXPECT_TRUE(matchAndVerifyResultFalse(
1258 "class X {};", ClassX,
1259 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("other-id")));
1260
1261 TypeMatcher TypeAHasClassB = hasDeclaration(
1262 recordDecl(hasName("A"), has(recordDecl(hasName("B")).bind("b"))));
1263
1264 EXPECT_TRUE(matchAndVerifyResultTrue(
1265 "class A { public: A *a; class B {}; };", TypeAHasClassB,
1266 std::make_unique<VerifyIdIsBoundTo<Decl>>("b")));
1267
1268 StatementMatcher MethodX =
1269 callExpr(callee(cxxMethodDecl(hasName("x")))).bind("x");
1270
1271 EXPECT_TRUE(matchAndVerifyResultTrue(
1272 "class A { void x() { x(); } };", MethodX,
1273 std::make_unique<VerifyIdIsBoundTo<CXXMemberCallExpr>>("x")));
1274 }
1275
TEST_P(ASTMatchersTest,Bind_SameNameInAlternatives)1276 TEST_P(ASTMatchersTest, Bind_SameNameInAlternatives) {
1277 StatementMatcher matcher = anyOf(
1278 binaryOperator(hasOperatorName("+"), hasLHS(expr().bind("x")),
1279 hasRHS(integerLiteral(equals(0)))),
1280 binaryOperator(hasOperatorName("+"), hasLHS(integerLiteral(equals(0))),
1281 hasRHS(expr().bind("x"))));
1282
1283 EXPECT_TRUE(matchAndVerifyResultTrue(
1284 // The first branch of the matcher binds x to 0 but then fails.
1285 // The second branch binds x to f() and succeeds.
1286 "int f() { return 0 + f(); }", matcher,
1287 std::make_unique<VerifyIdIsBoundTo<CallExpr>>("x")));
1288 }
1289
TEST_P(ASTMatchersTest,Bind_BindsIDForMemoizedResults)1290 TEST_P(ASTMatchersTest, Bind_BindsIDForMemoizedResults) {
1291 // Using the same matcher in two match expressions will make memoization
1292 // kick in.
1293 DeclarationMatcher ClassX = recordDecl(hasName("X")).bind("x");
1294 EXPECT_TRUE(matchAndVerifyResultTrue(
1295 "class A { class B { class X {}; }; };",
1296 DeclarationMatcher(
1297 anyOf(recordDecl(hasName("A"), hasDescendant(ClassX)),
1298 recordDecl(hasName("B"), hasDescendant(ClassX)))),
1299 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 2)));
1300 }
1301
TEST_P(ASTMatchersTest,HasType_MatchesAsString)1302 TEST_P(ASTMatchersTest, HasType_MatchesAsString) {
1303 if (!GetParam().isCXX()) {
1304 // FIXME: Add a test for `hasType()` that does not depend on C++.
1305 return;
1306 }
1307
1308 EXPECT_TRUE(
1309 matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }",
1310 cxxMemberCallExpr(on(hasType(asString("class Y *"))))));
1311 EXPECT_TRUE(
1312 matches("class X { void x(int x) {} };",
1313 cxxMethodDecl(hasParameter(0, hasType(asString("int"))))));
1314 EXPECT_TRUE(matches("namespace ns { struct A {}; } struct B { ns::A a; };",
1315 fieldDecl(hasType(asString("ns::A")))));
1316 EXPECT_TRUE(
1317 matches("namespace { struct A {}; } struct B { A a; };",
1318 fieldDecl(hasType(asString("struct (anonymous namespace)::A")))));
1319 }
1320
TEST_P(ASTMatchersTest,HasOverloadedOperatorName)1321 TEST_P(ASTMatchersTest, HasOverloadedOperatorName) {
1322 if (!GetParam().isCXX()) {
1323 return;
1324 }
1325
1326 StatementMatcher OpCallAndAnd =
1327 cxxOperatorCallExpr(hasOverloadedOperatorName("&&"));
1328 EXPECT_TRUE(matches("class Y { }; "
1329 "bool operator&&(Y x, Y y) { return true; }; "
1330 "Y a; Y b; bool c = a && b;",
1331 OpCallAndAnd));
1332 StatementMatcher OpCallLessLess =
1333 cxxOperatorCallExpr(hasOverloadedOperatorName("<<"));
1334 EXPECT_TRUE(notMatches("class Y { }; "
1335 "bool operator&&(Y x, Y y) { return true; }; "
1336 "Y a; Y b; bool c = a && b;",
1337 OpCallLessLess));
1338 StatementMatcher OpStarCall =
1339 cxxOperatorCallExpr(hasOverloadedOperatorName("*"));
1340 EXPECT_TRUE(
1341 matches("class Y; int operator*(Y &); void f(Y &y) { *y; }", OpStarCall));
1342 DeclarationMatcher ClassWithOpStar =
1343 cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*")));
1344 EXPECT_TRUE(matches("class Y { int operator*(); };", ClassWithOpStar));
1345 EXPECT_TRUE(notMatches("class Y { void myOperator(); };", ClassWithOpStar));
1346 DeclarationMatcher AnyOpStar = functionDecl(hasOverloadedOperatorName("*"));
1347 EXPECT_TRUE(matches("class Y; int operator*(Y &);", AnyOpStar));
1348 EXPECT_TRUE(matches("class Y { int operator*(); };", AnyOpStar));
1349 DeclarationMatcher AnyAndOp =
1350 functionDecl(hasAnyOverloadedOperatorName("&", "&&"));
1351 EXPECT_TRUE(matches("class Y; Y operator&(Y &, Y &);", AnyAndOp));
1352 EXPECT_TRUE(matches("class Y; Y operator&&(Y &, Y &);", AnyAndOp));
1353 EXPECT_TRUE(matches("class Y { Y operator&(Y &); };", AnyAndOp));
1354 EXPECT_TRUE(matches("class Y { Y operator&&(Y &); };", AnyAndOp));
1355 }
1356
TEST_P(ASTMatchersTest,HasOverloadedOperatorName_MatchesNestedCalls)1357 TEST_P(ASTMatchersTest, HasOverloadedOperatorName_MatchesNestedCalls) {
1358 if (!GetParam().isCXX()) {
1359 return;
1360 }
1361
1362 EXPECT_TRUE(matchAndVerifyResultTrue(
1363 "class Y { }; "
1364 "Y& operator&&(Y& x, Y& y) { return x; }; "
1365 "Y a; Y b; Y c; Y d = a && b && c;",
1366 cxxOperatorCallExpr(hasOverloadedOperatorName("&&")).bind("x"),
1367 std::make_unique<VerifyIdIsBoundTo<CXXOperatorCallExpr>>("x", 2)));
1368 EXPECT_TRUE(matches("class Y { }; "
1369 "Y& operator&&(Y& x, Y& y) { return x; }; "
1370 "Y a; Y b; Y c; Y d = a && b && c;",
1371 cxxOperatorCallExpr(hasParent(cxxOperatorCallExpr()))));
1372 EXPECT_TRUE(
1373 matches("class Y { }; "
1374 "Y& operator&&(Y& x, Y& y) { return x; }; "
1375 "Y a; Y b; Y c; Y d = a && b && c;",
1376 cxxOperatorCallExpr(hasDescendant(cxxOperatorCallExpr()))));
1377 }
1378
TEST_P(ASTMatchersTest,HasLocalStorage)1379 TEST_P(ASTMatchersTest, HasLocalStorage) {
1380 auto M = varDecl(hasName("X"), hasLocalStorage());
1381 EXPECT_TRUE(matches("void f() { int X; }", M));
1382 EXPECT_TRUE(notMatches("int X;", M));
1383 EXPECT_TRUE(notMatches("void f() { static int X; }", M));
1384 }
1385
TEST_P(ASTMatchersTest,HasGlobalStorage)1386 TEST_P(ASTMatchersTest, HasGlobalStorage) {
1387 auto M = varDecl(hasName("X"), hasGlobalStorage());
1388 EXPECT_TRUE(notMatches("void f() { int X; }", M));
1389 EXPECT_TRUE(matches("int X;", M));
1390 EXPECT_TRUE(matches("void f() { static int X; }", M));
1391 }
1392
TEST_P(ASTMatchersTest,IsStaticLocal)1393 TEST_P(ASTMatchersTest, IsStaticLocal) {
1394 auto M = varDecl(isStaticLocal());
1395 EXPECT_TRUE(matches("void f() { static int X; }", M));
1396 EXPECT_TRUE(notMatches("static int X;", M));
1397 EXPECT_TRUE(notMatches("void f() { int X; }", M));
1398 EXPECT_TRUE(notMatches("int X;", M));
1399 }
1400
TEST_P(ASTMatchersTest,StorageDuration)1401 TEST_P(ASTMatchersTest, StorageDuration) {
1402 StringRef T =
1403 "void f() { int x; static int y; } int a;static int b;extern int c;";
1404
1405 EXPECT_TRUE(matches(T, varDecl(hasName("x"), hasAutomaticStorageDuration())));
1406 EXPECT_TRUE(
1407 notMatches(T, varDecl(hasName("y"), hasAutomaticStorageDuration())));
1408 EXPECT_TRUE(
1409 notMatches(T, varDecl(hasName("a"), hasAutomaticStorageDuration())));
1410
1411 EXPECT_TRUE(matches(T, varDecl(hasName("y"), hasStaticStorageDuration())));
1412 EXPECT_TRUE(matches(T, varDecl(hasName("a"), hasStaticStorageDuration())));
1413 EXPECT_TRUE(matches(T, varDecl(hasName("b"), hasStaticStorageDuration())));
1414 EXPECT_TRUE(matches(T, varDecl(hasName("c"), hasStaticStorageDuration())));
1415 EXPECT_TRUE(notMatches(T, varDecl(hasName("x"), hasStaticStorageDuration())));
1416
1417 // FIXME: Add thread_local variables to the source code snippet.
1418 EXPECT_TRUE(notMatches(T, varDecl(hasName("x"), hasThreadStorageDuration())));
1419 EXPECT_TRUE(notMatches(T, varDecl(hasName("y"), hasThreadStorageDuration())));
1420 EXPECT_TRUE(notMatches(T, varDecl(hasName("a"), hasThreadStorageDuration())));
1421 }
1422
TEST_P(ASTMatchersTest,VarDecl_MatchesFunctionParameter)1423 TEST_P(ASTMatchersTest, VarDecl_MatchesFunctionParameter) {
1424 EXPECT_TRUE(matches("void f(int i) {}", varDecl(hasName("i"))));
1425 }
1426
TEST_P(ASTMatchersTest,SizeOfExpr_MatchesCorrectType)1427 TEST_P(ASTMatchersTest, SizeOfExpr_MatchesCorrectType) {
1428 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }",
1429 sizeOfExpr(hasArgumentOfType(asString("int")))));
1430 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }",
1431 sizeOfExpr(hasArgumentOfType(asString("float")))));
1432 EXPECT_TRUE(matches(
1433 "struct A {}; void x() { struct A a; int b = sizeof(a); }",
1434 sizeOfExpr(hasArgumentOfType(hasDeclaration(recordDecl(hasName("A")))))));
1435 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }",
1436 sizeOfExpr(hasArgumentOfType(
1437 hasDeclaration(recordDecl(hasName("string")))))));
1438 }
1439
TEST_P(ASTMatchersTest,IsInteger_MatchesIntegers)1440 TEST_P(ASTMatchersTest, IsInteger_MatchesIntegers) {
1441 EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isInteger()))));
1442 EXPECT_TRUE(
1443 matches("long long i = 0; void f(long long) { }; void g() {f(i);}",
1444 callExpr(hasArgument(
1445 0, declRefExpr(to(varDecl(hasType(isInteger()))))))));
1446 }
1447
TEST_P(ASTMatchersTest,IsInteger_ReportsNoFalsePositives)1448 TEST_P(ASTMatchersTest, IsInteger_ReportsNoFalsePositives) {
1449 if (!GetParam().isCXX()) {
1450 // FIXME: Add a similar negative test for `isInteger()` that does not depend
1451 // on C++.
1452 return;
1453 }
1454
1455 EXPECT_TRUE(notMatches("int *i;", varDecl(hasType(isInteger()))));
1456 EXPECT_TRUE(
1457 notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}",
1458 callExpr(hasArgument(
1459 0, declRefExpr(to(varDecl(hasType(isInteger()))))))));
1460 }
1461
TEST_P(ASTMatchersTest,IsSignedInteger_MatchesSignedIntegers)1462 TEST_P(ASTMatchersTest, IsSignedInteger_MatchesSignedIntegers) {
1463 EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isSignedInteger()))));
1464 EXPECT_TRUE(
1465 notMatches("unsigned i = 0;", varDecl(hasType(isSignedInteger()))));
1466 }
1467
TEST_P(ASTMatchersTest,IsUnsignedInteger_MatchesUnsignedIntegers)1468 TEST_P(ASTMatchersTest, IsUnsignedInteger_MatchesUnsignedIntegers) {
1469 EXPECT_TRUE(notMatches("int i = 0;", varDecl(hasType(isUnsignedInteger()))));
1470 EXPECT_TRUE(
1471 matches("unsigned i = 0;", varDecl(hasType(isUnsignedInteger()))));
1472 }
1473
TEST_P(ASTMatchersTest,IsAnyPointer_MatchesPointers)1474 TEST_P(ASTMatchersTest, IsAnyPointer_MatchesPointers) {
1475 if (!GetParam().isCXX11OrLater()) {
1476 // FIXME: Add a test for `isAnyPointer()` that does not depend on C++.
1477 return;
1478 }
1479
1480 EXPECT_TRUE(matches("int* i = nullptr;", varDecl(hasType(isAnyPointer()))));
1481 }
1482
TEST_P(ASTMatchersTest,IsAnyPointer_MatchesObjcPointer)1483 TEST_P(ASTMatchersTest, IsAnyPointer_MatchesObjcPointer) {
1484 EXPECT_TRUE(matchesObjC("@interface Foo @end Foo *f;",
1485 varDecl(hasType(isAnyPointer()))));
1486 }
1487
TEST_P(ASTMatchersTest,IsAnyPointer_ReportsNoFalsePositives)1488 TEST_P(ASTMatchersTest, IsAnyPointer_ReportsNoFalsePositives) {
1489 EXPECT_TRUE(notMatches("int i = 0;", varDecl(hasType(isAnyPointer()))));
1490 }
1491
TEST_P(ASTMatchersTest,IsAnyCharacter_MatchesCharacters)1492 TEST_P(ASTMatchersTest, IsAnyCharacter_MatchesCharacters) {
1493 EXPECT_TRUE(matches("char i = 0;", varDecl(hasType(isAnyCharacter()))));
1494 }
1495
TEST_P(ASTMatchersTest,IsAnyCharacter_ReportsNoFalsePositives)1496 TEST_P(ASTMatchersTest, IsAnyCharacter_ReportsNoFalsePositives) {
1497 EXPECT_TRUE(notMatches("int i;", varDecl(hasType(isAnyCharacter()))));
1498 }
1499
TEST_P(ASTMatchersTest,IsArrow_MatchesMemberVariablesViaArrow)1500 TEST_P(ASTMatchersTest, IsArrow_MatchesMemberVariablesViaArrow) {
1501 if (!GetParam().isCXX()) {
1502 // FIXME: Add a test for `isArrow()` that does not depend on C++.
1503 return;
1504 }
1505 if (GetParam().hasDelayedTemplateParsing()) {
1506 // FIXME: Fix this test to work with delayed template parsing.
1507 return;
1508 }
1509
1510 EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };",
1511 memberExpr(isArrow())));
1512 EXPECT_TRUE(
1513 matches("class Y { void x() { y; } int y; };", memberExpr(isArrow())));
1514 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };",
1515 memberExpr(isArrow())));
1516 EXPECT_TRUE(matches("template <class T> class Y { void x() { this->m; } };",
1517 cxxDependentScopeMemberExpr(isArrow())));
1518 EXPECT_TRUE(
1519 notMatches("template <class T> class Y { void x() { (*this).m; } };",
1520 cxxDependentScopeMemberExpr(isArrow())));
1521 }
1522
TEST_P(ASTMatchersTest,IsArrow_MatchesStaticMemberVariablesViaArrow)1523 TEST_P(ASTMatchersTest, IsArrow_MatchesStaticMemberVariablesViaArrow) {
1524 if (!GetParam().isCXX()) {
1525 // FIXME: Add a test for `isArrow()` that does not depend on C++.
1526 return;
1527 }
1528
1529 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
1530 memberExpr(isArrow())));
1531 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
1532 memberExpr(isArrow())));
1533 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } static int y; };",
1534 memberExpr(isArrow())));
1535 }
1536
TEST_P(ASTMatchersTest,IsArrow_MatchesMemberCallsViaArrow)1537 TEST_P(ASTMatchersTest, IsArrow_MatchesMemberCallsViaArrow) {
1538 if (!GetParam().isCXX()) {
1539 // FIXME: Add a test for `isArrow()` that does not depend on C++.
1540 return;
1541 }
1542 if (GetParam().hasDelayedTemplateParsing()) {
1543 // FIXME: Fix this test to work with delayed template parsing.
1544 return;
1545 }
1546
1547 EXPECT_TRUE(
1548 matches("class Y { void x() { this->x(); } };", memberExpr(isArrow())));
1549 EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpr(isArrow())));
1550 EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",
1551 memberExpr(isArrow())));
1552 EXPECT_TRUE(
1553 matches("class Y { template <class T> void x() { this->x<T>(); } };",
1554 unresolvedMemberExpr(isArrow())));
1555 EXPECT_TRUE(matches("class Y { template <class T> void x() { x<T>(); } };",
1556 unresolvedMemberExpr(isArrow())));
1557 EXPECT_TRUE(
1558 notMatches("class Y { template <class T> void x() { (*this).x<T>(); } };",
1559 unresolvedMemberExpr(isArrow())));
1560 }
1561
TEST_P(ASTMatchersTest,IsExplicit_CXXConversionDecl)1562 TEST_P(ASTMatchersTest, IsExplicit_CXXConversionDecl) {
1563 if (!GetParam().isCXX11OrLater()) {
1564 return;
1565 }
1566
1567 EXPECT_TRUE(matches("struct S { explicit operator int(); };",
1568 cxxConversionDecl(isExplicit())));
1569 EXPECT_TRUE(notMatches("struct S { operator int(); };",
1570 cxxConversionDecl(isExplicit())));
1571 }
1572
TEST_P(ASTMatchersTest,IsExplicit_CXXConversionDecl_CXX20)1573 TEST_P(ASTMatchersTest, IsExplicit_CXXConversionDecl_CXX20) {
1574 if (!GetParam().isCXX20OrLater()) {
1575 return;
1576 }
1577
1578 EXPECT_TRUE(
1579 notMatches("template<bool b> struct S { explicit(b) operator int(); };",
1580 cxxConversionDecl(isExplicit())));
1581 EXPECT_TRUE(matches("struct S { explicit(true) operator int(); };",
1582 cxxConversionDecl(isExplicit())));
1583 EXPECT_TRUE(notMatches("struct S { explicit(false) operator int(); };",
1584 cxxConversionDecl(isExplicit())));
1585 }
1586
TEST_P(ASTMatchersTest,ArgumentCountIs_CallExpr)1587 TEST_P(ASTMatchersTest, ArgumentCountIs_CallExpr) {
1588 StatementMatcher Call1Arg = callExpr(argumentCountIs(1));
1589
1590 EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg));
1591 EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg));
1592 }
1593
TEST_P(ASTMatchersTest,ArgumentCountIs_CallExpr_CXX)1594 TEST_P(ASTMatchersTest, ArgumentCountIs_CallExpr_CXX) {
1595 if (!GetParam().isCXX()) {
1596 return;
1597 }
1598
1599 StatementMatcher Call1Arg = callExpr(argumentCountIs(1));
1600 EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg));
1601 }
1602
TEST_P(ASTMatchersTest,ParameterCountIs)1603 TEST_P(ASTMatchersTest, ParameterCountIs) {
1604 DeclarationMatcher Function1Arg = functionDecl(parameterCountIs(1));
1605 EXPECT_TRUE(matches("void f(int i) {}", Function1Arg));
1606 EXPECT_TRUE(notMatches("void f() {}", Function1Arg));
1607 EXPECT_TRUE(notMatches("void f(int i, int j, int k) {}", Function1Arg));
1608 EXPECT_TRUE(matches("void f(int i, ...) {};", Function1Arg));
1609 }
1610
TEST_P(ASTMatchersTest,ParameterCountIs_CXX)1611 TEST_P(ASTMatchersTest, ParameterCountIs_CXX) {
1612 if (!GetParam().isCXX()) {
1613 return;
1614 }
1615
1616 DeclarationMatcher Function1Arg = functionDecl(parameterCountIs(1));
1617 EXPECT_TRUE(matches("class X { void f(int i) {} };", Function1Arg));
1618 }
1619
TEST_P(ASTMatchersTest,References)1620 TEST_P(ASTMatchersTest, References) {
1621 if (!GetParam().isCXX()) {
1622 // FIXME: Add a test for `references()` that does not depend on C++.
1623 return;
1624 }
1625
1626 DeclarationMatcher ReferenceClassX =
1627 varDecl(hasType(references(recordDecl(hasName("X")))));
1628 EXPECT_TRUE(
1629 matches("class X {}; void y(X y) { X &x = y; }", ReferenceClassX));
1630 EXPECT_TRUE(
1631 matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
1632 // The match here is on the implicit copy constructor code for
1633 // class X, not on code 'X x = y'.
1634 EXPECT_TRUE(matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
1635 EXPECT_TRUE(notMatches("class X {}; extern X x;", ReferenceClassX));
1636 EXPECT_TRUE(
1637 notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
1638 }
1639
TEST_P(ASTMatchersTest,HasLocalQualifiers)1640 TEST_P(ASTMatchersTest, HasLocalQualifiers) {
1641 if (!GetParam().isCXX11OrLater()) {
1642 // FIXME: Add a test for `hasLocalQualifiers()` that does not depend on C++.
1643 return;
1644 }
1645
1646 EXPECT_TRUE(notMatches("typedef const int const_int; const_int i = 1;",
1647 varDecl(hasType(hasLocalQualifiers()))));
1648 EXPECT_TRUE(matches("int *const j = nullptr;",
1649 varDecl(hasType(hasLocalQualifiers()))));
1650 EXPECT_TRUE(
1651 matches("int *volatile k;", varDecl(hasType(hasLocalQualifiers()))));
1652 EXPECT_TRUE(notMatches("int m;", varDecl(hasType(hasLocalQualifiers()))));
1653 }
1654
TEST_P(ASTMatchersTest,IsExternC_MatchesExternCFunctionDeclarations)1655 TEST_P(ASTMatchersTest, IsExternC_MatchesExternCFunctionDeclarations) {
1656 if (!GetParam().isCXX()) {
1657 return;
1658 }
1659
1660 EXPECT_TRUE(matches("extern \"C\" void f() {}", functionDecl(isExternC())));
1661 EXPECT_TRUE(
1662 matches("extern \"C\" { void f() {} }", functionDecl(isExternC())));
1663 EXPECT_TRUE(notMatches("void f() {}", functionDecl(isExternC())));
1664 }
1665
TEST_P(ASTMatchersTest,IsExternC_MatchesExternCVariableDeclarations)1666 TEST_P(ASTMatchersTest, IsExternC_MatchesExternCVariableDeclarations) {
1667 if (!GetParam().isCXX()) {
1668 return;
1669 }
1670
1671 EXPECT_TRUE(matches("extern \"C\" int i;", varDecl(isExternC())));
1672 EXPECT_TRUE(matches("extern \"C\" { int i; }", varDecl(isExternC())));
1673 EXPECT_TRUE(notMatches("int i;", varDecl(isExternC())));
1674 }
1675
TEST_P(ASTMatchersTest,IsStaticStorageClass)1676 TEST_P(ASTMatchersTest, IsStaticStorageClass) {
1677 EXPECT_TRUE(
1678 matches("static void f() {}", functionDecl(isStaticStorageClass())));
1679 EXPECT_TRUE(matches("static int i = 1;", varDecl(isStaticStorageClass())));
1680 EXPECT_TRUE(notMatches("int i = 1;", varDecl(isStaticStorageClass())));
1681 EXPECT_TRUE(notMatches("extern int i;", varDecl(isStaticStorageClass())));
1682 EXPECT_TRUE(notMatches("void f() {}", functionDecl(isStaticStorageClass())));
1683 }
1684
TEST_P(ASTMatchersTest,IsDefaulted)1685 TEST_P(ASTMatchersTest, IsDefaulted) {
1686 if (!GetParam().isCXX()) {
1687 return;
1688 }
1689
1690 EXPECT_TRUE(notMatches("class A { ~A(); };",
1691 functionDecl(hasName("~A"), isDefaulted())));
1692 EXPECT_TRUE(matches("class B { ~B() = default; };",
1693 functionDecl(hasName("~B"), isDefaulted())));
1694 }
1695
TEST_P(ASTMatchersTest,IsDeleted)1696 TEST_P(ASTMatchersTest, IsDeleted) {
1697 if (!GetParam().isCXX()) {
1698 return;
1699 }
1700
1701 EXPECT_TRUE(
1702 notMatches("void Func();", functionDecl(hasName("Func"), isDeleted())));
1703 EXPECT_TRUE(matches("void Func() = delete;",
1704 functionDecl(hasName("Func"), isDeleted())));
1705 }
1706
TEST_P(ASTMatchersTest,IsNoThrow_DynamicExceptionSpec)1707 TEST_P(ASTMatchersTest, IsNoThrow_DynamicExceptionSpec) {
1708 if (!GetParam().supportsCXXDynamicExceptionSpecification()) {
1709 return;
1710 }
1711
1712 EXPECT_TRUE(notMatches("void f();", functionDecl(isNoThrow())));
1713 EXPECT_TRUE(notMatches("void f() throw(int);", functionDecl(isNoThrow())));
1714 EXPECT_TRUE(matches("void f() throw();", functionDecl(isNoThrow())));
1715
1716 EXPECT_TRUE(notMatches("void f();", functionProtoType(isNoThrow())));
1717 EXPECT_TRUE(
1718 notMatches("void f() throw(int);", functionProtoType(isNoThrow())));
1719 EXPECT_TRUE(matches("void f() throw();", functionProtoType(isNoThrow())));
1720 }
1721
TEST_P(ASTMatchersTest,IsNoThrow_CXX11)1722 TEST_P(ASTMatchersTest, IsNoThrow_CXX11) {
1723 if (!GetParam().isCXX11OrLater()) {
1724 return;
1725 }
1726
1727 EXPECT_TRUE(
1728 notMatches("void f() noexcept(false);", functionDecl(isNoThrow())));
1729 EXPECT_TRUE(matches("void f() noexcept;", functionDecl(isNoThrow())));
1730
1731 EXPECT_TRUE(
1732 notMatches("void f() noexcept(false);", functionProtoType(isNoThrow())));
1733 EXPECT_TRUE(matches("void f() noexcept;", functionProtoType(isNoThrow())));
1734 }
1735
TEST_P(ASTMatchersTest,IsConstexpr)1736 TEST_P(ASTMatchersTest, IsConstexpr) {
1737 if (!GetParam().isCXX11OrLater()) {
1738 return;
1739 }
1740
1741 EXPECT_TRUE(matches("constexpr int foo = 42;",
1742 varDecl(hasName("foo"), isConstexpr())));
1743 EXPECT_TRUE(matches("constexpr int bar();",
1744 functionDecl(hasName("bar"), isConstexpr())));
1745 }
1746
TEST_P(ASTMatchersTest,IsConstexpr_MatchesIfConstexpr)1747 TEST_P(ASTMatchersTest, IsConstexpr_MatchesIfConstexpr) {
1748 if (!GetParam().isCXX17OrLater()) {
1749 return;
1750 }
1751
1752 EXPECT_TRUE(
1753 matches("void baz() { if constexpr(1 > 0) {} }", ifStmt(isConstexpr())));
1754 EXPECT_TRUE(
1755 notMatches("void baz() { if (1 > 0) {} }", ifStmt(isConstexpr())));
1756 }
1757
TEST_P(ASTMatchersTest,HasInitStatement_MatchesSelectionInitializers)1758 TEST_P(ASTMatchersTest, HasInitStatement_MatchesSelectionInitializers) {
1759 EXPECT_TRUE(notMatches("void baz() { if (1 > 0) {} }",
1760 ifStmt(hasInitStatement(anything()))));
1761 EXPECT_TRUE(notMatches("void baz(int i) { switch (i) { default: break; } }",
1762 switchStmt(hasInitStatement(anything()))));
1763 }
1764
TEST_P(ASTMatchersTest,HasInitStatement_MatchesSelectionInitializers_CXX)1765 TEST_P(ASTMatchersTest, HasInitStatement_MatchesSelectionInitializers_CXX) {
1766 if (!GetParam().isCXX()) {
1767 return;
1768 }
1769
1770 EXPECT_TRUE(notMatches("void baz() { if (int i = 1) {} }",
1771 ifStmt(hasInitStatement(anything()))));
1772 }
1773
TEST_P(ASTMatchersTest,HasInitStatement_MatchesSelectionInitializers_CXX17)1774 TEST_P(ASTMatchersTest, HasInitStatement_MatchesSelectionInitializers_CXX17) {
1775 if (!GetParam().isCXX17OrLater()) {
1776 return;
1777 }
1778
1779 EXPECT_TRUE(matches("void baz() { if (int i = 1; i > 0) {} }",
1780 ifStmt(hasInitStatement(anything()))));
1781 EXPECT_TRUE(
1782 matches("void baz(int i) { switch (int j = i; j) { default: break; } }",
1783 switchStmt(hasInitStatement(anything()))));
1784 }
1785
TEST_P(ASTMatchersTest,HasInitStatement_MatchesRangeForInitializers)1786 TEST_P(ASTMatchersTest, HasInitStatement_MatchesRangeForInitializers) {
1787 if (!GetParam().isCXX20OrLater()) {
1788 return;
1789 }
1790
1791 EXPECT_TRUE(matches("void baz() {"
1792 "int items[] = {};"
1793 "for (auto &arr = items; auto &item : arr) {}"
1794 "}",
1795 cxxForRangeStmt(hasInitStatement(anything()))));
1796 EXPECT_TRUE(notMatches("void baz() {"
1797 "int items[] = {};"
1798 "for (auto &item : items) {}"
1799 "}",
1800 cxxForRangeStmt(hasInitStatement(anything()))));
1801 }
1802
TEST_P(ASTMatchersTest,TemplateArgumentCountIs)1803 TEST_P(ASTMatchersTest, TemplateArgumentCountIs) {
1804 if (!GetParam().isCXX()) {
1805 return;
1806 }
1807
1808 EXPECT_TRUE(
1809 matches("template<typename T> struct C {}; C<int> c;",
1810 classTemplateSpecializationDecl(templateArgumentCountIs(1))));
1811 EXPECT_TRUE(
1812 notMatches("template<typename T> struct C {}; C<int> c;",
1813 classTemplateSpecializationDecl(templateArgumentCountIs(2))));
1814
1815 EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
1816 templateSpecializationType(templateArgumentCountIs(1))));
1817 EXPECT_TRUE(
1818 notMatches("template<typename T> struct C {}; C<int> c;",
1819 templateSpecializationType(templateArgumentCountIs(2))));
1820 }
1821
TEST_P(ASTMatchersTest,IsIntegral)1822 TEST_P(ASTMatchersTest, IsIntegral) {
1823 if (!GetParam().isCXX()) {
1824 return;
1825 }
1826
1827 EXPECT_TRUE(matches(
1828 "template<int T> struct C {}; C<42> c;",
1829 classTemplateSpecializationDecl(hasAnyTemplateArgument(isIntegral()))));
1830 EXPECT_TRUE(notMatches("template<typename T> struct C {}; C<int> c;",
1831 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1832 templateArgument(isIntegral())))));
1833 }
1834
TEST_P(ASTMatchersTest,EqualsIntegralValue)1835 TEST_P(ASTMatchersTest, EqualsIntegralValue) {
1836 if (!GetParam().isCXX()) {
1837 return;
1838 }
1839
1840 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
1841 classTemplateSpecializationDecl(
1842 hasAnyTemplateArgument(equalsIntegralValue("42")))));
1843 EXPECT_TRUE(matches("template<int T> struct C {}; C<-42> c;",
1844 classTemplateSpecializationDecl(
1845 hasAnyTemplateArgument(equalsIntegralValue("-42")))));
1846 EXPECT_TRUE(matches("template<int T> struct C {}; C<-0042> c;",
1847 classTemplateSpecializationDecl(
1848 hasAnyTemplateArgument(equalsIntegralValue("-34")))));
1849 EXPECT_TRUE(notMatches("template<int T> struct C {}; C<42> c;",
1850 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1851 equalsIntegralValue("0042")))));
1852 }
1853
TEST_P(ASTMatchersTest,AccessSpecDecl)1854 TEST_P(ASTMatchersTest, AccessSpecDecl) {
1855 if (!GetParam().isCXX()) {
1856 return;
1857 }
1858
1859 EXPECT_TRUE(matches("class C { public: int i; };", accessSpecDecl()));
1860 EXPECT_TRUE(
1861 matches("class C { public: int i; };", accessSpecDecl(isPublic())));
1862 EXPECT_TRUE(
1863 notMatches("class C { public: int i; };", accessSpecDecl(isProtected())));
1864 EXPECT_TRUE(
1865 notMatches("class C { public: int i; };", accessSpecDecl(isPrivate())));
1866
1867 EXPECT_TRUE(notMatches("class C { int i; };", accessSpecDecl()));
1868 }
1869
TEST_P(ASTMatchersTest,IsFinal)1870 TEST_P(ASTMatchersTest, IsFinal) {
1871 if (!GetParam().isCXX11OrLater()) {
1872 return;
1873 }
1874
1875 EXPECT_TRUE(matches("class X final {};", cxxRecordDecl(isFinal())));
1876 EXPECT_TRUE(matches("class X { virtual void f() final; };",
1877 cxxMethodDecl(isFinal())));
1878 EXPECT_TRUE(notMatches("class X {};", cxxRecordDecl(isFinal())));
1879 EXPECT_TRUE(
1880 notMatches("class X { virtual void f(); };", cxxMethodDecl(isFinal())));
1881 }
1882
TEST_P(ASTMatchersTest,IsVirtual)1883 TEST_P(ASTMatchersTest, IsVirtual) {
1884 if (!GetParam().isCXX()) {
1885 return;
1886 }
1887
1888 EXPECT_TRUE(matches("class X { virtual int f(); };",
1889 cxxMethodDecl(isVirtual(), hasName("::X::f"))));
1890 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isVirtual())));
1891 }
1892
TEST_P(ASTMatchersTest,IsVirtualAsWritten)1893 TEST_P(ASTMatchersTest, IsVirtualAsWritten) {
1894 if (!GetParam().isCXX()) {
1895 return;
1896 }
1897
1898 EXPECT_TRUE(matches("class A { virtual int f(); };"
1899 "class B : public A { int f(); };",
1900 cxxMethodDecl(isVirtualAsWritten(), hasName("::A::f"))));
1901 EXPECT_TRUE(
1902 notMatches("class A { virtual int f(); };"
1903 "class B : public A { int f(); };",
1904 cxxMethodDecl(isVirtualAsWritten(), hasName("::B::f"))));
1905 }
1906
TEST_P(ASTMatchersTest,IsPure)1907 TEST_P(ASTMatchersTest, IsPure) {
1908 if (!GetParam().isCXX()) {
1909 return;
1910 }
1911
1912 EXPECT_TRUE(matches("class X { virtual int f() = 0; };",
1913 cxxMethodDecl(isPure(), hasName("::X::f"))));
1914 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isPure())));
1915 }
1916
TEST_P(ASTMatchersTest,IsCopyAssignmentOperator)1917 TEST_P(ASTMatchersTest, IsCopyAssignmentOperator) {
1918 if (!GetParam().isCXX()) {
1919 return;
1920 }
1921
1922 auto CopyAssignment =
1923 cxxMethodDecl(isCopyAssignmentOperator(), unless(isImplicit()));
1924 EXPECT_TRUE(matches("class X { X &operator=(X); };", CopyAssignment));
1925 EXPECT_TRUE(matches("class X { X &operator=(X &); };", CopyAssignment));
1926 EXPECT_TRUE(matches("class X { X &operator=(const X &); };", CopyAssignment));
1927 EXPECT_TRUE(matches("class X { X &operator=(volatile X &); };", //
1928 CopyAssignment));
1929 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &); };",
1930 CopyAssignment));
1931 EXPECT_TRUE(notMatches("class X { X &operator=(X &&); };", CopyAssignment));
1932 }
1933
TEST_P(ASTMatchersTest,IsMoveAssignmentOperator)1934 TEST_P(ASTMatchersTest, IsMoveAssignmentOperator) {
1935 if (!GetParam().isCXX()) {
1936 return;
1937 }
1938
1939 auto MoveAssignment =
1940 cxxMethodDecl(isMoveAssignmentOperator(), unless(isImplicit()));
1941 EXPECT_TRUE(notMatches("class X { X &operator=(X); };", MoveAssignment));
1942 EXPECT_TRUE(matches("class X { X &operator=(X &&); };", MoveAssignment));
1943 EXPECT_TRUE(matches("class X { X &operator=(const X &&); };", //
1944 MoveAssignment));
1945 EXPECT_TRUE(matches("class X { X &operator=(volatile X &&); };", //
1946 MoveAssignment));
1947 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &&); };",
1948 MoveAssignment));
1949 EXPECT_TRUE(notMatches("class X { X &operator=(X &); };", MoveAssignment));
1950 }
1951
TEST_P(ASTMatchersTest,IsConst)1952 TEST_P(ASTMatchersTest, IsConst) {
1953 if (!GetParam().isCXX()) {
1954 return;
1955 }
1956
1957 EXPECT_TRUE(
1958 matches("struct A { void foo() const; };", cxxMethodDecl(isConst())));
1959 EXPECT_TRUE(
1960 notMatches("struct A { void foo(); };", cxxMethodDecl(isConst())));
1961 }
1962
TEST_P(ASTMatchersTest,IsOverride)1963 TEST_P(ASTMatchersTest, IsOverride) {
1964 if (!GetParam().isCXX()) {
1965 return;
1966 }
1967
1968 EXPECT_TRUE(matches("class X { virtual int f(); }; "
1969 "class Y : public X { int f(); };",
1970 cxxMethodDecl(isOverride(), hasName("::Y::f"))));
1971 EXPECT_TRUE(notMatches("class X { virtual int f(); }; "
1972 "class Y : public X { int f(); };",
1973 cxxMethodDecl(isOverride(), hasName("::X::f"))));
1974 EXPECT_TRUE(notMatches("class X { int f(); }; "
1975 "class Y : public X { int f(); };",
1976 cxxMethodDecl(isOverride())));
1977 EXPECT_TRUE(notMatches("class X { int f(); int f(int); }; ",
1978 cxxMethodDecl(isOverride())));
1979 EXPECT_TRUE(
1980 matches("template <typename Base> struct Y : Base { void f() override;};",
1981 cxxMethodDecl(isOverride(), hasName("::Y::f"))));
1982 }
1983
TEST_P(ASTMatchersTest,HasArgument_CXXConstructorDecl)1984 TEST_P(ASTMatchersTest, HasArgument_CXXConstructorDecl) {
1985 if (!GetParam().isCXX()) {
1986 return;
1987 }
1988
1989 auto Constructor = traverse(
1990 TK_AsIs,
1991 cxxConstructExpr(hasArgument(0, declRefExpr(to(varDecl(hasName("y")))))));
1992
1993 EXPECT_TRUE(matches(
1994 "class X { public: X(int); }; void x() { int y; X x(y); }", Constructor));
1995 EXPECT_TRUE(
1996 matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
1997 Constructor));
1998 EXPECT_TRUE(
1999 matches("class X { public: X(int); }; void x() { int y; X x = y; }",
2000 Constructor));
2001 EXPECT_TRUE(notMatches(
2002 "class X { public: X(int); }; void x() { int z; X x(z); }", Constructor));
2003
2004 StatementMatcher WrongIndex =
2005 traverse(TK_AsIs, cxxConstructExpr(hasArgument(
2006 42, declRefExpr(to(varDecl(hasName("y")))))));
2007 EXPECT_TRUE(notMatches(
2008 "class X { public: X(int); }; void x() { int y; X x(y); }", WrongIndex));
2009 }
2010
TEST_P(ASTMatchersTest,ArgumentCountIs_CXXConstructExpr)2011 TEST_P(ASTMatchersTest, ArgumentCountIs_CXXConstructExpr) {
2012 if (!GetParam().isCXX()) {
2013 return;
2014 }
2015
2016 auto Constructor1Arg =
2017 traverse(TK_AsIs, cxxConstructExpr(argumentCountIs(1)));
2018
2019 EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x(0); }",
2020 Constructor1Arg));
2021 EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x = X(0); }",
2022 Constructor1Arg));
2023 EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x = 0; }",
2024 Constructor1Arg));
2025 EXPECT_TRUE(
2026 notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
2027 Constructor1Arg));
2028 }
2029
TEST(ASTMatchersTest,NamesMember_CXXDependentScopeMemberExpr)2030 TEST(ASTMatchersTest, NamesMember_CXXDependentScopeMemberExpr) {
2031
2032 // Member functions:
2033 {
2034 auto Code = "template <typename T> struct S{ void mem(); }; template "
2035 "<typename T> void x() { S<T> s; s.mem(); }";
2036
2037 EXPECT_TRUE(matches(
2038 Code,
2039 cxxDependentScopeMemberExpr(
2040 hasObjectExpression(declRefExpr(hasType(templateSpecializationType(
2041 hasDeclaration(classTemplateDecl(has(cxxRecordDecl(
2042 has(cxxMethodDecl(hasName("mem")).bind("templMem")))))))))),
2043 memberHasSameNameAsBoundNode("templMem"))));
2044
2045 EXPECT_TRUE(
2046 matches(Code, cxxDependentScopeMemberExpr(hasMemberName("mem"))));
2047 }
2048
2049 // Member variables:
2050 {
2051 auto Code = "template <typename T> struct S{ int mem; }; template "
2052 "<typename T> void x() { S<T> s; s.mem; }";
2053
2054 EXPECT_TRUE(
2055 matches(Code, cxxDependentScopeMemberExpr(hasMemberName("mem"))));
2056
2057 EXPECT_TRUE(matches(
2058 Code,
2059 cxxDependentScopeMemberExpr(
2060 hasObjectExpression(declRefExpr(hasType(templateSpecializationType(
2061 hasDeclaration(classTemplateDecl(has(cxxRecordDecl(
2062 has(fieldDecl(hasName("mem")).bind("templMem")))))))))),
2063 memberHasSameNameAsBoundNode("templMem"))));
2064 }
2065
2066 // static member variables:
2067 {
2068 auto Code = "template <typename T> struct S{ static int mem; }; template "
2069 "<typename T> void x() { S<T> s; s.mem; }";
2070
2071 EXPECT_TRUE(
2072 matches(Code, cxxDependentScopeMemberExpr(hasMemberName("mem"))));
2073
2074 EXPECT_TRUE(matches(
2075 Code,
2076 cxxDependentScopeMemberExpr(
2077 hasObjectExpression(declRefExpr(hasType(templateSpecializationType(
2078 hasDeclaration(classTemplateDecl(has(cxxRecordDecl(
2079 has(varDecl(hasName("mem")).bind("templMem")))))))))),
2080 memberHasSameNameAsBoundNode("templMem"))));
2081 }
2082 {
2083 auto Code = R"cpp(
2084 template <typename T>
2085 struct S {
2086 bool operator==(int) const { return true; }
2087 };
2088
2089 template <typename T>
2090 void func(T t) {
2091 S<T> s;
2092 s.operator==(1);
2093 }
2094 )cpp";
2095
2096 EXPECT_TRUE(matches(
2097 Code, cxxDependentScopeMemberExpr(hasMemberName("operator=="))));
2098 }
2099
2100 // other named decl:
2101 {
2102 auto Code = "template <typename T> struct S{ static int mem; }; struct "
2103 "mem{}; template "
2104 "<typename T> void x() { S<T> s; s.mem; }";
2105
2106 EXPECT_TRUE(matches(
2107 Code,
2108 translationUnitDecl(has(cxxRecordDecl(hasName("mem"))),
2109 hasDescendant(cxxDependentScopeMemberExpr()))));
2110
2111 EXPECT_FALSE(matches(
2112 Code,
2113 translationUnitDecl(has(cxxRecordDecl(hasName("mem")).bind("templMem")),
2114 hasDescendant(cxxDependentScopeMemberExpr(
2115 memberHasSameNameAsBoundNode("templMem"))))));
2116 }
2117 }
2118
TEST(ASTMatchersTest,ArgumentCountIs_CXXUnresolvedConstructExpr)2119 TEST(ASTMatchersTest, ArgumentCountIs_CXXUnresolvedConstructExpr) {
2120 const auto *Code =
2121 "template <typename T> struct S{}; template <typename T> void "
2122 "x() { auto s = S<T>(); }";
2123
2124 EXPECT_TRUE(matches(Code, cxxUnresolvedConstructExpr(argumentCountIs(0))));
2125 EXPECT_TRUE(notMatches(Code, cxxUnresolvedConstructExpr(argumentCountIs(1))));
2126 }
2127
TEST(ASTMatchersTest,HasArgument_CXXUnresolvedConstructExpr)2128 TEST(ASTMatchersTest, HasArgument_CXXUnresolvedConstructExpr) {
2129 const auto *Code =
2130 "template <typename T> struct S{ S(int){} }; template <typename "
2131 "T> void x() { int y; auto s = S<T>(y); }";
2132 EXPECT_TRUE(matches(Code, cxxUnresolvedConstructExpr(hasArgument(
2133 0, declRefExpr(to(varDecl(hasName("y"))))))));
2134 EXPECT_TRUE(
2135 notMatches(Code, cxxUnresolvedConstructExpr(hasArgument(
2136 0, declRefExpr(to(varDecl(hasName("x"))))))));
2137 }
2138
TEST_P(ASTMatchersTest,IsListInitialization)2139 TEST_P(ASTMatchersTest, IsListInitialization) {
2140 if (!GetParam().isCXX11OrLater()) {
2141 return;
2142 }
2143
2144 auto ConstructorListInit =
2145 traverse(TK_AsIs, varDecl(has(cxxConstructExpr(isListInitialization()))));
2146
2147 EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x{0}; }",
2148 ConstructorListInit));
2149 EXPECT_FALSE(matches("class X { public: X(int); }; void x() { X x(0); }",
2150 ConstructorListInit));
2151 }
2152
TEST_P(ASTMatchersTest,IsImplicit_CXXConstructorDecl)2153 TEST_P(ASTMatchersTest, IsImplicit_CXXConstructorDecl) {
2154 if (!GetParam().isCXX()) {
2155 return;
2156 }
2157
2158 // This one doesn't match because the constructor is not added by the
2159 // compiler (it is not needed).
2160 EXPECT_TRUE(notMatches("class Foo { };", cxxConstructorDecl(isImplicit())));
2161 // The compiler added the implicit default constructor.
2162 EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
2163 cxxConstructorDecl(isImplicit())));
2164 EXPECT_TRUE(matches("class Foo { Foo(){} };",
2165 cxxConstructorDecl(unless(isImplicit()))));
2166 // The compiler added an implicit assignment operator.
2167 EXPECT_TRUE(matches("struct A { int x; } a = {0}, b = a; void f() { a = b; }",
2168 cxxMethodDecl(isImplicit(), hasName("operator="))));
2169 }
2170
TEST_P(ASTMatchersTest,IsExplicit_CXXConstructorDecl)2171 TEST_P(ASTMatchersTest, IsExplicit_CXXConstructorDecl) {
2172 if (!GetParam().isCXX()) {
2173 return;
2174 }
2175
2176 EXPECT_TRUE(matches("struct S { explicit S(int); };",
2177 cxxConstructorDecl(isExplicit())));
2178 EXPECT_TRUE(
2179 notMatches("struct S { S(int); };", cxxConstructorDecl(isExplicit())));
2180 }
2181
TEST_P(ASTMatchersTest,IsExplicit_CXXConstructorDecl_CXX20)2182 TEST_P(ASTMatchersTest, IsExplicit_CXXConstructorDecl_CXX20) {
2183 if (!GetParam().isCXX20OrLater()) {
2184 return;
2185 }
2186
2187 EXPECT_TRUE(notMatches("template<bool b> struct S { explicit(b) S(int);};",
2188 cxxConstructorDecl(isExplicit())));
2189 EXPECT_TRUE(matches("struct S { explicit(true) S(int);};",
2190 cxxConstructorDecl(isExplicit())));
2191 EXPECT_TRUE(notMatches("struct S { explicit(false) S(int);};",
2192 cxxConstructorDecl(isExplicit())));
2193 }
2194
TEST_P(ASTMatchersTest,IsExplicit_CXXDeductionGuideDecl)2195 TEST_P(ASTMatchersTest, IsExplicit_CXXDeductionGuideDecl) {
2196 if (!GetParam().isCXX17OrLater()) {
2197 return;
2198 }
2199
2200 EXPECT_TRUE(notMatches("template<typename T> struct S { S(int);};"
2201 "S(int) -> S<int>;",
2202 cxxDeductionGuideDecl(isExplicit())));
2203 EXPECT_TRUE(matches("template<typename T> struct S { S(int);};"
2204 "explicit S(int) -> S<int>;",
2205 cxxDeductionGuideDecl(isExplicit())));
2206 }
2207
TEST_P(ASTMatchersTest,IsExplicit_CXXDeductionGuideDecl_CXX20)2208 TEST_P(ASTMatchersTest, IsExplicit_CXXDeductionGuideDecl_CXX20) {
2209 if (!GetParam().isCXX20OrLater()) {
2210 return;
2211 }
2212
2213 EXPECT_TRUE(matches("template<typename T> struct S { S(int);};"
2214 "explicit(true) S(int) -> S<int>;",
2215 cxxDeductionGuideDecl(isExplicit())));
2216 EXPECT_TRUE(notMatches("template<typename T> struct S { S(int);};"
2217 "explicit(false) S(int) -> S<int>;",
2218 cxxDeductionGuideDecl(isExplicit())));
2219 EXPECT_TRUE(
2220 notMatches("template<typename T> struct S { S(int);};"
2221 "template<bool b = true> explicit(b) S(int) -> S<int>;",
2222 cxxDeductionGuideDecl(isExplicit())));
2223 }
2224
TEST_P(ASTMatchersTest,CXXConstructorDecl_Kinds)2225 TEST_P(ASTMatchersTest, CXXConstructorDecl_Kinds) {
2226 if (!GetParam().isCXX()) {
2227 return;
2228 }
2229
2230 EXPECT_TRUE(
2231 matches("struct S { S(); };", cxxConstructorDecl(isDefaultConstructor(),
2232 unless(isImplicit()))));
2233 EXPECT_TRUE(notMatches(
2234 "struct S { S(); };",
2235 cxxConstructorDecl(isCopyConstructor(), unless(isImplicit()))));
2236 EXPECT_TRUE(notMatches(
2237 "struct S { S(); };",
2238 cxxConstructorDecl(isMoveConstructor(), unless(isImplicit()))));
2239
2240 EXPECT_TRUE(notMatches(
2241 "struct S { S(const S&); };",
2242 cxxConstructorDecl(isDefaultConstructor(), unless(isImplicit()))));
2243 EXPECT_TRUE(
2244 matches("struct S { S(const S&); };",
2245 cxxConstructorDecl(isCopyConstructor(), unless(isImplicit()))));
2246 EXPECT_TRUE(notMatches(
2247 "struct S { S(const S&); };",
2248 cxxConstructorDecl(isMoveConstructor(), unless(isImplicit()))));
2249
2250 EXPECT_TRUE(notMatches(
2251 "struct S { S(S&&); };",
2252 cxxConstructorDecl(isDefaultConstructor(), unless(isImplicit()))));
2253 EXPECT_TRUE(notMatches(
2254 "struct S { S(S&&); };",
2255 cxxConstructorDecl(isCopyConstructor(), unless(isImplicit()))));
2256 EXPECT_TRUE(
2257 matches("struct S { S(S&&); };",
2258 cxxConstructorDecl(isMoveConstructor(), unless(isImplicit()))));
2259 }
2260
TEST_P(ASTMatchersTest,IsUserProvided)2261 TEST_P(ASTMatchersTest, IsUserProvided) {
2262 if (!GetParam().isCXX11OrLater()) {
2263 return;
2264 }
2265
2266 EXPECT_TRUE(notMatches("struct S { int X = 0; };",
2267 cxxConstructorDecl(isUserProvided())));
2268 EXPECT_TRUE(notMatches("struct S { S() = default; };",
2269 cxxConstructorDecl(isUserProvided())));
2270 EXPECT_TRUE(notMatches("struct S { S() = delete; };",
2271 cxxConstructorDecl(isUserProvided())));
2272 EXPECT_TRUE(
2273 matches("struct S { S(); };", cxxConstructorDecl(isUserProvided())));
2274 EXPECT_TRUE(matches("struct S { S(); }; S::S(){}",
2275 cxxConstructorDecl(isUserProvided())));
2276 }
2277
TEST_P(ASTMatchersTest,IsDelegatingConstructor)2278 TEST_P(ASTMatchersTest, IsDelegatingConstructor) {
2279 if (!GetParam().isCXX11OrLater()) {
2280 return;
2281 }
2282
2283 EXPECT_TRUE(notMatches("struct S { S(); S(int); int X; };",
2284 cxxConstructorDecl(isDelegatingConstructor())));
2285 EXPECT_TRUE(notMatches("struct S { S(){} S(int X) : X(X) {} int X; };",
2286 cxxConstructorDecl(isDelegatingConstructor())));
2287 EXPECT_TRUE(matches(
2288 "struct S { S() : S(0) {} S(int X) : X(X) {} int X; };",
2289 cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(0))));
2290 EXPECT_TRUE(matches(
2291 "struct S { S(); S(int X); int X; }; S::S(int X) : S() {}",
2292 cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(1))));
2293 }
2294
TEST_P(ASTMatchersTest,HasSize)2295 TEST_P(ASTMatchersTest, HasSize) {
2296 StatementMatcher Literal = stringLiteral(hasSize(4));
2297 EXPECT_TRUE(matches("const char *s = \"abcd\";", Literal));
2298 // with escaped characters
2299 EXPECT_TRUE(matches("const char *s = \"\x05\x06\x07\x08\";", Literal));
2300 // no matching, too small
2301 EXPECT_TRUE(notMatches("const char *s = \"ab\";", Literal));
2302 }
2303
TEST_P(ASTMatchersTest,HasSize_CXX)2304 TEST_P(ASTMatchersTest, HasSize_CXX) {
2305 if (!GetParam().isCXX()) {
2306 // FIXME: Fix this test to also work in non-C++ language modes.
2307 return;
2308 }
2309
2310 StatementMatcher Literal = stringLiteral(hasSize(4));
2311 // wide string
2312 EXPECT_TRUE(matches("const wchar_t *s = L\"abcd\";", Literal));
2313 }
2314
TEST_P(ASTMatchersTest,HasName_MatchesNamespaces)2315 TEST_P(ASTMatchersTest, HasName_MatchesNamespaces) {
2316 if (!GetParam().isCXX()) {
2317 return;
2318 }
2319
2320 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
2321 recordDecl(hasName("a::b::C"))));
2322 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
2323 recordDecl(hasName("::a::b::C"))));
2324 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
2325 recordDecl(hasName("b::C"))));
2326 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
2327 recordDecl(hasName("C"))));
2328 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2329 recordDecl(hasName("c::b::C"))));
2330 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2331 recordDecl(hasName("a::c::C"))));
2332 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2333 recordDecl(hasName("a::b::A"))));
2334 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2335 recordDecl(hasName("::C"))));
2336 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2337 recordDecl(hasName("::b::C"))));
2338 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2339 recordDecl(hasName("z::a::b::C"))));
2340 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
2341 recordDecl(hasName("a+b::C"))));
2342 EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
2343 recordDecl(hasName("C"))));
2344 }
2345
TEST_P(ASTMatchersTest,HasName_MatchesOuterClasses)2346 TEST_P(ASTMatchersTest, HasName_MatchesOuterClasses) {
2347 if (!GetParam().isCXX()) {
2348 return;
2349 }
2350
2351 EXPECT_TRUE(matches("class A { class B { class C; }; };",
2352 recordDecl(hasName("A::B::C"))));
2353 EXPECT_TRUE(matches("class A { class B { class C; }; };",
2354 recordDecl(hasName("::A::B::C"))));
2355 EXPECT_TRUE(matches("class A { class B { class C; }; };",
2356 recordDecl(hasName("B::C"))));
2357 EXPECT_TRUE(
2358 matches("class A { class B { class C; }; };", recordDecl(hasName("C"))));
2359 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2360 recordDecl(hasName("c::B::C"))));
2361 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2362 recordDecl(hasName("A::c::C"))));
2363 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2364 recordDecl(hasName("A::B::A"))));
2365 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2366 recordDecl(hasName("::C"))));
2367 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2368 recordDecl(hasName("::B::C"))));
2369 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2370 recordDecl(hasName("z::A::B::C"))));
2371 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
2372 recordDecl(hasName("A+B::C"))));
2373 }
2374
TEST_P(ASTMatchersTest,HasName_MatchesInlinedNamespaces)2375 TEST_P(ASTMatchersTest, HasName_MatchesInlinedNamespaces) {
2376 if (!GetParam().isCXX()) {
2377 return;
2378 }
2379
2380 StringRef code = "namespace a { inline namespace b { class C; } }";
2381 EXPECT_TRUE(matches(code, recordDecl(hasName("a::b::C"))));
2382 EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
2383 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::b::C"))));
2384 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
2385 }
2386
TEST_P(ASTMatchersTest,HasName_MatchesAnonymousNamespaces)2387 TEST_P(ASTMatchersTest, HasName_MatchesAnonymousNamespaces) {
2388 if (!GetParam().isCXX()) {
2389 return;
2390 }
2391
2392 StringRef code = "namespace a { namespace { class C; } }";
2393 EXPECT_TRUE(
2394 matches(code, recordDecl(hasName("a::(anonymous namespace)::C"))));
2395 EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
2396 EXPECT_TRUE(
2397 matches(code, recordDecl(hasName("::a::(anonymous namespace)::C"))));
2398 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
2399 }
2400
TEST_P(ASTMatchersTest,HasName_MatchesAnonymousOuterClasses)2401 TEST_P(ASTMatchersTest, HasName_MatchesAnonymousOuterClasses) {
2402 if (!GetParam().isCXX()) {
2403 return;
2404 }
2405
2406 EXPECT_TRUE(matches("class A { class { class C; } x; };",
2407 recordDecl(hasName("A::(anonymous class)::C"))));
2408 EXPECT_TRUE(matches("class A { class { class C; } x; };",
2409 recordDecl(hasName("::A::(anonymous class)::C"))));
2410 EXPECT_FALSE(matches("class A { class { class C; } x; };",
2411 recordDecl(hasName("::A::C"))));
2412 EXPECT_TRUE(matches("class A { struct { class C; } x; };",
2413 recordDecl(hasName("A::(anonymous struct)::C"))));
2414 EXPECT_TRUE(matches("class A { struct { class C; } x; };",
2415 recordDecl(hasName("::A::(anonymous struct)::C"))));
2416 EXPECT_FALSE(matches("class A { struct { class C; } x; };",
2417 recordDecl(hasName("::A::C"))));
2418 }
2419
TEST_P(ASTMatchersTest,HasName_MatchesFunctionScope)2420 TEST_P(ASTMatchersTest, HasName_MatchesFunctionScope) {
2421 if (!GetParam().isCXX()) {
2422 return;
2423 }
2424
2425 StringRef code =
2426 "namespace a { void F(int a) { struct S { int m; }; int i; } }";
2427 EXPECT_TRUE(matches(code, varDecl(hasName("i"))));
2428 EXPECT_FALSE(matches(code, varDecl(hasName("F()::i"))));
2429
2430 EXPECT_TRUE(matches(code, fieldDecl(hasName("m"))));
2431 EXPECT_TRUE(matches(code, fieldDecl(hasName("S::m"))));
2432 EXPECT_TRUE(matches(code, fieldDecl(hasName("F(int)::S::m"))));
2433 EXPECT_TRUE(matches(code, fieldDecl(hasName("a::F(int)::S::m"))));
2434 EXPECT_TRUE(matches(code, fieldDecl(hasName("::a::F(int)::S::m"))));
2435 }
2436
TEST_P(ASTMatchersTest,HasName_QualifiedStringMatchesThroughLinkage)2437 TEST_P(ASTMatchersTest, HasName_QualifiedStringMatchesThroughLinkage) {
2438 if (!GetParam().isCXX()) {
2439 return;
2440 }
2441
2442 // https://bugs.llvm.org/show_bug.cgi?id=42193
2443 StringRef code = R"cpp(namespace foo { extern "C" void test(); })cpp";
2444 EXPECT_TRUE(matches(code, functionDecl(hasName("test"))));
2445 EXPECT_TRUE(matches(code, functionDecl(hasName("foo::test"))));
2446 EXPECT_TRUE(matches(code, functionDecl(hasName("::foo::test"))));
2447 EXPECT_TRUE(notMatches(code, functionDecl(hasName("::test"))));
2448
2449 code = R"cpp(namespace foo { extern "C" { void test(); } })cpp";
2450 EXPECT_TRUE(matches(code, functionDecl(hasName("test"))));
2451 EXPECT_TRUE(matches(code, functionDecl(hasName("foo::test"))));
2452 EXPECT_TRUE(matches(code, functionDecl(hasName("::foo::test"))));
2453 EXPECT_TRUE(notMatches(code, functionDecl(hasName("::test"))));
2454 }
2455
TEST_P(ASTMatchersTest,HasAnyName)2456 TEST_P(ASTMatchersTest, HasAnyName) {
2457 if (!GetParam().isCXX()) {
2458 // FIXME: Add a test for `hasAnyName()` that does not depend on C++.
2459 return;
2460 }
2461
2462 StringRef Code = "namespace a { namespace b { class C; } }";
2463
2464 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "a::b::C"))));
2465 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("a::b::C", "XX"))));
2466 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX::C", "a::b::C"))));
2467 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "C"))));
2468
2469 EXPECT_TRUE(notMatches(Code, recordDecl(hasAnyName("::C", "::b::C"))));
2470 EXPECT_TRUE(
2471 matches(Code, recordDecl(hasAnyName("::C", "::b::C", "::a::b::C"))));
2472
2473 std::vector<StringRef> Names = {"::C", "::b::C", "::a::b::C"};
2474 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName(Names))));
2475 }
2476
TEST_P(ASTMatchersTest,IsDefinition)2477 TEST_P(ASTMatchersTest, IsDefinition) {
2478 DeclarationMatcher DefinitionOfClassA =
2479 recordDecl(hasName("A"), isDefinition());
2480 EXPECT_TRUE(matches("struct A {};", DefinitionOfClassA));
2481 EXPECT_TRUE(notMatches("struct A;", DefinitionOfClassA));
2482
2483 DeclarationMatcher DefinitionOfVariableA =
2484 varDecl(hasName("a"), isDefinition());
2485 EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));
2486 EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));
2487 }
2488
TEST_P(ASTMatchersTest,IsDefinition_CXX)2489 TEST_P(ASTMatchersTest, IsDefinition_CXX) {
2490 if (!GetParam().isCXX()) {
2491 return;
2492 }
2493
2494 DeclarationMatcher DefinitionOfMethodA =
2495 cxxMethodDecl(hasName("a"), isDefinition());
2496 EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));
2497 EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));
2498
2499 DeclarationMatcher DefinitionOfObjCMethodA =
2500 objcMethodDecl(hasName("a"), isDefinition());
2501 EXPECT_TRUE(matchesObjC("@interface A @end "
2502 "@implementation A; -(void)a {} @end",
2503 DefinitionOfObjCMethodA));
2504 EXPECT_TRUE(
2505 notMatchesObjC("@interface A; - (void)a; @end", DefinitionOfObjCMethodA));
2506 }
2507
TEST_P(ASTMatchersTest,HandlesNullQualTypes)2508 TEST_P(ASTMatchersTest, HandlesNullQualTypes) {
2509 if (!GetParam().isCXX()) {
2510 // FIXME: Add an equivalent test that does not depend on C++.
2511 return;
2512 }
2513
2514 // FIXME: Add a Type matcher so we can replace uses of this
2515 // variable with Type(True())
2516 const TypeMatcher AnyType = anything();
2517
2518 // We don't really care whether this matcher succeeds; we're testing that
2519 // it completes without crashing.
2520 EXPECT_TRUE(matches(
2521 "struct A { };"
2522 "template <typename T>"
2523 "void f(T t) {"
2524 " T local_t(t /* this becomes a null QualType in the AST */);"
2525 "}"
2526 "void g() {"
2527 " f(0);"
2528 "}",
2529 expr(hasType(TypeMatcher(anyOf(TypeMatcher(hasDeclaration(anything())),
2530 pointsTo(AnyType), references(AnyType)
2531 // Other QualType matchers should go here.
2532 ))))));
2533 }
2534
TEST_P(ASTMatchersTest,ObjCIvarRefExpr)2535 TEST_P(ASTMatchersTest, ObjCIvarRefExpr) {
2536 StringRef ObjCString =
2537 "@interface A @end "
2538 "@implementation A { A *x; } - (void) func { x = 0; } @end";
2539 EXPECT_TRUE(matchesObjC(ObjCString, objcIvarRefExpr()));
2540 EXPECT_TRUE(matchesObjC(
2541 ObjCString, objcIvarRefExpr(hasDeclaration(namedDecl(hasName("x"))))));
2542 EXPECT_FALSE(matchesObjC(
2543 ObjCString, objcIvarRefExpr(hasDeclaration(namedDecl(hasName("y"))))));
2544 }
2545
TEST_P(ASTMatchersTest,BlockExpr)2546 TEST_P(ASTMatchersTest, BlockExpr) {
2547 EXPECT_TRUE(matchesObjC("void f() { ^{}(); }", blockExpr()));
2548 }
2549
TEST_P(ASTMatchersTest,StatementCountIs_FindsNoStatementsInAnEmptyCompoundStatement)2550 TEST_P(ASTMatchersTest,
2551 StatementCountIs_FindsNoStatementsInAnEmptyCompoundStatement) {
2552 EXPECT_TRUE(matches("void f() { }", compoundStmt(statementCountIs(0))));
2553 EXPECT_TRUE(notMatches("void f() {}", compoundStmt(statementCountIs(1))));
2554 }
2555
TEST_P(ASTMatchersTest,StatementCountIs_AppearsToMatchOnlyOneCount)2556 TEST_P(ASTMatchersTest, StatementCountIs_AppearsToMatchOnlyOneCount) {
2557 EXPECT_TRUE(matches("void f() { 1; }", compoundStmt(statementCountIs(1))));
2558 EXPECT_TRUE(notMatches("void f() { 1; }", compoundStmt(statementCountIs(0))));
2559 EXPECT_TRUE(notMatches("void f() { 1; }", compoundStmt(statementCountIs(2))));
2560 }
2561
TEST_P(ASTMatchersTest,StatementCountIs_WorksWithMultipleStatements)2562 TEST_P(ASTMatchersTest, StatementCountIs_WorksWithMultipleStatements) {
2563 EXPECT_TRUE(
2564 matches("void f() { 1; 2; 3; }", compoundStmt(statementCountIs(3))));
2565 }
2566
TEST_P(ASTMatchersTest,StatementCountIs_WorksWithNestedCompoundStatements)2567 TEST_P(ASTMatchersTest, StatementCountIs_WorksWithNestedCompoundStatements) {
2568 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
2569 compoundStmt(statementCountIs(1))));
2570 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
2571 compoundStmt(statementCountIs(2))));
2572 EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
2573 compoundStmt(statementCountIs(3))));
2574 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
2575 compoundStmt(statementCountIs(4))));
2576 }
2577
TEST_P(ASTMatchersTest,Member_WorksInSimplestCase)2578 TEST_P(ASTMatchersTest, Member_WorksInSimplestCase) {
2579 if (!GetParam().isCXX()) {
2580 // FIXME: Add a test for `member()` that does not depend on C++.
2581 return;
2582 }
2583 EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
2584 memberExpr(member(hasName("first")))));
2585 }
2586
TEST_P(ASTMatchersTest,Member_DoesNotMatchTheBaseExpression)2587 TEST_P(ASTMatchersTest, Member_DoesNotMatchTheBaseExpression) {
2588 if (!GetParam().isCXX()) {
2589 // FIXME: Add a test for `member()` that does not depend on C++.
2590 return;
2591 }
2592
2593 // Don't pick out the wrong part of the member expression, this should
2594 // be checking the member (name) only.
2595 EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
2596 memberExpr(member(hasName("first")))));
2597 }
2598
TEST_P(ASTMatchersTest,Member_MatchesInMemberFunctionCall)2599 TEST_P(ASTMatchersTest, Member_MatchesInMemberFunctionCall) {
2600 if (!GetParam().isCXX()) {
2601 return;
2602 }
2603
2604 EXPECT_TRUE(matches("void f() {"
2605 " struct { void first() {}; } s;"
2606 " s.first();"
2607 "};",
2608 memberExpr(member(hasName("first")))));
2609 }
2610
TEST_P(ASTMatchersTest,FieldDecl)2611 TEST_P(ASTMatchersTest, FieldDecl) {
2612 EXPECT_TRUE(
2613 matches("struct A { int i; }; void f() { struct A a; a.i = 2; }",
2614 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
2615 EXPECT_TRUE(
2616 notMatches("struct A { float f; }; void f() { struct A a; a.f = 2.0f; }",
2617 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
2618 }
2619
TEST_P(ASTMatchersTest,IsBitField)2620 TEST_P(ASTMatchersTest, IsBitField) {
2621 EXPECT_TRUE(matches("struct C { int a : 2; int b; };",
2622 fieldDecl(isBitField(), hasName("a"))));
2623 EXPECT_TRUE(notMatches("struct C { int a : 2; int b; };",
2624 fieldDecl(isBitField(), hasName("b"))));
2625 EXPECT_TRUE(matches("struct C { int a : 2; int b : 4; };",
2626 fieldDecl(isBitField(), hasBitWidth(2), hasName("a"))));
2627 }
2628
TEST_P(ASTMatchersTest,HasInClassInitializer)2629 TEST_P(ASTMatchersTest, HasInClassInitializer) {
2630 if (!GetParam().isCXX()) {
2631 return;
2632 }
2633
2634 EXPECT_TRUE(
2635 matches("class C { int a = 2; int b; };",
2636 fieldDecl(hasInClassInitializer(integerLiteral(equals(2))),
2637 hasName("a"))));
2638 EXPECT_TRUE(
2639 notMatches("class C { int a = 2; int b; };",
2640 fieldDecl(hasInClassInitializer(anything()), hasName("b"))));
2641 }
2642
TEST_P(ASTMatchersTest,IsPublic_IsProtected_IsPrivate)2643 TEST_P(ASTMatchersTest, IsPublic_IsProtected_IsPrivate) {
2644 if (!GetParam().isCXX()) {
2645 return;
2646 }
2647
2648 EXPECT_TRUE(
2649 matches("struct A { int i; };", fieldDecl(isPublic(), hasName("i"))));
2650 EXPECT_TRUE(notMatches("struct A { int i; };",
2651 fieldDecl(isProtected(), hasName("i"))));
2652 EXPECT_TRUE(
2653 notMatches("struct A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
2654
2655 EXPECT_TRUE(
2656 notMatches("class A { int i; };", fieldDecl(isPublic(), hasName("i"))));
2657 EXPECT_TRUE(notMatches("class A { int i; };",
2658 fieldDecl(isProtected(), hasName("i"))));
2659 EXPECT_TRUE(
2660 matches("class A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
2661
2662 EXPECT_TRUE(notMatches("class A { protected: int i; };",
2663 fieldDecl(isPublic(), hasName("i"))));
2664 EXPECT_TRUE(matches("class A { protected: int i; };",
2665 fieldDecl(isProtected(), hasName("i"))));
2666 EXPECT_TRUE(notMatches("class A { protected: int i; };",
2667 fieldDecl(isPrivate(), hasName("i"))));
2668
2669 // Non-member decls have the AccessSpecifier AS_none and thus aren't matched.
2670 EXPECT_TRUE(notMatches("int i;", varDecl(isPublic(), hasName("i"))));
2671 EXPECT_TRUE(notMatches("int i;", varDecl(isProtected(), hasName("i"))));
2672 EXPECT_TRUE(notMatches("int i;", varDecl(isPrivate(), hasName("i"))));
2673 }
2674
TEST_P(ASTMatchersTest,HasDynamicExceptionSpec_MatchesDynamicExceptionSpecifications)2675 TEST_P(ASTMatchersTest,
2676 HasDynamicExceptionSpec_MatchesDynamicExceptionSpecifications) {
2677 if (!GetParam().supportsCXXDynamicExceptionSpecification()) {
2678 return;
2679 }
2680
2681 EXPECT_TRUE(notMatches("void f();", functionDecl(hasDynamicExceptionSpec())));
2682 EXPECT_TRUE(
2683 matches("void j() throw();", functionDecl(hasDynamicExceptionSpec())));
2684 EXPECT_TRUE(
2685 matches("void k() throw(int);", functionDecl(hasDynamicExceptionSpec())));
2686 EXPECT_TRUE(
2687 matches("void l() throw(...);", functionDecl(hasDynamicExceptionSpec())));
2688
2689 EXPECT_TRUE(
2690 notMatches("void f();", functionProtoType(hasDynamicExceptionSpec())));
2691 EXPECT_TRUE(matches("void j() throw();",
2692 functionProtoType(hasDynamicExceptionSpec())));
2693 EXPECT_TRUE(matches("void k() throw(int);",
2694 functionProtoType(hasDynamicExceptionSpec())));
2695 EXPECT_TRUE(matches("void l() throw(...);",
2696 functionProtoType(hasDynamicExceptionSpec())));
2697 }
2698
TEST_P(ASTMatchersTest,HasDynamicExceptionSpec_MatchesDynamicExceptionSpecifications_CXX11)2699 TEST_P(ASTMatchersTest,
2700 HasDynamicExceptionSpec_MatchesDynamicExceptionSpecifications_CXX11) {
2701 if (!GetParam().isCXX11OrLater()) {
2702 return;
2703 }
2704
2705 EXPECT_TRUE(notMatches("void g() noexcept;",
2706 functionDecl(hasDynamicExceptionSpec())));
2707 EXPECT_TRUE(notMatches("void h() noexcept(true);",
2708 functionDecl(hasDynamicExceptionSpec())));
2709 EXPECT_TRUE(notMatches("void i() noexcept(false);",
2710 functionDecl(hasDynamicExceptionSpec())));
2711
2712 EXPECT_TRUE(notMatches("void g() noexcept;",
2713 functionProtoType(hasDynamicExceptionSpec())));
2714 EXPECT_TRUE(notMatches("void h() noexcept(true);",
2715 functionProtoType(hasDynamicExceptionSpec())));
2716 EXPECT_TRUE(notMatches("void i() noexcept(false);",
2717 functionProtoType(hasDynamicExceptionSpec())));
2718 }
2719
TEST_P(ASTMatchersTest,HasObjectExpression_DoesNotMatchMember)2720 TEST_P(ASTMatchersTest, HasObjectExpression_DoesNotMatchMember) {
2721 if (!GetParam().isCXX()) {
2722 return;
2723 }
2724
2725 EXPECT_TRUE(notMatches(
2726 "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
2727 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
2728 }
2729
TEST_P(ASTMatchersTest,HasObjectExpression_MatchesBaseOfVariable)2730 TEST_P(ASTMatchersTest, HasObjectExpression_MatchesBaseOfVariable) {
2731 EXPECT_TRUE(matches(
2732 "struct X { int m; }; void f(struct X x) { x.m; }",
2733 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
2734 EXPECT_TRUE(matches("struct X { int m; }; void f(struct X* x) { x->m; }",
2735 memberExpr(hasObjectExpression(
2736 hasType(pointsTo(recordDecl(hasName("X"))))))));
2737 }
2738
TEST_P(ASTMatchersTest,HasObjectExpression_MatchesBaseOfVariable_CXX)2739 TEST_P(ASTMatchersTest, HasObjectExpression_MatchesBaseOfVariable_CXX) {
2740 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
2741 // FIXME: Fix this test to work with delayed template parsing.
2742 return;
2743 }
2744
2745 EXPECT_TRUE(matches("template <class T> struct X { void f() { T t; t.m; } };",
2746 cxxDependentScopeMemberExpr(hasObjectExpression(
2747 declRefExpr(to(namedDecl(hasName("t"))))))));
2748 EXPECT_TRUE(
2749 matches("template <class T> struct X { void f() { T t; t->m; } };",
2750 cxxDependentScopeMemberExpr(hasObjectExpression(
2751 declRefExpr(to(namedDecl(hasName("t"))))))));
2752 }
2753
TEST_P(ASTMatchersTest,HasObjectExpression_MatchesBaseOfMemberFunc)2754 TEST_P(ASTMatchersTest, HasObjectExpression_MatchesBaseOfMemberFunc) {
2755 if (!GetParam().isCXX()) {
2756 return;
2757 }
2758
2759 EXPECT_TRUE(matches(
2760 "struct X { void f(); }; void g(X x) { x.f(); }",
2761 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
2762 }
2763
TEST_P(ASTMatchersTest,HasObjectExpression_MatchesBaseOfMemberFunc_Template)2764 TEST_P(ASTMatchersTest, HasObjectExpression_MatchesBaseOfMemberFunc_Template) {
2765 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
2766 // FIXME: Fix this test to work with delayed template parsing.
2767 return;
2768 }
2769
2770 EXPECT_TRUE(matches("struct X { template <class T> void f(); };"
2771 "template <class T> void g(X x) { x.f<T>(); }",
2772 unresolvedMemberExpr(hasObjectExpression(
2773 hasType(recordDecl(hasName("X")))))));
2774 EXPECT_TRUE(matches("template <class T> void f(T t) { t.g(); }",
2775 cxxDependentScopeMemberExpr(hasObjectExpression(
2776 declRefExpr(to(namedDecl(hasName("t"))))))));
2777 }
2778
TEST_P(ASTMatchersTest,HasObjectExpression_ImplicitlyFormedMemberExpression)2779 TEST_P(ASTMatchersTest, HasObjectExpression_ImplicitlyFormedMemberExpression) {
2780 if (!GetParam().isCXX()) {
2781 return;
2782 }
2783
2784 EXPECT_TRUE(matches("class X {}; struct S { X m; void f() { this->m; } };",
2785 memberExpr(hasObjectExpression(
2786 hasType(pointsTo(recordDecl(hasName("S"))))))));
2787 EXPECT_TRUE(matches("class X {}; struct S { X m; void f() { m; } };",
2788 memberExpr(hasObjectExpression(
2789 hasType(pointsTo(recordDecl(hasName("S"))))))));
2790 }
2791
TEST_P(ASTMatchersTest,FieldDecl_DoesNotMatchNonFieldMembers)2792 TEST_P(ASTMatchersTest, FieldDecl_DoesNotMatchNonFieldMembers) {
2793 if (!GetParam().isCXX()) {
2794 return;
2795 }
2796
2797 EXPECT_TRUE(notMatches("class X { void m(); };", fieldDecl(hasName("m"))));
2798 EXPECT_TRUE(notMatches("class X { class m {}; };", fieldDecl(hasName("m"))));
2799 EXPECT_TRUE(notMatches("class X { enum { m }; };", fieldDecl(hasName("m"))));
2800 EXPECT_TRUE(notMatches("class X { enum m {}; };", fieldDecl(hasName("m"))));
2801 }
2802
TEST_P(ASTMatchersTest,FieldDecl_MatchesField)2803 TEST_P(ASTMatchersTest, FieldDecl_MatchesField) {
2804 EXPECT_TRUE(matches("struct X { int m; };", fieldDecl(hasName("m"))));
2805 }
2806
TEST_P(ASTMatchersTest,IsVolatileQualified)2807 TEST_P(ASTMatchersTest, IsVolatileQualified) {
2808 EXPECT_TRUE(
2809 matches("volatile int i = 42;", varDecl(hasType(isVolatileQualified()))));
2810 EXPECT_TRUE(
2811 notMatches("volatile int *i;", varDecl(hasType(isVolatileQualified()))));
2812 EXPECT_TRUE(matches("typedef volatile int v_int; v_int i = 42;",
2813 varDecl(hasType(isVolatileQualified()))));
2814 }
2815
TEST_P(ASTMatchersTest,IsConstQualified_MatchesConstInt)2816 TEST_P(ASTMatchersTest, IsConstQualified_MatchesConstInt) {
2817 EXPECT_TRUE(
2818 matches("const int i = 42;", varDecl(hasType(isConstQualified()))));
2819 }
2820
TEST_P(ASTMatchersTest,IsConstQualified_MatchesConstPointer)2821 TEST_P(ASTMatchersTest, IsConstQualified_MatchesConstPointer) {
2822 EXPECT_TRUE(matches("int i = 42; int* const p = &i;",
2823 varDecl(hasType(isConstQualified()))));
2824 }
2825
TEST_P(ASTMatchersTest,IsConstQualified_MatchesThroughTypedef)2826 TEST_P(ASTMatchersTest, IsConstQualified_MatchesThroughTypedef) {
2827 EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
2828 varDecl(hasType(isConstQualified()))));
2829 EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p = ((int*)0);",
2830 varDecl(hasType(isConstQualified()))));
2831 }
2832
TEST_P(ASTMatchersTest,IsConstQualified_DoesNotMatchInappropriately)2833 TEST_P(ASTMatchersTest, IsConstQualified_DoesNotMatchInappropriately) {
2834 EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
2835 varDecl(hasType(isConstQualified()))));
2836 EXPECT_TRUE(
2837 notMatches("int const* p;", varDecl(hasType(isConstQualified()))));
2838 }
2839
TEST_P(ASTMatchersTest,DeclCountIs_DeclCountIsCorrect)2840 TEST_P(ASTMatchersTest, DeclCountIs_DeclCountIsCorrect) {
2841 EXPECT_TRUE(matches("void f() {int i,j;}", declStmt(declCountIs(2))));
2842 EXPECT_TRUE(
2843 notMatches("void f() {int i,j; int k;}", declStmt(declCountIs(3))));
2844 EXPECT_TRUE(
2845 notMatches("void f() {int i,j, k, l;}", declStmt(declCountIs(3))));
2846 }
2847
TEST_P(ASTMatchersTest,EachOf_TriggersForEachMatch)2848 TEST_P(ASTMatchersTest, EachOf_TriggersForEachMatch) {
2849 EXPECT_TRUE(matchAndVerifyResultTrue(
2850 "class A { int a; int b; };",
2851 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
2852 has(fieldDecl(hasName("b")).bind("v")))),
2853 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 2)));
2854 }
2855
TEST_P(ASTMatchersTest,EachOf_BehavesLikeAnyOfUnlessBothMatch)2856 TEST_P(ASTMatchersTest, EachOf_BehavesLikeAnyOfUnlessBothMatch) {
2857 EXPECT_TRUE(matchAndVerifyResultTrue(
2858 "struct A { int a; int c; };",
2859 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
2860 has(fieldDecl(hasName("b")).bind("v")))),
2861 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 1)));
2862 EXPECT_TRUE(matchAndVerifyResultTrue(
2863 "struct A { int c; int b; };",
2864 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
2865 has(fieldDecl(hasName("b")).bind("v")))),
2866 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 1)));
2867 EXPECT_TRUE(
2868 notMatches("struct A { int c; int d; };",
2869 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
2870 has(fieldDecl(hasName("b")).bind("v"))))));
2871 }
2872
TEST_P(ASTMatchersTest,Optionally_SubmatchersDoNotMatch)2873 TEST_P(ASTMatchersTest, Optionally_SubmatchersDoNotMatch) {
2874 EXPECT_TRUE(matchAndVerifyResultFalse(
2875 "class A { int a; int b; };",
2876 recordDecl(optionally(has(fieldDecl(hasName("c")).bind("c")))),
2877 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("c")));
2878 }
2879
2880 // Regression test.
TEST_P(ASTMatchersTest,Optionally_SubmatchersDoNotMatchButPreserveBindings)2881 TEST_P(ASTMatchersTest, Optionally_SubmatchersDoNotMatchButPreserveBindings) {
2882 StringRef Code = "class A { int a; int b; };";
2883 auto Matcher = recordDecl(decl().bind("decl"),
2884 optionally(has(fieldDecl(hasName("c")).bind("v"))));
2885 // "decl" is still bound.
2886 EXPECT_TRUE(matchAndVerifyResultTrue(
2887 Code, Matcher, std::make_unique<VerifyIdIsBoundTo<RecordDecl>>("decl")));
2888 // "v" is not bound, but the match still suceeded.
2889 EXPECT_TRUE(matchAndVerifyResultFalse(
2890 Code, Matcher, std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v")));
2891 }
2892
TEST_P(ASTMatchersTest,Optionally_SubmatchersMatch)2893 TEST_P(ASTMatchersTest, Optionally_SubmatchersMatch) {
2894 EXPECT_TRUE(matchAndVerifyResultTrue(
2895 "class A { int a; int c; };",
2896 recordDecl(optionally(has(fieldDecl(hasName("a")).bind("v")))),
2897 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v")));
2898 }
2899
TEST_P(ASTMatchersTest,IsTemplateInstantiation_MatchesImplicitClassTemplateInstantiation)2900 TEST_P(ASTMatchersTest,
2901 IsTemplateInstantiation_MatchesImplicitClassTemplateInstantiation) {
2902 if (!GetParam().isCXX()) {
2903 return;
2904 }
2905
2906 // Make sure that we can both match the class by name (::X) and by the type
2907 // the template was instantiated with (via a field).
2908
2909 EXPECT_TRUE(
2910 matches("template <typename T> class X {}; class A {}; X<A> x;",
2911 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
2912
2913 EXPECT_TRUE(matches(
2914 "template <typename T> class X { T t; }; class A {}; X<A> x;",
2915 cxxRecordDecl(
2916 isTemplateInstantiation(),
2917 hasDescendant(fieldDecl(hasType(recordDecl(hasName("A"))))))));
2918 }
2919
TEST_P(ASTMatchersTest,IsTemplateInstantiation_MatchesImplicitFunctionTemplateInstantiation)2920 TEST_P(ASTMatchersTest,
2921 IsTemplateInstantiation_MatchesImplicitFunctionTemplateInstantiation) {
2922 if (!GetParam().isCXX()) {
2923 return;
2924 }
2925
2926 EXPECT_TRUE(matches(
2927 "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
2928 functionDecl(hasParameter(0, hasType(recordDecl(hasName("A")))),
2929 isTemplateInstantiation())));
2930 }
2931
TEST_P(ASTMatchersTest,IsTemplateInstantiation_MatchesExplicitClassTemplateInstantiation)2932 TEST_P(ASTMatchersTest,
2933 IsTemplateInstantiation_MatchesExplicitClassTemplateInstantiation) {
2934 if (!GetParam().isCXX()) {
2935 return;
2936 }
2937
2938 EXPECT_TRUE(matches("template <typename T> class X { T t; }; class A {};"
2939 "template class X<A>;",
2940 cxxRecordDecl(isTemplateInstantiation(),
2941 hasDescendant(fieldDecl(
2942 hasType(recordDecl(hasName("A"))))))));
2943
2944 // Make sure that we match the instantiation instead of the template
2945 // definition by checking whether the member function is present.
2946 EXPECT_TRUE(
2947 matches("template <typename T> class X { void f() { T t; } };"
2948 "extern template class X<int>;",
2949 cxxRecordDecl(isTemplateInstantiation(),
2950 unless(hasDescendant(varDecl(hasName("t")))))));
2951 }
2952
TEST_P(ASTMatchersTest,IsTemplateInstantiation_MatchesInstantiationOfPartiallySpecializedClassTemplate)2953 TEST_P(
2954 ASTMatchersTest,
2955 IsTemplateInstantiation_MatchesInstantiationOfPartiallySpecializedClassTemplate) {
2956 if (!GetParam().isCXX()) {
2957 return;
2958 }
2959
2960 EXPECT_TRUE(
2961 matches("template <typename T> class X {};"
2962 "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
2963 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
2964 }
2965
TEST_P(ASTMatchersTest,IsTemplateInstantiation_MatchesInstantiationOfClassTemplateNestedInNonTemplate)2966 TEST_P(
2967 ASTMatchersTest,
2968 IsTemplateInstantiation_MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
2969 if (!GetParam().isCXX()) {
2970 return;
2971 }
2972
2973 EXPECT_TRUE(
2974 matches("class A {};"
2975 "class X {"
2976 " template <typename U> class Y { U u; };"
2977 " Y<A> y;"
2978 "};",
2979 cxxRecordDecl(hasName("::X::Y"), isTemplateInstantiation())));
2980 }
2981
TEST_P(ASTMatchersTest,IsTemplateInstantiation_DoesNotMatchInstantiationsInsideOfInstantiation)2982 TEST_P(
2983 ASTMatchersTest,
2984 IsTemplateInstantiation_DoesNotMatchInstantiationsInsideOfInstantiation) {
2985 if (!GetParam().isCXX()) {
2986 return;
2987 }
2988
2989 // FIXME: Figure out whether this makes sense. It doesn't affect the
2990 // normal use case as long as the uppermost instantiation always is marked
2991 // as template instantiation, but it might be confusing as a predicate.
2992 EXPECT_TRUE(matches(
2993 "class A {};"
2994 "template <typename T> class X {"
2995 " template <typename U> class Y { U u; };"
2996 " Y<T> y;"
2997 "}; X<A> x;",
2998 cxxRecordDecl(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
2999 }
3000
TEST_P(ASTMatchersTest,IsTemplateInstantiation_DoesNotMatchExplicitClassTemplateSpecialization)3001 TEST_P(
3002 ASTMatchersTest,
3003 IsTemplateInstantiation_DoesNotMatchExplicitClassTemplateSpecialization) {
3004 if (!GetParam().isCXX()) {
3005 return;
3006 }
3007
3008 EXPECT_TRUE(
3009 notMatches("template <typename T> class X {}; class A {};"
3010 "template <> class X<A> {}; X<A> x;",
3011 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
3012 }
3013
TEST_P(ASTMatchersTest,IsTemplateInstantiation_DoesNotMatchNonTemplate)3014 TEST_P(ASTMatchersTest, IsTemplateInstantiation_DoesNotMatchNonTemplate) {
3015 if (!GetParam().isCXX()) {
3016 return;
3017 }
3018
3019 EXPECT_TRUE(notMatches("class A {}; class Y { A a; };",
3020 cxxRecordDecl(isTemplateInstantiation())));
3021 }
3022
TEST_P(ASTMatchersTest,IsInstantiated_MatchesInstantiation)3023 TEST_P(ASTMatchersTest, IsInstantiated_MatchesInstantiation) {
3024 if (!GetParam().isCXX()) {
3025 return;
3026 }
3027
3028 EXPECT_TRUE(
3029 matches("template<typename T> class A { T i; }; class Y { A<int> a; };",
3030 cxxRecordDecl(isInstantiated())));
3031 }
3032
TEST_P(ASTMatchersTest,IsInstantiated_NotMatchesDefinition)3033 TEST_P(ASTMatchersTest, IsInstantiated_NotMatchesDefinition) {
3034 if (!GetParam().isCXX()) {
3035 return;
3036 }
3037
3038 EXPECT_TRUE(notMatches("template<typename T> class A { T i; };",
3039 cxxRecordDecl(isInstantiated())));
3040 }
3041
TEST_P(ASTMatchersTest,IsInTemplateInstantiation_MatchesInstantiationStmt)3042 TEST_P(ASTMatchersTest, IsInTemplateInstantiation_MatchesInstantiationStmt) {
3043 if (!GetParam().isCXX()) {
3044 return;
3045 }
3046
3047 EXPECT_TRUE(matches("template<typename T> struct A { A() { T i; } };"
3048 "class Y { A<int> a; }; Y y;",
3049 declStmt(isInTemplateInstantiation())));
3050 }
3051
TEST_P(ASTMatchersTest,IsInTemplateInstantiation_NotMatchesDefinitionStmt)3052 TEST_P(ASTMatchersTest, IsInTemplateInstantiation_NotMatchesDefinitionStmt) {
3053 if (!GetParam().isCXX()) {
3054 return;
3055 }
3056
3057 EXPECT_TRUE(notMatches("template<typename T> struct A { void x() { T i; } };",
3058 declStmt(isInTemplateInstantiation())));
3059 }
3060
TEST_P(ASTMatchersTest,IsInstantiated_MatchesFunctionInstantiation)3061 TEST_P(ASTMatchersTest, IsInstantiated_MatchesFunctionInstantiation) {
3062 if (!GetParam().isCXX()) {
3063 return;
3064 }
3065
3066 EXPECT_TRUE(
3067 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
3068 functionDecl(isInstantiated())));
3069 }
3070
TEST_P(ASTMatchersTest,IsInstantiated_NotMatchesFunctionDefinition)3071 TEST_P(ASTMatchersTest, IsInstantiated_NotMatchesFunctionDefinition) {
3072 if (!GetParam().isCXX()) {
3073 return;
3074 }
3075
3076 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
3077 varDecl(isInstantiated())));
3078 }
3079
TEST_P(ASTMatchersTest,IsInTemplateInstantiation_MatchesFunctionInstantiationStmt)3080 TEST_P(ASTMatchersTest,
3081 IsInTemplateInstantiation_MatchesFunctionInstantiationStmt) {
3082 if (!GetParam().isCXX()) {
3083 return;
3084 }
3085
3086 EXPECT_TRUE(
3087 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
3088 declStmt(isInTemplateInstantiation())));
3089 }
3090
TEST_P(ASTMatchersTest,IsInTemplateInstantiation_NotMatchesFunctionDefinitionStmt)3091 TEST_P(ASTMatchersTest,
3092 IsInTemplateInstantiation_NotMatchesFunctionDefinitionStmt) {
3093 if (!GetParam().isCXX()) {
3094 return;
3095 }
3096
3097 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
3098 declStmt(isInTemplateInstantiation())));
3099 }
3100
TEST_P(ASTMatchersTest,IsInTemplateInstantiation_Sharing)3101 TEST_P(ASTMatchersTest, IsInTemplateInstantiation_Sharing) {
3102 if (!GetParam().isCXX()) {
3103 return;
3104 }
3105
3106 auto Matcher = binaryOperator(unless(isInTemplateInstantiation()));
3107 // FIXME: Node sharing is an implementation detail, exposing it is ugly
3108 // and makes the matcher behave in non-obvious ways.
3109 EXPECT_TRUE(notMatches(
3110 "int j; template<typename T> void A(T t) { j += 42; } void x() { A(0); }",
3111 Matcher));
3112 EXPECT_TRUE(matches(
3113 "int j; template<typename T> void A(T t) { j += t; } void x() { A(0); }",
3114 Matcher));
3115 }
3116
TEST_P(ASTMatchersTest,IsInstantiationDependent_MatchesNonValueTypeDependent)3117 TEST_P(ASTMatchersTest, IsInstantiationDependent_MatchesNonValueTypeDependent) {
3118 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3119 // FIXME: Fix this test to work with delayed template parsing.
3120 return;
3121 }
3122
3123 EXPECT_TRUE(matches(
3124 "template<typename T> void f() { (void) sizeof(sizeof(T() + T())); }",
3125 expr(isInstantiationDependent())));
3126 }
3127
TEST_P(ASTMatchersTest,IsInstantiationDependent_MatchesValueDependent)3128 TEST_P(ASTMatchersTest, IsInstantiationDependent_MatchesValueDependent) {
3129 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3130 // FIXME: Fix this test to work with delayed template parsing.
3131 return;
3132 }
3133
3134 EXPECT_TRUE(matches("template<int T> int f() { return T; }",
3135 expr(isInstantiationDependent())));
3136 }
3137
TEST_P(ASTMatchersTest,IsInstantiationDependent_MatchesTypeDependent)3138 TEST_P(ASTMatchersTest, IsInstantiationDependent_MatchesTypeDependent) {
3139 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3140 // FIXME: Fix this test to work with delayed template parsing.
3141 return;
3142 }
3143
3144 EXPECT_TRUE(matches("template<typename T> T f() { return T(); }",
3145 expr(isInstantiationDependent())));
3146 }
3147
TEST_P(ASTMatchersTest,IsTypeDependent_MatchesTypeDependent)3148 TEST_P(ASTMatchersTest, IsTypeDependent_MatchesTypeDependent) {
3149 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3150 // FIXME: Fix this test to work with delayed template parsing.
3151 return;
3152 }
3153
3154 EXPECT_TRUE(matches("template<typename T> T f() { return T(); }",
3155 expr(isTypeDependent())));
3156 }
3157
TEST_P(ASTMatchersTest,IsTypeDependent_NotMatchesValueDependent)3158 TEST_P(ASTMatchersTest, IsTypeDependent_NotMatchesValueDependent) {
3159 if (!GetParam().isCXX()) {
3160 return;
3161 }
3162
3163 EXPECT_TRUE(notMatches("template<int T> int f() { return T; }",
3164 expr(isTypeDependent())));
3165 }
3166
TEST_P(ASTMatchersTest,IsValueDependent_MatchesValueDependent)3167 TEST_P(ASTMatchersTest, IsValueDependent_MatchesValueDependent) {
3168 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3169 // FIXME: Fix this test to work with delayed template parsing.
3170 return;
3171 }
3172
3173 EXPECT_TRUE(matches("template<int T> int f() { return T; }",
3174 expr(isValueDependent())));
3175 }
3176
TEST_P(ASTMatchersTest,IsValueDependent_MatchesTypeDependent)3177 TEST_P(ASTMatchersTest, IsValueDependent_MatchesTypeDependent) {
3178 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3179 // FIXME: Fix this test to work with delayed template parsing.
3180 return;
3181 }
3182
3183 EXPECT_TRUE(matches("template<typename T> T f() { return T(); }",
3184 expr(isValueDependent())));
3185 }
3186
TEST_P(ASTMatchersTest,IsValueDependent_MatchesInstantiationDependent)3187 TEST_P(ASTMatchersTest, IsValueDependent_MatchesInstantiationDependent) {
3188 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3189 // FIXME: Fix this test to work with delayed template parsing.
3190 return;
3191 }
3192
3193 EXPECT_TRUE(matches(
3194 "template<typename T> void f() { (void) sizeof(sizeof(T() + T())); }",
3195 expr(isValueDependent())));
3196 }
3197
TEST_P(ASTMatchersTest,IsExplicitTemplateSpecialization_DoesNotMatchPrimaryTemplate)3198 TEST_P(ASTMatchersTest,
3199 IsExplicitTemplateSpecialization_DoesNotMatchPrimaryTemplate) {
3200 if (!GetParam().isCXX()) {
3201 return;
3202 }
3203
3204 EXPECT_TRUE(notMatches("template <typename T> class X {};",
3205 cxxRecordDecl(isExplicitTemplateSpecialization())));
3206 EXPECT_TRUE(notMatches("template <typename T> void f(T t);",
3207 functionDecl(isExplicitTemplateSpecialization())));
3208 }
3209
TEST_P(ASTMatchersTest,IsExplicitTemplateSpecialization_DoesNotMatchExplicitTemplateInstantiations)3210 TEST_P(
3211 ASTMatchersTest,
3212 IsExplicitTemplateSpecialization_DoesNotMatchExplicitTemplateInstantiations) {
3213 if (!GetParam().isCXX()) {
3214 return;
3215 }
3216
3217 EXPECT_TRUE(
3218 notMatches("template <typename T> class X {};"
3219 "template class X<int>; extern template class X<long>;",
3220 cxxRecordDecl(isExplicitTemplateSpecialization())));
3221 EXPECT_TRUE(
3222 notMatches("template <typename T> void f(T t) {}"
3223 "template void f(int t); extern template void f(long t);",
3224 functionDecl(isExplicitTemplateSpecialization())));
3225 }
3226
TEST_P(ASTMatchersTest,IsExplicitTemplateSpecialization_DoesNotMatchImplicitTemplateInstantiations)3227 TEST_P(
3228 ASTMatchersTest,
3229 IsExplicitTemplateSpecialization_DoesNotMatchImplicitTemplateInstantiations) {
3230 if (!GetParam().isCXX()) {
3231 return;
3232 }
3233
3234 EXPECT_TRUE(notMatches("template <typename T> class X {}; X<int> x;",
3235 cxxRecordDecl(isExplicitTemplateSpecialization())));
3236 EXPECT_TRUE(
3237 notMatches("template <typename T> void f(T t); void g() { f(10); }",
3238 functionDecl(isExplicitTemplateSpecialization())));
3239 }
3240
TEST_P(ASTMatchersTest,IsExplicitTemplateSpecialization_MatchesExplicitTemplateSpecializations)3241 TEST_P(
3242 ASTMatchersTest,
3243 IsExplicitTemplateSpecialization_MatchesExplicitTemplateSpecializations) {
3244 if (!GetParam().isCXX()) {
3245 return;
3246 }
3247
3248 EXPECT_TRUE(matches("template <typename T> class X {};"
3249 "template<> class X<int> {};",
3250 cxxRecordDecl(isExplicitTemplateSpecialization())));
3251 EXPECT_TRUE(matches("template <typename T> void f(T t) {}"
3252 "template<> void f(int t) {}",
3253 functionDecl(isExplicitTemplateSpecialization())));
3254 }
3255
TEST_P(ASTMatchersTest,IsNoReturn)3256 TEST_P(ASTMatchersTest, IsNoReturn) {
3257 EXPECT_TRUE(notMatches("void func();", functionDecl(isNoReturn())));
3258 EXPECT_TRUE(notMatches("void func() {}", functionDecl(isNoReturn())));
3259
3260 EXPECT_TRUE(matches("__attribute__((noreturn)) void func();",
3261 functionDecl(isNoReturn())));
3262 EXPECT_TRUE(matches("__attribute__((noreturn)) void func() {}",
3263 functionDecl(isNoReturn())));
3264
3265 EXPECT_TRUE(matches("_Noreturn void func();", functionDecl(isNoReturn())));
3266 EXPECT_TRUE(matches("_Noreturn void func() {}", functionDecl(isNoReturn())));
3267 }
3268
TEST_P(ASTMatchersTest,IsNoReturn_CXX)3269 TEST_P(ASTMatchersTest, IsNoReturn_CXX) {
3270 if (!GetParam().isCXX()) {
3271 return;
3272 }
3273
3274 EXPECT_TRUE(
3275 notMatches("struct S { void func(); };", functionDecl(isNoReturn())));
3276 EXPECT_TRUE(
3277 notMatches("struct S { void func() {} };", functionDecl(isNoReturn())));
3278
3279 EXPECT_TRUE(notMatches("struct S { static void func(); };",
3280 functionDecl(isNoReturn())));
3281 EXPECT_TRUE(notMatches("struct S { static void func() {} };",
3282 functionDecl(isNoReturn())));
3283
3284 EXPECT_TRUE(notMatches("struct S { S(); };", functionDecl(isNoReturn())));
3285 EXPECT_TRUE(notMatches("struct S { S() {} };", functionDecl(isNoReturn())));
3286
3287 // ---
3288
3289 EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) void func(); };",
3290 functionDecl(isNoReturn())));
3291 EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) void func() {} };",
3292 functionDecl(isNoReturn())));
3293
3294 EXPECT_TRUE(
3295 matches("struct S { __attribute__((noreturn)) static void func(); };",
3296 functionDecl(isNoReturn())));
3297 EXPECT_TRUE(
3298 matches("struct S { __attribute__((noreturn)) static void func() {} };",
3299 functionDecl(isNoReturn())));
3300
3301 EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) S(); };",
3302 functionDecl(isNoReturn())));
3303 EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) S() {} };",
3304 functionDecl(isNoReturn())));
3305 }
3306
TEST_P(ASTMatchersTest,IsNoReturn_CXX11Attribute)3307 TEST_P(ASTMatchersTest, IsNoReturn_CXX11Attribute) {
3308 if (!GetParam().isCXX11OrLater()) {
3309 return;
3310 }
3311
3312 EXPECT_TRUE(matches("[[noreturn]] void func();", functionDecl(isNoReturn())));
3313 EXPECT_TRUE(
3314 matches("[[noreturn]] void func() {}", functionDecl(isNoReturn())));
3315
3316 EXPECT_TRUE(matches("struct S { [[noreturn]] void func(); };",
3317 functionDecl(isNoReturn())));
3318 EXPECT_TRUE(matches("struct S { [[noreturn]] void func() {} };",
3319 functionDecl(isNoReturn())));
3320
3321 EXPECT_TRUE(matches("struct S { [[noreturn]] static void func(); };",
3322 functionDecl(isNoReturn())));
3323 EXPECT_TRUE(matches("struct S { [[noreturn]] static void func() {} };",
3324 functionDecl(isNoReturn())));
3325
3326 EXPECT_TRUE(
3327 matches("struct S { [[noreturn]] S(); };", functionDecl(isNoReturn())));
3328 EXPECT_TRUE(
3329 matches("struct S { [[noreturn]] S() {} };", functionDecl(isNoReturn())));
3330 }
3331
TEST_P(ASTMatchersTest,BooleanType)3332 TEST_P(ASTMatchersTest, BooleanType) {
3333 if (!GetParam().isCXX()) {
3334 // FIXME: Add a test for `booleanType()` that does not depend on C++.
3335 return;
3336 }
3337
3338 EXPECT_TRUE(matches("struct S { bool func(); };",
3339 cxxMethodDecl(returns(booleanType()))));
3340 EXPECT_TRUE(notMatches("struct S { void func(); };",
3341 cxxMethodDecl(returns(booleanType()))));
3342 }
3343
TEST_P(ASTMatchersTest,VoidType)3344 TEST_P(ASTMatchersTest, VoidType) {
3345 if (!GetParam().isCXX()) {
3346 // FIXME: Add a test for `voidType()` that does not depend on C++.
3347 return;
3348 }
3349
3350 EXPECT_TRUE(matches("struct S { void func(); };",
3351 cxxMethodDecl(returns(voidType()))));
3352 }
3353
TEST_P(ASTMatchersTest,RealFloatingPointType)3354 TEST_P(ASTMatchersTest, RealFloatingPointType) {
3355 if (!GetParam().isCXX()) {
3356 // FIXME: Add a test for `realFloatingPointType()` that does not depend on
3357 // C++.
3358 return;
3359 }
3360
3361 EXPECT_TRUE(matches("struct S { float func(); };",
3362 cxxMethodDecl(returns(realFloatingPointType()))));
3363 EXPECT_TRUE(notMatches("struct S { int func(); };",
3364 cxxMethodDecl(returns(realFloatingPointType()))));
3365 EXPECT_TRUE(matches("struct S { long double func(); };",
3366 cxxMethodDecl(returns(realFloatingPointType()))));
3367 }
3368
TEST_P(ASTMatchersTest,ArrayType)3369 TEST_P(ASTMatchersTest, ArrayType) {
3370 EXPECT_TRUE(matches("int a[] = {2,3};", arrayType()));
3371 EXPECT_TRUE(matches("int a[42];", arrayType()));
3372 EXPECT_TRUE(matches("void f(int b) { int a[b]; }", arrayType()));
3373
3374 EXPECT_TRUE(notMatches("struct A {}; struct A a[7];",
3375 arrayType(hasElementType(builtinType()))));
3376
3377 EXPECT_TRUE(matches("int const a[] = { 2, 3 };",
3378 qualType(arrayType(hasElementType(builtinType())))));
3379 EXPECT_TRUE(matches(
3380 "int const a[] = { 2, 3 };",
3381 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
3382 EXPECT_TRUE(matches("typedef const int T; T x[] = { 1, 2 };",
3383 qualType(isConstQualified(), arrayType())));
3384
3385 EXPECT_TRUE(notMatches(
3386 "int a[] = { 2, 3 };",
3387 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
3388 EXPECT_TRUE(notMatches(
3389 "int a[] = { 2, 3 };",
3390 qualType(arrayType(hasElementType(isConstQualified(), builtinType())))));
3391 EXPECT_TRUE(notMatches("int const a[] = { 2, 3 };",
3392 qualType(arrayType(hasElementType(builtinType())),
3393 unless(isConstQualified()))));
3394
3395 EXPECT_TRUE(
3396 matches("int a[2];", constantArrayType(hasElementType(builtinType()))));
3397 EXPECT_TRUE(matches("const int a = 0;", qualType(isInteger())));
3398 }
3399
TEST_P(ASTMatchersTest,DecayedType)3400 TEST_P(ASTMatchersTest, DecayedType) {
3401 EXPECT_TRUE(
3402 matches("void f(int i[]);",
3403 valueDecl(hasType(decayedType(hasDecayedType(pointerType()))))));
3404 EXPECT_TRUE(notMatches("int i[7];", decayedType()));
3405 }
3406
TEST_P(ASTMatchersTest,ComplexType)3407 TEST_P(ASTMatchersTest, ComplexType) {
3408 EXPECT_TRUE(matches("_Complex float f;", complexType()));
3409 EXPECT_TRUE(
3410 matches("_Complex float f;", complexType(hasElementType(builtinType()))));
3411 EXPECT_TRUE(notMatches("_Complex float f;",
3412 complexType(hasElementType(isInteger()))));
3413 }
3414
TEST_P(ASTMatchersTest,IsAnonymous)3415 TEST_P(ASTMatchersTest, IsAnonymous) {
3416 if (!GetParam().isCXX()) {
3417 return;
3418 }
3419
3420 EXPECT_TRUE(notMatches("namespace N {}", namespaceDecl(isAnonymous())));
3421 EXPECT_TRUE(matches("namespace {}", namespaceDecl(isAnonymous())));
3422 }
3423
TEST_P(ASTMatchersTest,InStdNamespace)3424 TEST_P(ASTMatchersTest, InStdNamespace) {
3425 if (!GetParam().isCXX()) {
3426 return;
3427 }
3428
3429 EXPECT_TRUE(notMatches("class vector {};"
3430 "namespace foo {"
3431 " class vector {};"
3432 "}"
3433 "namespace foo {"
3434 " namespace std {"
3435 " class vector {};"
3436 " }"
3437 "}",
3438 cxxRecordDecl(hasName("vector"), isInStdNamespace())));
3439
3440 EXPECT_TRUE(matches("namespace std {"
3441 " class vector {};"
3442 "}",
3443 cxxRecordDecl(hasName("vector"), isInStdNamespace())));
3444 }
3445
TEST_P(ASTMatchersTest,InStdNamespace_CXX11)3446 TEST_P(ASTMatchersTest, InStdNamespace_CXX11) {
3447 if (!GetParam().isCXX11OrLater()) {
3448 return;
3449 }
3450
3451 EXPECT_TRUE(matches("namespace std {"
3452 " inline namespace __1 {"
3453 " class vector {};"
3454 " }"
3455 "}",
3456 cxxRecordDecl(hasName("vector"), isInStdNamespace())));
3457 EXPECT_TRUE(notMatches("namespace std {"
3458 " inline namespace __1 {"
3459 " inline namespace __fs {"
3460 " namespace filesystem {"
3461 " inline namespace v1 {"
3462 " class path {};"
3463 " }"
3464 " }"
3465 " }"
3466 " }"
3467 "}",
3468 cxxRecordDecl(hasName("path"), isInStdNamespace())));
3469 EXPECT_TRUE(
3470 matches("namespace std {"
3471 " inline namespace __1 {"
3472 " inline namespace __fs {"
3473 " namespace filesystem {"
3474 " inline namespace v1 {"
3475 " class path {};"
3476 " }"
3477 " }"
3478 " }"
3479 " }"
3480 "}",
3481 cxxRecordDecl(hasName("path"),
3482 hasAncestor(namespaceDecl(hasName("filesystem"),
3483 isInStdNamespace())))));
3484 }
3485
TEST_P(ASTMatchersTest,EqualsBoundNodeMatcher_QualType)3486 TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_QualType) {
3487 EXPECT_TRUE(matches(
3488 "int i = 1;", varDecl(hasType(qualType().bind("type")),
3489 hasInitializer(ignoringParenImpCasts(
3490 hasType(qualType(equalsBoundNode("type"))))))));
3491 EXPECT_TRUE(notMatches("int i = 1.f;",
3492 varDecl(hasType(qualType().bind("type")),
3493 hasInitializer(ignoringParenImpCasts(hasType(
3494 qualType(equalsBoundNode("type"))))))));
3495 }
3496
TEST_P(ASTMatchersTest,EqualsBoundNodeMatcher_NonMatchingTypes)3497 TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_NonMatchingTypes) {
3498 EXPECT_TRUE(notMatches(
3499 "int i = 1;", varDecl(namedDecl(hasName("i")).bind("name"),
3500 hasInitializer(ignoringParenImpCasts(
3501 hasType(qualType(equalsBoundNode("type"))))))));
3502 }
3503
TEST_P(ASTMatchersTest,EqualsBoundNodeMatcher_Stmt)3504 TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_Stmt) {
3505 EXPECT_TRUE(
3506 matches("void f() { if(1) {} }",
3507 stmt(allOf(ifStmt().bind("if"),
3508 hasParent(stmt(has(stmt(equalsBoundNode("if")))))))));
3509
3510 EXPECT_TRUE(notMatches(
3511 "void f() { if(1) { if (1) {} } }",
3512 stmt(allOf(ifStmt().bind("if"), has(stmt(equalsBoundNode("if")))))));
3513 }
3514
TEST_P(ASTMatchersTest,EqualsBoundNodeMatcher_Decl)3515 TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_Decl) {
3516 if (!GetParam().isCXX()) {
3517 // FIXME: Add a test for `equalsBoundNode()` for declarations that does not
3518 // depend on C++.
3519 return;
3520 }
3521
3522 EXPECT_TRUE(matches(
3523 "class X { class Y {}; };",
3524 decl(allOf(recordDecl(hasName("::X::Y")).bind("record"),
3525 hasParent(decl(has(decl(equalsBoundNode("record")))))))));
3526
3527 EXPECT_TRUE(notMatches("class X { class Y {}; };",
3528 decl(allOf(recordDecl(hasName("::X")).bind("record"),
3529 has(decl(equalsBoundNode("record")))))));
3530 }
3531
TEST_P(ASTMatchersTest,EqualsBoundNodeMatcher_Type)3532 TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_Type) {
3533 if (!GetParam().isCXX()) {
3534 // FIXME: Add a test for `equalsBoundNode()` for types that does not depend
3535 // on C++.
3536 return;
3537 }
3538 EXPECT_TRUE(matches(
3539 "class X { int a; int b; };",
3540 recordDecl(
3541 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
3542 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
3543
3544 EXPECT_TRUE(notMatches(
3545 "class X { int a; double b; };",
3546 recordDecl(
3547 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
3548 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
3549 }
3550
TEST_P(ASTMatchersTest,EqualsBoundNodeMatcher_UsingForEachDescendant)3551 TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_UsingForEachDescendant) {
3552 EXPECT_TRUE(matchAndVerifyResultTrue(
3553 "int f() {"
3554 " if (1) {"
3555 " int i = 9;"
3556 " }"
3557 " int j = 10;"
3558 " {"
3559 " float k = 9.0;"
3560 " }"
3561 " return 0;"
3562 "}",
3563 // Look for variable declarations within functions whose type is the same
3564 // as the function return type.
3565 functionDecl(
3566 returns(qualType().bind("type")),
3567 forEachDescendant(varDecl(hasType(qualType(equalsBoundNode("type"))))
3568 .bind("decl"))),
3569 // Only i and j should match, not k.
3570 std::make_unique<VerifyIdIsBoundTo<VarDecl>>("decl", 2)));
3571 }
3572
TEST_P(ASTMatchersTest,EqualsBoundNodeMatcher_FiltersMatchedCombinations)3573 TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_FiltersMatchedCombinations) {
3574 EXPECT_TRUE(matchAndVerifyResultTrue(
3575 "void f() {"
3576 " int x;"
3577 " double d;"
3578 " x = d + x - d + x;"
3579 "}",
3580 functionDecl(
3581 hasName("f"), forEachDescendant(varDecl().bind("d")),
3582 forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d")))))),
3583 std::make_unique<VerifyIdIsBoundTo<VarDecl>>("d", 5)));
3584 }
3585
TEST_P(ASTMatchersTest,EqualsBoundNodeMatcher_UnlessDescendantsOfAncestorsMatch)3586 TEST_P(ASTMatchersTest,
3587 EqualsBoundNodeMatcher_UnlessDescendantsOfAncestorsMatch) {
3588 EXPECT_TRUE(matchAndVerifyResultTrue(
3589 "struct StringRef { int size() const; const char* data() const; };"
3590 "void f(StringRef v) {"
3591 " v.data();"
3592 "}",
3593 cxxMemberCallExpr(
3594 callee(cxxMethodDecl(hasName("data"))),
3595 on(declRefExpr(to(
3596 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
3597 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
3598 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
3599 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
3600 .bind("data"),
3601 std::make_unique<VerifyIdIsBoundTo<Expr>>("data", 1)));
3602
3603 EXPECT_FALSE(matches(
3604 "struct StringRef { int size() const; const char* data() const; };"
3605 "void f(StringRef v) {"
3606 " v.data();"
3607 " v.size();"
3608 "}",
3609 cxxMemberCallExpr(
3610 callee(cxxMethodDecl(hasName("data"))),
3611 on(declRefExpr(to(
3612 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
3613 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
3614 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
3615 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
3616 .bind("data")));
3617 }
3618
TEST_P(ASTMatchersTest,NullPointerConstant)3619 TEST_P(ASTMatchersTest, NullPointerConstant) {
3620 EXPECT_TRUE(matches("#define NULL ((void *)0)\n"
3621 "void *v1 = NULL;",
3622 expr(nullPointerConstant())));
3623 EXPECT_TRUE(matches("char *cp = (char *)0;", expr(nullPointerConstant())));
3624 EXPECT_TRUE(matches("int *ip = 0;", expr(nullPointerConstant())));
3625 EXPECT_TRUE(matches("int i = 0;", expr(nullPointerConstant())));
3626 }
3627
TEST_P(ASTMatchersTest,NullPointerConstant_GNUNull)3628 TEST_P(ASTMatchersTest, NullPointerConstant_GNUNull) {
3629 if (!GetParam().isCXX()) {
3630 return;
3631 }
3632
3633 EXPECT_TRUE(matches("void *p = __null;", expr(nullPointerConstant())));
3634 }
3635
TEST_P(ASTMatchersTest,NullPointerConstant_GNUNullInTemplate)3636 TEST_P(ASTMatchersTest, NullPointerConstant_GNUNullInTemplate) {
3637 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {
3638 // FIXME: Fix this test to work with delayed template parsing.
3639 return;
3640 }
3641
3642 const char kTest[] = R"(
3643 template <typename T>
3644 struct MyTemplate {
3645 MyTemplate() : field_(__null) {}
3646 T* field_;
3647 };
3648 )";
3649 EXPECT_TRUE(matches(kTest, expr(nullPointerConstant())));
3650 }
3651
TEST_P(ASTMatchersTest,NullPointerConstant_CXX11Nullptr)3652 TEST_P(ASTMatchersTest, NullPointerConstant_CXX11Nullptr) {
3653 if (!GetParam().isCXX11OrLater()) {
3654 return;
3655 }
3656
3657 EXPECT_TRUE(matches("void *p = nullptr;", expr(nullPointerConstant())));
3658 }
3659
TEST_P(ASTMatchersTest,HasExternalFormalLinkage)3660 TEST_P(ASTMatchersTest, HasExternalFormalLinkage) {
3661 EXPECT_TRUE(matches("int a = 0;",
3662 namedDecl(hasName("a"), hasExternalFormalLinkage())));
3663 EXPECT_TRUE(notMatches("static int a = 0;",
3664 namedDecl(hasName("a"), hasExternalFormalLinkage())));
3665 EXPECT_TRUE(notMatches("static void f(void) { int a = 0; }",
3666 namedDecl(hasName("a"), hasExternalFormalLinkage())));
3667 EXPECT_TRUE(notMatches("void f(void) { int a = 0; }",
3668 namedDecl(hasName("a"), hasExternalFormalLinkage())));
3669 }
3670
TEST_P(ASTMatchersTest,HasExternalFormalLinkage_CXX)3671 TEST_P(ASTMatchersTest, HasExternalFormalLinkage_CXX) {
3672 if (!GetParam().isCXX()) {
3673 return;
3674 }
3675
3676 EXPECT_TRUE(notMatches("namespace { int a = 0; }",
3677 namedDecl(hasName("a"), hasExternalFormalLinkage())));
3678 }
3679
TEST_P(ASTMatchersTest,HasDefaultArgument)3680 TEST_P(ASTMatchersTest, HasDefaultArgument) {
3681 if (!GetParam().isCXX()) {
3682 return;
3683 }
3684
3685 EXPECT_TRUE(
3686 matches("void x(int val = 0) {}", parmVarDecl(hasDefaultArgument())));
3687 EXPECT_TRUE(
3688 notMatches("void x(int val) {}", parmVarDecl(hasDefaultArgument())));
3689 }
3690
TEST_P(ASTMatchersTest,IsAtPosition)3691 TEST_P(ASTMatchersTest, IsAtPosition) {
3692 EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1))));
3693 EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(0))));
3694 EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1))));
3695 EXPECT_TRUE(notMatches("void x(int val) {}", parmVarDecl(isAtPosition(1))));
3696 }
3697
TEST_P(ASTMatchersTest,IsAtPosition_FunctionDecl)3698 TEST_P(ASTMatchersTest, IsAtPosition_FunctionDecl) {
3699 EXPECT_TRUE(matches("void x(int a);", parmVarDecl(isAtPosition(0))));
3700 EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(0))));
3701 EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(1))));
3702 EXPECT_TRUE(notMatches("void x(int val);", parmVarDecl(isAtPosition(1))));
3703 }
3704
TEST_P(ASTMatchersTest,IsAtPosition_Lambda)3705 TEST_P(ASTMatchersTest, IsAtPosition_Lambda) {
3706 if (!GetParam().isCXX11OrLater()) {
3707 return;
3708 }
3709
3710 EXPECT_TRUE(
3711 matches("void x() { [](int a) {}; }", parmVarDecl(isAtPosition(0))));
3712 EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",
3713 parmVarDecl(isAtPosition(0))));
3714 EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",
3715 parmVarDecl(isAtPosition(1))));
3716 EXPECT_TRUE(
3717 notMatches("void x() { [](int val) {}; }", parmVarDecl(isAtPosition(1))));
3718 }
3719
TEST_P(ASTMatchersTest,IsAtPosition_BlockDecl)3720 TEST_P(ASTMatchersTest, IsAtPosition_BlockDecl) {
3721 EXPECT_TRUE(matchesObjC(
3722 "void func() { void (^my_block)(int arg) = ^void(int arg) {}; } ",
3723 parmVarDecl(isAtPosition(0))));
3724
3725 EXPECT_TRUE(matchesObjC("void func() { void (^my_block)(int x, int y) = "
3726 "^void(int x, int y) {}; } ",
3727 parmVarDecl(isAtPosition(1))));
3728
3729 EXPECT_TRUE(notMatchesObjC(
3730 "void func() { void (^my_block)(int arg) = ^void(int arg) {}; } ",
3731 parmVarDecl(isAtPosition(1))));
3732 }
3733
TEST_P(ASTMatchersTest,IsArray)3734 TEST_P(ASTMatchersTest, IsArray) {
3735 if (!GetParam().isCXX()) {
3736 return;
3737 }
3738
3739 EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",
3740 cxxNewExpr(isArray())));
3741 }
3742
TEST_P(ASTMatchersTest,HasArraySize)3743 TEST_P(ASTMatchersTest, HasArraySize) {
3744 if (!GetParam().isCXX()) {
3745 return;
3746 }
3747
3748 EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",
3749 cxxNewExpr(hasArraySize(
3750 ignoringParenImpCasts(integerLiteral(equals(10)))))));
3751 }
3752
TEST_P(ASTMatchersTest,HasDefinition_MatchesStructDefinition)3753 TEST_P(ASTMatchersTest, HasDefinition_MatchesStructDefinition) {
3754 if (!GetParam().isCXX()) {
3755 return;
3756 }
3757
3758 EXPECT_TRUE(matches("struct x {};", cxxRecordDecl(hasDefinition())));
3759 EXPECT_TRUE(notMatches("struct x;", cxxRecordDecl(hasDefinition())));
3760 }
3761
TEST_P(ASTMatchersTest,HasDefinition_MatchesClassDefinition)3762 TEST_P(ASTMatchersTest, HasDefinition_MatchesClassDefinition) {
3763 if (!GetParam().isCXX()) {
3764 return;
3765 }
3766
3767 EXPECT_TRUE(matches("class x {};", cxxRecordDecl(hasDefinition())));
3768 EXPECT_TRUE(notMatches("class x;", cxxRecordDecl(hasDefinition())));
3769 }
3770
TEST_P(ASTMatchersTest,HasDefinition_MatchesUnionDefinition)3771 TEST_P(ASTMatchersTest, HasDefinition_MatchesUnionDefinition) {
3772 if (!GetParam().isCXX()) {
3773 return;
3774 }
3775
3776 EXPECT_TRUE(matches("union x {};", cxxRecordDecl(hasDefinition())));
3777 EXPECT_TRUE(notMatches("union x;", cxxRecordDecl(hasDefinition())));
3778 }
3779
TEST_P(ASTMatchersTest,IsScoped_MatchesScopedEnum)3780 TEST_P(ASTMatchersTest, IsScoped_MatchesScopedEnum) {
3781 if (!GetParam().isCXX11OrLater()) {
3782 return;
3783 }
3784 EXPECT_TRUE(matches("enum class X {};", enumDecl(isScoped())));
3785 }
3786
TEST_P(ASTMatchersTest,IsScoped_NotMatchesRegularEnum)3787 TEST_P(ASTMatchersTest, IsScoped_NotMatchesRegularEnum) {
3788 EXPECT_TRUE(notMatches("enum E { E1 };", enumDecl(isScoped())));
3789 }
3790
TEST_P(ASTMatchersTest,IsStruct)3791 TEST_P(ASTMatchersTest, IsStruct) {
3792 EXPECT_TRUE(matches("struct S {};", tagDecl(isStruct())));
3793 }
3794
TEST_P(ASTMatchersTest,IsUnion)3795 TEST_P(ASTMatchersTest, IsUnion) {
3796 EXPECT_TRUE(matches("union U {};", tagDecl(isUnion())));
3797 }
3798
TEST_P(ASTMatchersTest,IsEnum)3799 TEST_P(ASTMatchersTest, IsEnum) {
3800 EXPECT_TRUE(matches("enum E { E1 };", tagDecl(isEnum())));
3801 }
3802
TEST_P(ASTMatchersTest,IsClass)3803 TEST_P(ASTMatchersTest, IsClass) {
3804 if (!GetParam().isCXX()) {
3805 return;
3806 }
3807
3808 EXPECT_TRUE(matches("class C {};", tagDecl(isClass())));
3809 }
3810
TEST_P(ASTMatchersTest,HasTrailingReturn_MatchesTrailingReturn)3811 TEST_P(ASTMatchersTest, HasTrailingReturn_MatchesTrailingReturn) {
3812 if (!GetParam().isCXX11OrLater()) {
3813 return;
3814 }
3815
3816 EXPECT_TRUE(matches("auto Y() -> int { return 0; }",
3817 functionDecl(hasTrailingReturn())));
3818 EXPECT_TRUE(matches("auto X() -> int;", functionDecl(hasTrailingReturn())));
3819 EXPECT_TRUE(
3820 notMatches("int X() { return 0; }", functionDecl(hasTrailingReturn())));
3821 EXPECT_TRUE(notMatches("int X();", functionDecl(hasTrailingReturn())));
3822 EXPECT_TRUE(notMatches("void X();", functionDecl(hasTrailingReturn())));
3823 }
3824
TEST_P(ASTMatchersTest,HasTrailingReturn_MatchesLambdaTrailingReturn)3825 TEST_P(ASTMatchersTest, HasTrailingReturn_MatchesLambdaTrailingReturn) {
3826 if (!GetParam().isCXX11OrLater()) {
3827 return;
3828 }
3829
3830 EXPECT_TRUE(matches(
3831 "auto lambda2 = [](double x, double y) -> double {return x + y;};",
3832 functionDecl(hasTrailingReturn())));
3833 EXPECT_TRUE(
3834 notMatches("auto lambda2 = [](double x, double y) {return x + y;};",
3835 functionDecl(hasTrailingReturn())));
3836 }
3837
TEST_P(ASTMatchersTest,IsAssignmentOperator)3838 TEST_P(ASTMatchersTest, IsAssignmentOperator) {
3839 if (!GetParam().isCXX()) {
3840 return;
3841 }
3842
3843 StatementMatcher BinAsgmtOperator = binaryOperator(isAssignmentOperator());
3844 StatementMatcher CXXAsgmtOperator =
3845 cxxOperatorCallExpr(isAssignmentOperator());
3846
3847 EXPECT_TRUE(matches("void x() { int a; a += 1; }", BinAsgmtOperator));
3848 EXPECT_TRUE(matches("void x() { int a; a = 2; }", BinAsgmtOperator));
3849 EXPECT_TRUE(matches("void x() { int a; a &= 3; }", BinAsgmtOperator));
3850 EXPECT_TRUE(matches("struct S { S& operator=(const S&); };"
3851 "void x() { S s1, s2; s1 = s2; }",
3852 CXXAsgmtOperator));
3853 EXPECT_TRUE(
3854 notMatches("void x() { int a; if(a == 0) return; }", BinAsgmtOperator));
3855 }
3856
TEST_P(ASTMatchersTest,IsComparisonOperator)3857 TEST_P(ASTMatchersTest, IsComparisonOperator) {
3858 if (!GetParam().isCXX()) {
3859 return;
3860 }
3861
3862 StatementMatcher BinCompOperator = binaryOperator(isComparisonOperator());
3863 StatementMatcher CXXCompOperator =
3864 cxxOperatorCallExpr(isComparisonOperator());
3865
3866 EXPECT_TRUE(matches("void x() { int a; a == 1; }", BinCompOperator));
3867 EXPECT_TRUE(matches("void x() { int a; a > 2; }", BinCompOperator));
3868 EXPECT_TRUE(matches("struct S { bool operator==(const S&); };"
3869 "void x() { S s1, s2; bool b1 = s1 == s2; }",
3870 CXXCompOperator));
3871 EXPECT_TRUE(
3872 notMatches("void x() { int a; if(a = 0) return; }", BinCompOperator));
3873 }
3874
TEST_P(ASTMatchersTest,HasInit)3875 TEST_P(ASTMatchersTest, HasInit) {
3876 if (!GetParam().isCXX11OrLater()) {
3877 // FIXME: Add a test for `hasInit()` that does not depend on C++.
3878 return;
3879 }
3880
3881 EXPECT_TRUE(matches("int x{0};", initListExpr(hasInit(0, expr()))));
3882 EXPECT_FALSE(matches("int x{0};", initListExpr(hasInit(1, expr()))));
3883 EXPECT_FALSE(matches("int x;", initListExpr(hasInit(0, expr()))));
3884 }
3885
TEST_P(ASTMatchersTest,IsMain)3886 TEST_P(ASTMatchersTest, IsMain) {
3887 EXPECT_TRUE(matches("int main() {}", functionDecl(isMain())));
3888
3889 EXPECT_TRUE(notMatches("int main2() {}", functionDecl(isMain())));
3890 }
3891
TEST_P(ASTMatchersTest,OMPExecutableDirective_IsStandaloneDirective)3892 TEST_P(ASTMatchersTest, OMPExecutableDirective_IsStandaloneDirective) {
3893 auto Matcher = ompExecutableDirective(isStandaloneDirective());
3894
3895 StringRef Source0 = R"(
3896 void x() {
3897 #pragma omp parallel
3898 ;
3899 })";
3900 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
3901
3902 StringRef Source1 = R"(
3903 void x() {
3904 #pragma omp taskyield
3905 })";
3906 EXPECT_TRUE(matchesWithOpenMP(Source1, Matcher));
3907 }
3908
TEST_P(ASTMatchersTest,OMPExecutableDirective_HasStructuredBlock)3909 TEST_P(ASTMatchersTest, OMPExecutableDirective_HasStructuredBlock) {
3910 StringRef Source0 = R"(
3911 void x() {
3912 #pragma omp parallel
3913 ;
3914 })";
3915 EXPECT_TRUE(matchesWithOpenMP(
3916 Source0, ompExecutableDirective(hasStructuredBlock(nullStmt()))));
3917
3918 StringRef Source1 = R"(
3919 void x() {
3920 #pragma omp parallel
3921 {;}
3922 })";
3923 EXPECT_TRUE(notMatchesWithOpenMP(
3924 Source1, ompExecutableDirective(hasStructuredBlock(nullStmt()))));
3925 EXPECT_TRUE(matchesWithOpenMP(
3926 Source1, ompExecutableDirective(hasStructuredBlock(compoundStmt()))));
3927
3928 StringRef Source2 = R"(
3929 void x() {
3930 #pragma omp taskyield
3931 {;}
3932 })";
3933 EXPECT_TRUE(notMatchesWithOpenMP(
3934 Source2, ompExecutableDirective(hasStructuredBlock(anything()))));
3935 }
3936
TEST_P(ASTMatchersTest,OMPExecutableDirective_HasClause)3937 TEST_P(ASTMatchersTest, OMPExecutableDirective_HasClause) {
3938 auto Matcher = ompExecutableDirective(hasAnyClause(anything()));
3939
3940 StringRef Source0 = R"(
3941 void x() {
3942 ;
3943 })";
3944 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
3945
3946 StringRef Source1 = R"(
3947 void x() {
3948 #pragma omp parallel
3949 ;
3950 })";
3951 EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));
3952
3953 StringRef Source2 = R"(
3954 void x() {
3955 #pragma omp parallel default(none)
3956 ;
3957 })";
3958 EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher));
3959
3960 StringRef Source3 = R"(
3961 void x() {
3962 #pragma omp parallel default(shared)
3963 ;
3964 })";
3965 EXPECT_TRUE(matchesWithOpenMP(Source3, Matcher));
3966
3967 StringRef Source4 = R"(
3968 void x() {
3969 #pragma omp parallel default(firstprivate)
3970 ;
3971 })";
3972 EXPECT_TRUE(matchesWithOpenMP51(Source4, Matcher));
3973
3974 StringRef Source5 = R"(
3975 void x(int x) {
3976 #pragma omp parallel num_threads(x)
3977 ;
3978 })";
3979 EXPECT_TRUE(matchesWithOpenMP(Source5, Matcher));
3980 }
3981
TEST_P(ASTMatchersTest,OMPDefaultClause_IsNoneKind)3982 TEST_P(ASTMatchersTest, OMPDefaultClause_IsNoneKind) {
3983 auto Matcher =
3984 ompExecutableDirective(hasAnyClause(ompDefaultClause(isNoneKind())));
3985
3986 StringRef Source0 = R"(
3987 void x() {
3988 ;
3989 })";
3990 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
3991
3992 StringRef Source1 = R"(
3993 void x() {
3994 #pragma omp parallel
3995 ;
3996 })";
3997 EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));
3998
3999 StringRef Source2 = R"(
4000 void x() {
4001 #pragma omp parallel default(none)
4002 ;
4003 })";
4004 EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher));
4005
4006 StringRef Source3 = R"(
4007 void x() {
4008 #pragma omp parallel default(shared)
4009 ;
4010 })";
4011 EXPECT_TRUE(notMatchesWithOpenMP(Source3, Matcher));
4012
4013 StringRef Source4 = R"(
4014 void x(int x) {
4015 #pragma omp parallel default(firstprivate)
4016 ;
4017 })";
4018 EXPECT_TRUE(notMatchesWithOpenMP51(Source4, Matcher));
4019
4020 const std::string Source5 = R"(
4021 void x(int x) {
4022 #pragma omp parallel num_threads(x)
4023 ;
4024 })";
4025 EXPECT_TRUE(notMatchesWithOpenMP(Source5, Matcher));
4026 }
4027
TEST_P(ASTMatchersTest,OMPDefaultClause_IsSharedKind)4028 TEST_P(ASTMatchersTest, OMPDefaultClause_IsSharedKind) {
4029 auto Matcher =
4030 ompExecutableDirective(hasAnyClause(ompDefaultClause(isSharedKind())));
4031
4032 StringRef Source0 = R"(
4033 void x() {
4034 ;
4035 })";
4036 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
4037
4038 StringRef Source1 = R"(
4039 void x() {
4040 #pragma omp parallel
4041 ;
4042 })";
4043 EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));
4044
4045 StringRef Source2 = R"(
4046 void x() {
4047 #pragma omp parallel default(shared)
4048 ;
4049 })";
4050 EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher));
4051
4052 StringRef Source3 = R"(
4053 void x() {
4054 #pragma omp parallel default(none)
4055 ;
4056 })";
4057 EXPECT_TRUE(notMatchesWithOpenMP(Source3, Matcher));
4058
4059 StringRef Source4 = R"(
4060 void x(int x) {
4061 #pragma omp parallel default(firstprivate)
4062 ;
4063 })";
4064 EXPECT_TRUE(notMatchesWithOpenMP51(Source4, Matcher));
4065
4066 const std::string Source5 = R"(
4067 void x(int x) {
4068 #pragma omp parallel num_threads(x)
4069 ;
4070 })";
4071 EXPECT_TRUE(notMatchesWithOpenMP(Source5, Matcher));
4072 }
4073
TEST(OMPDefaultClause,isFirstPrivateKind)4074 TEST(OMPDefaultClause, isFirstPrivateKind) {
4075 auto Matcher = ompExecutableDirective(
4076 hasAnyClause(ompDefaultClause(isFirstPrivateKind())));
4077
4078 const std::string Source0 = R"(
4079 void x() {
4080 ;
4081 })";
4082 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
4083
4084 const std::string Source1 = R"(
4085 void x() {
4086 #pragma omp parallel
4087 ;
4088 })";
4089 EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));
4090
4091 const std::string Source2 = R"(
4092 void x() {
4093 #pragma omp parallel default(shared)
4094 ;
4095 })";
4096 EXPECT_TRUE(notMatchesWithOpenMP(Source2, Matcher));
4097
4098 const std::string Source3 = R"(
4099 void x() {
4100 #pragma omp parallel default(none)
4101 ;
4102 })";
4103 EXPECT_TRUE(notMatchesWithOpenMP(Source3, Matcher));
4104
4105 const std::string Source4 = R"(
4106 void x(int x) {
4107 #pragma omp parallel default(firstprivate)
4108 ;
4109 })";
4110 EXPECT_TRUE(matchesWithOpenMP51(Source4, Matcher));
4111
4112 const std::string Source5 = R"(
4113 void x(int x) {
4114 #pragma omp parallel num_threads(x)
4115 ;
4116 })";
4117 EXPECT_TRUE(notMatchesWithOpenMP(Source5, Matcher));
4118 }
4119
TEST_P(ASTMatchersTest,OMPExecutableDirective_IsAllowedToContainClauseKind)4120 TEST_P(ASTMatchersTest, OMPExecutableDirective_IsAllowedToContainClauseKind) {
4121 auto Matcher = ompExecutableDirective(
4122 isAllowedToContainClauseKind(llvm::omp::OMPC_default));
4123
4124 StringRef Source0 = R"(
4125 void x() {
4126 ;
4127 })";
4128 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
4129
4130 StringRef Source1 = R"(
4131 void x() {
4132 #pragma omp parallel
4133 ;
4134 })";
4135 EXPECT_TRUE(matchesWithOpenMP(Source1, Matcher));
4136
4137 StringRef Source2 = R"(
4138 void x() {
4139 #pragma omp parallel default(none)
4140 ;
4141 })";
4142 EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher));
4143
4144 StringRef Source3 = R"(
4145 void x() {
4146 #pragma omp parallel default(shared)
4147 ;
4148 })";
4149 EXPECT_TRUE(matchesWithOpenMP(Source3, Matcher));
4150
4151 StringRef Source4 = R"(
4152 void x() {
4153 #pragma omp parallel default(firstprivate)
4154 ;
4155 })";
4156 EXPECT_TRUE(matchesWithOpenMP51(Source4, Matcher));
4157
4158 StringRef Source5 = R"(
4159 void x(int x) {
4160 #pragma omp parallel num_threads(x)
4161 ;
4162 })";
4163 EXPECT_TRUE(matchesWithOpenMP(Source5, Matcher));
4164
4165 StringRef Source6 = R"(
4166 void x() {
4167 #pragma omp taskyield
4168 })";
4169 EXPECT_TRUE(notMatchesWithOpenMP(Source6, Matcher));
4170
4171 StringRef Source7 = R"(
4172 void x() {
4173 #pragma omp task
4174 ;
4175 })";
4176 EXPECT_TRUE(matchesWithOpenMP(Source7, Matcher));
4177 }
4178
TEST_P(ASTMatchersTest,HasAnyBase_DirectBase)4179 TEST_P(ASTMatchersTest, HasAnyBase_DirectBase) {
4180 if (!GetParam().isCXX()) {
4181 return;
4182 }
4183 EXPECT_TRUE(matches(
4184 "struct Base {};"
4185 "struct ExpectedMatch : Base {};",
4186 cxxRecordDecl(hasName("ExpectedMatch"),
4187 hasAnyBase(hasType(cxxRecordDecl(hasName("Base")))))));
4188 }
4189
TEST_P(ASTMatchersTest,HasAnyBase_IndirectBase)4190 TEST_P(ASTMatchersTest, HasAnyBase_IndirectBase) {
4191 if (!GetParam().isCXX()) {
4192 return;
4193 }
4194 EXPECT_TRUE(matches(
4195 "struct Base {};"
4196 "struct Intermediate : Base {};"
4197 "struct ExpectedMatch : Intermediate {};",
4198 cxxRecordDecl(hasName("ExpectedMatch"),
4199 hasAnyBase(hasType(cxxRecordDecl(hasName("Base")))))));
4200 }
4201
TEST_P(ASTMatchersTest,HasAnyBase_NoBase)4202 TEST_P(ASTMatchersTest, HasAnyBase_NoBase) {
4203 if (!GetParam().isCXX()) {
4204 return;
4205 }
4206 EXPECT_TRUE(notMatches("struct Foo {};"
4207 "struct Bar {};",
4208 cxxRecordDecl(hasAnyBase(hasType(cxxRecordDecl())))));
4209 }
4210
TEST_P(ASTMatchersTest,HasAnyBase_IsPublic_Public)4211 TEST_P(ASTMatchersTest, HasAnyBase_IsPublic_Public) {
4212 if (!GetParam().isCXX()) {
4213 return;
4214 }
4215 EXPECT_TRUE(matches("class Base {};"
4216 "class Derived : public Base {};",
4217 cxxRecordDecl(hasAnyBase(isPublic()))));
4218 }
4219
TEST_P(ASTMatchersTest,HasAnyBase_IsPublic_DefaultAccessSpecifierPublic)4220 TEST_P(ASTMatchersTest, HasAnyBase_IsPublic_DefaultAccessSpecifierPublic) {
4221 if (!GetParam().isCXX()) {
4222 return;
4223 }
4224 EXPECT_TRUE(matches("class Base {};"
4225 "struct Derived : Base {};",
4226 cxxRecordDecl(hasAnyBase(isPublic()))));
4227 }
4228
TEST_P(ASTMatchersTest,HasAnyBase_IsPublic_Private)4229 TEST_P(ASTMatchersTest, HasAnyBase_IsPublic_Private) {
4230 if (!GetParam().isCXX()) {
4231 return;
4232 }
4233 EXPECT_TRUE(notMatches("class Base {};"
4234 "class Derived : private Base {};",
4235 cxxRecordDecl(hasAnyBase(isPublic()))));
4236 }
4237
TEST_P(ASTMatchersTest,HasAnyBase_IsPublic_DefaultAccessSpecifierPrivate)4238 TEST_P(ASTMatchersTest, HasAnyBase_IsPublic_DefaultAccessSpecifierPrivate) {
4239 if (!GetParam().isCXX()) {
4240 return;
4241 }
4242 EXPECT_TRUE(notMatches("class Base {};"
4243 "class Derived : Base {};",
4244 cxxRecordDecl(hasAnyBase(isPublic()))));
4245 }
4246
TEST_P(ASTMatchersTest,HasAnyBase_IsPublic_Protected)4247 TEST_P(ASTMatchersTest, HasAnyBase_IsPublic_Protected) {
4248 if (!GetParam().isCXX()) {
4249 return;
4250 }
4251 EXPECT_TRUE(notMatches("class Base {};"
4252 "class Derived : protected Base {};",
4253 cxxRecordDecl(hasAnyBase(isPublic()))));
4254 }
4255
TEST_P(ASTMatchersTest,HasAnyBase_IsPrivate_Private)4256 TEST_P(ASTMatchersTest, HasAnyBase_IsPrivate_Private) {
4257 if (!GetParam().isCXX()) {
4258 return;
4259 }
4260 EXPECT_TRUE(matches("class Base {};"
4261 "class Derived : private Base {};",
4262 cxxRecordDecl(hasAnyBase(isPrivate()))));
4263 }
4264
TEST_P(ASTMatchersTest,HasAnyBase_IsPrivate_DefaultAccessSpecifierPrivate)4265 TEST_P(ASTMatchersTest, HasAnyBase_IsPrivate_DefaultAccessSpecifierPrivate) {
4266 if (!GetParam().isCXX()) {
4267 return;
4268 }
4269 EXPECT_TRUE(matches("struct Base {};"
4270 "class Derived : Base {};",
4271 cxxRecordDecl(hasAnyBase(isPrivate()))));
4272 }
4273
TEST_P(ASTMatchersTest,HasAnyBase_IsPrivate_Public)4274 TEST_P(ASTMatchersTest, HasAnyBase_IsPrivate_Public) {
4275 if (!GetParam().isCXX()) {
4276 return;
4277 }
4278 EXPECT_TRUE(notMatches("class Base {};"
4279 "class Derived : public Base {};",
4280 cxxRecordDecl(hasAnyBase(isPrivate()))));
4281 }
4282
TEST_P(ASTMatchersTest,HasAnyBase_IsPrivate_DefaultAccessSpecifierPublic)4283 TEST_P(ASTMatchersTest, HasAnyBase_IsPrivate_DefaultAccessSpecifierPublic) {
4284 if (!GetParam().isCXX()) {
4285 return;
4286 }
4287 EXPECT_TRUE(notMatches("class Base {};"
4288 "struct Derived : Base {};",
4289 cxxRecordDecl(hasAnyBase(isPrivate()))));
4290 }
4291
TEST_P(ASTMatchersTest,HasAnyBase_IsPrivate_Protected)4292 TEST_P(ASTMatchersTest, HasAnyBase_IsPrivate_Protected) {
4293 if (!GetParam().isCXX()) {
4294 return;
4295 }
4296 EXPECT_TRUE(notMatches("class Base {};"
4297 "class Derived : protected Base {};",
4298 cxxRecordDecl(hasAnyBase(isPrivate()))));
4299 }
4300
TEST_P(ASTMatchersTest,HasAnyBase_IsProtected_Protected)4301 TEST_P(ASTMatchersTest, HasAnyBase_IsProtected_Protected) {
4302 if (!GetParam().isCXX()) {
4303 return;
4304 }
4305 EXPECT_TRUE(matches("class Base {};"
4306 "class Derived : protected Base {};",
4307 cxxRecordDecl(hasAnyBase(isProtected()))));
4308 }
4309
TEST_P(ASTMatchersTest,HasAnyBase_IsProtected_Public)4310 TEST_P(ASTMatchersTest, HasAnyBase_IsProtected_Public) {
4311 if (!GetParam().isCXX()) {
4312 return;
4313 }
4314 EXPECT_TRUE(notMatches("class Base {};"
4315 "class Derived : public Base {};",
4316 cxxRecordDecl(hasAnyBase(isProtected()))));
4317 }
4318
TEST_P(ASTMatchersTest,HasAnyBase_IsProtected_Private)4319 TEST_P(ASTMatchersTest, HasAnyBase_IsProtected_Private) {
4320 if (!GetParam().isCXX()) {
4321 return;
4322 }
4323 EXPECT_TRUE(notMatches("class Base {};"
4324 "class Derived : private Base {};",
4325 cxxRecordDecl(hasAnyBase(isProtected()))));
4326 }
4327
TEST_P(ASTMatchersTest,HasAnyBase_IsVirtual_Directly)4328 TEST_P(ASTMatchersTest, HasAnyBase_IsVirtual_Directly) {
4329 if (!GetParam().isCXX()) {
4330 return;
4331 }
4332 EXPECT_TRUE(matches("class Base {};"
4333 "class Derived : virtual Base {};",
4334 cxxRecordDecl(hasAnyBase(isVirtual()))));
4335 }
4336
TEST_P(ASTMatchersTest,HasAnyBase_IsVirtual_Indirectly)4337 TEST_P(ASTMatchersTest, HasAnyBase_IsVirtual_Indirectly) {
4338 if (!GetParam().isCXX()) {
4339 return;
4340 }
4341 EXPECT_TRUE(
4342 matches("class Base {};"
4343 "class Intermediate : virtual Base {};"
4344 "class Derived : Intermediate {};",
4345 cxxRecordDecl(hasName("Derived"), hasAnyBase(isVirtual()))));
4346 }
4347
TEST_P(ASTMatchersTest,HasAnyBase_IsVirtual_NoVirtualBase)4348 TEST_P(ASTMatchersTest, HasAnyBase_IsVirtual_NoVirtualBase) {
4349 if (!GetParam().isCXX()) {
4350 return;
4351 }
4352 EXPECT_TRUE(notMatches("class Base {};"
4353 "class Derived : Base {};",
4354 cxxRecordDecl(hasAnyBase(isVirtual()))));
4355 }
4356
TEST_P(ASTMatchersTest,HasDirectBase)4357 TEST_P(ASTMatchersTest, HasDirectBase) {
4358 if (!GetParam().isCXX()) {
4359 return;
4360 }
4361
4362 EXPECT_TRUE(matches(
4363 R"cc(
4364 class Base {};
4365 class Derived : Base{};
4366 )cc",
4367 cxxRecordDecl(hasName("Derived"),
4368 hasDirectBase(hasType(cxxRecordDecl(hasName("Base")))))));
4369
4370 StringRef MultiDerived = R"cc(
4371 class Base {};
4372 class Base2 {};
4373 class Derived : Base, Base2{};
4374 )cc";
4375
4376 EXPECT_TRUE(matches(
4377 MultiDerived,
4378 cxxRecordDecl(hasName("Derived"),
4379 hasDirectBase(hasType(cxxRecordDecl(hasName("Base")))))));
4380 EXPECT_TRUE(matches(
4381 MultiDerived,
4382 cxxRecordDecl(hasName("Derived"),
4383 hasDirectBase(hasType(cxxRecordDecl(hasName("Base2")))))));
4384
4385 StringRef Indirect = R"cc(
4386 class Base {};
4387 class Intermediate : Base {};
4388 class Derived : Intermediate{};
4389 )cc";
4390
4391 EXPECT_TRUE(
4392 matches(Indirect, cxxRecordDecl(hasName("Derived"),
4393 hasDirectBase(hasType(cxxRecordDecl(
4394 hasName("Intermediate")))))));
4395 EXPECT_TRUE(notMatches(
4396 Indirect,
4397 cxxRecordDecl(hasName("Derived"),
4398 hasDirectBase(hasType(cxxRecordDecl(hasName("Base")))))));
4399 }
4400 } // namespace ast_matchers
4401 } // namespace clang
4402