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