1 //== unittests/ASTMatchers/ASTMatchersNodeTest.cpp - AST matcher unit tests ==// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "ASTMatchersTest.h" 10 #include "clang/AST/PrettyPrinter.h" 11 #include "clang/ASTMatchers/ASTMatchFinder.h" 12 #include "clang/ASTMatchers/ASTMatchers.h" 13 #include "clang/Tooling/Tooling.h" 14 #include "llvm/ADT/Triple.h" 15 #include "llvm/Support/Host.h" 16 #include "gtest/gtest.h" 17 18 namespace clang { 19 namespace ast_matchers { 20 21 TEST_P(ASTMatchersTest, Decl_CXX) { 22 if (!GetParam().isCXX()) { 23 // FIXME: Add a test for `decl()` that does not depend on C++. 24 return; 25 } 26 EXPECT_TRUE(notMatches("", decl(usingDecl()))); 27 EXPECT_TRUE( 28 matches("namespace x { class X {}; } using x::X;", decl(usingDecl()))); 29 } 30 31 TEST_P(ASTMatchersTest, NameableDeclaration_MatchesVariousDecls) { 32 DeclarationMatcher NamedX = namedDecl(hasName("X")); 33 EXPECT_TRUE(matches("typedef int X;", NamedX)); 34 EXPECT_TRUE(matches("int X;", NamedX)); 35 EXPECT_TRUE(matches("void foo() { int X; }", NamedX)); 36 EXPECT_TRUE(matches("enum X { A, B, C };", NamedX)); 37 38 EXPECT_TRUE(notMatches("#define X 1", NamedX)); 39 } 40 41 TEST_P(ASTMatchersTest, NamedDecl_CXX) { 42 if (!GetParam().isCXX()) { 43 return; 44 } 45 DeclarationMatcher NamedX = namedDecl(hasName("X")); 46 EXPECT_TRUE(matches("class foo { virtual void X(); };", NamedX)); 47 EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", NamedX)); 48 EXPECT_TRUE(matches("namespace X { }", NamedX)); 49 } 50 51 TEST_P(ASTMatchersTest, MatchesNameRE) { 52 DeclarationMatcher NamedX = namedDecl(matchesName("::X")); 53 EXPECT_TRUE(matches("typedef int Xa;", NamedX)); 54 EXPECT_TRUE(matches("int Xb;", NamedX)); 55 EXPECT_TRUE(matches("void foo() { int Xgh; }", NamedX)); 56 EXPECT_TRUE(matches("enum X { A, B, C };", NamedX)); 57 58 EXPECT_TRUE(notMatches("#define Xkl 1", NamedX)); 59 60 DeclarationMatcher StartsWithNo = namedDecl(matchesName("::no")); 61 EXPECT_TRUE(matches("int no_foo;", StartsWithNo)); 62 63 DeclarationMatcher Abc = namedDecl(matchesName("a.*b.*c")); 64 EXPECT_TRUE(matches("int abc;", Abc)); 65 EXPECT_TRUE(matches("int aFOObBARc;", Abc)); 66 EXPECT_TRUE(notMatches("int cab;", Abc)); 67 EXPECT_TRUE(matches("int cabc;", Abc)); 68 69 DeclarationMatcher StartsWithK = namedDecl(matchesName(":k[^:]*$")); 70 EXPECT_TRUE(matches("int k;", StartsWithK)); 71 EXPECT_TRUE(matches("int kAbc;", StartsWithK)); 72 } 73 74 TEST_P(ASTMatchersTest, MatchesNameRE_CXX) { 75 if (!GetParam().isCXX()) { 76 return; 77 } 78 DeclarationMatcher NamedX = namedDecl(matchesName("::X")); 79 EXPECT_TRUE(matches("class foo { virtual void Xc(); };", NamedX)); 80 EXPECT_TRUE(matches("void foo() try { } catch(int Xdef) { }", NamedX)); 81 EXPECT_TRUE(matches("namespace Xij { }", NamedX)); 82 83 DeclarationMatcher StartsWithNo = namedDecl(matchesName("::no")); 84 EXPECT_TRUE(matches("class foo { virtual void nobody(); };", StartsWithNo)); 85 86 DeclarationMatcher StartsWithK = namedDecl(matchesName(":k[^:]*$")); 87 EXPECT_TRUE(matches("namespace x { int kTest; }", StartsWithK)); 88 EXPECT_TRUE(matches("class C { int k; };", StartsWithK)); 89 EXPECT_TRUE(notMatches("class C { int ckc; };", StartsWithK)); 90 EXPECT_TRUE(notMatches("int K;", StartsWithK)); 91 92 DeclarationMatcher StartsWithKIgnoreCase = 93 namedDecl(matchesName(":k[^:]*$", llvm::Regex::IgnoreCase)); 94 EXPECT_TRUE(matches("int k;", StartsWithKIgnoreCase)); 95 EXPECT_TRUE(matches("int K;", StartsWithKIgnoreCase)); 96 } 97 98 TEST_P(ASTMatchersTest, DeclarationMatcher_MatchClass) { 99 if (!GetParam().isCXX()) { 100 return; 101 } 102 103 DeclarationMatcher ClassX = recordDecl(recordDecl(hasName("X"))); 104 EXPECT_TRUE(matches("class X;", ClassX)); 105 EXPECT_TRUE(matches("class X {};", ClassX)); 106 EXPECT_TRUE(matches("template<class T> class X {};", ClassX)); 107 EXPECT_TRUE(notMatches("", ClassX)); 108 } 109 110 TEST_P(ASTMatchersTest, TranslationUnitDecl) { 111 if (!GetParam().isCXX()) { 112 // FIXME: Add a test for `translationUnitDecl()` that does not depend on 113 // C++. 114 return; 115 } 116 StringRef Code = "int MyVar1;\n" 117 "namespace NameSpace {\n" 118 "int MyVar2;\n" 119 "} // namespace NameSpace\n"; 120 EXPECT_TRUE(matches( 121 Code, varDecl(hasName("MyVar1"), hasDeclContext(translationUnitDecl())))); 122 EXPECT_FALSE(matches( 123 Code, varDecl(hasName("MyVar2"), hasDeclContext(translationUnitDecl())))); 124 EXPECT_TRUE(matches( 125 Code, 126 varDecl(hasName("MyVar2"), 127 hasDeclContext(decl(hasDeclContext(translationUnitDecl())))))); 128 } 129 130 TEST_P(ASTMatchersTest, LinkageSpecDecl) { 131 if (!GetParam().isCXX()) { 132 return; 133 } 134 EXPECT_TRUE(matches("extern \"C\" { void foo() {}; }", linkageSpecDecl())); 135 EXPECT_TRUE(notMatches("void foo() {};", linkageSpecDecl())); 136 } 137 138 TEST_P(ASTMatchersTest, ClassTemplateDecl_DoesNotMatchClass) { 139 if (!GetParam().isCXX()) { 140 return; 141 } 142 DeclarationMatcher ClassX = classTemplateDecl(hasName("X")); 143 EXPECT_TRUE(notMatches("class X;", ClassX)); 144 EXPECT_TRUE(notMatches("class X {};", ClassX)); 145 } 146 147 TEST_P(ASTMatchersTest, ClassTemplateDecl_MatchesClassTemplate) { 148 if (!GetParam().isCXX()) { 149 return; 150 } 151 DeclarationMatcher ClassX = classTemplateDecl(hasName("X")); 152 EXPECT_TRUE(matches("template<typename T> class X {};", ClassX)); 153 EXPECT_TRUE(matches("class Z { template<class T> class X {}; };", ClassX)); 154 } 155 156 TEST_P(ASTMatchersTest, 157 ClassTemplateDecl_DoesNotMatchClassTemplateExplicitSpecialization) { 158 if (!GetParam().isCXX()) { 159 return; 160 } 161 EXPECT_TRUE(notMatches( 162 "template<typename T> class X { };" 163 "template<> class X<int> { int a; };", 164 classTemplateDecl(hasName("X"), hasDescendant(fieldDecl(hasName("a")))))); 165 } 166 167 TEST_P(ASTMatchersTest, 168 ClassTemplateDecl_DoesNotMatchClassTemplatePartialSpecialization) { 169 if (!GetParam().isCXX()) { 170 return; 171 } 172 EXPECT_TRUE(notMatches( 173 "template<typename T, typename U> class X { };" 174 "template<typename T> class X<T, int> { int a; };", 175 classTemplateDecl(hasName("X"), hasDescendant(fieldDecl(hasName("a")))))); 176 } 177 178 TEST(ASTMatchersTestCUDA, CUDAKernelCallExpr) { 179 EXPECT_TRUE(matchesWithCuda("__global__ void f() { }" 180 "void g() { f<<<1, 2>>>(); }", 181 cudaKernelCallExpr())); 182 EXPECT_TRUE(notMatchesWithCuda("void f() {}", cudaKernelCallExpr())); 183 } 184 185 TEST(ASTMatchersTestCUDA, HasAttrCUDA) { 186 EXPECT_TRUE(matchesWithCuda("__attribute__((device)) void f() {}", 187 hasAttr(clang::attr::CUDADevice))); 188 EXPECT_FALSE(notMatchesWithCuda("__attribute__((global)) void f() {}", 189 hasAttr(clang::attr::CUDAGlobal))); 190 } 191 192 TEST_P(ASTMatchersTest, ValueDecl) { 193 if (!GetParam().isCXX()) { 194 // FIXME: Fix this test in non-C++ language modes. 195 return; 196 } 197 EXPECT_TRUE(matches("enum EnumType { EnumValue };", 198 valueDecl(hasType(asString("enum EnumType"))))); 199 EXPECT_TRUE(matches("void FunctionDecl();", 200 valueDecl(hasType(asString("void (void)"))))); 201 } 202 203 TEST_P(ASTMatchersTest, FriendDecl) { 204 if (!GetParam().isCXX()) { 205 return; 206 } 207 EXPECT_TRUE(matches("class Y { friend class X; };", 208 friendDecl(hasType(asString("class X"))))); 209 EXPECT_TRUE(matches("class Y { friend class X; };", 210 friendDecl(hasType(recordDecl(hasName("X")))))); 211 212 EXPECT_TRUE(matches("class Y { friend void f(); };", 213 functionDecl(hasName("f"), hasParent(friendDecl())))); 214 } 215 216 TEST_P(ASTMatchersTest, EnumDecl_DoesNotMatchClasses) { 217 if (!GetParam().isCXX()) { 218 return; 219 } 220 EXPECT_TRUE(notMatches("class X {};", enumDecl(hasName("X")))); 221 } 222 223 TEST_P(ASTMatchersTest, EnumDecl_MatchesEnums) { 224 if (!GetParam().isCXX()) { 225 // FIXME: Fix this test in non-C++ language modes. 226 return; 227 } 228 EXPECT_TRUE(matches("enum X {};", enumDecl(hasName("X")))); 229 } 230 231 TEST_P(ASTMatchersTest, EnumConstantDecl) { 232 if (!GetParam().isCXX()) { 233 // FIXME: Fix this test in non-C++ language modes. 234 return; 235 } 236 DeclarationMatcher Matcher = enumConstantDecl(hasName("A")); 237 EXPECT_TRUE(matches("enum X{ A };", Matcher)); 238 EXPECT_TRUE(notMatches("enum X{ B };", Matcher)); 239 EXPECT_TRUE(notMatches("enum X {};", Matcher)); 240 } 241 242 TEST_P(ASTMatchersTest, TagDecl) { 243 if (!GetParam().isCXX()) { 244 // FIXME: Fix this test in non-C++ language modes. 245 return; 246 } 247 EXPECT_TRUE(matches("struct X {};", tagDecl(hasName("X")))); 248 EXPECT_TRUE(matches("union U {};", tagDecl(hasName("U")))); 249 EXPECT_TRUE(matches("enum E {};", tagDecl(hasName("E")))); 250 } 251 252 TEST_P(ASTMatchersTest, TagDecl_CXX) { 253 if (!GetParam().isCXX()) { 254 return; 255 } 256 EXPECT_TRUE(matches("class C {};", tagDecl(hasName("C")))); 257 } 258 259 TEST_P(ASTMatchersTest, UnresolvedLookupExpr) { 260 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) { 261 // FIXME: Fix this test to work with delayed template parsing. 262 return; 263 } 264 265 EXPECT_TRUE(matches("template<typename T>" 266 "T foo() { T a; return a; }" 267 "template<typename T>" 268 "void bar() {" 269 " foo<T>();" 270 "}", 271 unresolvedLookupExpr())); 272 } 273 274 TEST_P(ASTMatchersTest, UsesADL) { 275 if (!GetParam().isCXX()) { 276 return; 277 } 278 279 StatementMatcher ADLMatch = callExpr(usesADL()); 280 StatementMatcher ADLMatchOper = cxxOperatorCallExpr(usesADL()); 281 StringRef NS_Str = R"cpp( 282 namespace NS { 283 struct X {}; 284 void f(X); 285 void operator+(X, X); 286 } 287 struct MyX {}; 288 void f(...); 289 void operator+(MyX, MyX); 290 )cpp"; 291 292 auto MkStr = [&](StringRef Body) { 293 return (NS_Str + "void test_fn() { " + Body + " }").str(); 294 }; 295 296 EXPECT_TRUE(matches(MkStr("NS::X x; f(x);"), ADLMatch)); 297 EXPECT_TRUE(notMatches(MkStr("NS::X x; NS::f(x);"), ADLMatch)); 298 EXPECT_TRUE(notMatches(MkStr("MyX x; f(x);"), ADLMatch)); 299 EXPECT_TRUE(notMatches(MkStr("NS::X x; using NS::f; f(x);"), ADLMatch)); 300 301 // Operator call expressions 302 EXPECT_TRUE(matches(MkStr("NS::X x; x + x;"), ADLMatch)); 303 EXPECT_TRUE(matches(MkStr("NS::X x; x + x;"), ADLMatchOper)); 304 EXPECT_TRUE(notMatches(MkStr("MyX x; x + x;"), ADLMatch)); 305 EXPECT_TRUE(notMatches(MkStr("MyX x; x + x;"), ADLMatchOper)); 306 EXPECT_TRUE(matches(MkStr("NS::X x; operator+(x, x);"), ADLMatch)); 307 EXPECT_TRUE(notMatches(MkStr("NS::X x; NS::operator+(x, x);"), ADLMatch)); 308 } 309 310 TEST_P(ASTMatchersTest, CallExpr_CXX) { 311 if (!GetParam().isCXX()) { 312 // FIXME: Add a test for `callExpr()` that does not depend on C++. 313 return; 314 } 315 // FIXME: Do we want to overload Call() to directly take 316 // Matcher<Decl>, too? 317 StatementMatcher MethodX = 318 callExpr(hasDeclaration(cxxMethodDecl(hasName("x")))); 319 320 EXPECT_TRUE(matches("class Y { void x() { x(); } };", MethodX)); 321 EXPECT_TRUE(notMatches("class Y { void x() {} };", MethodX)); 322 323 StatementMatcher MethodOnY = 324 cxxMemberCallExpr(on(hasType(recordDecl(hasName("Y"))))); 325 326 EXPECT_TRUE(matches("class Y { public: void x(); }; void z() { Y y; y.x(); }", 327 MethodOnY)); 328 EXPECT_TRUE(matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }", 329 MethodOnY)); 330 EXPECT_TRUE(notMatches( 331 "class Y { public: void x(); }; void z(Y *&y) { y->x(); }", MethodOnY)); 332 EXPECT_TRUE(notMatches( 333 "class Y { public: void x(); }; void z(Y y[]) { y->x(); }", MethodOnY)); 334 EXPECT_TRUE(notMatches( 335 "class Y { public: void x(); }; void z() { Y *y; y->x(); }", MethodOnY)); 336 337 StatementMatcher MethodOnYPointer = 338 cxxMemberCallExpr(on(hasType(pointsTo(recordDecl(hasName("Y")))))); 339 340 EXPECT_TRUE( 341 matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }", 342 MethodOnYPointer)); 343 EXPECT_TRUE( 344 matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }", 345 MethodOnYPointer)); 346 EXPECT_TRUE( 347 matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }", 348 MethodOnYPointer)); 349 EXPECT_TRUE( 350 notMatches("class Y { public: void x(); }; void z() { Y y; y.x(); }", 351 MethodOnYPointer)); 352 EXPECT_TRUE( 353 notMatches("class Y { public: void x(); }; void z(Y &y) { y.x(); }", 354 MethodOnYPointer)); 355 } 356 357 TEST_P(ASTMatchersTest, LambdaExpr) { 358 if (!GetParam().isCXX11OrLater()) { 359 return; 360 } 361 EXPECT_TRUE(matches("auto f = [] (int i) { return i; };", lambdaExpr())); 362 } 363 364 TEST_P(ASTMatchersTest, CXXForRangeStmt) { 365 EXPECT_TRUE( 366 notMatches("void f() { for (int i; i<5; ++i); }", cxxForRangeStmt())); 367 } 368 369 TEST_P(ASTMatchersTest, CXXForRangeStmt_CXX11) { 370 if (!GetParam().isCXX11OrLater()) { 371 return; 372 } 373 EXPECT_TRUE(matches("int as[] = { 1, 2, 3 };" 374 "void f() { for (auto &a : as); }", 375 cxxForRangeStmt())); 376 } 377 378 TEST_P(ASTMatchersTest, SubstNonTypeTemplateParmExpr) { 379 if (!GetParam().isCXX()) { 380 return; 381 } 382 EXPECT_FALSE(matches("template<int N>\n" 383 "struct A { static const int n = 0; };\n" 384 "struct B : public A<42> {};", 385 traverse(TK_AsIs, substNonTypeTemplateParmExpr()))); 386 EXPECT_TRUE(matches("template<int N>\n" 387 "struct A { static const int n = N; };\n" 388 "struct B : public A<42> {};", 389 traverse(TK_AsIs, substNonTypeTemplateParmExpr()))); 390 } 391 392 TEST_P(ASTMatchersTest, NonTypeTemplateParmDecl) { 393 if (!GetParam().isCXX()) { 394 return; 395 } 396 EXPECT_TRUE(matches("template <int N> void f();", 397 nonTypeTemplateParmDecl(hasName("N")))); 398 EXPECT_TRUE( 399 notMatches("template <typename T> void f();", nonTypeTemplateParmDecl())); 400 } 401 402 TEST_P(ASTMatchersTest, TemplateTypeParmDecl) { 403 if (!GetParam().isCXX()) { 404 return; 405 } 406 EXPECT_TRUE(matches("template <typename T> void f();", 407 templateTypeParmDecl(hasName("T")))); 408 EXPECT_TRUE(notMatches("template <int N> void f();", templateTypeParmDecl())); 409 } 410 411 TEST_P(ASTMatchersTest, TemplateTemplateParmDecl) { 412 if (!GetParam().isCXX()) 413 return; 414 EXPECT_TRUE(matches("template <template <typename> class Z> void f();", 415 templateTemplateParmDecl(hasName("Z")))); 416 EXPECT_TRUE(notMatches("template <typename, int> void f();", 417 templateTemplateParmDecl())); 418 } 419 420 TEST_P(ASTMatchersTest, UserDefinedLiteral) { 421 if (!GetParam().isCXX11OrLater()) { 422 return; 423 } 424 EXPECT_TRUE(matches("constexpr char operator \"\" _inc (const char i) {" 425 " return i + 1;" 426 "}" 427 "char c = 'a'_inc;", 428 userDefinedLiteral())); 429 } 430 431 TEST_P(ASTMatchersTest, FlowControl) { 432 EXPECT_TRUE(matches("void f() { while(1) { break; } }", breakStmt())); 433 EXPECT_TRUE(matches("void f() { while(1) { continue; } }", continueStmt())); 434 EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", gotoStmt())); 435 EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", 436 labelStmt(hasDeclaration(labelDecl(hasName("FOO")))))); 437 EXPECT_TRUE(matches("void f() { FOO: ; void *ptr = &&FOO; goto *ptr; }", 438 addrLabelExpr())); 439 EXPECT_TRUE(matches("void f() { return; }", returnStmt())); 440 } 441 442 TEST_P(ASTMatchersTest, CXXOperatorCallExpr) { 443 if (!GetParam().isCXX()) { 444 return; 445 } 446 447 StatementMatcher OpCall = cxxOperatorCallExpr(); 448 // Unary operator 449 EXPECT_TRUE(matches("class Y { }; " 450 "bool operator!(Y x) { return false; }; " 451 "Y y; bool c = !y;", 452 OpCall)); 453 // No match -- special operators like "new", "delete" 454 // FIXME: operator new takes size_t, for which we need stddef.h, for which 455 // we need to figure out include paths in the test. 456 // EXPECT_TRUE(NotMatches("#include <stddef.h>\n" 457 // "class Y { }; " 458 // "void *operator new(size_t size) { return 0; } " 459 // "Y *y = new Y;", OpCall)); 460 EXPECT_TRUE(notMatches("class Y { }; " 461 "void operator delete(void *p) { } " 462 "void a() {Y *y = new Y; delete y;}", 463 OpCall)); 464 // Binary operator 465 EXPECT_TRUE(matches("class Y { }; " 466 "bool operator&&(Y x, Y y) { return true; }; " 467 "Y a; Y b; bool c = a && b;", 468 OpCall)); 469 // No match -- normal operator, not an overloaded one. 470 EXPECT_TRUE(notMatches("bool x = true, y = true; bool t = x && y;", OpCall)); 471 EXPECT_TRUE(notMatches("int t = 5 << 2;", OpCall)); 472 } 473 474 TEST_P(ASTMatchersTest, ThisPointerType) { 475 if (!GetParam().isCXX()) { 476 return; 477 } 478 479 StatementMatcher MethodOnY = traverse( 480 TK_AsIs, cxxMemberCallExpr(thisPointerType(recordDecl(hasName("Y"))))); 481 482 EXPECT_TRUE(matches("class Y { public: void x(); }; void z() { Y y; y.x(); }", 483 MethodOnY)); 484 EXPECT_TRUE(matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }", 485 MethodOnY)); 486 EXPECT_TRUE(matches( 487 "class Y { public: void x(); }; void z(Y *&y) { y->x(); }", MethodOnY)); 488 EXPECT_TRUE(matches( 489 "class Y { public: void x(); }; void z(Y y[]) { y->x(); }", MethodOnY)); 490 EXPECT_TRUE(matches( 491 "class Y { public: void x(); }; void z() { Y *y; y->x(); }", MethodOnY)); 492 493 EXPECT_TRUE(matches("class Y {" 494 " public: virtual void x();" 495 "};" 496 "class X : public Y {" 497 " public: virtual void x();" 498 "};" 499 "void z() { X *x; x->Y::x(); }", 500 MethodOnY)); 501 } 502 503 TEST_P(ASTMatchersTest, DeclRefExpr) { 504 if (!GetParam().isCXX()) { 505 // FIXME: Add a test for `declRefExpr()` that does not depend on C++. 506 return; 507 } 508 StatementMatcher Reference = declRefExpr(to(varDecl(hasInitializer( 509 cxxMemberCallExpr(thisPointerType(recordDecl(hasName("Y")))))))); 510 511 EXPECT_TRUE(matches("class Y {" 512 " public:" 513 " bool x() const;" 514 "};" 515 "void z(const Y &y) {" 516 " bool b = y.x();" 517 " if (b) {}" 518 "}", 519 Reference)); 520 521 EXPECT_TRUE(notMatches("class Y {" 522 " public:" 523 " bool x() const;" 524 "};" 525 "void z(const Y &y) {" 526 " bool b = y.x();" 527 "}", 528 Reference)); 529 } 530 531 TEST_P(ASTMatchersTest, CXXMemberCallExpr) { 532 if (!GetParam().isCXX()) { 533 return; 534 } 535 StatementMatcher CallOnVariableY = 536 cxxMemberCallExpr(on(declRefExpr(to(varDecl(hasName("y")))))); 537 538 EXPECT_TRUE(matches("class Y { public: void x() { Y y; y.x(); } };", 539 CallOnVariableY)); 540 EXPECT_TRUE(matches("class Y { public: void x() const { Y y; y.x(); } };", 541 CallOnVariableY)); 542 EXPECT_TRUE(matches("class Y { public: void x(); };" 543 "class X : public Y { void z() { X y; y.x(); } };", 544 CallOnVariableY)); 545 EXPECT_TRUE(matches("class Y { public: void x(); };" 546 "class X : public Y { void z() { X *y; y->x(); } };", 547 CallOnVariableY)); 548 EXPECT_TRUE(notMatches( 549 "class Y { public: void x(); };" 550 "class X : public Y { void z() { unsigned long y; ((X*)y)->x(); } };", 551 CallOnVariableY)); 552 } 553 554 TEST_P(ASTMatchersTest, UnaryExprOrTypeTraitExpr) { 555 EXPECT_TRUE( 556 matches("void x() { int a = sizeof(a); }", unaryExprOrTypeTraitExpr())); 557 } 558 559 TEST_P(ASTMatchersTest, AlignOfExpr) { 560 EXPECT_TRUE( 561 notMatches("void x() { int a = sizeof(a); }", alignOfExpr(anything()))); 562 // FIXME: Uncomment once alignof is enabled. 563 // EXPECT_TRUE(matches("void x() { int a = alignof(a); }", 564 // unaryExprOrTypeTraitExpr())); 565 // EXPECT_TRUE(notMatches("void x() { int a = alignof(a); }", 566 // sizeOfExpr())); 567 } 568 569 TEST_P(ASTMatchersTest, MemberExpr_DoesNotMatchClasses) { 570 if (!GetParam().isCXX()) { 571 return; 572 } 573 EXPECT_TRUE(notMatches("class Y { void x() {} };", memberExpr())); 574 EXPECT_TRUE(notMatches("class Y { void x() {} };", unresolvedMemberExpr())); 575 EXPECT_TRUE( 576 notMatches("class Y { void x() {} };", cxxDependentScopeMemberExpr())); 577 } 578 579 TEST_P(ASTMatchersTest, MemberExpr_MatchesMemberFunctionCall) { 580 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) { 581 // FIXME: Fix this test to work with delayed template parsing. 582 return; 583 } 584 EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpr())); 585 EXPECT_TRUE(matches("class Y { template <class T> void x() { x<T>(); } };", 586 unresolvedMemberExpr())); 587 EXPECT_TRUE(matches("template <class T> void x() { T t; t.f(); }", 588 cxxDependentScopeMemberExpr())); 589 } 590 591 TEST_P(ASTMatchersTest, MemberExpr_MatchesVariable) { 592 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) { 593 // FIXME: Fix this test to work with delayed template parsing. 594 return; 595 } 596 EXPECT_TRUE( 597 matches("class Y { void x() { this->y; } int y; };", memberExpr())); 598 EXPECT_TRUE(matches("class Y { void x() { y; } int y; };", memberExpr())); 599 EXPECT_TRUE( 600 matches("class Y { void x() { Y y; y.y; } int y; };", memberExpr())); 601 EXPECT_TRUE(matches("template <class T>" 602 "class X : T { void f() { this->T::v; } };", 603 cxxDependentScopeMemberExpr())); 604 EXPECT_TRUE(matches("template <class T> class X : T { void f() { T::v; } };", 605 cxxDependentScopeMemberExpr())); 606 EXPECT_TRUE(matches("template <class T> void x() { T t; t.v; }", 607 cxxDependentScopeMemberExpr())); 608 } 609 610 TEST_P(ASTMatchersTest, MemberExpr_MatchesStaticVariable) { 611 if (!GetParam().isCXX()) { 612 return; 613 } 614 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };", 615 memberExpr())); 616 EXPECT_TRUE( 617 notMatches("class Y { void x() { y; } static int y; };", memberExpr())); 618 EXPECT_TRUE(notMatches("class Y { void x() { Y::y; } static int y; };", 619 memberExpr())); 620 } 621 622 TEST_P(ASTMatchersTest, FunctionDecl) { 623 StatementMatcher CallFunctionF = callExpr(callee(functionDecl(hasName("f")))); 624 625 EXPECT_TRUE(matches("void f() { f(); }", CallFunctionF)); 626 EXPECT_TRUE(notMatches("void f() { }", CallFunctionF)); 627 628 EXPECT_TRUE(notMatches("void f(int);", functionDecl(isVariadic()))); 629 EXPECT_TRUE(notMatches("void f();", functionDecl(isVariadic()))); 630 EXPECT_TRUE(matches("void f(int, ...);", functionDecl(parameterCountIs(1)))); 631 } 632 633 TEST_P(ASTMatchersTest, FunctionDecl_C) { 634 if (!GetParam().isC()) { 635 return; 636 } 637 EXPECT_TRUE(notMatches("void f();", functionDecl(isVariadic()))); 638 EXPECT_TRUE(matches("void f();", functionDecl(parameterCountIs(0)))); 639 } 640 641 TEST_P(ASTMatchersTest, FunctionDecl_CXX) { 642 if (!GetParam().isCXX()) { 643 return; 644 } 645 646 StatementMatcher CallFunctionF = callExpr(callee(functionDecl(hasName("f")))); 647 648 if (!GetParam().hasDelayedTemplateParsing()) { 649 // FIXME: Fix this test to work with delayed template parsing. 650 // Dependent contexts, but a non-dependent call. 651 EXPECT_TRUE( 652 matches("void f(); template <int N> void g() { f(); }", CallFunctionF)); 653 EXPECT_TRUE( 654 matches("void f(); template <int N> struct S { void g() { f(); } };", 655 CallFunctionF)); 656 } 657 658 // Depedent calls don't match. 659 EXPECT_TRUE( 660 notMatches("void f(int); template <typename T> void g(T t) { f(t); }", 661 CallFunctionF)); 662 EXPECT_TRUE( 663 notMatches("void f(int);" 664 "template <typename T> struct S { void g(T t) { f(t); } };", 665 CallFunctionF)); 666 667 EXPECT_TRUE(matches("void f(...);", functionDecl(isVariadic()))); 668 EXPECT_TRUE(matches("void f(...);", functionDecl(parameterCountIs(0)))); 669 } 670 671 TEST_P(ASTMatchersTest, FunctionDecl_CXX11) { 672 if (!GetParam().isCXX11OrLater()) { 673 return; 674 } 675 676 EXPECT_TRUE(notMatches("template <typename... Ts> void f(Ts...);", 677 functionDecl(isVariadic()))); 678 } 679 680 TEST_P(ASTMatchersTest, 681 FunctionTemplateDecl_MatchesFunctionTemplateDeclarations) { 682 if (!GetParam().isCXX()) { 683 return; 684 } 685 EXPECT_TRUE(matches("template <typename T> void f(T t) {}", 686 functionTemplateDecl(hasName("f")))); 687 } 688 689 TEST_P(ASTMatchersTest, FunctionTemplate_DoesNotMatchFunctionDeclarations) { 690 EXPECT_TRUE( 691 notMatches("void f(double d);", functionTemplateDecl(hasName("f")))); 692 EXPECT_TRUE( 693 notMatches("void f(int t) {}", functionTemplateDecl(hasName("f")))); 694 } 695 696 TEST_P(ASTMatchersTest, 697 FunctionTemplateDecl_DoesNotMatchFunctionTemplateSpecializations) { 698 if (!GetParam().isCXX()) { 699 return; 700 } 701 EXPECT_TRUE(notMatches( 702 "void g(); template <typename T> void f(T t) {}" 703 "template <> void f(int t) { g(); }", 704 functionTemplateDecl(hasName("f"), hasDescendant(declRefExpr(to( 705 functionDecl(hasName("g")))))))); 706 } 707 708 TEST_P(ASTMatchersTest, ClassTemplateSpecializationDecl) { 709 if (!GetParam().isCXX()) { 710 return; 711 } 712 EXPECT_TRUE(matches("template<typename T> struct A {};" 713 "template<> struct A<int> {};", 714 classTemplateSpecializationDecl())); 715 EXPECT_TRUE(matches("template<typename T> struct A {}; A<int> a;", 716 classTemplateSpecializationDecl())); 717 EXPECT_TRUE(notMatches("template<typename T> struct A {};", 718 classTemplateSpecializationDecl())); 719 } 720 721 TEST_P(ASTMatchersTest, DeclaratorDecl) { 722 EXPECT_TRUE(matches("int x;", declaratorDecl())); 723 EXPECT_TRUE(notMatches("struct A {};", declaratorDecl())); 724 } 725 726 TEST_P(ASTMatchersTest, DeclaratorDecl_CXX) { 727 if (!GetParam().isCXX()) { 728 return; 729 } 730 EXPECT_TRUE(notMatches("class A {};", declaratorDecl())); 731 } 732 733 TEST_P(ASTMatchersTest, ParmVarDecl) { 734 EXPECT_TRUE(matches("void f(int x);", parmVarDecl())); 735 EXPECT_TRUE(notMatches("void f();", parmVarDecl())); 736 } 737 738 TEST_P(ASTMatchersTest, Matcher_ConstructorCall) { 739 if (!GetParam().isCXX()) { 740 return; 741 } 742 743 StatementMatcher Constructor = traverse(TK_AsIs, cxxConstructExpr()); 744 745 EXPECT_TRUE( 746 matches("class X { public: X(); }; void x() { X x; }", Constructor)); 747 EXPECT_TRUE(matches("class X { public: X(); }; void x() { X x = X(); }", 748 Constructor)); 749 EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x = 0; }", 750 Constructor)); 751 EXPECT_TRUE(matches("class X {}; void x(int) { X x; }", Constructor)); 752 } 753 754 TEST_P(ASTMatchersTest, Match_ConstructorInitializers) { 755 if (!GetParam().isCXX()) { 756 return; 757 } 758 EXPECT_TRUE(matches("class C { int i; public: C(int ii) : i(ii) {} };", 759 cxxCtorInitializer(forField(hasName("i"))))); 760 } 761 762 TEST_P(ASTMatchersTest, Matcher_ThisExpr) { 763 if (!GetParam().isCXX()) { 764 return; 765 } 766 EXPECT_TRUE( 767 matches("struct X { int a; int f () { return a; } };", cxxThisExpr())); 768 EXPECT_TRUE( 769 notMatches("struct X { int f () { int a; return a; } };", cxxThisExpr())); 770 } 771 772 TEST_P(ASTMatchersTest, Matcher_BindTemporaryExpression) { 773 if (!GetParam().isCXX()) { 774 return; 775 } 776 777 StatementMatcher TempExpression = traverse(TK_AsIs, cxxBindTemporaryExpr()); 778 779 StringRef ClassString = "class string { public: string(); ~string(); }; "; 780 781 EXPECT_TRUE(matches( 782 ClassString + "string GetStringByValue();" 783 "void FunctionTakesString(string s);" 784 "void run() { FunctionTakesString(GetStringByValue()); }", 785 TempExpression)); 786 787 EXPECT_TRUE(notMatches(ClassString + 788 "string* GetStringPointer(); " 789 "void FunctionTakesStringPtr(string* s);" 790 "void run() {" 791 " string* s = GetStringPointer();" 792 " FunctionTakesStringPtr(GetStringPointer());" 793 " FunctionTakesStringPtr(s);" 794 "}", 795 TempExpression)); 796 797 EXPECT_TRUE(notMatches("class no_dtor {};" 798 "no_dtor GetObjByValue();" 799 "void ConsumeObj(no_dtor param);" 800 "void run() { ConsumeObj(GetObjByValue()); }", 801 TempExpression)); 802 } 803 804 TEST_P(ASTMatchersTest, MaterializeTemporaryExpr_MatchesTemporaryCXX11CXX14) { 805 if (GetParam().Language != Lang_CXX11 && GetParam().Language != Lang_CXX14) { 806 return; 807 } 808 809 StatementMatcher TempExpression = 810 traverse(TK_AsIs, materializeTemporaryExpr()); 811 812 EXPECT_TRUE(matches("class string { public: string(); }; " 813 "string GetStringByValue();" 814 "void FunctionTakesString(string s);" 815 "void run() { FunctionTakesString(GetStringByValue()); }", 816 TempExpression)); 817 } 818 819 TEST_P(ASTMatchersTest, MaterializeTemporaryExpr_MatchesTemporary) { 820 if (!GetParam().isCXX()) { 821 return; 822 } 823 824 StringRef ClassString = "class string { public: string(); int length(); }; "; 825 StatementMatcher TempExpression = 826 traverse(TK_AsIs, materializeTemporaryExpr()); 827 828 EXPECT_TRUE(notMatches(ClassString + 829 "string* GetStringPointer(); " 830 "void FunctionTakesStringPtr(string* s);" 831 "void run() {" 832 " string* s = GetStringPointer();" 833 " FunctionTakesStringPtr(GetStringPointer());" 834 " FunctionTakesStringPtr(s);" 835 "}", 836 TempExpression)); 837 838 EXPECT_TRUE(matches(ClassString + 839 "string GetStringByValue();" 840 "void run() { int k = GetStringByValue().length(); }", 841 TempExpression)); 842 843 EXPECT_TRUE(notMatches(ClassString + "string GetStringByValue();" 844 "void run() { GetStringByValue(); }", 845 TempExpression)); 846 } 847 848 TEST_P(ASTMatchersTest, Matcher_NewExpression) { 849 if (!GetParam().isCXX()) { 850 return; 851 } 852 853 StatementMatcher New = cxxNewExpr(); 854 855 EXPECT_TRUE(matches("class X { public: X(); }; void x() { new X; }", New)); 856 EXPECT_TRUE(matches("class X { public: X(); }; void x() { new X(); }", New)); 857 EXPECT_TRUE( 858 matches("class X { public: X(int); }; void x() { new X(0); }", New)); 859 EXPECT_TRUE(matches("class X {}; void x(int) { new X; }", New)); 860 } 861 862 TEST_P(ASTMatchersTest, Matcher_DeleteExpression) { 863 if (!GetParam().isCXX()) { 864 return; 865 } 866 EXPECT_TRUE( 867 matches("struct A {}; void f(A* a) { delete a; }", cxxDeleteExpr())); 868 } 869 870 TEST_P(ASTMatchersTest, Matcher_NoexceptExpression) { 871 if (!GetParam().isCXX11OrLater()) { 872 return; 873 } 874 StatementMatcher NoExcept = cxxNoexceptExpr(); 875 EXPECT_TRUE(matches("void foo(); bool bar = noexcept(foo());", NoExcept)); 876 EXPECT_TRUE( 877 matches("void foo() noexcept; bool bar = noexcept(foo());", NoExcept)); 878 EXPECT_TRUE(notMatches("void foo() noexcept;", NoExcept)); 879 EXPECT_TRUE(notMatches("void foo() noexcept(1+1);", NoExcept)); 880 EXPECT_TRUE(matches("void foo() noexcept(noexcept(1+1));", NoExcept)); 881 } 882 883 TEST_P(ASTMatchersTest, Matcher_DefaultArgument) { 884 if (!GetParam().isCXX()) { 885 return; 886 } 887 StatementMatcher Arg = cxxDefaultArgExpr(); 888 EXPECT_TRUE(matches("void x(int, int = 0) { int y; x(y); }", Arg)); 889 EXPECT_TRUE( 890 matches("class X { void x(int, int = 0) { int y; x(y); } };", Arg)); 891 EXPECT_TRUE(notMatches("void x(int, int = 0) { int y; x(y, 0); }", Arg)); 892 } 893 894 TEST_P(ASTMatchersTest, StringLiteral) { 895 StatementMatcher Literal = stringLiteral(); 896 EXPECT_TRUE(matches("const char *s = \"string\";", Literal)); 897 // with escaped characters 898 EXPECT_TRUE(matches("const char *s = \"\x05five\";", Literal)); 899 // no matching -- though the data type is the same, there is no string literal 900 EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal)); 901 } 902 903 TEST_P(ASTMatchersTest, StringLiteral_CXX) { 904 if (!GetParam().isCXX()) { 905 return; 906 } 907 EXPECT_TRUE(matches("const wchar_t *s = L\"string\";", stringLiteral())); 908 } 909 910 TEST_P(ASTMatchersTest, CharacterLiteral) { 911 EXPECT_TRUE(matches("const char c = 'c';", characterLiteral())); 912 EXPECT_TRUE(notMatches("const char c = 0x1;", characterLiteral())); 913 } 914 915 TEST_P(ASTMatchersTest, CharacterLiteral_CXX) { 916 if (!GetParam().isCXX()) { 917 return; 918 } 919 // wide character 920 EXPECT_TRUE(matches("const char c = L'c';", characterLiteral())); 921 // wide character, Hex encoded, NOT MATCHED! 922 EXPECT_TRUE(notMatches("const wchar_t c = 0x2126;", characterLiteral())); 923 } 924 925 TEST_P(ASTMatchersTest, IntegerLiteral) { 926 StatementMatcher HasIntLiteral = integerLiteral(); 927 EXPECT_TRUE(matches("int i = 10;", HasIntLiteral)); 928 EXPECT_TRUE(matches("int i = 0x1AB;", HasIntLiteral)); 929 EXPECT_TRUE(matches("int i = 10L;", HasIntLiteral)); 930 EXPECT_TRUE(matches("int i = 10U;", HasIntLiteral)); 931 932 // Non-matching cases (character literals, float and double) 933 EXPECT_TRUE(notMatches("int i = L'a';", 934 HasIntLiteral)); // this is actually a character 935 // literal cast to int 936 EXPECT_TRUE(notMatches("int i = 'a';", HasIntLiteral)); 937 EXPECT_TRUE(notMatches("int i = 1e10;", HasIntLiteral)); 938 EXPECT_TRUE(notMatches("int i = 10.0;", HasIntLiteral)); 939 940 // Negative integers. 941 EXPECT_TRUE( 942 matches("int i = -10;", 943 unaryOperator(hasOperatorName("-"), 944 hasUnaryOperand(integerLiteral(equals(10)))))); 945 } 946 947 TEST_P(ASTMatchersTest, FloatLiteral) { 948 StatementMatcher HasFloatLiteral = floatLiteral(); 949 EXPECT_TRUE(matches("float i = 10.0;", HasFloatLiteral)); 950 EXPECT_TRUE(matches("float i = 10.0f;", HasFloatLiteral)); 951 EXPECT_TRUE(matches("double i = 10.0;", HasFloatLiteral)); 952 EXPECT_TRUE(matches("double i = 10.0L;", HasFloatLiteral)); 953 EXPECT_TRUE(matches("double i = 1e10;", HasFloatLiteral)); 954 EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0)))); 955 EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0f)))); 956 EXPECT_TRUE( 957 matches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(5.0))))); 958 959 EXPECT_TRUE(notMatches("float i = 10;", HasFloatLiteral)); 960 EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0)))); 961 EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0f)))); 962 EXPECT_TRUE( 963 notMatches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(6.0))))); 964 } 965 966 TEST_P(ASTMatchersTest, CXXNullPtrLiteralExpr) { 967 if (!GetParam().isCXX11OrLater()) { 968 return; 969 } 970 EXPECT_TRUE(matches("int* i = nullptr;", cxxNullPtrLiteralExpr())); 971 } 972 973 TEST_P(ASTMatchersTest, ChooseExpr) { 974 EXPECT_TRUE(matches("void f() { (void)__builtin_choose_expr(1, 2, 3); }", 975 chooseExpr())); 976 } 977 978 TEST_P(ASTMatchersTest, GNUNullExpr) { 979 if (!GetParam().isCXX()) { 980 return; 981 } 982 EXPECT_TRUE(matches("int* i = __null;", gnuNullExpr())); 983 } 984 985 TEST_P(ASTMatchersTest, GenericSelectionExpr) { 986 EXPECT_TRUE(matches("void f() { (void)_Generic(1, int: 1, float: 2.0); }", 987 genericSelectionExpr())); 988 } 989 990 TEST_P(ASTMatchersTest, AtomicExpr) { 991 EXPECT_TRUE(matches("void foo() { int *ptr; __atomic_load_n(ptr, 1); }", 992 atomicExpr())); 993 } 994 995 TEST_P(ASTMatchersTest, Initializers_C99) { 996 if (!GetParam().isC99OrLater()) { 997 return; 998 } 999 EXPECT_TRUE(matches( 1000 "void foo() { struct point { double x; double y; };" 1001 " struct point ptarray[10] = " 1002 " { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }", 1003 initListExpr(hasSyntacticForm(initListExpr( 1004 has(designatedInitExpr(designatorCountIs(2), 1005 hasDescendant(floatLiteral(equals(1.0))), 1006 hasDescendant(integerLiteral(equals(2))))), 1007 has(designatedInitExpr(designatorCountIs(2), 1008 hasDescendant(floatLiteral(equals(2.0))), 1009 hasDescendant(integerLiteral(equals(2))))), 1010 has(designatedInitExpr( 1011 designatorCountIs(2), hasDescendant(floatLiteral(equals(1.0))), 1012 hasDescendant(integerLiteral(equals(0)))))))))); 1013 } 1014 1015 TEST_P(ASTMatchersTest, Initializers_CXX) { 1016 if (GetParam().Language != Lang_CXX03) { 1017 // FIXME: Make this test pass with other C++ standard versions. 1018 return; 1019 } 1020 EXPECT_TRUE(matches( 1021 "void foo() { struct point { double x; double y; };" 1022 " struct point ptarray[10] = " 1023 " { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }", 1024 initListExpr( 1025 has(cxxConstructExpr(requiresZeroInitialization())), 1026 has(initListExpr( 1027 hasType(asString("struct point")), has(floatLiteral(equals(1.0))), 1028 has(implicitValueInitExpr(hasType(asString("double")))))), 1029 has(initListExpr(hasType(asString("struct point")), 1030 has(floatLiteral(equals(2.0))), 1031 has(floatLiteral(equals(1.0)))))))); 1032 } 1033 1034 TEST_P(ASTMatchersTest, ParenListExpr) { 1035 if (!GetParam().isCXX()) { 1036 return; 1037 } 1038 EXPECT_TRUE( 1039 matches("template<typename T> class foo { void bar() { foo X(*this); } };" 1040 "template class foo<int>;", 1041 varDecl(hasInitializer(parenListExpr(has(unaryOperator())))))); 1042 } 1043 1044 TEST_P(ASTMatchersTest, StmtExpr) { 1045 EXPECT_TRUE(matches("void declToImport() { int C = ({int X=4; X;}); }", 1046 varDecl(hasInitializer(stmtExpr())))); 1047 } 1048 1049 TEST_P(ASTMatchersTest, PredefinedExpr) { 1050 // __func__ expands as StringLiteral("foo") 1051 EXPECT_TRUE(matches("void foo() { __func__; }", 1052 predefinedExpr(hasType(asString("const char [4]")), 1053 has(stringLiteral())))); 1054 } 1055 1056 TEST_P(ASTMatchersTest, AsmStatement) { 1057 EXPECT_TRUE(matches("void foo() { __asm(\"mov al, 2\"); }", asmStmt())); 1058 } 1059 1060 TEST_P(ASTMatchersTest, HasCondition) { 1061 if (!GetParam().isCXX()) { 1062 // FIXME: Add a test for `hasCondition()` that does not depend on C++. 1063 return; 1064 } 1065 1066 StatementMatcher Condition = 1067 ifStmt(hasCondition(cxxBoolLiteral(equals(true)))); 1068 1069 EXPECT_TRUE(matches("void x() { if (true) {} }", Condition)); 1070 EXPECT_TRUE(notMatches("void x() { if (false) {} }", Condition)); 1071 EXPECT_TRUE(notMatches("void x() { bool a = true; if (a) {} }", Condition)); 1072 EXPECT_TRUE(notMatches("void x() { if (true || false) {} }", Condition)); 1073 EXPECT_TRUE(notMatches("void x() { if (1) {} }", Condition)); 1074 } 1075 1076 TEST_P(ASTMatchersTest, ConditionalOperator) { 1077 if (!GetParam().isCXX()) { 1078 // FIXME: Add a test for `conditionalOperator()` that does not depend on 1079 // C++. 1080 return; 1081 } 1082 1083 StatementMatcher Conditional = 1084 conditionalOperator(hasCondition(cxxBoolLiteral(equals(true))), 1085 hasTrueExpression(cxxBoolLiteral(equals(false)))); 1086 1087 EXPECT_TRUE(matches("void x() { true ? false : true; }", Conditional)); 1088 EXPECT_TRUE(notMatches("void x() { false ? false : true; }", Conditional)); 1089 EXPECT_TRUE(notMatches("void x() { true ? true : false; }", Conditional)); 1090 1091 StatementMatcher ConditionalFalse = 1092 conditionalOperator(hasFalseExpression(cxxBoolLiteral(equals(false)))); 1093 1094 EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse)); 1095 EXPECT_TRUE( 1096 notMatches("void x() { true ? false : true; }", ConditionalFalse)); 1097 1098 EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse)); 1099 EXPECT_TRUE( 1100 notMatches("void x() { true ? false : true; }", ConditionalFalse)); 1101 } 1102 1103 TEST_P(ASTMatchersTest, BinaryConditionalOperator) { 1104 if (!GetParam().isCXX()) { 1105 // FIXME: This test should work in non-C++ language modes. 1106 return; 1107 } 1108 1109 StatementMatcher AlwaysOne = traverse( 1110 TK_AsIs, binaryConditionalOperator( 1111 hasCondition(implicitCastExpr(has(opaqueValueExpr( 1112 hasSourceExpression((integerLiteral(equals(1)))))))), 1113 hasFalseExpression(integerLiteral(equals(0))))); 1114 1115 EXPECT_TRUE(matches("void x() { 1 ?: 0; }", AlwaysOne)); 1116 1117 StatementMatcher FourNotFive = binaryConditionalOperator( 1118 hasTrueExpression( 1119 opaqueValueExpr(hasSourceExpression((integerLiteral(equals(4)))))), 1120 hasFalseExpression(integerLiteral(equals(5)))); 1121 1122 EXPECT_TRUE(matches("void x() { 4 ?: 5; }", FourNotFive)); 1123 } 1124 1125 TEST_P(ASTMatchersTest, ArraySubscriptExpr) { 1126 EXPECT_TRUE( 1127 matches("int i[2]; void f() { i[1] = 1; }", arraySubscriptExpr())); 1128 EXPECT_TRUE(notMatches("int i; void f() { i = 1; }", arraySubscriptExpr())); 1129 } 1130 1131 TEST_P(ASTMatchersTest, ForStmt) { 1132 EXPECT_TRUE(matches("void f() { for(;;); }", forStmt())); 1133 EXPECT_TRUE(matches("void f() { if(1) for(;;); }", forStmt())); 1134 } 1135 1136 TEST_P(ASTMatchersTest, ForStmt_CXX11) { 1137 if (!GetParam().isCXX11OrLater()) { 1138 return; 1139 } 1140 EXPECT_TRUE(notMatches("int as[] = { 1, 2, 3 };" 1141 "void f() { for (auto &a : as); }", 1142 forStmt())); 1143 } 1144 1145 TEST_P(ASTMatchersTest, ForStmt_NoFalsePositives) { 1146 EXPECT_TRUE(notMatches("void f() { ; }", forStmt())); 1147 EXPECT_TRUE(notMatches("void f() { if(1); }", forStmt())); 1148 } 1149 1150 TEST_P(ASTMatchersTest, CompoundStatement) { 1151 EXPECT_TRUE(notMatches("void f();", compoundStmt())); 1152 EXPECT_TRUE(matches("void f() {}", compoundStmt())); 1153 EXPECT_TRUE(matches("void f() {{}}", compoundStmt())); 1154 } 1155 1156 TEST_P(ASTMatchersTest, CompoundStatement_DoesNotMatchEmptyStruct) { 1157 if (!GetParam().isCXX()) { 1158 // FIXME: Add a similar test that does not depend on C++. 1159 return; 1160 } 1161 // It's not a compound statement just because there's "{}" in the source 1162 // text. This is an AST search, not grep. 1163 EXPECT_TRUE(notMatches("namespace n { struct S {}; }", compoundStmt())); 1164 EXPECT_TRUE( 1165 matches("namespace n { struct S { void f() {{}} }; }", compoundStmt())); 1166 } 1167 1168 TEST_P(ASTMatchersTest, CastExpr_MatchesExplicitCasts) { 1169 EXPECT_TRUE(matches("void *p = (void *)(&p);", castExpr())); 1170 } 1171 1172 TEST_P(ASTMatchersTest, CastExpr_MatchesExplicitCasts_CXX) { 1173 if (!GetParam().isCXX()) { 1174 return; 1175 } 1176 EXPECT_TRUE(matches("char *p = reinterpret_cast<char *>(&p);", castExpr())); 1177 EXPECT_TRUE(matches("char q, *p = const_cast<char *>(&q);", castExpr())); 1178 EXPECT_TRUE(matches("char c = char(0);", castExpr())); 1179 } 1180 1181 TEST_P(ASTMatchersTest, CastExpression_MatchesImplicitCasts) { 1182 // This test creates an implicit cast from int to char. 1183 EXPECT_TRUE(matches("char c = 0;", traverse(TK_AsIs, castExpr()))); 1184 // This test creates an implicit cast from lvalue to rvalue. 1185 EXPECT_TRUE(matches("void f() { char c = 0, d = c; }", 1186 traverse(TK_AsIs, castExpr()))); 1187 } 1188 1189 TEST_P(ASTMatchersTest, CastExpr_DoesNotMatchNonCasts) { 1190 if (GetParam().Language == Lang_C89 || GetParam().Language == Lang_C99) { 1191 // This does have a cast in C 1192 EXPECT_TRUE(matches("char c = '0';", implicitCastExpr())); 1193 } else { 1194 EXPECT_TRUE(notMatches("char c = '0';", castExpr())); 1195 } 1196 EXPECT_TRUE(notMatches("int i = (0);", castExpr())); 1197 EXPECT_TRUE(notMatches("int i = 0;", castExpr())); 1198 } 1199 1200 TEST_P(ASTMatchersTest, CastExpr_DoesNotMatchNonCasts_CXX) { 1201 if (!GetParam().isCXX()) { 1202 return; 1203 } 1204 EXPECT_TRUE(notMatches("char c, &q = c;", castExpr())); 1205 } 1206 1207 TEST_P(ASTMatchersTest, CXXReinterpretCastExpr) { 1208 if (!GetParam().isCXX()) { 1209 return; 1210 } 1211 EXPECT_TRUE(matches("char* p = reinterpret_cast<char*>(&p);", 1212 cxxReinterpretCastExpr())); 1213 } 1214 1215 TEST_P(ASTMatchersTest, CXXReinterpretCastExpr_DoesNotMatchOtherCasts) { 1216 if (!GetParam().isCXX()) { 1217 return; 1218 } 1219 EXPECT_TRUE(notMatches("char* p = (char*)(&p);", cxxReinterpretCastExpr())); 1220 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);", 1221 cxxReinterpretCastExpr())); 1222 EXPECT_TRUE(notMatches("void* p = static_cast<void*>(&p);", 1223 cxxReinterpretCastExpr())); 1224 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};" 1225 "B b;" 1226 "D* p = dynamic_cast<D*>(&b);", 1227 cxxReinterpretCastExpr())); 1228 } 1229 1230 TEST_P(ASTMatchersTest, CXXFunctionalCastExpr_MatchesSimpleCase) { 1231 if (!GetParam().isCXX()) { 1232 return; 1233 } 1234 StringRef foo_class = "class Foo { public: Foo(const char*); };"; 1235 EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }", 1236 cxxFunctionalCastExpr())); 1237 } 1238 1239 TEST_P(ASTMatchersTest, CXXFunctionalCastExpr_DoesNotMatchOtherCasts) { 1240 if (!GetParam().isCXX()) { 1241 return; 1242 } 1243 StringRef FooClass = "class Foo { public: Foo(const char*); };"; 1244 EXPECT_TRUE( 1245 notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }", 1246 cxxFunctionalCastExpr())); 1247 EXPECT_TRUE(notMatches(FooClass + "void r() { Foo f = \"hello world\"; }", 1248 cxxFunctionalCastExpr())); 1249 } 1250 1251 TEST_P(ASTMatchersTest, CXXDynamicCastExpr) { 1252 if (!GetParam().isCXX()) { 1253 return; 1254 } 1255 EXPECT_TRUE(matches("struct B { virtual ~B() {} }; struct D : B {};" 1256 "B b;" 1257 "D* p = dynamic_cast<D*>(&b);", 1258 cxxDynamicCastExpr())); 1259 } 1260 1261 TEST_P(ASTMatchersTest, CXXStaticCastExpr_MatchesSimpleCase) { 1262 if (!GetParam().isCXX()) { 1263 return; 1264 } 1265 EXPECT_TRUE(matches("void* p(static_cast<void*>(&p));", cxxStaticCastExpr())); 1266 } 1267 1268 TEST_P(ASTMatchersTest, CXXStaticCastExpr_DoesNotMatchOtherCasts) { 1269 if (!GetParam().isCXX()) { 1270 return; 1271 } 1272 EXPECT_TRUE(notMatches("char* p = (char*)(&p);", cxxStaticCastExpr())); 1273 EXPECT_TRUE( 1274 notMatches("char q, *p = const_cast<char*>(&q);", cxxStaticCastExpr())); 1275 EXPECT_TRUE(notMatches("void* p = reinterpret_cast<char*>(&p);", 1276 cxxStaticCastExpr())); 1277 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};" 1278 "B b;" 1279 "D* p = dynamic_cast<D*>(&b);", 1280 cxxStaticCastExpr())); 1281 } 1282 1283 TEST_P(ASTMatchersTest, CStyleCastExpr_MatchesSimpleCase) { 1284 EXPECT_TRUE(matches("int i = (int) 2.2f;", cStyleCastExpr())); 1285 } 1286 1287 TEST_P(ASTMatchersTest, CStyleCastExpr_DoesNotMatchOtherCasts) { 1288 if (!GetParam().isCXX()) { 1289 return; 1290 } 1291 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);" 1292 "char q, *r = const_cast<char*>(&q);" 1293 "void* s = reinterpret_cast<char*>(&s);" 1294 "struct B { virtual ~B() {} }; struct D : B {};" 1295 "B b;" 1296 "D* t = dynamic_cast<D*>(&b);", 1297 cStyleCastExpr())); 1298 } 1299 1300 TEST_P(ASTMatchersTest, ImplicitCastExpr_MatchesSimpleCase) { 1301 // This test creates an implicit const cast. 1302 EXPECT_TRUE( 1303 matches("void f() { int x = 0; const int y = x; }", 1304 traverse(TK_AsIs, varDecl(hasInitializer(implicitCastExpr()))))); 1305 // This test creates an implicit cast from int to char. 1306 EXPECT_TRUE( 1307 matches("char c = 0;", 1308 traverse(TK_AsIs, varDecl(hasInitializer(implicitCastExpr()))))); 1309 // This test creates an implicit array-to-pointer cast. 1310 EXPECT_TRUE( 1311 matches("int arr[6]; int *p = arr;", 1312 traverse(TK_AsIs, varDecl(hasInitializer(implicitCastExpr()))))); 1313 } 1314 1315 TEST_P(ASTMatchersTest, ImplicitCastExpr_DoesNotMatchIncorrectly) { 1316 // This test verifies that implicitCastExpr() matches exactly when implicit 1317 // casts are present, and that it ignores explicit and paren casts. 1318 1319 // These two test cases have no casts. 1320 EXPECT_TRUE( 1321 notMatches("int x = 0;", varDecl(hasInitializer(implicitCastExpr())))); 1322 EXPECT_TRUE( 1323 notMatches("int x = (0);", varDecl(hasInitializer(implicitCastExpr())))); 1324 EXPECT_TRUE(notMatches("void f() { int x = 0; double d = (double) x; }", 1325 varDecl(hasInitializer(implicitCastExpr())))); 1326 } 1327 1328 TEST_P(ASTMatchersTest, ImplicitCastExpr_DoesNotMatchIncorrectly_CXX) { 1329 if (!GetParam().isCXX()) { 1330 return; 1331 } 1332 EXPECT_TRUE(notMatches("int x = 0, &y = x;", 1333 varDecl(hasInitializer(implicitCastExpr())))); 1334 EXPECT_TRUE(notMatches("const int *p; int *q = const_cast<int *>(p);", 1335 varDecl(hasInitializer(implicitCastExpr())))); 1336 } 1337 1338 TEST_P(ASTMatchersTest, Stmt_DoesNotMatchDeclarations) { 1339 EXPECT_TRUE(notMatches("struct X {};", stmt())); 1340 } 1341 1342 TEST_P(ASTMatchersTest, Stmt_MatchesCompoundStatments) { 1343 EXPECT_TRUE(matches("void x() {}", stmt())); 1344 } 1345 1346 TEST_P(ASTMatchersTest, DeclStmt_DoesNotMatchCompoundStatements) { 1347 EXPECT_TRUE(notMatches("void x() {}", declStmt())); 1348 } 1349 1350 TEST_P(ASTMatchersTest, DeclStmt_MatchesVariableDeclarationStatements) { 1351 EXPECT_TRUE(matches("void x() { int a; }", declStmt())); 1352 } 1353 1354 TEST_P(ASTMatchersTest, ExprWithCleanups_MatchesExprWithCleanups) { 1355 if (!GetParam().isCXX()) { 1356 return; 1357 } 1358 EXPECT_TRUE( 1359 matches("struct Foo { ~Foo(); };" 1360 "const Foo f = Foo();", 1361 traverse(TK_AsIs, varDecl(hasInitializer(exprWithCleanups()))))); 1362 EXPECT_FALSE( 1363 matches("struct Foo { }; Foo a;" 1364 "const Foo f = a;", 1365 traverse(TK_AsIs, varDecl(hasInitializer(exprWithCleanups()))))); 1366 } 1367 1368 TEST_P(ASTMatchersTest, InitListExpr) { 1369 EXPECT_TRUE(matches("int a[] = { 1, 2 };", 1370 initListExpr(hasType(asString("int [2]"))))); 1371 EXPECT_TRUE(matches("struct B { int x, y; }; struct B b = { 5, 6 };", 1372 initListExpr(hasType(recordDecl(hasName("B")))))); 1373 EXPECT_TRUE( 1374 matches("int i[1] = {42, [0] = 43};", integerLiteral(equals(42)))); 1375 } 1376 1377 TEST_P(ASTMatchersTest, InitListExpr_CXX) { 1378 if (!GetParam().isCXX()) { 1379 return; 1380 } 1381 EXPECT_TRUE(matches("struct S { S(void (*a)()); };" 1382 "void f();" 1383 "S s[1] = { &f };", 1384 declRefExpr(to(functionDecl(hasName("f")))))); 1385 } 1386 1387 TEST_P(ASTMatchersTest, 1388 CXXStdInitializerListExpression_MatchesCXXStdInitializerListExpression) { 1389 if (!GetParam().isCXX11OrLater()) { 1390 return; 1391 } 1392 StringRef code = "namespace std {" 1393 "template <typename> class initializer_list {" 1394 " public: initializer_list() noexcept {}" 1395 "};" 1396 "}" 1397 "struct A {" 1398 " A(std::initializer_list<int>) {}" 1399 "};"; 1400 EXPECT_TRUE(matches( 1401 code + "A a{0};", 1402 traverse(TK_AsIs, cxxConstructExpr(has(cxxStdInitializerListExpr()), 1403 hasDeclaration(cxxConstructorDecl( 1404 ofClass(hasName("A")))))))); 1405 EXPECT_TRUE(matches( 1406 code + "A a = {0};", 1407 traverse(TK_AsIs, cxxConstructExpr(has(cxxStdInitializerListExpr()), 1408 hasDeclaration(cxxConstructorDecl( 1409 ofClass(hasName("A")))))))); 1410 1411 EXPECT_TRUE(notMatches("int a[] = { 1, 2 };", cxxStdInitializerListExpr())); 1412 EXPECT_TRUE(notMatches("struct B { int x, y; }; B b = { 5, 6 };", 1413 cxxStdInitializerListExpr())); 1414 } 1415 1416 TEST_P(ASTMatchersTest, UsingDecl_MatchesUsingDeclarations) { 1417 if (!GetParam().isCXX()) { 1418 return; 1419 } 1420 EXPECT_TRUE(matches("namespace X { int x; } using X::x;", usingDecl())); 1421 } 1422 1423 TEST_P(ASTMatchersTest, UsingDecl_MatchesShadowUsingDelcarations) { 1424 if (!GetParam().isCXX()) { 1425 return; 1426 } 1427 EXPECT_TRUE(matches("namespace f { int a; } using f::a;", 1428 usingDecl(hasAnyUsingShadowDecl(hasName("a"))))); 1429 } 1430 1431 TEST_P(ASTMatchersTest, UsingDirectiveDecl_MatchesUsingNamespace) { 1432 if (!GetParam().isCXX()) { 1433 return; 1434 } 1435 EXPECT_TRUE(matches("namespace X { int x; } using namespace X;", 1436 usingDirectiveDecl())); 1437 EXPECT_FALSE( 1438 matches("namespace X { int x; } using X::x;", usingDirectiveDecl())); 1439 } 1440 1441 TEST_P(ASTMatchersTest, WhileStmt) { 1442 EXPECT_TRUE(notMatches("void x() {}", whileStmt())); 1443 EXPECT_TRUE(matches("void x() { while(1); }", whileStmt())); 1444 EXPECT_TRUE(notMatches("void x() { do {} while(1); }", whileStmt())); 1445 } 1446 1447 TEST_P(ASTMatchersTest, DoStmt_MatchesDoLoops) { 1448 EXPECT_TRUE(matches("void x() { do {} while(1); }", doStmt())); 1449 EXPECT_TRUE(matches("void x() { do ; while(0); }", doStmt())); 1450 } 1451 1452 TEST_P(ASTMatchersTest, DoStmt_DoesNotMatchWhileLoops) { 1453 EXPECT_TRUE(notMatches("void x() { while(1) {} }", doStmt())); 1454 } 1455 1456 TEST_P(ASTMatchersTest, SwitchCase_MatchesCase) { 1457 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchCase())); 1458 EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchCase())); 1459 EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchCase())); 1460 EXPECT_TRUE(notMatches("void x() { switch(42) {} }", switchCase())); 1461 } 1462 1463 TEST_P(ASTMatchersTest, SwitchCase_MatchesSwitch) { 1464 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchStmt())); 1465 EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchStmt())); 1466 EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchStmt())); 1467 EXPECT_TRUE(notMatches("void x() {}", switchStmt())); 1468 } 1469 1470 TEST_P(ASTMatchersTest, CxxExceptionHandling_SimpleCases) { 1471 if (!GetParam().isCXX()) { 1472 return; 1473 } 1474 EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", cxxCatchStmt())); 1475 EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", cxxTryStmt())); 1476 EXPECT_TRUE( 1477 notMatches("void foo() try { } catch(int X) { }", cxxThrowExpr())); 1478 EXPECT_TRUE( 1479 matches("void foo() try { throw; } catch(int X) { }", cxxThrowExpr())); 1480 EXPECT_TRUE( 1481 matches("void foo() try { throw 5;} catch(int X) { }", cxxThrowExpr())); 1482 EXPECT_TRUE(matches("void foo() try { throw; } catch(...) { }", 1483 cxxCatchStmt(isCatchAll()))); 1484 EXPECT_TRUE(notMatches("void foo() try { throw; } catch(int) { }", 1485 cxxCatchStmt(isCatchAll()))); 1486 EXPECT_TRUE(matches("void foo() try {} catch(int X) { }", 1487 varDecl(isExceptionVariable()))); 1488 EXPECT_TRUE(notMatches("void foo() try { int X; } catch (...) { }", 1489 varDecl(isExceptionVariable()))); 1490 } 1491 1492 TEST_P(ASTMatchersTest, ParenExpr_SimpleCases) { 1493 EXPECT_TRUE(matches("int i = (3);", traverse(TK_AsIs, parenExpr()))); 1494 EXPECT_TRUE(matches("int i = (3 + 7);", traverse(TK_AsIs, parenExpr()))); 1495 EXPECT_TRUE(notMatches("int i = 3;", traverse(TK_AsIs, parenExpr()))); 1496 EXPECT_TRUE(notMatches("int f() { return 1; }; void g() { int a = f(); }", 1497 traverse(TK_AsIs, parenExpr()))); 1498 } 1499 1500 TEST_P(ASTMatchersTest, IgnoringParens) { 1501 EXPECT_FALSE(matches("const char* str = (\"my-string\");", 1502 traverse(TK_AsIs, implicitCastExpr(hasSourceExpression( 1503 stringLiteral()))))); 1504 EXPECT_TRUE( 1505 matches("const char* str = (\"my-string\");", 1506 traverse(TK_AsIs, implicitCastExpr(hasSourceExpression( 1507 ignoringParens(stringLiteral())))))); 1508 } 1509 1510 TEST_P(ASTMatchersTest, QualType) { 1511 EXPECT_TRUE(matches("struct S {};", qualType().bind("loc"))); 1512 } 1513 1514 TEST_P(ASTMatchersTest, ConstantArrayType) { 1515 EXPECT_TRUE(matches("int a[2];", constantArrayType())); 1516 EXPECT_TRUE(notMatches("void f() { int a[] = { 2, 3 }; int b[a[0]]; }", 1517 constantArrayType(hasElementType(builtinType())))); 1518 1519 EXPECT_TRUE(matches("int a[42];", constantArrayType(hasSize(42)))); 1520 EXPECT_TRUE(matches("int b[2*21];", constantArrayType(hasSize(42)))); 1521 EXPECT_TRUE(notMatches("int c[41], d[43];", constantArrayType(hasSize(42)))); 1522 } 1523 1524 TEST_P(ASTMatchersTest, DependentSizedArrayType) { 1525 if (!GetParam().isCXX()) { 1526 return; 1527 } 1528 EXPECT_TRUE( 1529 matches("template <typename T, int Size> class array { T data[Size]; };", 1530 dependentSizedArrayType())); 1531 EXPECT_TRUE( 1532 notMatches("int a[42]; int b[] = { 2, 3 }; void f() { int c[b[0]]; }", 1533 dependentSizedArrayType())); 1534 } 1535 1536 TEST_P(ASTMatchersTest, IncompleteArrayType) { 1537 EXPECT_TRUE(matches("int a[] = { 2, 3 };", incompleteArrayType())); 1538 EXPECT_TRUE(matches("void f(int a[]) {}", incompleteArrayType())); 1539 1540 EXPECT_TRUE(notMatches("int a[42]; void f() { int b[a[0]]; }", 1541 incompleteArrayType())); 1542 } 1543 1544 TEST_P(ASTMatchersTest, VariableArrayType) { 1545 EXPECT_TRUE(matches("void f(int b) { int a[b]; }", variableArrayType())); 1546 EXPECT_TRUE(notMatches("int a[] = {2, 3}; int b[42];", variableArrayType())); 1547 1548 EXPECT_TRUE(matches("void f(int b) { int a[b]; }", 1549 variableArrayType(hasSizeExpr(ignoringImpCasts( 1550 declRefExpr(to(varDecl(hasName("b"))))))))); 1551 } 1552 1553 TEST_P(ASTMatchersTest, AtomicType) { 1554 if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getOS() != 1555 llvm::Triple::Win32) { 1556 // FIXME: Make this work for MSVC. 1557 EXPECT_TRUE(matches("_Atomic(int) i;", atomicType())); 1558 1559 EXPECT_TRUE( 1560 matches("_Atomic(int) i;", atomicType(hasValueType(isInteger())))); 1561 EXPECT_TRUE( 1562 notMatches("_Atomic(float) f;", atomicType(hasValueType(isInteger())))); 1563 } 1564 } 1565 1566 TEST_P(ASTMatchersTest, AutoType) { 1567 if (!GetParam().isCXX11OrLater()) { 1568 return; 1569 } 1570 EXPECT_TRUE(matches("auto i = 2;", autoType())); 1571 EXPECT_TRUE(matches("int v[] = { 2, 3 }; void f() { for (int i : v) {} }", 1572 autoType())); 1573 1574 EXPECT_TRUE(matches("auto i = 2;", varDecl(hasType(isInteger())))); 1575 EXPECT_TRUE(matches("struct X{}; auto x = X{};", 1576 varDecl(hasType(recordDecl(hasName("X")))))); 1577 1578 // FIXME: Matching against the type-as-written can't work here, because the 1579 // type as written was not deduced. 1580 // EXPECT_TRUE(matches("auto a = 1;", 1581 // autoType(hasDeducedType(isInteger())))); 1582 // EXPECT_TRUE(notMatches("auto b = 2.0;", 1583 // autoType(hasDeducedType(isInteger())))); 1584 } 1585 1586 TEST_P(ASTMatchersTest, DecltypeType) { 1587 if (!GetParam().isCXX11OrLater()) { 1588 return; 1589 } 1590 EXPECT_TRUE(matches("decltype(1 + 1) sum = 1 + 1;", decltypeType())); 1591 EXPECT_TRUE(matches("decltype(1 + 1) sum = 1 + 1;", 1592 decltypeType(hasUnderlyingType(isInteger())))); 1593 } 1594 1595 TEST_P(ASTMatchersTest, FunctionType) { 1596 EXPECT_TRUE(matches("int (*f)(int);", functionType())); 1597 EXPECT_TRUE(matches("void f(int i) {}", functionType())); 1598 } 1599 1600 TEST_P(ASTMatchersTest, IgnoringParens_Type) { 1601 EXPECT_TRUE( 1602 notMatches("void (*fp)(void);", pointerType(pointee(functionType())))); 1603 EXPECT_TRUE(matches("void (*fp)(void);", 1604 pointerType(pointee(ignoringParens(functionType()))))); 1605 } 1606 1607 TEST_P(ASTMatchersTest, FunctionProtoType) { 1608 EXPECT_TRUE(matches("int (*f)(int);", functionProtoType())); 1609 EXPECT_TRUE(matches("void f(int i);", functionProtoType())); 1610 EXPECT_TRUE(matches("void f(void);", functionProtoType(parameterCountIs(0)))); 1611 } 1612 1613 TEST_P(ASTMatchersTest, FunctionProtoType_C) { 1614 if (!GetParam().isC()) { 1615 return; 1616 } 1617 EXPECT_TRUE(notMatches("void f();", functionProtoType())); 1618 } 1619 1620 TEST_P(ASTMatchersTest, FunctionProtoType_CXX) { 1621 if (!GetParam().isCXX()) { 1622 return; 1623 } 1624 EXPECT_TRUE(matches("void f();", functionProtoType(parameterCountIs(0)))); 1625 } 1626 1627 TEST_P(ASTMatchersTest, ParenType) { 1628 EXPECT_TRUE( 1629 matches("int (*array)[4];", varDecl(hasType(pointsTo(parenType()))))); 1630 EXPECT_TRUE(notMatches("int *array[4];", varDecl(hasType(parenType())))); 1631 1632 EXPECT_TRUE(matches( 1633 "int (*ptr_to_func)(int);", 1634 varDecl(hasType(pointsTo(parenType(innerType(functionType()))))))); 1635 EXPECT_TRUE(notMatches( 1636 "int (*ptr_to_array)[4];", 1637 varDecl(hasType(pointsTo(parenType(innerType(functionType()))))))); 1638 } 1639 1640 TEST_P(ASTMatchersTest, PointerType) { 1641 // FIXME: Reactive when these tests can be more specific (not matching 1642 // implicit code on certain platforms), likely when we have hasDescendant for 1643 // Types/TypeLocs. 1644 // EXPECT_TRUE(matchAndVerifyResultTrue( 1645 // "int* a;", 1646 // pointerTypeLoc(pointeeLoc(typeLoc().bind("loc"))), 1647 // std::make_unique<VerifyIdIsBoundTo<TypeLoc>>("loc", 1))); 1648 // EXPECT_TRUE(matchAndVerifyResultTrue( 1649 // "int* a;", 1650 // pointerTypeLoc().bind("loc"), 1651 // std::make_unique<VerifyIdIsBoundTo<TypeLoc>>("loc", 1))); 1652 EXPECT_TRUE(matches("int** a;", loc(pointerType(pointee(qualType()))))); 1653 EXPECT_TRUE(matches("int** a;", loc(pointerType(pointee(pointerType()))))); 1654 EXPECT_TRUE(matches("int* b; int* * const a = &b;", 1655 loc(qualType(isConstQualified(), pointerType())))); 1656 1657 StringRef Fragment = "int *ptr;"; 1658 EXPECT_TRUE(notMatches(Fragment, 1659 varDecl(hasName("ptr"), hasType(blockPointerType())))); 1660 EXPECT_TRUE(notMatches( 1661 Fragment, varDecl(hasName("ptr"), hasType(memberPointerType())))); 1662 EXPECT_TRUE( 1663 matches(Fragment, varDecl(hasName("ptr"), hasType(pointerType())))); 1664 EXPECT_TRUE( 1665 notMatches(Fragment, varDecl(hasName("ptr"), hasType(referenceType())))); 1666 } 1667 1668 TEST_P(ASTMatchersTest, PointerType_CXX) { 1669 if (!GetParam().isCXX()) { 1670 return; 1671 } 1672 StringRef Fragment = "struct A { int i; }; int A::* ptr = &A::i;"; 1673 EXPECT_TRUE(notMatches(Fragment, 1674 varDecl(hasName("ptr"), hasType(blockPointerType())))); 1675 EXPECT_TRUE( 1676 matches(Fragment, varDecl(hasName("ptr"), hasType(memberPointerType())))); 1677 EXPECT_TRUE( 1678 notMatches(Fragment, varDecl(hasName("ptr"), hasType(pointerType())))); 1679 EXPECT_TRUE( 1680 notMatches(Fragment, varDecl(hasName("ptr"), hasType(referenceType())))); 1681 EXPECT_TRUE(notMatches( 1682 Fragment, varDecl(hasName("ptr"), hasType(lValueReferenceType())))); 1683 EXPECT_TRUE(notMatches( 1684 Fragment, varDecl(hasName("ptr"), hasType(rValueReferenceType())))); 1685 1686 Fragment = "int a; int &ref = a;"; 1687 EXPECT_TRUE(notMatches(Fragment, 1688 varDecl(hasName("ref"), hasType(blockPointerType())))); 1689 EXPECT_TRUE(notMatches( 1690 Fragment, varDecl(hasName("ref"), hasType(memberPointerType())))); 1691 EXPECT_TRUE( 1692 notMatches(Fragment, varDecl(hasName("ref"), hasType(pointerType())))); 1693 EXPECT_TRUE( 1694 matches(Fragment, varDecl(hasName("ref"), hasType(referenceType())))); 1695 EXPECT_TRUE(matches(Fragment, 1696 varDecl(hasName("ref"), hasType(lValueReferenceType())))); 1697 EXPECT_TRUE(notMatches( 1698 Fragment, varDecl(hasName("ref"), hasType(rValueReferenceType())))); 1699 } 1700 1701 TEST_P(ASTMatchersTest, PointerType_CXX11) { 1702 if (!GetParam().isCXX11OrLater()) { 1703 return; 1704 } 1705 StringRef Fragment = "int &&ref = 2;"; 1706 EXPECT_TRUE(notMatches(Fragment, 1707 varDecl(hasName("ref"), hasType(blockPointerType())))); 1708 EXPECT_TRUE(notMatches( 1709 Fragment, varDecl(hasName("ref"), hasType(memberPointerType())))); 1710 EXPECT_TRUE( 1711 notMatches(Fragment, varDecl(hasName("ref"), hasType(pointerType())))); 1712 EXPECT_TRUE( 1713 matches(Fragment, varDecl(hasName("ref"), hasType(referenceType())))); 1714 EXPECT_TRUE(notMatches( 1715 Fragment, varDecl(hasName("ref"), hasType(lValueReferenceType())))); 1716 EXPECT_TRUE(matches(Fragment, 1717 varDecl(hasName("ref"), hasType(rValueReferenceType())))); 1718 } 1719 1720 TEST_P(ASTMatchersTest, AutoRefTypes) { 1721 if (!GetParam().isCXX11OrLater()) { 1722 return; 1723 } 1724 1725 StringRef Fragment = "auto a = 1;" 1726 "auto b = a;" 1727 "auto &c = a;" 1728 "auto &&d = c;" 1729 "auto &&e = 2;"; 1730 EXPECT_TRUE( 1731 notMatches(Fragment, varDecl(hasName("a"), hasType(referenceType())))); 1732 EXPECT_TRUE( 1733 notMatches(Fragment, varDecl(hasName("b"), hasType(referenceType())))); 1734 EXPECT_TRUE( 1735 matches(Fragment, varDecl(hasName("c"), hasType(referenceType())))); 1736 EXPECT_TRUE( 1737 matches(Fragment, varDecl(hasName("c"), hasType(lValueReferenceType())))); 1738 EXPECT_TRUE(notMatches( 1739 Fragment, varDecl(hasName("c"), hasType(rValueReferenceType())))); 1740 EXPECT_TRUE( 1741 matches(Fragment, varDecl(hasName("d"), hasType(referenceType())))); 1742 EXPECT_TRUE( 1743 matches(Fragment, varDecl(hasName("d"), hasType(lValueReferenceType())))); 1744 EXPECT_TRUE(notMatches( 1745 Fragment, varDecl(hasName("d"), hasType(rValueReferenceType())))); 1746 EXPECT_TRUE( 1747 matches(Fragment, varDecl(hasName("e"), hasType(referenceType())))); 1748 EXPECT_TRUE(notMatches( 1749 Fragment, varDecl(hasName("e"), hasType(lValueReferenceType())))); 1750 EXPECT_TRUE( 1751 matches(Fragment, varDecl(hasName("e"), hasType(rValueReferenceType())))); 1752 } 1753 1754 TEST_P(ASTMatchersTest, EnumType) { 1755 EXPECT_TRUE( 1756 matches("enum Color { Green }; enum Color color;", loc(enumType()))); 1757 } 1758 1759 TEST_P(ASTMatchersTest, EnumType_CXX) { 1760 if (!GetParam().isCXX()) { 1761 return; 1762 } 1763 EXPECT_TRUE(matches("enum Color { Green }; Color color;", loc(enumType()))); 1764 } 1765 1766 TEST_P(ASTMatchersTest, EnumType_CXX11) { 1767 if (!GetParam().isCXX11OrLater()) { 1768 return; 1769 } 1770 EXPECT_TRUE( 1771 matches("enum class Color { Green }; Color color;", loc(enumType()))); 1772 } 1773 1774 TEST_P(ASTMatchersTest, PointerType_MatchesPointersToConstTypes) { 1775 EXPECT_TRUE(matches("int b; int * const a = &b;", loc(pointerType()))); 1776 EXPECT_TRUE(matches("int b; int * const a = &b;", loc(pointerType()))); 1777 EXPECT_TRUE(matches("int b; const int * a = &b;", 1778 loc(pointerType(pointee(builtinType()))))); 1779 EXPECT_TRUE(matches("int b; const int * a = &b;", 1780 pointerType(pointee(builtinType())))); 1781 } 1782 1783 TEST_P(ASTMatchersTest, TypedefType) { 1784 EXPECT_TRUE(matches("typedef int X; X a;", 1785 varDecl(hasName("a"), hasType(typedefType())))); 1786 } 1787 1788 TEST_P(ASTMatchersTest, TemplateSpecializationType) { 1789 if (!GetParam().isCXX()) { 1790 return; 1791 } 1792 EXPECT_TRUE(matches("template <typename T> class A{}; A<int> a;", 1793 templateSpecializationType())); 1794 } 1795 1796 TEST_P(ASTMatchersTest, DeducedTemplateSpecializationType) { 1797 if (!GetParam().isCXX17OrLater()) { 1798 return; 1799 } 1800 EXPECT_TRUE( 1801 matches("template <typename T> class A{ public: A(T) {} }; A a(1);", 1802 deducedTemplateSpecializationType())); 1803 } 1804 1805 TEST_P(ASTMatchersTest, RecordType) { 1806 EXPECT_TRUE(matches("struct S {}; struct S s;", 1807 recordType(hasDeclaration(recordDecl(hasName("S")))))); 1808 EXPECT_TRUE(notMatches("int i;", 1809 recordType(hasDeclaration(recordDecl(hasName("S")))))); 1810 } 1811 1812 TEST_P(ASTMatchersTest, RecordType_CXX) { 1813 if (!GetParam().isCXX()) { 1814 return; 1815 } 1816 EXPECT_TRUE(matches("class C {}; C c;", recordType())); 1817 EXPECT_TRUE(matches("struct S {}; S s;", 1818 recordType(hasDeclaration(recordDecl(hasName("S")))))); 1819 } 1820 1821 TEST_P(ASTMatchersTest, ElaboratedType) { 1822 if (!GetParam().isCXX()) { 1823 // FIXME: Add a test for `elaboratedType()` that does not depend on C++. 1824 return; 1825 } 1826 EXPECT_TRUE(matches("namespace N {" 1827 " namespace M {" 1828 " class D {};" 1829 " }" 1830 "}" 1831 "N::M::D d;", 1832 elaboratedType())); 1833 EXPECT_TRUE(matches("class C {} c;", elaboratedType())); 1834 EXPECT_TRUE(notMatches("class C {}; C c;", elaboratedType())); 1835 } 1836 1837 TEST_P(ASTMatchersTest, SubstTemplateTypeParmType) { 1838 if (!GetParam().isCXX()) { 1839 return; 1840 } 1841 StringRef code = "template <typename T>" 1842 "int F() {" 1843 " return 1 + T();" 1844 "}" 1845 "int i = F<int>();"; 1846 EXPECT_FALSE(matches(code, binaryOperator(hasLHS( 1847 expr(hasType(substTemplateTypeParmType())))))); 1848 EXPECT_TRUE(matches(code, binaryOperator(hasRHS( 1849 expr(hasType(substTemplateTypeParmType())))))); 1850 } 1851 1852 TEST_P(ASTMatchersTest, NestedNameSpecifier) { 1853 if (!GetParam().isCXX()) { 1854 return; 1855 } 1856 EXPECT_TRUE( 1857 matches("namespace ns { struct A {}; } ns::A a;", nestedNameSpecifier())); 1858 EXPECT_TRUE(matches("template <typename T> class A { typename T::B b; };", 1859 nestedNameSpecifier())); 1860 EXPECT_TRUE( 1861 matches("struct A { void f(); }; void A::f() {}", nestedNameSpecifier())); 1862 EXPECT_TRUE(matches("namespace a { namespace b {} } namespace ab = a::b;", 1863 nestedNameSpecifier())); 1864 1865 EXPECT_TRUE(matches("struct A { static void f() {} }; void g() { A::f(); }", 1866 nestedNameSpecifier())); 1867 EXPECT_TRUE( 1868 notMatches("struct A { static void f() {} }; void g(A* a) { a->f(); }", 1869 nestedNameSpecifier())); 1870 } 1871 1872 TEST_P(ASTMatchersTest, NullStmt) { 1873 EXPECT_TRUE(matches("void f() {int i;;}", nullStmt())); 1874 EXPECT_TRUE(notMatches("void f() {int i;}", nullStmt())); 1875 } 1876 1877 TEST_P(ASTMatchersTest, NamespaceAliasDecl) { 1878 if (!GetParam().isCXX()) { 1879 return; 1880 } 1881 EXPECT_TRUE(matches("namespace test {} namespace alias = ::test;", 1882 namespaceAliasDecl(hasName("alias")))); 1883 } 1884 1885 TEST_P(ASTMatchersTest, NestedNameSpecifier_MatchesTypes) { 1886 if (!GetParam().isCXX()) { 1887 return; 1888 } 1889 NestedNameSpecifierMatcher Matcher = nestedNameSpecifier( 1890 specifiesType(hasDeclaration(recordDecl(hasName("A"))))); 1891 EXPECT_TRUE(matches("struct A { struct B {}; }; A::B b;", Matcher)); 1892 EXPECT_TRUE( 1893 matches("struct A { struct B { struct C {}; }; }; A::B::C c;", Matcher)); 1894 EXPECT_TRUE(notMatches("namespace A { struct B {}; } A::B b;", Matcher)); 1895 } 1896 1897 TEST_P(ASTMatchersTest, NestedNameSpecifier_MatchesNamespaceDecls) { 1898 if (!GetParam().isCXX()) { 1899 return; 1900 } 1901 NestedNameSpecifierMatcher Matcher = 1902 nestedNameSpecifier(specifiesNamespace(hasName("ns"))); 1903 EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;", Matcher)); 1904 EXPECT_TRUE(notMatches("namespace xx { struct A {}; } xx::A a;", Matcher)); 1905 EXPECT_TRUE(notMatches("struct ns { struct A {}; }; ns::A a;", Matcher)); 1906 } 1907 1908 TEST_P(ASTMatchersTest, 1909 NestedNameSpecifier_MatchesNestedNameSpecifierPrefixes) { 1910 if (!GetParam().isCXX()) { 1911 return; 1912 } 1913 EXPECT_TRUE(matches( 1914 "struct A { struct B { struct C {}; }; }; A::B::C c;", 1915 nestedNameSpecifier(hasPrefix(specifiesType(asString("struct A")))))); 1916 EXPECT_TRUE(matches("struct A { struct B { struct C {}; }; }; A::B::C c;", 1917 nestedNameSpecifierLoc(hasPrefix(specifiesTypeLoc( 1918 loc(qualType(asString("struct A")))))))); 1919 EXPECT_TRUE(matches( 1920 "namespace N { struct A { struct B { struct C {}; }; }; } N::A::B::C c;", 1921 nestedNameSpecifierLoc(hasPrefix( 1922 specifiesTypeLoc(loc(qualType(asString("struct N::A")))))))); 1923 } 1924 1925 template <typename T> 1926 class VerifyAncestorHasChildIsEqual : public BoundNodesCallback { 1927 public: 1928 bool run(const BoundNodes *Nodes) override { return false; } 1929 1930 bool run(const BoundNodes *Nodes, ASTContext *Context) override { 1931 const T *Node = Nodes->getNodeAs<T>(""); 1932 return verify(*Nodes, *Context, Node); 1933 } 1934 1935 bool verify(const BoundNodes &Nodes, ASTContext &Context, const Stmt *Node) { 1936 // Use the original typed pointer to verify we can pass pointers to subtypes 1937 // to equalsNode. 1938 const T *TypedNode = cast<T>(Node); 1939 return selectFirst<T>( 1940 "", match(stmt(hasParent( 1941 stmt(has(stmt(equalsNode(TypedNode)))).bind(""))), 1942 *Node, Context)) != nullptr; 1943 } 1944 bool verify(const BoundNodes &Nodes, ASTContext &Context, const Decl *Node) { 1945 // Use the original typed pointer to verify we can pass pointers to subtypes 1946 // to equalsNode. 1947 const T *TypedNode = cast<T>(Node); 1948 return selectFirst<T>( 1949 "", match(decl(hasParent( 1950 decl(has(decl(equalsNode(TypedNode)))).bind(""))), 1951 *Node, Context)) != nullptr; 1952 } 1953 bool verify(const BoundNodes &Nodes, ASTContext &Context, const Type *Node) { 1954 // Use the original typed pointer to verify we can pass pointers to subtypes 1955 // to equalsNode. 1956 const T *TypedNode = cast<T>(Node); 1957 const auto *Dec = Nodes.getNodeAs<FieldDecl>("decl"); 1958 return selectFirst<T>( 1959 "", match(fieldDecl(hasParent(decl(has(fieldDecl( 1960 hasType(type(equalsNode(TypedNode)).bind(""))))))), 1961 *Dec, Context)) != nullptr; 1962 } 1963 }; 1964 1965 TEST_P(ASTMatchersTest, IsEqualTo_MatchesNodesByIdentity) { 1966 EXPECT_TRUE(matchAndVerifyResultTrue( 1967 "void f() { if (1) if(1) {} }", ifStmt().bind(""), 1968 std::make_unique<VerifyAncestorHasChildIsEqual<IfStmt>>())); 1969 } 1970 1971 TEST_P(ASTMatchersTest, IsEqualTo_MatchesNodesByIdentity_Cxx) { 1972 if (!GetParam().isCXX()) { 1973 return; 1974 } 1975 EXPECT_TRUE(matchAndVerifyResultTrue( 1976 "class X { class Y {}; };", recordDecl(hasName("::X::Y")).bind(""), 1977 std::make_unique<VerifyAncestorHasChildIsEqual<CXXRecordDecl>>())); 1978 EXPECT_TRUE(matchAndVerifyResultTrue( 1979 "class X { class Y {} y; };", 1980 fieldDecl(hasName("y"), hasType(type().bind(""))).bind("decl"), 1981 std::make_unique<VerifyAncestorHasChildIsEqual<Type>>())); 1982 } 1983 1984 TEST_P(ASTMatchersTest, TypedefDecl) { 1985 EXPECT_TRUE(matches("typedef int typedefDeclTest;", 1986 typedefDecl(hasName("typedefDeclTest")))); 1987 } 1988 1989 TEST_P(ASTMatchersTest, TypedefDecl_Cxx) { 1990 if (!GetParam().isCXX11OrLater()) { 1991 return; 1992 } 1993 EXPECT_TRUE(notMatches("using typedefDeclTest = int;", 1994 typedefDecl(hasName("typedefDeclTest")))); 1995 } 1996 1997 TEST_P(ASTMatchersTest, TypeAliasDecl) { 1998 EXPECT_TRUE(notMatches("typedef int typeAliasTest;", 1999 typeAliasDecl(hasName("typeAliasTest")))); 2000 } 2001 2002 TEST_P(ASTMatchersTest, TypeAliasDecl_CXX) { 2003 if (!GetParam().isCXX11OrLater()) { 2004 return; 2005 } 2006 EXPECT_TRUE(matches("using typeAliasTest = int;", 2007 typeAliasDecl(hasName("typeAliasTest")))); 2008 } 2009 2010 TEST_P(ASTMatchersTest, TypedefNameDecl) { 2011 EXPECT_TRUE(matches("typedef int typedefNameDeclTest1;", 2012 typedefNameDecl(hasName("typedefNameDeclTest1")))); 2013 } 2014 2015 TEST_P(ASTMatchersTest, TypedefNameDecl_CXX) { 2016 if (!GetParam().isCXX11OrLater()) { 2017 return; 2018 } 2019 EXPECT_TRUE(matches("using typedefNameDeclTest = int;", 2020 typedefNameDecl(hasName("typedefNameDeclTest")))); 2021 } 2022 2023 TEST_P(ASTMatchersTest, TypeAliasTemplateDecl) { 2024 if (!GetParam().isCXX11OrLater()) { 2025 return; 2026 } 2027 StringRef Code = R"( 2028 template <typename T> 2029 class X { T t; }; 2030 2031 template <typename T> 2032 using typeAliasTemplateDecl = X<T>; 2033 2034 using typeAliasDecl = X<int>; 2035 )"; 2036 EXPECT_TRUE( 2037 matches(Code, typeAliasTemplateDecl(hasName("typeAliasTemplateDecl")))); 2038 EXPECT_TRUE( 2039 notMatches(Code, typeAliasTemplateDecl(hasName("typeAliasDecl")))); 2040 } 2041 2042 TEST(ASTMatchersTestObjC, ObjCMessageExpr) { 2043 // Don't find ObjCMessageExpr where none are present. 2044 EXPECT_TRUE(notMatchesObjC("", objcMessageExpr(anything()))); 2045 2046 StringRef Objc1String = "@interface Str " 2047 " - (Str *)uppercaseString;" 2048 "@end " 2049 "@interface foo " 2050 "- (void)contents;" 2051 "- (void)meth:(Str *)text;" 2052 "@end " 2053 " " 2054 "@implementation foo " 2055 "- (void) meth:(Str *)text { " 2056 " [self contents];" 2057 " Str *up = [text uppercaseString];" 2058 "} " 2059 "@end "; 2060 EXPECT_TRUE(matchesObjC(Objc1String, objcMessageExpr(anything()))); 2061 EXPECT_TRUE(matchesObjC(Objc1String, 2062 objcMessageExpr(hasAnySelector({"contents", "meth:"})) 2063 2064 )); 2065 EXPECT_TRUE( 2066 matchesObjC(Objc1String, objcMessageExpr(hasSelector("contents")))); 2067 EXPECT_TRUE(matchesObjC( 2068 Objc1String, objcMessageExpr(hasAnySelector("contents", "contentsA")))); 2069 EXPECT_FALSE(matchesObjC( 2070 Objc1String, objcMessageExpr(hasAnySelector("contentsB", "contentsC")))); 2071 EXPECT_TRUE( 2072 matchesObjC(Objc1String, objcMessageExpr(matchesSelector("cont*")))); 2073 EXPECT_FALSE( 2074 matchesObjC(Objc1String, objcMessageExpr(matchesSelector("?cont*")))); 2075 EXPECT_TRUE( 2076 notMatchesObjC(Objc1String, objcMessageExpr(hasSelector("contents"), 2077 hasNullSelector()))); 2078 EXPECT_TRUE(matchesObjC(Objc1String, objcMessageExpr(hasSelector("contents"), 2079 hasUnarySelector()))); 2080 EXPECT_TRUE(matchesObjC(Objc1String, objcMessageExpr(hasSelector("contents"), 2081 numSelectorArgs(0)))); 2082 EXPECT_TRUE( 2083 matchesObjC(Objc1String, objcMessageExpr(matchesSelector("uppercase*"), 2084 argumentCountIs(0)))); 2085 } 2086 2087 TEST(ASTMatchersTestObjC, ObjCDecls) { 2088 StringRef ObjCString = "@protocol Proto " 2089 "- (void)protoDidThing; " 2090 "@end " 2091 "@interface Thing " 2092 "@property int enabled; " 2093 "@end " 2094 "@interface Thing (ABC) " 2095 "- (void)abc_doThing; " 2096 "@end " 2097 "@implementation Thing " 2098 "{ id _ivar; } " 2099 "- (void)anything {} " 2100 "@end " 2101 "@implementation Thing (ABC) " 2102 "- (void)abc_doThing {} " 2103 "@end "; 2104 2105 EXPECT_TRUE(matchesObjC(ObjCString, objcProtocolDecl(hasName("Proto")))); 2106 EXPECT_TRUE( 2107 matchesObjC(ObjCString, objcImplementationDecl(hasName("Thing")))); 2108 EXPECT_TRUE(matchesObjC(ObjCString, objcCategoryDecl(hasName("ABC")))); 2109 EXPECT_TRUE(matchesObjC(ObjCString, objcCategoryImplDecl(hasName("ABC")))); 2110 EXPECT_TRUE( 2111 matchesObjC(ObjCString, objcMethodDecl(hasName("protoDidThing")))); 2112 EXPECT_TRUE(matchesObjC(ObjCString, objcMethodDecl(hasName("abc_doThing")))); 2113 EXPECT_TRUE(matchesObjC(ObjCString, objcMethodDecl(hasName("anything")))); 2114 EXPECT_TRUE(matchesObjC(ObjCString, objcIvarDecl(hasName("_ivar")))); 2115 EXPECT_TRUE(matchesObjC(ObjCString, objcPropertyDecl(hasName("enabled")))); 2116 } 2117 2118 TEST(ASTMatchersTestObjC, ObjCExceptionStmts) { 2119 StringRef ObjCString = "void f(id obj) {" 2120 " @try {" 2121 " @throw obj;" 2122 " } @catch (...) {" 2123 " } @finally {}" 2124 "}"; 2125 2126 EXPECT_TRUE(matchesObjC(ObjCString, objcTryStmt())); 2127 EXPECT_TRUE(matchesObjC(ObjCString, objcThrowStmt())); 2128 EXPECT_TRUE(matchesObjC(ObjCString, objcCatchStmt())); 2129 EXPECT_TRUE(matchesObjC(ObjCString, objcFinallyStmt())); 2130 } 2131 2132 TEST(ASTMatchersTest, DecompositionDecl) { 2133 StringRef Code = R"cpp( 2134 void foo() 2135 { 2136 int arr[3]; 2137 auto &[f, s, t] = arr; 2138 2139 f = 42; 2140 } 2141 )cpp"; 2142 EXPECT_TRUE(matchesConditionally( 2143 Code, decompositionDecl(hasBinding(0, bindingDecl(hasName("f")))), true, 2144 {"-std=c++17"})); 2145 EXPECT_FALSE(matchesConditionally( 2146 Code, decompositionDecl(hasBinding(42, bindingDecl(hasName("f")))), true, 2147 {"-std=c++17"})); 2148 EXPECT_FALSE(matchesConditionally( 2149 Code, decompositionDecl(hasBinding(0, bindingDecl(hasName("s")))), true, 2150 {"-std=c++17"})); 2151 EXPECT_TRUE(matchesConditionally( 2152 Code, decompositionDecl(hasBinding(1, bindingDecl(hasName("s")))), true, 2153 {"-std=c++17"})); 2154 2155 EXPECT_TRUE(matchesConditionally( 2156 Code, 2157 bindingDecl(decl().bind("self"), hasName("f"), 2158 forDecomposition(decompositionDecl( 2159 hasAnyBinding(bindingDecl(equalsBoundNode("self")))))), 2160 true, {"-std=c++17"})); 2161 } 2162 2163 TEST(ASTMatchersTestObjC, ObjCAutoreleasePoolStmt) { 2164 StringRef ObjCString = "void f() {" 2165 "@autoreleasepool {" 2166 " int x = 1;" 2167 "}" 2168 "}"; 2169 EXPECT_TRUE(matchesObjC(ObjCString, autoreleasePoolStmt())); 2170 StringRef ObjCStringNoPool = "void f() { int x = 1; }"; 2171 EXPECT_FALSE(matchesObjC(ObjCStringNoPool, autoreleasePoolStmt())); 2172 } 2173 2174 TEST(ASTMatchersTestOpenMP, OMPExecutableDirective) { 2175 auto Matcher = stmt(ompExecutableDirective()); 2176 2177 StringRef Source0 = R"( 2178 void x() { 2179 #pragma omp parallel 2180 ; 2181 })"; 2182 EXPECT_TRUE(matchesWithOpenMP(Source0, Matcher)); 2183 2184 StringRef Source1 = R"( 2185 void x() { 2186 #pragma omp taskyield 2187 ; 2188 })"; 2189 EXPECT_TRUE(matchesWithOpenMP(Source1, Matcher)); 2190 2191 StringRef Source2 = R"( 2192 void x() { 2193 ; 2194 })"; 2195 EXPECT_TRUE(notMatchesWithOpenMP(Source2, Matcher)); 2196 } 2197 2198 TEST(ASTMatchersTestOpenMP, OMPDefaultClause) { 2199 auto Matcher = ompExecutableDirective(hasAnyClause(ompDefaultClause())); 2200 2201 StringRef Source0 = R"( 2202 void x() { 2203 ; 2204 })"; 2205 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher)); 2206 2207 StringRef Source1 = R"( 2208 void x() { 2209 #pragma omp parallel 2210 ; 2211 })"; 2212 EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher)); 2213 2214 StringRef Source2 = R"( 2215 void x() { 2216 #pragma omp parallel default(none) 2217 ; 2218 })"; 2219 EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher)); 2220 2221 StringRef Source3 = R"( 2222 void x() { 2223 #pragma omp parallel default(shared) 2224 ; 2225 })"; 2226 EXPECT_TRUE(matchesWithOpenMP(Source3, Matcher)); 2227 2228 StringRef Source4 = R"( 2229 void x() { 2230 #pragma omp parallel default(firstprivate) 2231 ; 2232 })"; 2233 EXPECT_TRUE(matchesWithOpenMP51(Source4, Matcher)); 2234 2235 StringRef Source5 = R"( 2236 void x(int x) { 2237 #pragma omp parallel num_threads(x) 2238 ; 2239 })"; 2240 EXPECT_TRUE(notMatchesWithOpenMP(Source5, Matcher)); 2241 } 2242 2243 TEST(ASTMatchersTest, Finder_DynamicOnlyAcceptsSomeMatchers) { 2244 MatchFinder Finder; 2245 EXPECT_TRUE(Finder.addDynamicMatcher(decl(), nullptr)); 2246 EXPECT_TRUE(Finder.addDynamicMatcher(callExpr(), nullptr)); 2247 EXPECT_TRUE( 2248 Finder.addDynamicMatcher(constantArrayType(hasSize(42)), nullptr)); 2249 2250 // Do not accept non-toplevel matchers. 2251 EXPECT_FALSE(Finder.addDynamicMatcher(isMain(), nullptr)); 2252 EXPECT_FALSE(Finder.addDynamicMatcher(hasName("x"), nullptr)); 2253 } 2254 2255 TEST(MatchFinderAPI, MatchesDynamic) { 2256 StringRef SourceCode = "struct A { void f() {} };"; 2257 auto Matcher = functionDecl(isDefinition()).bind("method"); 2258 2259 auto astUnit = tooling::buildASTFromCode(SourceCode); 2260 2261 auto GlobalBoundNodes = matchDynamic(Matcher, astUnit->getASTContext()); 2262 2263 EXPECT_EQ(GlobalBoundNodes.size(), 1u); 2264 EXPECT_EQ(GlobalBoundNodes[0].getMap().size(), 1u); 2265 2266 auto GlobalMethodNode = GlobalBoundNodes[0].getNodeAs<FunctionDecl>("method"); 2267 EXPECT_TRUE(GlobalMethodNode != nullptr); 2268 2269 auto MethodBoundNodes = 2270 matchDynamic(Matcher, *GlobalMethodNode, astUnit->getASTContext()); 2271 EXPECT_EQ(MethodBoundNodes.size(), 1u); 2272 EXPECT_EQ(MethodBoundNodes[0].getMap().size(), 1u); 2273 2274 auto MethodNode = MethodBoundNodes[0].getNodeAs<FunctionDecl>("method"); 2275 EXPECT_EQ(MethodNode, GlobalMethodNode); 2276 } 2277 2278 static std::vector<TestClangConfig> allTestClangConfigs() { 2279 std::vector<TestClangConfig> all_configs; 2280 for (TestLanguage lang : {Lang_C89, Lang_C99, Lang_CXX03, Lang_CXX11, 2281 Lang_CXX14, Lang_CXX17, Lang_CXX20}) { 2282 TestClangConfig config; 2283 config.Language = lang; 2284 2285 // Use an unknown-unknown triple so we don't instantiate the full system 2286 // toolchain. On Linux, instantiating the toolchain involves stat'ing 2287 // large portions of /usr/lib, and this slows down not only this test, but 2288 // all other tests, via contention in the kernel. 2289 // 2290 // FIXME: This is a hack to work around the fact that there's no way to do 2291 // the equivalent of runToolOnCodeWithArgs without instantiating a full 2292 // Driver. We should consider having a function, at least for tests, that 2293 // invokes cc1. 2294 config.Target = "i386-unknown-unknown"; 2295 all_configs.push_back(config); 2296 2297 // Windows target is interesting to test because it enables 2298 // `-fdelayed-template-parsing`. 2299 config.Target = "x86_64-pc-win32-msvc"; 2300 all_configs.push_back(config); 2301 } 2302 return all_configs; 2303 } 2304 2305 INSTANTIATE_TEST_CASE_P(ASTMatchersTests, ASTMatchersTest, 2306 testing::ValuesIn(allTestClangConfigs()), ); 2307 2308 } // namespace ast_matchers 2309 } // namespace clang 2310