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