1 //= unittests/ASTMatchers/ASTMatchersTraversalTest.cpp - matchers 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/Attrs.inc" 11 #include "clang/AST/DeclCXX.h" 12 #include "clang/AST/PrettyPrinter.h" 13 #include "clang/ASTMatchers/ASTMatchFinder.h" 14 #include "clang/ASTMatchers/ASTMatchers.h" 15 #include "clang/Tooling/Tooling.h" 16 #include "llvm/ADT/StringRef.h" 17 #include "llvm/TargetParser/Host.h" 18 #include "llvm/TargetParser/Triple.h" 19 #include "gtest/gtest.h" 20 21 namespace clang { 22 namespace ast_matchers { 23 24 TEST(DeclarationMatcher, hasMethod) { 25 EXPECT_TRUE(matches("class A { void func(); };", 26 cxxRecordDecl(hasMethod(hasName("func"))))); 27 EXPECT_TRUE(notMatches("class A { void func(); };", 28 cxxRecordDecl(hasMethod(isPublic())))); 29 } 30 31 TEST(DeclarationMatcher, ClassDerivedFromDependentTemplateSpecialization) { 32 EXPECT_TRUE(matches( 33 "template <typename T> struct A {" 34 " template <typename T2> struct F {};" 35 "};" 36 "template <typename T> struct B : A<T>::template F<T> {};" 37 "B<int> b;", 38 cxxRecordDecl(hasName("B"), isDerivedFrom(recordDecl())))); 39 } 40 41 TEST(DeclarationMatcher, hasDeclContext) { 42 EXPECT_TRUE(matches( 43 "namespace N {" 44 " namespace M {" 45 " class D {};" 46 " }" 47 "}", 48 recordDecl(hasDeclContext(namespaceDecl(hasName("M")))))); 49 EXPECT_TRUE(notMatches( 50 "namespace N {" 51 " namespace M {" 52 " class D {};" 53 " }" 54 "}", 55 recordDecl(hasDeclContext(namespaceDecl(hasName("N")))))); 56 57 EXPECT_TRUE(matches("namespace {" 58 " namespace M {" 59 " class D {};" 60 " }" 61 "}", 62 recordDecl(hasDeclContext(namespaceDecl( 63 hasName("M"), hasDeclContext(namespaceDecl())))))); 64 65 EXPECT_TRUE(matches("class D{};", decl(hasDeclContext(decl())))); 66 } 67 68 TEST(HasDescendant, MatchesDescendantTypes) { 69 EXPECT_TRUE(matches("void f() { int i = 3; }", 70 decl(hasDescendant(loc(builtinType()))))); 71 EXPECT_TRUE(matches("void f() { int i = 3; }", 72 stmt(hasDescendant(builtinType())))); 73 74 EXPECT_TRUE(matches("void f() { int i = 3; }", 75 stmt(hasDescendant(loc(builtinType()))))); 76 EXPECT_TRUE(matches("void f() { int i = 3; }", 77 stmt(hasDescendant(qualType(builtinType()))))); 78 79 EXPECT_TRUE(notMatches("void f() { float f = 2.0f; }", 80 stmt(hasDescendant(isInteger())))); 81 82 EXPECT_TRUE(matchAndVerifyResultTrue( 83 "void f() { int a; float c; int d; int e; }", 84 functionDecl(forEachDescendant( 85 varDecl(hasDescendant(isInteger())).bind("x"))), 86 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 3))); 87 } 88 89 TEST(HasDescendant, MatchesDescendantsOfTypes) { 90 EXPECT_TRUE(matches("void f() { int*** i; }", 91 qualType(hasDescendant(builtinType())))); 92 EXPECT_TRUE(matches("void f() { int*** i; }", 93 qualType(hasDescendant( 94 pointerType(pointee(builtinType())))))); 95 EXPECT_TRUE(matches("void f() { int*** i; }", 96 typeLoc(hasDescendant(loc(builtinType()))))); 97 98 EXPECT_TRUE(matchAndVerifyResultTrue( 99 "void f() { int*** i; }", 100 qualType(asString("int ***"), forEachDescendant(pointerType().bind("x"))), 101 std::make_unique<VerifyIdIsBoundTo<Type>>("x", 2))); 102 } 103 104 105 TEST(Has, MatchesChildrenOfTypes) { 106 EXPECT_TRUE(matches("int i;", 107 varDecl(hasName("i"), has(isInteger())))); 108 EXPECT_TRUE(notMatches("int** i;", 109 varDecl(hasName("i"), has(isInteger())))); 110 EXPECT_TRUE(matchAndVerifyResultTrue( 111 "int (*f)(float, int);", 112 qualType(functionType(), forEach(qualType(isInteger()).bind("x"))), 113 std::make_unique<VerifyIdIsBoundTo<QualType>>("x", 2))); 114 } 115 116 TEST(Has, MatchesChildTypes) { 117 EXPECT_TRUE(matches( 118 "int* i;", 119 varDecl(hasName("i"), hasType(qualType(has(builtinType())))))); 120 EXPECT_TRUE(notMatches( 121 "int* i;", 122 varDecl(hasName("i"), hasType(qualType(has(pointerType())))))); 123 } 124 125 TEST(StatementMatcher, Has) { 126 StatementMatcher HasVariableI = 127 expr(hasType(pointsTo(recordDecl(hasName("X")))), 128 has(ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("i"))))))); 129 130 EXPECT_TRUE(matches( 131 "class X; X *x(int); void c() { int i; x(i); }", HasVariableI)); 132 EXPECT_TRUE(notMatches( 133 "class X; X *x(int); void c() { int i; x(42); }", HasVariableI)); 134 } 135 136 TEST(StatementMatcher, HasDescendant) { 137 StatementMatcher HasDescendantVariableI = 138 expr(hasType(pointsTo(recordDecl(hasName("X")))), 139 hasDescendant(declRefExpr(to(varDecl(hasName("i")))))); 140 141 EXPECT_TRUE(matches( 142 "class X; X *x(bool); bool b(int); void c() { int i; x(b(i)); }", 143 HasDescendantVariableI)); 144 EXPECT_TRUE(notMatches( 145 "class X; X *x(bool); bool b(int); void c() { int i; x(b(42)); }", 146 HasDescendantVariableI)); 147 } 148 149 TEST(TypeMatcher, MatchesClassType) { 150 TypeMatcher TypeA = hasDeclaration(recordDecl(hasName("A"))); 151 152 EXPECT_TRUE(matches("class A { public: A *a; };", TypeA)); 153 EXPECT_TRUE(notMatches("class A {};", TypeA)); 154 155 TypeMatcher TypeDerivedFromA = 156 hasDeclaration(cxxRecordDecl(isDerivedFrom("A"))); 157 158 EXPECT_TRUE(matches("class A {}; class B : public A { public: B *b; };", 159 TypeDerivedFromA)); 160 EXPECT_TRUE(notMatches("class A {};", TypeA)); 161 162 TypeMatcher TypeAHasClassB = hasDeclaration( 163 recordDecl(hasName("A"), has(recordDecl(hasName("B"))))); 164 165 EXPECT_TRUE( 166 matches("class A { public: A *a; class B {}; };", TypeAHasClassB)); 167 168 EXPECT_TRUE(matchesC("struct S {}; void f(void) { struct S s; }", 169 varDecl(hasType(namedDecl(hasName("S")))))); 170 } 171 172 TEST(TypeMatcher, MatchesDeclTypes) { 173 // TypedefType -> TypedefNameDecl 174 EXPECT_TRUE(matches("typedef int I; void f(I i);", 175 parmVarDecl(hasType(namedDecl(hasName("I")))))); 176 // ObjCObjectPointerType 177 EXPECT_TRUE(matchesObjC("@interface Foo @end void f(Foo *f);", 178 parmVarDecl(hasType(objcObjectPointerType())))); 179 // ObjCObjectPointerType -> ObjCInterfaceType -> ObjCInterfaceDecl 180 EXPECT_TRUE(matchesObjC( 181 "@interface Foo @end void f(Foo *f);", 182 parmVarDecl(hasType(pointsTo(objcInterfaceDecl(hasName("Foo"))))))); 183 // TemplateTypeParmType 184 EXPECT_TRUE(matches("template <typename T> void f(T t);", 185 parmVarDecl(hasType(templateTypeParmType())))); 186 // TemplateTypeParmType -> TemplateTypeParmDecl 187 EXPECT_TRUE(matches("template <typename T> void f(T t);", 188 parmVarDecl(hasType(namedDecl(hasName("T")))))); 189 // InjectedClassNameType 190 EXPECT_TRUE(matches("template <typename T> struct S {" 191 " void f(S s);" 192 "};", 193 parmVarDecl(hasType(elaboratedType( 194 namesType(injectedClassNameType())))))); 195 EXPECT_TRUE(notMatches("template <typename T> struct S {" 196 " void g(S<T> s);" 197 "};", 198 parmVarDecl(hasType(elaboratedType( 199 namesType(injectedClassNameType())))))); 200 // InjectedClassNameType -> CXXRecordDecl 201 EXPECT_TRUE(matches("template <typename T> struct S {" 202 " void f(S s);" 203 "};", 204 parmVarDecl(hasType(namedDecl(hasName("S")))))); 205 206 static const char Using[] = "template <typename T>" 207 "struct Base {" 208 " typedef T Foo;" 209 "};" 210 "" 211 "template <typename T>" 212 "struct S : private Base<T> {" 213 " using typename Base<T>::Foo;" 214 " void f(Foo);" 215 "};"; 216 // UnresolvedUsingTypenameDecl 217 EXPECT_TRUE(matches(Using, unresolvedUsingTypenameDecl(hasName("Foo")))); 218 // UnresolvedUsingTypenameType -> UnresolvedUsingTypenameDecl 219 EXPECT_TRUE(matches(Using, parmVarDecl(hasType(namedDecl(hasName("Foo")))))); 220 } 221 222 TEST(HasDeclaration, HasDeclarationOfEnumType) { 223 EXPECT_TRUE(matches("enum X {}; void y(X *x) { x; }", 224 expr(hasType(pointsTo( 225 qualType(hasDeclaration(enumDecl(hasName("X"))))))))); 226 } 227 228 TEST(HasDeclaration, HasGetDeclTraitTest) { 229 static_assert(internal::has_getDecl<TypedefType>::value, 230 "Expected TypedefType to have a getDecl."); 231 static_assert(internal::has_getDecl<RecordType>::value, 232 "Expected RecordType to have a getDecl."); 233 static_assert(!internal::has_getDecl<TemplateSpecializationType>::value, 234 "Expected TemplateSpecializationType to *not* have a getDecl."); 235 } 236 237 TEST(HasDeclaration, ElaboratedType) { 238 EXPECT_TRUE(matches( 239 "namespace n { template <typename T> struct X {}; }" 240 "void f(n::X<int>);", 241 parmVarDecl(hasType(qualType(hasDeclaration(cxxRecordDecl())))))); 242 EXPECT_TRUE(matches( 243 "namespace n { template <typename T> struct X {}; }" 244 "void f(n::X<int>);", 245 parmVarDecl(hasType(elaboratedType(hasDeclaration(cxxRecordDecl())))))); 246 } 247 248 TEST(HasDeclaration, HasDeclarationOfTypeWithDecl) { 249 EXPECT_TRUE(matches( 250 "typedef int X; X a;", 251 varDecl(hasName("a"), hasType(elaboratedType(namesType( 252 typedefType(hasDeclaration(decl())))))))); 253 254 // FIXME: Add tests for other types with getDecl() (e.g. RecordType) 255 } 256 257 TEST(HasDeclaration, HasDeclarationOfTemplateSpecializationType) { 258 EXPECT_TRUE(matches( 259 "template <typename T> class A {}; A<int> a;", 260 varDecl(hasType(elaboratedType(namesType(templateSpecializationType( 261 hasDeclaration(namedDecl(hasName("A")))))))))); 262 EXPECT_TRUE(matches( 263 "template <typename T> class A {};" 264 "template <typename T> class B { A<T> a; };", 265 fieldDecl(hasType(elaboratedType(namesType(templateSpecializationType( 266 hasDeclaration(namedDecl(hasName("A")))))))))); 267 EXPECT_TRUE(matches( 268 "template <typename T> class A {}; A<int> a;", 269 varDecl(hasType(elaboratedType(namesType( 270 templateSpecializationType(hasDeclaration(cxxRecordDecl())))))))); 271 } 272 273 TEST(HasDeclaration, HasDeclarationOfCXXNewExpr) { 274 EXPECT_TRUE( 275 matches("int *A = new int();", 276 cxxNewExpr(hasDeclaration(functionDecl(parameterCountIs(1)))))); 277 } 278 279 TEST(HasDeclaration, HasDeclarationOfTypeAlias) { 280 EXPECT_TRUE(matches( 281 "template <typename T> using C = T; C<int> c;", 282 varDecl(hasType(elaboratedType(namesType(templateSpecializationType( 283 hasDeclaration(typeAliasTemplateDecl())))))))); 284 } 285 286 TEST(HasDeclaration, HasDeclarationOfObjCInterface) { 287 EXPECT_TRUE(matchesObjC("@interface BaseClass @end void f() {BaseClass* b;}", 288 varDecl(hasType(objcObjectPointerType( 289 pointee(hasDeclaration(objcInterfaceDecl()))))))); 290 } 291 292 TEST(HasUnqualifiedDesugaredType, DesugarsUsing) { 293 EXPECT_TRUE( 294 matches("struct A {}; using B = A; B b;", 295 varDecl(hasType(hasUnqualifiedDesugaredType(recordType()))))); 296 EXPECT_TRUE( 297 matches("struct A {}; using B = A; using C = B; C b;", 298 varDecl(hasType(hasUnqualifiedDesugaredType(recordType()))))); 299 } 300 301 TEST(HasUnderlyingDecl, Matches) { 302 EXPECT_TRUE(matches("namespace N { template <class T> void f(T t); }" 303 "template <class T> void g() { using N::f; f(T()); }", 304 unresolvedLookupExpr(hasAnyDeclaration( 305 namedDecl(hasUnderlyingDecl(hasName("::N::f"))))))); 306 EXPECT_TRUE(matches( 307 "namespace N { template <class T> void f(T t); }" 308 "template <class T> void g() { N::f(T()); }", 309 unresolvedLookupExpr(hasAnyDeclaration(namedDecl(hasName("::N::f")))))); 310 EXPECT_TRUE(notMatches( 311 "namespace N { template <class T> void f(T t); }" 312 "template <class T> void g() { using N::f; f(T()); }", 313 unresolvedLookupExpr(hasAnyDeclaration(namedDecl(hasName("::N::f")))))); 314 } 315 316 TEST(HasType, TakesQualTypeMatcherAndMatchesExpr) { 317 TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X"))); 318 EXPECT_TRUE( 319 matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX)))); 320 EXPECT_TRUE( 321 notMatches("class X {}; void y(X *x) { x; }", 322 expr(hasType(ClassX)))); 323 EXPECT_TRUE( 324 matches("class X {}; void y(X *x) { x; }", 325 expr(hasType(pointsTo(ClassX))))); 326 } 327 328 TEST(HasType, TakesQualTypeMatcherAndMatchesValueDecl) { 329 TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X"))); 330 EXPECT_TRUE( 331 matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX)))); 332 EXPECT_TRUE( 333 notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX)))); 334 EXPECT_TRUE( 335 matches("class X {}; void y() { X *x; }", 336 varDecl(hasType(pointsTo(ClassX))))); 337 } 338 339 TEST(HasType, TakesQualTypeMatcherAndMatchesCXXBaseSpecifier) { 340 TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X"))); 341 CXXBaseSpecifierMatcher BaseClassX = cxxBaseSpecifier(hasType(ClassX)); 342 DeclarationMatcher ClassHasBaseClassX = 343 cxxRecordDecl(hasDirectBase(BaseClassX)); 344 EXPECT_TRUE(matches("class X {}; class Y : X {};", ClassHasBaseClassX)); 345 EXPECT_TRUE(notMatches("class Z {}; class Y : Z {};", ClassHasBaseClassX)); 346 } 347 348 TEST(HasType, TakesDeclMatcherAndMatchesExpr) { 349 DeclarationMatcher ClassX = recordDecl(hasName("X")); 350 EXPECT_TRUE( 351 matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX)))); 352 EXPECT_TRUE( 353 notMatches("class X {}; void y(X *x) { x; }", 354 expr(hasType(ClassX)))); 355 } 356 357 TEST(HasType, TakesDeclMatcherAndMatchesValueDecl) { 358 DeclarationMatcher ClassX = recordDecl(hasName("X")); 359 EXPECT_TRUE( 360 matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX)))); 361 EXPECT_TRUE( 362 notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX)))); 363 } 364 365 TEST(HasType, TakesDeclMatcherAndMatchesCXXBaseSpecifier) { 366 DeclarationMatcher ClassX = recordDecl(hasName("X")); 367 CXXBaseSpecifierMatcher BaseClassX = cxxBaseSpecifier(hasType(ClassX)); 368 DeclarationMatcher ClassHasBaseClassX = 369 cxxRecordDecl(hasDirectBase(BaseClassX)); 370 EXPECT_TRUE(matches("class X {}; class Y : X {};", ClassHasBaseClassX)); 371 EXPECT_TRUE(notMatches("class Z {}; class Y : Z {};", ClassHasBaseClassX)); 372 } 373 374 TEST(HasType, MatchesTypedefDecl) { 375 EXPECT_TRUE(matches("typedef int X;", typedefDecl(hasType(asString("int"))))); 376 EXPECT_TRUE(matches("typedef const int T;", 377 typedefDecl(hasType(asString("const int"))))); 378 EXPECT_TRUE(notMatches("typedef const int T;", 379 typedefDecl(hasType(asString("int"))))); 380 EXPECT_TRUE(matches("typedef int foo; typedef foo bar;", 381 typedefDecl(hasType(asString("foo")), hasName("bar")))); 382 } 383 384 TEST(HasType, MatchesTypedefNameDecl) { 385 EXPECT_TRUE(matches("using X = int;", typedefNameDecl(hasType(asString("int"))))); 386 EXPECT_TRUE(matches("using T = const int;", 387 typedefNameDecl(hasType(asString("const int"))))); 388 EXPECT_TRUE(notMatches("using T = const int;", 389 typedefNameDecl(hasType(asString("int"))))); 390 EXPECT_TRUE(matches("using foo = int; using bar = foo;", 391 typedefNameDecl(hasType(asString("foo")), hasName("bar")))); 392 } 393 394 TEST(HasTypeLoc, MatchesBlockDecl) { 395 EXPECT_TRUE(matchesConditionally( 396 "auto x = ^int (int a, int b) { return a + b; };", 397 blockDecl(hasTypeLoc(loc(asString("int (int, int)")))), true, 398 {"-fblocks"})); 399 } 400 401 TEST(HasTypeLoc, MatchesCXXBaseSpecifierAndCtorInitializer) { 402 llvm::StringRef code = R"cpp( 403 class Foo {}; 404 class Bar : public Foo { 405 Bar() : Foo() {} 406 }; 407 )cpp"; 408 409 EXPECT_TRUE(matches( 410 code, cxxRecordDecl(hasAnyBase(hasTypeLoc(loc(asString("Foo"))))))); 411 EXPECT_TRUE( 412 matches(code, cxxCtorInitializer(hasTypeLoc(loc(asString("Foo")))))); 413 } 414 415 TEST(HasTypeLoc, MatchesCXXFunctionalCastExpr) { 416 EXPECT_TRUE(matches("auto x = int(3);", 417 cxxFunctionalCastExpr(hasTypeLoc(loc(asString("int")))))); 418 } 419 420 TEST(HasTypeLoc, MatchesCXXNewExpr) { 421 EXPECT_TRUE(matches("auto* x = new int(3);", 422 cxxNewExpr(hasTypeLoc(loc(asString("int")))))); 423 EXPECT_TRUE(matches("class Foo{}; auto* x = new Foo();", 424 cxxNewExpr(hasTypeLoc(loc(asString("Foo")))))); 425 } 426 427 TEST(HasTypeLoc, MatchesCXXTemporaryObjectExpr) { 428 EXPECT_TRUE( 429 matches("struct Foo { Foo(int, int); }; auto x = Foo(1, 2);", 430 cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("Foo")))))); 431 } 432 433 TEST(HasTypeLoc, MatchesCXXUnresolvedConstructExpr) { 434 EXPECT_TRUE( 435 matches("template <typename T> T make() { return T(); }", 436 cxxUnresolvedConstructExpr(hasTypeLoc(loc(asString("T")))))); 437 } 438 439 TEST(HasTypeLoc, MatchesCompoundLiteralExpr) { 440 EXPECT_TRUE( 441 matches("int* x = (int[2]) { 0, 1 };", 442 compoundLiteralExpr(hasTypeLoc(loc(asString("int[2]")))))); 443 } 444 445 TEST(HasTypeLoc, MatchesDeclaratorDecl) { 446 EXPECT_TRUE(matches("int x;", 447 varDecl(hasName("x"), hasTypeLoc(loc(asString("int")))))); 448 EXPECT_TRUE(matches("int x(3);", 449 varDecl(hasName("x"), hasTypeLoc(loc(asString("int")))))); 450 EXPECT_TRUE(matches("struct Foo { Foo(int, int); }; Foo x(1, 2);", 451 varDecl(hasName("x"), hasTypeLoc(loc(asString("Foo")))))); 452 453 // Make sure we don't crash on implicit constructors. 454 EXPECT_TRUE(notMatches("class X {}; X x;", 455 declaratorDecl(hasTypeLoc(loc(asString("int")))))); 456 } 457 458 TEST(HasTypeLoc, MatchesExplicitCastExpr) { 459 EXPECT_TRUE(matches("auto x = (int) 3;", 460 explicitCastExpr(hasTypeLoc(loc(asString("int")))))); 461 EXPECT_TRUE(matches("auto x = static_cast<int>(3);", 462 explicitCastExpr(hasTypeLoc(loc(asString("int")))))); 463 } 464 465 TEST(HasTypeLoc, MatchesObjCPropertyDecl) { 466 EXPECT_TRUE(matchesObjC(R"objc( 467 @interface Foo 468 @property int enabled; 469 @end 470 )objc", 471 objcPropertyDecl(hasTypeLoc(loc(asString("int")))))); 472 } 473 474 TEST(HasTypeLoc, MatchesTemplateArgumentLoc) { 475 EXPECT_TRUE(matches("template <typename T> class Foo {}; Foo<int> x;", 476 templateArgumentLoc(hasTypeLoc(loc(asString("int")))))); 477 } 478 479 TEST(HasTypeLoc, MatchesTypedefNameDecl) { 480 EXPECT_TRUE(matches("typedef int X;", 481 typedefNameDecl(hasTypeLoc(loc(asString("int")))))); 482 EXPECT_TRUE(matches("using X = int;", 483 typedefNameDecl(hasTypeLoc(loc(asString("int")))))); 484 } 485 486 TEST(Callee, MatchesDeclarations) { 487 StatementMatcher CallMethodX = callExpr(callee(cxxMethodDecl(hasName("x")))); 488 489 EXPECT_TRUE(matches("class Y { void x() { x(); } };", CallMethodX)); 490 EXPECT_TRUE(notMatches("class Y { void x() {} };", CallMethodX)); 491 492 CallMethodX = traverse(TK_AsIs, callExpr(callee(cxxConversionDecl()))); 493 EXPECT_TRUE( 494 matches("struct Y { operator int() const; }; int i = Y();", CallMethodX)); 495 EXPECT_TRUE(notMatches("struct Y { operator int() const; }; Y y = Y();", 496 CallMethodX)); 497 } 498 499 TEST(Callee, MatchesMemberExpressions) { 500 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };", 501 callExpr(callee(memberExpr())))); 502 EXPECT_TRUE( 503 notMatches("class Y { void x() { this->x(); } };", callExpr(callee(callExpr())))); 504 } 505 506 TEST(Matcher, Argument) { 507 StatementMatcher CallArgumentY = callExpr( 508 hasArgument(0, declRefExpr(to(varDecl(hasName("y")))))); 509 510 EXPECT_TRUE(matches("void x(int) { int y; x(y); }", CallArgumentY)); 511 EXPECT_TRUE( 512 matches("class X { void x(int) { int y; x(y); } };", CallArgumentY)); 513 EXPECT_TRUE(notMatches("void x(int) { int z; x(z); }", CallArgumentY)); 514 515 StatementMatcher WrongIndex = callExpr( 516 hasArgument(42, declRefExpr(to(varDecl(hasName("y")))))); 517 EXPECT_TRUE(notMatches("void x(int) { int y; x(y); }", WrongIndex)); 518 } 519 520 TEST(Matcher, AnyArgument) { 521 auto HasArgumentY = hasAnyArgument( 522 ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("y")))))); 523 StatementMatcher CallArgumentY = callExpr(HasArgumentY); 524 StatementMatcher CtorArgumentY = cxxConstructExpr(HasArgumentY); 525 StatementMatcher UnresolvedCtorArgumentY = 526 cxxUnresolvedConstructExpr(HasArgumentY); 527 StatementMatcher ObjCCallArgumentY = objcMessageExpr(HasArgumentY); 528 EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY)); 529 EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY)); 530 EXPECT_TRUE(matches("struct Y { Y(int, int); };" 531 "void x() { int y; (void)Y(1, y); }", 532 CtorArgumentY)); 533 EXPECT_TRUE(matches("struct Y { Y(int, int); };" 534 "void x() { int y; (void)Y(y, 42); }", 535 CtorArgumentY)); 536 EXPECT_TRUE(matches("template <class Y> void x() { int y; (void)Y(1, y); }", 537 UnresolvedCtorArgumentY)); 538 EXPECT_TRUE(matches("template <class Y> void x() { int y; (void)Y(y, 42); }", 539 UnresolvedCtorArgumentY)); 540 EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) y; @end " 541 "void x(I* i) { int y; [i f:y]; }", 542 ObjCCallArgumentY)); 543 EXPECT_FALSE(matchesObjC("@interface I -(void)f:(int) z; @end " 544 "void x(I* i) { int z; [i f:z]; }", 545 ObjCCallArgumentY)); 546 EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY)); 547 EXPECT_TRUE(notMatches("struct Y { Y(int, int); };" 548 "void x() { int y; (void)Y(1, 2); }", 549 CtorArgumentY)); 550 EXPECT_TRUE(notMatches("template <class Y>" 551 "void x() { int y; (void)Y(1, 2); }", 552 UnresolvedCtorArgumentY)); 553 554 StatementMatcher ImplicitCastedArgument = 555 traverse(TK_AsIs, callExpr(hasAnyArgument(implicitCastExpr()))); 556 EXPECT_TRUE(matches("void x(long) { int y; x(y); }", ImplicitCastedArgument)); 557 } 558 559 TEST(Matcher, HasReceiver) { 560 EXPECT_TRUE(matchesObjC( 561 "@interface NSString @end " 562 "void f(NSString *x) {" 563 "[x containsString];" 564 "}", 565 objcMessageExpr(hasReceiver(declRefExpr(to(varDecl(hasName("x")))))))); 566 567 EXPECT_FALSE(matchesObjC( 568 "@interface NSString +(NSString *) stringWithFormat; @end " 569 "void f() { [NSString stringWithFormat]; }", 570 objcMessageExpr(hasReceiver(declRefExpr(to(varDecl(hasName("x")))))))); 571 } 572 573 TEST(Matcher, MatchesMethodsOnLambda) { 574 StringRef Code = R"cpp( 575 struct A { 576 ~A() {} 577 }; 578 void foo() 579 { 580 A a; 581 auto l = [a] { }; 582 auto lCopy = l; 583 auto lPtrDecay = +[] { }; 584 (void)lPtrDecay; 585 } 586 )cpp"; 587 588 EXPECT_TRUE(matches( 589 Code, cxxConstructorDecl( 590 hasBody(compoundStmt()), 591 hasAncestor(lambdaExpr(hasAncestor(varDecl(hasName("l"))))), 592 isCopyConstructor()))); 593 EXPECT_TRUE(matches( 594 Code, cxxConstructorDecl( 595 hasBody(compoundStmt()), 596 hasAncestor(lambdaExpr(hasAncestor(varDecl(hasName("l"))))), 597 isMoveConstructor()))); 598 EXPECT_TRUE(matches( 599 Code, cxxDestructorDecl( 600 hasBody(compoundStmt()), 601 hasAncestor(lambdaExpr(hasAncestor(varDecl(hasName("l")))))))); 602 EXPECT_TRUE(matches( 603 Code, cxxConversionDecl(hasBody(compoundStmt(has(returnStmt( 604 hasReturnValue(implicitCastExpr()))))), 605 hasAncestor(lambdaExpr(hasAncestor( 606 varDecl(hasName("lPtrDecay")))))))); 607 } 608 609 TEST(Matcher, MatchesCoroutine) { 610 FileContentMappings M; 611 M.push_back(std::make_pair("/coro_header", R"cpp( 612 namespace std { 613 614 template <class... Args> 615 struct void_t_imp { 616 using type = void; 617 }; 618 template <class... Args> 619 using void_t = typename void_t_imp<Args...>::type; 620 621 template <class T, class = void> 622 struct traits_sfinae_base {}; 623 624 template <class T> 625 struct traits_sfinae_base<T, void_t<typename T::promise_type>> { 626 using promise_type = typename T::promise_type; 627 }; 628 629 template <class Ret, class... Args> 630 struct coroutine_traits : public traits_sfinae_base<Ret> {}; 631 } // namespace std 632 struct awaitable { 633 bool await_ready() noexcept; 634 template <typename F> 635 void await_suspend(F) noexcept; 636 void await_resume() noexcept; 637 } a; 638 struct promise { 639 void get_return_object(); 640 awaitable initial_suspend(); 641 awaitable final_suspend() noexcept; 642 awaitable yield_value(int); // expected-note 2{{candidate}} 643 void return_value(int); // expected-note 2{{here}} 644 void unhandled_exception(); 645 }; 646 template <typename... T> 647 struct std::coroutine_traits<void, T...> { using promise_type = promise; }; 648 namespace std { 649 template <class PromiseType = void> 650 struct coroutine_handle { 651 static coroutine_handle from_address(void *) noexcept; 652 }; 653 } // namespace std 654 )cpp")); 655 StringRef CoReturnCode = R"cpp( 656 #include <coro_header> 657 void check_match_co_return() { 658 co_return 1; 659 } 660 )cpp"; 661 EXPECT_TRUE(matchesConditionally(CoReturnCode, 662 coreturnStmt(isExpansionInMainFile()), true, 663 {"-std=c++20", "-I/"}, M)); 664 StringRef CoAwaitCode = R"cpp( 665 #include <coro_header> 666 void check_match_co_await() { 667 co_await a; 668 co_return 1; 669 } 670 )cpp"; 671 EXPECT_TRUE(matchesConditionally(CoAwaitCode, 672 coawaitExpr(isExpansionInMainFile()), true, 673 {"-std=c++20", "-I/"}, M)); 674 StringRef CoYieldCode = R"cpp( 675 #include <coro_header> 676 void check_match_co_yield() { 677 co_yield 1.0; 678 co_return 1; 679 } 680 )cpp"; 681 EXPECT_TRUE(matchesConditionally(CoYieldCode, 682 coyieldExpr(isExpansionInMainFile()), true, 683 {"-std=c++20", "-I/"}, M)); 684 685 StringRef NonCoroCode = R"cpp( 686 #include <coro_header> 687 void non_coro_function() { 688 } 689 )cpp"; 690 691 EXPECT_TRUE(matchesConditionally(CoReturnCode, coroutineBodyStmt(), true, 692 {"-std=c++20", "-I/"}, M)); 693 EXPECT_TRUE(matchesConditionally(CoAwaitCode, coroutineBodyStmt(), true, 694 {"-std=c++20", "-I/"}, M)); 695 EXPECT_TRUE(matchesConditionally(CoYieldCode, coroutineBodyStmt(), true, 696 {"-std=c++20", "-I/"}, M)); 697 698 EXPECT_FALSE(matchesConditionally(NonCoroCode, coroutineBodyStmt(), true, 699 {"-std=c++20", "-I/"}, M)); 700 701 StringRef CoroWithDeclCode = R"cpp( 702 #include <coro_header> 703 void coro() { 704 int thevar; 705 co_return 1; 706 } 707 )cpp"; 708 EXPECT_TRUE(matchesConditionally( 709 CoroWithDeclCode, 710 coroutineBodyStmt(hasBody(compoundStmt( 711 has(declStmt(containsDeclaration(0, varDecl(hasName("thevar")))))))), 712 true, {"-std=c++20", "-I/"}, M)); 713 714 StringRef CoroWithTryCatchDeclCode = R"cpp( 715 #include <coro_header> 716 void coro() try { 717 int thevar; 718 co_return 1; 719 } catch (...) { co_return 1; } 720 )cpp"; 721 EXPECT_TRUE(matchesConditionally( 722 CoroWithTryCatchDeclCode, 723 coroutineBodyStmt(hasBody(compoundStmt(has(cxxTryStmt(has(compoundStmt(has( 724 declStmt(containsDeclaration(0, varDecl(hasName("thevar")))))))))))), 725 true, {"-std=c++20", "-I/"}, M)); 726 } 727 728 TEST(Matcher, isClassMessage) { 729 EXPECT_TRUE(matchesObjC( 730 "@interface NSString +(NSString *) stringWithFormat; @end " 731 "void f() { [NSString stringWithFormat]; }", 732 objcMessageExpr(isClassMessage()))); 733 734 EXPECT_FALSE(matchesObjC( 735 "@interface NSString @end " 736 "void f(NSString *x) {" 737 "[x containsString];" 738 "}", 739 objcMessageExpr(isClassMessage()))); 740 } 741 742 TEST(Matcher, isInstanceMessage) { 743 EXPECT_TRUE(matchesObjC( 744 "@interface NSString @end " 745 "void f(NSString *x) {" 746 "[x containsString];" 747 "}", 748 objcMessageExpr(isInstanceMessage()))); 749 750 EXPECT_FALSE(matchesObjC( 751 "@interface NSString +(NSString *) stringWithFormat; @end " 752 "void f() { [NSString stringWithFormat]; }", 753 objcMessageExpr(isInstanceMessage()))); 754 755 } 756 757 TEST(Matcher, isClassMethod) { 758 EXPECT_TRUE(matchesObjC( 759 "@interface Bar + (void)bar; @end", 760 objcMethodDecl(isClassMethod()))); 761 762 EXPECT_TRUE(matchesObjC( 763 "@interface Bar @end" 764 "@implementation Bar + (void)bar {} @end", 765 objcMethodDecl(isClassMethod()))); 766 767 EXPECT_FALSE(matchesObjC( 768 "@interface Foo - (void)foo; @end", 769 objcMethodDecl(isClassMethod()))); 770 771 EXPECT_FALSE(matchesObjC( 772 "@interface Foo @end " 773 "@implementation Foo - (void)foo {} @end", 774 objcMethodDecl(isClassMethod()))); 775 } 776 777 TEST(Matcher, isInstanceMethod) { 778 EXPECT_TRUE(matchesObjC( 779 "@interface Foo - (void)foo; @end", 780 objcMethodDecl(isInstanceMethod()))); 781 782 EXPECT_TRUE(matchesObjC( 783 "@interface Foo @end " 784 "@implementation Foo - (void)foo {} @end", 785 objcMethodDecl(isInstanceMethod()))); 786 787 EXPECT_FALSE(matchesObjC( 788 "@interface Bar + (void)bar; @end", 789 objcMethodDecl(isInstanceMethod()))); 790 791 EXPECT_FALSE(matchesObjC( 792 "@interface Bar @end" 793 "@implementation Bar + (void)bar {} @end", 794 objcMethodDecl(isInstanceMethod()))); 795 } 796 797 TEST(MatcherCXXMemberCallExpr, On) { 798 StringRef Snippet1 = R"cc( 799 struct Y { 800 void m(); 801 }; 802 void z(Y y) { y.m(); } 803 )cc"; 804 StringRef Snippet2 = R"cc( 805 struct Y { 806 void m(); 807 }; 808 struct X : public Y {}; 809 void z(X x) { x.m(); } 810 )cc"; 811 auto MatchesY = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y"))))); 812 EXPECT_TRUE(matches(Snippet1, MatchesY)); 813 EXPECT_TRUE(notMatches(Snippet2, MatchesY)); 814 815 auto MatchesX = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("X"))))); 816 EXPECT_TRUE(matches(Snippet2, MatchesX)); 817 818 // Parens are ignored. 819 StringRef Snippet3 = R"cc( 820 struct Y { 821 void m(); 822 }; 823 Y g(); 824 void z(Y y) { (g()).m(); } 825 )cc"; 826 auto MatchesCall = cxxMemberCallExpr(on(callExpr())); 827 EXPECT_TRUE(matches(Snippet3, MatchesCall)); 828 } 829 830 TEST(MatcherCXXMemberCallExpr, OnImplicitObjectArgument) { 831 StringRef Snippet1 = R"cc( 832 struct Y { 833 void m(); 834 }; 835 void z(Y y) { y.m(); } 836 )cc"; 837 StringRef Snippet2 = R"cc( 838 struct Y { 839 void m(); 840 }; 841 struct X : public Y {}; 842 void z(X x) { x.m(); } 843 )cc"; 844 auto MatchesY = traverse(TK_AsIs, cxxMemberCallExpr(onImplicitObjectArgument( 845 hasType(cxxRecordDecl(hasName("Y")))))); 846 EXPECT_TRUE(matches(Snippet1, MatchesY)); 847 EXPECT_TRUE(matches(Snippet2, MatchesY)); 848 849 auto MatchesX = traverse(TK_AsIs, cxxMemberCallExpr(onImplicitObjectArgument( 850 hasType(cxxRecordDecl(hasName("X")))))); 851 EXPECT_TRUE(notMatches(Snippet2, MatchesX)); 852 853 // Parens are not ignored. 854 StringRef Snippet3 = R"cc( 855 struct Y { 856 void m(); 857 }; 858 Y g(); 859 void z(Y y) { (g()).m(); } 860 )cc"; 861 auto MatchesCall = traverse( 862 TK_AsIs, cxxMemberCallExpr(onImplicitObjectArgument(callExpr()))); 863 EXPECT_TRUE(notMatches(Snippet3, MatchesCall)); 864 } 865 866 TEST(Matcher, HasObjectExpr) { 867 StringRef Snippet1 = R"cc( 868 struct X { 869 int m; 870 int f(X x) { return x.m; } 871 }; 872 )cc"; 873 StringRef Snippet2 = R"cc( 874 struct X { 875 int m; 876 int f(X x) { return m; } 877 }; 878 )cc"; 879 auto MatchesX = 880 memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X"))))); 881 EXPECT_TRUE(matches(Snippet1, MatchesX)); 882 EXPECT_TRUE(notMatches(Snippet2, MatchesX)); 883 884 auto MatchesXPointer = memberExpr( 885 hasObjectExpression(hasType(pointsTo(cxxRecordDecl(hasName("X")))))); 886 EXPECT_TRUE(notMatches(Snippet1, MatchesXPointer)); 887 EXPECT_TRUE(matches(Snippet2, MatchesXPointer)); 888 } 889 890 TEST(ForEachArgumentWithParam, ReportsNoFalsePositives) { 891 StatementMatcher ArgumentY = 892 declRefExpr(to(varDecl(hasName("y")))).bind("arg"); 893 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param"); 894 StatementMatcher CallExpr = 895 callExpr(forEachArgumentWithParam(ArgumentY, IntParam)); 896 897 // IntParam does not match. 898 EXPECT_TRUE(notMatches("void f(int* i) { int* y; f(y); }", CallExpr)); 899 // ArgumentY does not match. 900 EXPECT_TRUE(notMatches("void f(int i) { int x; f(x); }", CallExpr)); 901 } 902 903 TEST(ForEachArgumentWithParam, MatchesCXXMemberCallExpr) { 904 StatementMatcher ArgumentY = 905 declRefExpr(to(varDecl(hasName("y")))).bind("arg"); 906 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param"); 907 StatementMatcher CallExpr = 908 callExpr(forEachArgumentWithParam(ArgumentY, IntParam)); 909 EXPECT_TRUE(matchAndVerifyResultTrue( 910 "struct S {" 911 " const S& operator[](int i) { return *this; }" 912 "};" 913 "void f(S S1) {" 914 " int y = 1;" 915 " S1[y];" 916 "}", 917 CallExpr, std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param", 1))); 918 919 StatementMatcher CallExpr2 = 920 callExpr(forEachArgumentWithParam(ArgumentY, IntParam)); 921 EXPECT_TRUE(matchAndVerifyResultTrue( 922 "struct S {" 923 " static void g(int i);" 924 "};" 925 "void f() {" 926 " int y = 1;" 927 " S::g(y);" 928 "}", 929 CallExpr2, std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param", 1))); 930 } 931 932 TEST(ForEachArgumentWithParam, MatchesCallExpr) { 933 StatementMatcher ArgumentY = 934 declRefExpr(to(varDecl(hasName("y")))).bind("arg"); 935 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param"); 936 StatementMatcher CallExpr = 937 callExpr(forEachArgumentWithParam(ArgumentY, IntParam)); 938 939 EXPECT_TRUE( 940 matchAndVerifyResultTrue("void f(int i) { int y; f(y); }", CallExpr, 941 std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>( 942 "param"))); 943 EXPECT_TRUE( 944 matchAndVerifyResultTrue("void f(int i) { int y; f(y); }", CallExpr, 945 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>( 946 "arg"))); 947 948 EXPECT_TRUE(matchAndVerifyResultTrue( 949 "void f(int i, int j) { int y; f(y, y); }", CallExpr, 950 std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param", 2))); 951 EXPECT_TRUE(matchAndVerifyResultTrue( 952 "void f(int i, int j) { int y; f(y, y); }", CallExpr, 953 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg", 2))); 954 } 955 956 TEST(ForEachArgumentWithParam, MatchesConstructExpr) { 957 StatementMatcher ArgumentY = 958 declRefExpr(to(varDecl(hasName("y")))).bind("arg"); 959 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param"); 960 StatementMatcher ConstructExpr = traverse( 961 TK_AsIs, cxxConstructExpr(forEachArgumentWithParam(ArgumentY, IntParam))); 962 963 EXPECT_TRUE(matchAndVerifyResultTrue( 964 "struct C {" 965 " C(int i) {}" 966 "};" 967 "int y = 0;" 968 "C Obj(y);", 969 ConstructExpr, 970 std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param"))); 971 } 972 973 TEST(ForEachArgumentWithParam, HandlesBoundNodesForNonMatches) { 974 EXPECT_TRUE(matchAndVerifyResultTrue( 975 "void g(int i, int j) {" 976 " int a;" 977 " int b;" 978 " int c;" 979 " g(a, 0);" 980 " g(a, b);" 981 " g(0, b);" 982 "}", 983 functionDecl( 984 forEachDescendant(varDecl().bind("v")), 985 forEachDescendant(callExpr(forEachArgumentWithParam( 986 declRefExpr(to(decl(equalsBoundNode("v")))), parmVarDecl())))), 987 std::make_unique<VerifyIdIsBoundTo<VarDecl>>("v", 4))); 988 } 989 990 TEST_P(ASTMatchersTest, 991 ForEachArgumentWithParamMatchesExplicitObjectParamOnOperatorCalls) { 992 if (!GetParam().isCXX23OrLater()) { 993 return; 994 } 995 996 auto DeclRef = declRefExpr(to(varDecl().bind("declOfArg"))).bind("arg"); 997 auto SelfParam = parmVarDecl().bind("param"); 998 StatementMatcher CallExpr = 999 callExpr(forEachArgumentWithParam(DeclRef, SelfParam)); 1000 1001 StringRef S = R"cpp( 1002 struct A { 1003 int operator()(this const A &self); 1004 }; 1005 A obj; 1006 int global = obj(); 1007 )cpp"; 1008 1009 auto Args = GetParam().getCommandLineArgs(); 1010 auto Filename = getFilenameForTesting(GetParam().Language); 1011 1012 EXPECT_TRUE(matchAndVerifyResultTrue( 1013 S, CallExpr, 1014 std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param", "self"), Args, 1015 Filename)); 1016 EXPECT_TRUE(matchAndVerifyResultTrue( 1017 S, CallExpr, 1018 std::make_unique<VerifyIdIsBoundTo<VarDecl>>("declOfArg", "obj"), Args, 1019 Filename)); 1020 } 1021 1022 TEST(ForEachArgumentWithParamType, ReportsNoFalsePositives) { 1023 StatementMatcher ArgumentY = 1024 declRefExpr(to(varDecl(hasName("y")))).bind("arg"); 1025 TypeMatcher IntType = qualType(isInteger()).bind("type"); 1026 StatementMatcher CallExpr = 1027 callExpr(forEachArgumentWithParamType(ArgumentY, IntType)); 1028 1029 // IntParam does not match. 1030 EXPECT_TRUE(notMatches("void f(int* i) { int* y; f(y); }", CallExpr)); 1031 // ArgumentY does not match. 1032 EXPECT_TRUE(notMatches("void f(int i) { int x; f(x); }", CallExpr)); 1033 } 1034 1035 TEST(ForEachArgumentWithParamType, MatchesCXXMemberCallExpr) { 1036 StatementMatcher ArgumentY = 1037 declRefExpr(to(varDecl(hasName("y")))).bind("arg"); 1038 TypeMatcher IntType = qualType(isInteger()).bind("type"); 1039 StatementMatcher CallExpr = 1040 callExpr(forEachArgumentWithParamType(ArgumentY, IntType)); 1041 EXPECT_TRUE(matchAndVerifyResultTrue( 1042 "struct S {" 1043 " const S& operator[](int i) { return *this; }" 1044 "};" 1045 "void f(S S1) {" 1046 " int y = 1;" 1047 " S1[y];" 1048 "}", 1049 CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type", 1))); 1050 1051 StatementMatcher CallExpr2 = 1052 callExpr(forEachArgumentWithParamType(ArgumentY, IntType)); 1053 EXPECT_TRUE(matchAndVerifyResultTrue( 1054 "struct S {" 1055 " static void g(int i);" 1056 "};" 1057 "void f() {" 1058 " int y = 1;" 1059 " S::g(y);" 1060 "}", 1061 CallExpr2, std::make_unique<VerifyIdIsBoundTo<QualType>>("type", 1))); 1062 } 1063 1064 TEST(ForEachArgumentWithParamType, MatchesCallExpr) { 1065 StatementMatcher ArgumentY = 1066 declRefExpr(to(varDecl(hasName("y")))).bind("arg"); 1067 TypeMatcher IntType = qualType(isInteger()).bind("type"); 1068 StatementMatcher CallExpr = 1069 callExpr(forEachArgumentWithParamType(ArgumentY, IntType)); 1070 1071 EXPECT_TRUE(matchAndVerifyResultTrue( 1072 "void f(int i) { int y; f(y); }", CallExpr, 1073 std::make_unique<VerifyIdIsBoundTo<QualType>>("type"))); 1074 EXPECT_TRUE(matchAndVerifyResultTrue( 1075 "void f(int i) { int y; f(y); }", CallExpr, 1076 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg"))); 1077 1078 EXPECT_TRUE(matchAndVerifyResultTrue( 1079 "void f(int i, int j) { int y; f(y, y); }", CallExpr, 1080 std::make_unique<VerifyIdIsBoundTo<QualType>>("type", 2))); 1081 EXPECT_TRUE(matchAndVerifyResultTrue( 1082 "void f(int i, int j) { int y; f(y, y); }", CallExpr, 1083 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg", 2))); 1084 } 1085 1086 TEST(ForEachArgumentWithParamType, MatchesConstructExpr) { 1087 StatementMatcher ArgumentY = 1088 declRefExpr(to(varDecl(hasName("y")))).bind("arg"); 1089 TypeMatcher IntType = qualType(isInteger()).bind("type"); 1090 StatementMatcher ConstructExpr = 1091 cxxConstructExpr(forEachArgumentWithParamType(ArgumentY, IntType)); 1092 1093 EXPECT_TRUE(matchAndVerifyResultTrue( 1094 "struct C {" 1095 " C(int i) {}" 1096 "};" 1097 "int y = 0;" 1098 "C Obj(y);", 1099 ConstructExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type"))); 1100 EXPECT_TRUE(matchAndVerifyResultTrue( 1101 "struct C {" 1102 " C(int i) {}" 1103 "};" 1104 "int y = 0;" 1105 "C Obj(y);", 1106 ConstructExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg"))); 1107 } 1108 1109 TEST(ForEachArgumentWithParamType, HandlesKandRFunctions) { 1110 StatementMatcher ArgumentY = 1111 declRefExpr(to(varDecl(hasName("y")))).bind("arg"); 1112 TypeMatcher IntType = qualType(isInteger()).bind("type"); 1113 StatementMatcher CallExpr = 1114 callExpr(forEachArgumentWithParamType(ArgumentY, IntType)); 1115 1116 EXPECT_TRUE(matchesC("void f();\n" 1117 "void call_it(void) { int x, y; f(x, y); }\n" 1118 "void f(a, b) int a, b; {}\n" 1119 "void call_it2(void) { int x, y; f(x, y); }", 1120 CallExpr)); 1121 } 1122 1123 TEST(ForEachArgumentWithParamType, HandlesBoundNodesForNonMatches) { 1124 EXPECT_TRUE(matchAndVerifyResultTrue( 1125 "void g(int i, int j) {" 1126 " int a;" 1127 " int b;" 1128 " int c;" 1129 " g(a, 0);" 1130 " g(a, b);" 1131 " g(0, b);" 1132 "}", 1133 functionDecl( 1134 forEachDescendant(varDecl().bind("v")), 1135 forEachDescendant(callExpr(forEachArgumentWithParamType( 1136 declRefExpr(to(decl(equalsBoundNode("v")))), qualType())))), 1137 std::make_unique<VerifyIdIsBoundTo<VarDecl>>("v", 4))); 1138 } 1139 1140 TEST(ForEachArgumentWithParamType, MatchesFunctionPtrCalls) { 1141 StatementMatcher ArgumentY = 1142 declRefExpr(to(varDecl(hasName("y")))).bind("arg"); 1143 TypeMatcher IntType = qualType(builtinType()).bind("type"); 1144 StatementMatcher CallExpr = 1145 callExpr(forEachArgumentWithParamType(ArgumentY, IntType)); 1146 1147 EXPECT_TRUE(matchAndVerifyResultTrue( 1148 "void f(int i) {" 1149 "void (*f_ptr)(int) = f; int y; f_ptr(y); }", 1150 CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type"))); 1151 EXPECT_TRUE(matchAndVerifyResultTrue( 1152 "void f(int i) {" 1153 "void (*f_ptr)(int) = f; int y; f_ptr(y); }", 1154 CallExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg"))); 1155 } 1156 1157 TEST(ForEachArgumentWithParamType, MatchesMemberFunctionPtrCalls) { 1158 StatementMatcher ArgumentY = 1159 declRefExpr(to(varDecl(hasName("y")))).bind("arg"); 1160 TypeMatcher IntType = qualType(builtinType()).bind("type"); 1161 StatementMatcher CallExpr = 1162 callExpr(forEachArgumentWithParamType(ArgumentY, IntType)); 1163 1164 StringRef S = "struct A {\n" 1165 " int f(int i) { return i + 1; }\n" 1166 " int (A::*x)(int);\n" 1167 "};\n" 1168 "void f() {\n" 1169 " int y = 42;\n" 1170 " A a;\n" 1171 " a.x = &A::f;\n" 1172 " (a.*(a.x))(y);\n" 1173 "}"; 1174 EXPECT_TRUE(matchAndVerifyResultTrue( 1175 S, CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type"))); 1176 EXPECT_TRUE(matchAndVerifyResultTrue( 1177 S, CallExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg"))); 1178 } 1179 1180 TEST(ForEachArgumentWithParamType, MatchesVariadicFunctionPtrCalls) { 1181 StatementMatcher ArgumentY = 1182 declRefExpr(to(varDecl(hasName("y")))).bind("arg"); 1183 TypeMatcher IntType = qualType(builtinType()).bind("type"); 1184 StatementMatcher CallExpr = 1185 callExpr(forEachArgumentWithParamType(ArgumentY, IntType)); 1186 1187 StringRef S = R"cpp( 1188 void fcntl(int fd, int cmd, ...) {} 1189 1190 template <typename Func> 1191 void f(Func F) { 1192 int y = 42; 1193 F(y, 1, 3); 1194 } 1195 1196 void g() { f(fcntl); } 1197 )cpp"; 1198 1199 EXPECT_TRUE(matchAndVerifyResultTrue( 1200 S, CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("type"))); 1201 EXPECT_TRUE(matchAndVerifyResultTrue( 1202 S, CallExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg"))); 1203 } 1204 1205 TEST_P(ASTMatchersTest, 1206 ForEachArgumentWithParamTypeMatchesExplicitObjectParamOnOperatorCalls) { 1207 if (!GetParam().isCXX23OrLater()) { 1208 return; 1209 } 1210 1211 auto DeclRef = declRefExpr(to(varDecl().bind("declOfArg"))).bind("arg"); 1212 auto SelfTy = qualType(asString("const A &")).bind("selfType"); 1213 StatementMatcher CallExpr = 1214 callExpr(forEachArgumentWithParamType(DeclRef, SelfTy)); 1215 1216 StringRef S = R"cpp( 1217 struct A { 1218 int operator()(this const A &self); 1219 }; 1220 A obj; 1221 int global = obj(); 1222 )cpp"; 1223 1224 auto Args = GetParam().getCommandLineArgs(); 1225 auto Filename = getFilenameForTesting(GetParam().Language); 1226 1227 EXPECT_TRUE(matchAndVerifyResultTrue( 1228 S, CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("selfType"), 1229 Args, Filename)); 1230 EXPECT_TRUE(matchAndVerifyResultTrue( 1231 S, CallExpr, 1232 std::make_unique<VerifyIdIsBoundTo<VarDecl>>("declOfArg", "obj"), Args, 1233 Filename)); 1234 } 1235 1236 TEST(QualType, hasCanonicalType) { 1237 EXPECT_TRUE(notMatches("typedef int &int_ref;" 1238 "int a;" 1239 "int_ref b = a;", 1240 varDecl(hasType(qualType(referenceType()))))); 1241 EXPECT_TRUE( 1242 matches("typedef int &int_ref;" 1243 "int a;" 1244 "int_ref b = a;", 1245 varDecl(hasType(qualType(hasCanonicalType(referenceType())))))); 1246 } 1247 1248 TEST(HasParameter, CallsInnerMatcher) { 1249 EXPECT_TRUE(matches("class X { void x(int) {} };", 1250 cxxMethodDecl(hasParameter(0, varDecl())))); 1251 EXPECT_TRUE(notMatches("class X { void x(int) {} };", 1252 cxxMethodDecl(hasParameter(0, hasName("x"))))); 1253 EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) x; @end", 1254 objcMethodDecl(hasParameter(0, hasName("x"))))); 1255 EXPECT_TRUE(matchesObjC("int main() { void (^b)(int) = ^(int p) {}; }", 1256 blockDecl(hasParameter(0, hasName("p"))))); 1257 } 1258 1259 TEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) { 1260 EXPECT_TRUE(notMatches("class X { void x(int) {} };", 1261 cxxMethodDecl(hasParameter(42, varDecl())))); 1262 } 1263 1264 TEST(HasType, MatchesParameterVariableTypesStrictly) { 1265 EXPECT_TRUE(matches( 1266 "class X { void x(X x) {} };", 1267 cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X"))))))); 1268 EXPECT_TRUE(notMatches( 1269 "class X { void x(const X &x) {} };", 1270 cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X"))))))); 1271 EXPECT_TRUE(matches("class X { void x(const X *x) {} };", 1272 cxxMethodDecl(hasParameter( 1273 0, hasType(pointsTo(recordDecl(hasName("X")))))))); 1274 EXPECT_TRUE(matches("class X { void x(const X &x) {} };", 1275 cxxMethodDecl(hasParameter( 1276 0, hasType(references(recordDecl(hasName("X")))))))); 1277 } 1278 1279 TEST(HasAnyParameter, MatchesIndependentlyOfPosition) { 1280 EXPECT_TRUE(matches( 1281 "class Y {}; class X { void x(X x, Y y) {} };", 1282 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X"))))))); 1283 EXPECT_TRUE(matches( 1284 "class Y {}; class X { void x(Y y, X x) {} };", 1285 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X"))))))); 1286 EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) x; @end", 1287 objcMethodDecl(hasAnyParameter(hasName("x"))))); 1288 EXPECT_TRUE(matchesObjC("int main() { void (^b)(int) = ^(int p) {}; }", 1289 blockDecl(hasAnyParameter(hasName("p"))))); 1290 } 1291 1292 TEST(Returns, MatchesReturnTypes) { 1293 EXPECT_TRUE(matches("class Y { int f() { return 1; } };", 1294 functionDecl(returns(asString("int"))))); 1295 EXPECT_TRUE(notMatches("class Y { int f() { return 1; } };", 1296 functionDecl(returns(asString("float"))))); 1297 EXPECT_TRUE(matches("class Y { Y getMe() { return *this; } };", 1298 functionDecl(returns(hasDeclaration( 1299 recordDecl(hasName("Y"))))))); 1300 } 1301 1302 TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) { 1303 EXPECT_TRUE(notMatches( 1304 "class Y {}; class X { void x(int) {} };", 1305 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X"))))))); 1306 } 1307 1308 TEST(HasAnyParameter, DoesNotMatchThisPointer) { 1309 EXPECT_TRUE(notMatches("class Y {}; class X { void x() {} };", 1310 cxxMethodDecl(hasAnyParameter( 1311 hasType(pointsTo(recordDecl(hasName("X")))))))); 1312 } 1313 1314 TEST(HasName, MatchesParameterVariableDeclarations) { 1315 EXPECT_TRUE(matches("class Y {}; class X { void x(int x) {} };", 1316 cxxMethodDecl(hasAnyParameter(hasName("x"))))); 1317 EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };", 1318 cxxMethodDecl(hasAnyParameter(hasName("x"))))); 1319 } 1320 1321 TEST(Matcher, MatchesTypeTemplateArgument) { 1322 EXPECT_TRUE(matches( 1323 "template<typename T> struct B {};" 1324 "B<int> b;", 1325 classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToType( 1326 asString("int")))))); 1327 } 1328 1329 TEST(Matcher, MatchesTemplateTemplateArgument) { 1330 EXPECT_TRUE(matches("template<template <typename> class S> class X {};" 1331 "template<typename T> class Y {};" 1332 "X<Y> xi;", 1333 classTemplateSpecializationDecl(hasAnyTemplateArgument( 1334 refersToTemplate(templateName()))))); 1335 } 1336 1337 TEST(Matcher, MatchesDeclarationReferenceTemplateArgument) { 1338 EXPECT_TRUE(matches( 1339 "struct B { int next; };" 1340 "template<int(B::*next_ptr)> struct A {};" 1341 "A<&B::next> a;", 1342 classTemplateSpecializationDecl(hasAnyTemplateArgument( 1343 refersToDeclaration(fieldDecl(hasName("next"))))))); 1344 1345 EXPECT_TRUE(notMatches( 1346 "template <typename T> struct A {};" 1347 "A<int> a;", 1348 classTemplateSpecializationDecl(hasAnyTemplateArgument( 1349 refersToDeclaration(decl()))))); 1350 1351 EXPECT_TRUE(matches( 1352 "struct B { int next; };" 1353 "template<int(B::*next_ptr)> struct A {};" 1354 "A<&B::next> a;", 1355 templateSpecializationType(hasAnyTemplateArgument(isExpr( 1356 hasDescendant(declRefExpr(to(fieldDecl(hasName("next")))))))))); 1357 1358 EXPECT_TRUE(notMatches( 1359 "template <typename T> struct A {};" 1360 "A<int> a;", 1361 templateSpecializationType(hasAnyTemplateArgument( 1362 refersToDeclaration(decl()))))); 1363 } 1364 1365 1366 TEST(Matcher, MatchesSpecificArgument) { 1367 EXPECT_TRUE(matches( 1368 "template<typename T, typename U> class A {};" 1369 "A<bool, int> a;", 1370 classTemplateSpecializationDecl(hasTemplateArgument( 1371 1, refersToType(asString("int")))))); 1372 EXPECT_TRUE(notMatches( 1373 "template<typename T, typename U> class A {};" 1374 "A<int, bool> a;", 1375 classTemplateSpecializationDecl(hasTemplateArgument( 1376 1, refersToType(asString("int")))))); 1377 1378 EXPECT_TRUE(matches( 1379 "template<typename T, typename U> class A {};" 1380 "A<bool, int> a;", 1381 templateSpecializationType(hasTemplateArgument( 1382 1, refersToType(asString("int")))))); 1383 EXPECT_TRUE(notMatches( 1384 "template<typename T, typename U> class A {};" 1385 "A<int, bool> a;", 1386 templateSpecializationType(hasTemplateArgument( 1387 1, refersToType(asString("int")))))); 1388 1389 EXPECT_TRUE(matches( 1390 "template<typename T> void f() {};" 1391 "void func() { f<int>(); }", 1392 functionDecl(hasTemplateArgument(0, refersToType(asString("int")))))); 1393 EXPECT_TRUE(notMatches( 1394 "template<typename T> void f() {};", 1395 functionDecl(hasTemplateArgument(0, refersToType(asString("int")))))); 1396 } 1397 1398 TEST(TemplateArgument, Matches) { 1399 EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;", 1400 classTemplateSpecializationDecl( 1401 hasAnyTemplateArgument(templateArgument())))); 1402 EXPECT_TRUE(matches( 1403 "template<typename T> struct C {}; C<int> c;", 1404 templateSpecializationType(hasAnyTemplateArgument(templateArgument())))); 1405 1406 EXPECT_TRUE(matches( 1407 "template<typename T> void f() {};" 1408 "void func() { f<int>(); }", 1409 functionDecl(hasAnyTemplateArgument(templateArgument())))); 1410 } 1411 1412 TEST(TemplateTypeParmDecl, CXXMethodDecl) { 1413 const char input[] = 1414 "template<typename T>\n" 1415 "class Class {\n" 1416 " void method();\n" 1417 "};\n" 1418 "template<typename U>\n" 1419 "void Class<U>::method() {}\n"; 1420 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T")))); 1421 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U")))); 1422 } 1423 1424 TEST(TemplateTypeParmDecl, VarDecl) { 1425 const char input[] = 1426 "template<typename T>\n" 1427 "class Class {\n" 1428 " static T pi;\n" 1429 "};\n" 1430 "template<typename U>\n" 1431 "U Class<U>::pi = U(3.1415926535897932385);\n"; 1432 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T")))); 1433 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U")))); 1434 } 1435 1436 TEST(TemplateTypeParmDecl, VarTemplatePartialSpecializationDecl) { 1437 const char input[] = 1438 "template<typename T>\n" 1439 "struct Struct {\n" 1440 " template<typename T2> static int field;\n" 1441 "};\n" 1442 "template<typename U>\n" 1443 "template<typename U2>\n" 1444 "int Struct<U>::field<U2*> = 123;\n"; 1445 EXPECT_TRUE( 1446 matches(input, templateTypeParmDecl(hasName("T")), langCxx14OrLater())); 1447 EXPECT_TRUE( 1448 matches(input, templateTypeParmDecl(hasName("T2")), langCxx14OrLater())); 1449 EXPECT_TRUE( 1450 matches(input, templateTypeParmDecl(hasName("U")), langCxx14OrLater())); 1451 EXPECT_TRUE( 1452 matches(input, templateTypeParmDecl(hasName("U2")), langCxx14OrLater())); 1453 } 1454 1455 TEST(TemplateTypeParmDecl, ClassTemplatePartialSpecializationDecl) { 1456 const char input[] = 1457 "template<typename T>\n" 1458 "class Class {\n" 1459 " template<typename T2> struct Struct;\n" 1460 "};\n" 1461 "template<typename U>\n" 1462 "template<typename U2>\n" 1463 "struct Class<U>::Struct<U2*> {};\n"; 1464 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T")))); 1465 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T2")))); 1466 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U")))); 1467 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U2")))); 1468 } 1469 1470 TEST(TemplateTypeParmDecl, EnumDecl) { 1471 const char input[] = 1472 "template<typename T>\n" 1473 "struct Struct {\n" 1474 " enum class Enum : T;\n" 1475 "};\n" 1476 "template<typename U>\n" 1477 "enum class Struct<U>::Enum : U {\n" 1478 " e1,\n" 1479 " e2\n" 1480 "};\n"; 1481 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T")))); 1482 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U")))); 1483 } 1484 1485 TEST(TemplateTypeParmDecl, RecordDecl) { 1486 const char input[] = 1487 "template<typename T>\n" 1488 "class Class {\n" 1489 " struct Struct;\n" 1490 "};\n" 1491 "template<typename U>\n" 1492 "struct Class<U>::Struct {\n" 1493 " U field;\n" 1494 "};\n"; 1495 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("T")))); 1496 EXPECT_TRUE(matches(input, templateTypeParmDecl(hasName("U")))); 1497 } 1498 1499 TEST(RefersToIntegralType, Matches) { 1500 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;", 1501 classTemplateSpecializationDecl( 1502 hasAnyTemplateArgument(refersToIntegralType( 1503 asString("int")))))); 1504 EXPECT_TRUE(notMatches("template<unsigned T> struct C {}; C<42> c;", 1505 classTemplateSpecializationDecl(hasAnyTemplateArgument( 1506 refersToIntegralType(asString("int")))))); 1507 } 1508 1509 TEST(ConstructorDeclaration, SimpleCase) { 1510 EXPECT_TRUE(matches("class Foo { Foo(int i); };", 1511 cxxConstructorDecl(ofClass(hasName("Foo"))))); 1512 EXPECT_TRUE(notMatches("class Foo { Foo(int i); };", 1513 cxxConstructorDecl(ofClass(hasName("Bar"))))); 1514 } 1515 1516 TEST(DestructorDeclaration, MatchesVirtualDestructor) { 1517 EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };", 1518 cxxDestructorDecl(ofClass(hasName("Foo"))))); 1519 } 1520 1521 TEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) { 1522 EXPECT_TRUE(notMatches("class Foo {};", 1523 cxxDestructorDecl(ofClass(hasName("Foo"))))); 1524 } 1525 1526 TEST(HasAnyConstructorInitializer, SimpleCase) { 1527 EXPECT_TRUE( 1528 notMatches("class Foo { Foo() { } };", 1529 cxxConstructorDecl(hasAnyConstructorInitializer(anything())))); 1530 EXPECT_TRUE( 1531 matches("class Foo {" 1532 " Foo() : foo_() { }" 1533 " int foo_;" 1534 "};", 1535 cxxConstructorDecl(hasAnyConstructorInitializer(anything())))); 1536 } 1537 1538 TEST(HasAnyConstructorInitializer, ForField) { 1539 static const char Code[] = 1540 "class Baz { };" 1541 "class Foo {" 1542 " Foo() : foo_(), bar_() { }" 1543 " Baz foo_;" 1544 " struct {" 1545 " Baz bar_;" 1546 " };" 1547 "};"; 1548 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( 1549 forField(hasType(recordDecl(hasName("Baz")))))))); 1550 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( 1551 forField(hasName("foo_")))))); 1552 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( 1553 forField(hasName("bar_")))))); 1554 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( 1555 forField(hasType(recordDecl(hasName("Bar")))))))); 1556 } 1557 1558 TEST(HasAnyConstructorInitializer, WithInitializer) { 1559 static const char Code[] = 1560 "class Foo {" 1561 " Foo() : foo_(0) { }" 1562 " int foo_;" 1563 "};"; 1564 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( 1565 withInitializer(integerLiteral(equals(0))))))); 1566 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( 1567 withInitializer(integerLiteral(equals(1))))))); 1568 } 1569 1570 TEST(HasAnyConstructorInitializer, IsWritten) { 1571 static const char Code[] = 1572 "struct Bar { Bar(){} };" 1573 "class Foo {" 1574 " Foo() : foo_() { }" 1575 " Bar foo_;" 1576 " Bar bar_;" 1577 "};"; 1578 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( 1579 allOf(forField(hasName("foo_")), isWritten()))))); 1580 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( 1581 allOf(forField(hasName("bar_")), isWritten()))))); 1582 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer( 1583 allOf(forField(hasName("bar_")), unless(isWritten())))))); 1584 } 1585 1586 TEST(HasAnyConstructorInitializer, IsBaseInitializer) { 1587 static const char Code[] = 1588 "struct B {};" 1589 "struct D : B {" 1590 " int I;" 1591 " D(int i) : I(i) {}" 1592 "};" 1593 "struct E : B {" 1594 " E() : B() {}" 1595 "};"; 1596 EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf( 1597 hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())), 1598 hasName("E"))))); 1599 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf( 1600 hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())), 1601 hasName("D"))))); 1602 EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf( 1603 hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())), 1604 hasName("D"))))); 1605 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf( 1606 hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())), 1607 hasName("E"))))); 1608 } 1609 1610 TEST(IfStmt, ChildTraversalMatchers) { 1611 EXPECT_TRUE(matches("void f() { if (false) true; else false; }", 1612 ifStmt(hasThen(cxxBoolLiteral(equals(true)))))); 1613 EXPECT_TRUE(notMatches("void f() { if (false) false; else true; }", 1614 ifStmt(hasThen(cxxBoolLiteral(equals(true)))))); 1615 EXPECT_TRUE(matches("void f() { if (false) false; else true; }", 1616 ifStmt(hasElse(cxxBoolLiteral(equals(true)))))); 1617 EXPECT_TRUE(notMatches("void f() { if (false) true; else false; }", 1618 ifStmt(hasElse(cxxBoolLiteral(equals(true)))))); 1619 } 1620 1621 TEST(MatchBinaryOperator, HasOperatorName) { 1622 StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||")); 1623 1624 EXPECT_TRUE(matches("void x() { true || false; }", OperatorOr)); 1625 EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr)); 1626 } 1627 1628 TEST(MatchBinaryOperator, HasAnyOperatorName) { 1629 StatementMatcher Matcher = 1630 binaryOperator(hasAnyOperatorName("+", "-", "*", "/")); 1631 1632 EXPECT_TRUE(matches("int x(int I) { return I + 2; }", Matcher)); 1633 EXPECT_TRUE(matches("int x(int I) { return I - 2; }", Matcher)); 1634 EXPECT_TRUE(matches("int x(int I) { return I * 2; }", Matcher)); 1635 EXPECT_TRUE(matches("int x(int I) { return I / 2; }", Matcher)); 1636 EXPECT_TRUE(notMatches("int x(int I) { return I % 2; }", Matcher)); 1637 // Ensure '+= isn't mistaken. 1638 EXPECT_TRUE(notMatches("void x(int &I) { I += 1; }", Matcher)); 1639 } 1640 1641 TEST(MatchBinaryOperator, HasLHSAndHasRHS) { 1642 StatementMatcher OperatorTrueFalse = 1643 binaryOperator(hasLHS(cxxBoolLiteral(equals(true))), 1644 hasRHS(cxxBoolLiteral(equals(false)))); 1645 1646 EXPECT_TRUE(matches("void x() { true || false; }", OperatorTrueFalse)); 1647 EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse)); 1648 EXPECT_TRUE(notMatches("void x() { false || true; }", OperatorTrueFalse)); 1649 1650 StatementMatcher OperatorIntPointer = arraySubscriptExpr( 1651 hasLHS(hasType(isInteger())), 1652 traverse(TK_AsIs, hasRHS(hasType(pointsTo(qualType()))))); 1653 EXPECT_TRUE(matches("void x() { 1[\"abc\"]; }", OperatorIntPointer)); 1654 EXPECT_TRUE(notMatches("void x() { \"abc\"[1]; }", OperatorIntPointer)); 1655 1656 StringRef Code = R"cpp( 1657 struct HasOpEqMem 1658 { 1659 bool operator==(const HasOpEqMem& other) const 1660 { 1661 return true; 1662 } 1663 }; 1664 1665 struct HasOpFree 1666 { 1667 }; 1668 bool operator==(const HasOpFree& lhs, const HasOpFree& rhs) 1669 { 1670 return true; 1671 } 1672 1673 void opMem() 1674 { 1675 HasOpEqMem s1; 1676 HasOpEqMem s2; 1677 if (s1 == s2) 1678 return; 1679 } 1680 1681 void opFree() 1682 { 1683 HasOpFree s1; 1684 HasOpFree s2; 1685 if (s1 == s2) 1686 return; 1687 } 1688 )cpp"; 1689 auto s1Expr = declRefExpr(to(varDecl(hasName("s1")))); 1690 auto s2Expr = declRefExpr(to(varDecl(hasName("s2")))); 1691 EXPECT_TRUE(matches( 1692 Code, 1693 traverse(TK_IgnoreUnlessSpelledInSource, 1694 cxxOperatorCallExpr(forFunction(functionDecl(hasName("opMem"))), 1695 hasOperatorName("=="), hasLHS(s1Expr), 1696 hasRHS(s2Expr))))); 1697 EXPECT_TRUE(matches( 1698 Code, traverse(TK_IgnoreUnlessSpelledInSource, 1699 cxxOperatorCallExpr( 1700 forFunction(functionDecl(hasName("opMem"))), 1701 hasAnyOperatorName("!=", "=="), hasLHS(s1Expr))))); 1702 EXPECT_TRUE(matches( 1703 Code, traverse(TK_IgnoreUnlessSpelledInSource, 1704 cxxOperatorCallExpr( 1705 forFunction(functionDecl(hasName("opMem"))), 1706 hasOperatorName("=="), hasOperands(s1Expr, s2Expr))))); 1707 EXPECT_TRUE(matches( 1708 Code, traverse(TK_IgnoreUnlessSpelledInSource, 1709 cxxOperatorCallExpr( 1710 forFunction(functionDecl(hasName("opMem"))), 1711 hasOperatorName("=="), hasEitherOperand(s2Expr))))); 1712 1713 EXPECT_TRUE(matches( 1714 Code, 1715 traverse(TK_IgnoreUnlessSpelledInSource, 1716 cxxOperatorCallExpr(forFunction(functionDecl(hasName("opFree"))), 1717 hasOperatorName("=="), hasLHS(s1Expr), 1718 hasRHS(s2Expr))))); 1719 EXPECT_TRUE(matches( 1720 Code, traverse(TK_IgnoreUnlessSpelledInSource, 1721 cxxOperatorCallExpr( 1722 forFunction(functionDecl(hasName("opFree"))), 1723 hasAnyOperatorName("!=", "=="), hasLHS(s1Expr))))); 1724 EXPECT_TRUE(matches( 1725 Code, traverse(TK_IgnoreUnlessSpelledInSource, 1726 cxxOperatorCallExpr( 1727 forFunction(functionDecl(hasName("opFree"))), 1728 hasOperatorName("=="), hasOperands(s1Expr, s2Expr))))); 1729 EXPECT_TRUE(matches( 1730 Code, traverse(TK_IgnoreUnlessSpelledInSource, 1731 cxxOperatorCallExpr( 1732 forFunction(functionDecl(hasName("opFree"))), 1733 hasOperatorName("=="), hasEitherOperand(s2Expr))))); 1734 } 1735 1736 TEST(MatchBinaryOperator, HasEitherOperand) { 1737 StatementMatcher HasOperand = 1738 binaryOperator(hasEitherOperand(cxxBoolLiteral(equals(false)))); 1739 1740 EXPECT_TRUE(matches("void x() { true || false; }", HasOperand)); 1741 EXPECT_TRUE(matches("void x() { false && true; }", HasOperand)); 1742 EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand)); 1743 } 1744 1745 TEST(MatchBinaryOperator, HasOperands) { 1746 StatementMatcher HasOperands = binaryOperator( 1747 hasOperands(integerLiteral(equals(1)), integerLiteral(equals(2)))); 1748 EXPECT_TRUE(matches("void x() { 1 + 2; }", HasOperands)); 1749 EXPECT_TRUE(matches("void x() { 2 + 1; }", HasOperands)); 1750 EXPECT_TRUE(notMatches("void x() { 1 + 1; }", HasOperands)); 1751 EXPECT_TRUE(notMatches("void x() { 2 + 2; }", HasOperands)); 1752 EXPECT_TRUE(notMatches("void x() { 0 + 0; }", HasOperands)); 1753 EXPECT_TRUE(notMatches("void x() { 0 + 1; }", HasOperands)); 1754 } 1755 1756 TEST(MatchBinaryOperator, HasOperandsEnsureOrdering) { 1757 StatementMatcher HasOperandsWithBindings = binaryOperator(hasOperands( 1758 cStyleCastExpr(has(declRefExpr(hasDeclaration(valueDecl().bind("d"))))), 1759 declRefExpr(hasDeclaration(valueDecl(equalsBoundNode("d")))))); 1760 EXPECT_TRUE(matches( 1761 "int a; int b = ((int) a) + a;", 1762 traverse(TK_IgnoreUnlessSpelledInSource, HasOperandsWithBindings))); 1763 EXPECT_TRUE(matches( 1764 "int a; int b = a + ((int) a);", 1765 traverse(TK_IgnoreUnlessSpelledInSource, HasOperandsWithBindings))); 1766 } 1767 1768 TEST(Matcher, BinaryOperatorTypes) { 1769 // Integration test that verifies the AST provides all binary operators in 1770 // a way we expect. 1771 // FIXME: Operator ',' 1772 EXPECT_TRUE( 1773 matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(",")))); 1774 EXPECT_TRUE( 1775 matches("bool b; bool c = (b = true);", 1776 binaryOperator(hasOperatorName("=")))); 1777 EXPECT_TRUE( 1778 matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!=")))); 1779 EXPECT_TRUE( 1780 matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("==")))); 1781 EXPECT_TRUE(matches("bool b = 1 < 2;", binaryOperator(hasOperatorName("<")))); 1782 EXPECT_TRUE( 1783 matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<=")))); 1784 EXPECT_TRUE( 1785 matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<")))); 1786 EXPECT_TRUE( 1787 matches("int i = 1; int j = (i <<= 2);", 1788 binaryOperator(hasOperatorName("<<=")))); 1789 EXPECT_TRUE(matches("bool b = 1 > 2;", binaryOperator(hasOperatorName(">")))); 1790 EXPECT_TRUE( 1791 matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">=")))); 1792 EXPECT_TRUE( 1793 matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>")))); 1794 EXPECT_TRUE( 1795 matches("int i = 1; int j = (i >>= 2);", 1796 binaryOperator(hasOperatorName(">>=")))); 1797 EXPECT_TRUE( 1798 matches("int i = 42 ^ 23;", binaryOperator(hasOperatorName("^")))); 1799 EXPECT_TRUE( 1800 matches("int i = 42; int j = (i ^= 42);", 1801 binaryOperator(hasOperatorName("^=")))); 1802 EXPECT_TRUE( 1803 matches("int i = 42 % 23;", binaryOperator(hasOperatorName("%")))); 1804 EXPECT_TRUE( 1805 matches("int i = 42; int j = (i %= 42);", 1806 binaryOperator(hasOperatorName("%=")))); 1807 EXPECT_TRUE( 1808 matches("bool b = 42 &23;", binaryOperator(hasOperatorName("&")))); 1809 EXPECT_TRUE( 1810 matches("bool b = true && false;", 1811 binaryOperator(hasOperatorName("&&")))); 1812 EXPECT_TRUE( 1813 matches("bool b = true; bool c = (b &= false);", 1814 binaryOperator(hasOperatorName("&=")))); 1815 EXPECT_TRUE( 1816 matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|")))); 1817 EXPECT_TRUE( 1818 matches("bool b = true || false;", 1819 binaryOperator(hasOperatorName("||")))); 1820 EXPECT_TRUE( 1821 matches("bool b = true; bool c = (b |= false);", 1822 binaryOperator(hasOperatorName("|=")))); 1823 EXPECT_TRUE( 1824 matches("int i = 42 *23;", binaryOperator(hasOperatorName("*")))); 1825 EXPECT_TRUE( 1826 matches("int i = 42; int j = (i *= 23);", 1827 binaryOperator(hasOperatorName("*=")))); 1828 EXPECT_TRUE( 1829 matches("int i = 42 / 23;", binaryOperator(hasOperatorName("/")))); 1830 EXPECT_TRUE( 1831 matches("int i = 42; int j = (i /= 23);", 1832 binaryOperator(hasOperatorName("/=")))); 1833 EXPECT_TRUE( 1834 matches("int i = 42 + 23;", binaryOperator(hasOperatorName("+")))); 1835 EXPECT_TRUE( 1836 matches("int i = 42; int j = (i += 23);", 1837 binaryOperator(hasOperatorName("+=")))); 1838 EXPECT_TRUE( 1839 matches("int i = 42 - 23;", binaryOperator(hasOperatorName("-")))); 1840 EXPECT_TRUE( 1841 matches("int i = 42; int j = (i -= 23);", 1842 binaryOperator(hasOperatorName("-=")))); 1843 EXPECT_TRUE( 1844 matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };", 1845 binaryOperator(hasOperatorName("->*")))); 1846 EXPECT_TRUE( 1847 matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };", 1848 binaryOperator(hasOperatorName(".*")))); 1849 1850 // Member expressions as operators are not supported in matches. 1851 EXPECT_TRUE( 1852 notMatches("struct A { void x(A *a) { a->x(this); } };", 1853 binaryOperator(hasOperatorName("->")))); 1854 1855 // Initializer assignments are not represented as operator equals. 1856 EXPECT_TRUE( 1857 notMatches("bool b = true;", binaryOperator(hasOperatorName("=")))); 1858 1859 // Array indexing is not represented as operator. 1860 EXPECT_TRUE(notMatches("int a[42]; void x() { a[23]; }", unaryOperator())); 1861 1862 // Overloaded operators do not match at all. 1863 EXPECT_TRUE(notMatches( 1864 "struct A { bool operator&&(const A &a) const { return false; } };" 1865 "void x() { A a, b; a && b; }", 1866 binaryOperator())); 1867 } 1868 1869 TEST(MatchUnaryOperator, HasOperatorName) { 1870 StatementMatcher OperatorNot = unaryOperator(hasOperatorName("!")); 1871 1872 EXPECT_TRUE(matches("void x() { !true; } ", OperatorNot)); 1873 EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot)); 1874 } 1875 1876 TEST(MatchUnaryOperator, HasAnyOperatorName) { 1877 StatementMatcher Matcher = unaryOperator(hasAnyOperatorName("-", "*", "++")); 1878 1879 EXPECT_TRUE(matches("int x(int *I) { return *I; }", Matcher)); 1880 EXPECT_TRUE(matches("int x(int I) { return -I; }", Matcher)); 1881 EXPECT_TRUE(matches("void x(int &I) { I++; }", Matcher)); 1882 EXPECT_TRUE(matches("void x(int &I) { ++I; }", Matcher)); 1883 EXPECT_TRUE(notMatches("void x(int &I) { I--; }", Matcher)); 1884 EXPECT_TRUE(notMatches("void x(int &I) { --I; }", Matcher)); 1885 EXPECT_TRUE(notMatches("int *x(int &I) { return &I; }", Matcher)); 1886 } 1887 1888 TEST(MatchUnaryOperator, HasUnaryOperand) { 1889 StatementMatcher OperatorOnFalse = 1890 unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false)))); 1891 1892 EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse)); 1893 EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse)); 1894 1895 StringRef Code = R"cpp( 1896 struct HasOpBangMem 1897 { 1898 bool operator!() const 1899 { 1900 return false; 1901 } 1902 }; 1903 struct HasOpBangFree 1904 { 1905 }; 1906 bool operator!(HasOpBangFree const&) 1907 { 1908 return false; 1909 } 1910 1911 void opMem() 1912 { 1913 HasOpBangMem s1; 1914 if (!s1) 1915 return; 1916 } 1917 void opFree() 1918 { 1919 HasOpBangFree s1; 1920 if (!s1) 1921 return; 1922 } 1923 )cpp"; 1924 auto s1Expr = declRefExpr(to(varDecl(hasName("s1")))); 1925 EXPECT_TRUE(matches( 1926 Code, traverse(TK_IgnoreUnlessSpelledInSource, 1927 cxxOperatorCallExpr( 1928 forFunction(functionDecl(hasName("opMem"))), 1929 hasOperatorName("!"), hasUnaryOperand(s1Expr))))); 1930 EXPECT_TRUE(matches( 1931 Code, 1932 traverse(TK_IgnoreUnlessSpelledInSource, 1933 cxxOperatorCallExpr(forFunction(functionDecl(hasName("opMem"))), 1934 hasAnyOperatorName("+", "!"), 1935 hasUnaryOperand(s1Expr))))); 1936 1937 EXPECT_TRUE(matches( 1938 Code, traverse(TK_IgnoreUnlessSpelledInSource, 1939 cxxOperatorCallExpr( 1940 forFunction(functionDecl(hasName("opFree"))), 1941 hasOperatorName("!"), hasUnaryOperand(s1Expr))))); 1942 EXPECT_TRUE(matches( 1943 Code, 1944 traverse(TK_IgnoreUnlessSpelledInSource, 1945 cxxOperatorCallExpr(forFunction(functionDecl(hasName("opFree"))), 1946 hasAnyOperatorName("+", "!"), 1947 hasUnaryOperand(s1Expr))))); 1948 1949 Code = R"cpp( 1950 struct HasIncOperatorsMem 1951 { 1952 HasIncOperatorsMem& operator++(); 1953 HasIncOperatorsMem operator++(int); 1954 }; 1955 struct HasIncOperatorsFree 1956 { 1957 }; 1958 HasIncOperatorsFree& operator++(HasIncOperatorsFree&); 1959 HasIncOperatorsFree operator++(HasIncOperatorsFree&, int); 1960 1961 void prefixIncOperatorMem() 1962 { 1963 HasIncOperatorsMem s1; 1964 ++s1; 1965 } 1966 void prefixIncOperatorFree() 1967 { 1968 HasIncOperatorsFree s1; 1969 ++s1; 1970 } 1971 void postfixIncOperatorMem() 1972 { 1973 HasIncOperatorsMem s1; 1974 s1++; 1975 } 1976 void postfixIncOperatorFree() 1977 { 1978 HasIncOperatorsFree s1; 1979 s1++; 1980 } 1981 1982 struct HasOpPlusInt 1983 { 1984 HasOpPlusInt& operator+(int); 1985 }; 1986 void plusIntOperator() 1987 { 1988 HasOpPlusInt s1; 1989 s1+1; 1990 } 1991 )cpp"; 1992 1993 EXPECT_TRUE(matches( 1994 Code, 1995 traverse(TK_IgnoreUnlessSpelledInSource, 1996 cxxOperatorCallExpr( 1997 forFunction(functionDecl(hasName("prefixIncOperatorMem"))), 1998 hasOperatorName("++"), hasUnaryOperand(declRefExpr()))))); 1999 2000 EXPECT_TRUE(matches( 2001 Code, 2002 traverse(TK_IgnoreUnlessSpelledInSource, 2003 cxxOperatorCallExpr( 2004 forFunction(functionDecl(hasName("prefixIncOperatorFree"))), 2005 hasOperatorName("++"), hasUnaryOperand(declRefExpr()))))); 2006 2007 EXPECT_TRUE(matches( 2008 Code, 2009 traverse(TK_IgnoreUnlessSpelledInSource, 2010 cxxOperatorCallExpr( 2011 forFunction(functionDecl(hasName("postfixIncOperatorMem"))), 2012 hasOperatorName("++"), hasUnaryOperand(declRefExpr()))))); 2013 2014 EXPECT_TRUE(matches( 2015 Code, 2016 traverse(TK_IgnoreUnlessSpelledInSource, 2017 cxxOperatorCallExpr( 2018 forFunction(functionDecl(hasName("postfixIncOperatorFree"))), 2019 hasOperatorName("++"), hasUnaryOperand(declRefExpr()))))); 2020 2021 EXPECT_FALSE(matches( 2022 Code, traverse(TK_IgnoreUnlessSpelledInSource, 2023 cxxOperatorCallExpr( 2024 forFunction(functionDecl(hasName("plusIntOperator"))), 2025 hasOperatorName("+"), hasUnaryOperand(expr()))))); 2026 2027 Code = R"cpp( 2028 struct HasOpArrow 2029 { 2030 int& operator*(); 2031 }; 2032 void foo() 2033 { 2034 HasOpArrow s1; 2035 *s1; 2036 } 2037 )cpp"; 2038 2039 EXPECT_TRUE( 2040 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, 2041 cxxOperatorCallExpr(hasOperatorName("*"), 2042 hasUnaryOperand(expr()))))); 2043 } 2044 2045 TEST(Matcher, UnaryOperatorTypes) { 2046 // Integration test that verifies the AST provides all unary operators in 2047 // a way we expect. 2048 EXPECT_TRUE(matches("bool b = !true;", unaryOperator(hasOperatorName("!")))); 2049 EXPECT_TRUE( 2050 matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&")))); 2051 EXPECT_TRUE(matches("int i = ~ 1;", unaryOperator(hasOperatorName("~")))); 2052 EXPECT_TRUE( 2053 matches("bool *p; bool b = *p;", unaryOperator(hasOperatorName("*")))); 2054 EXPECT_TRUE( 2055 matches("int i; int j = +i;", unaryOperator(hasOperatorName("+")))); 2056 EXPECT_TRUE( 2057 matches("int i; int j = -i;", unaryOperator(hasOperatorName("-")))); 2058 EXPECT_TRUE( 2059 matches("int i; int j = ++i;", unaryOperator(hasOperatorName("++")))); 2060 EXPECT_TRUE( 2061 matches("int i; int j = i++;", unaryOperator(hasOperatorName("++")))); 2062 EXPECT_TRUE( 2063 matches("int i; int j = --i;", unaryOperator(hasOperatorName("--")))); 2064 EXPECT_TRUE( 2065 matches("int i; int j = i--;", unaryOperator(hasOperatorName("--")))); 2066 2067 // We don't match conversion operators. 2068 EXPECT_TRUE(notMatches("int i; double d = (double)i;", unaryOperator())); 2069 2070 // Function calls are not represented as operator. 2071 EXPECT_TRUE(notMatches("void f(); void x() { f(); }", unaryOperator())); 2072 2073 // Overloaded operators do not match at all. 2074 // FIXME: We probably want to add that. 2075 EXPECT_TRUE(notMatches( 2076 "struct A { bool operator!() const { return false; } };" 2077 "void x() { A a; !a; }", unaryOperator(hasOperatorName("!")))); 2078 } 2079 2080 TEST_P(ASTMatchersTest, HasInit) { 2081 if (!GetParam().isCXX11OrLater()) { 2082 // FIXME: Add a test for `hasInit()` that does not depend on C++. 2083 return; 2084 } 2085 2086 EXPECT_TRUE(matches("int x{0};", initListExpr(hasInit(0, expr())))); 2087 EXPECT_FALSE(matches("int x{0};", initListExpr(hasInit(1, expr())))); 2088 EXPECT_FALSE(matches("int x;", initListExpr(hasInit(0, expr())))); 2089 } 2090 2091 TEST_P(ASTMatchersTest, HasFoldInit) { 2092 if (!GetParam().isCXX17OrLater()) { 2093 return; 2094 } 2095 2096 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { " 2097 "return (0 + ... + args); }", 2098 cxxFoldExpr(hasFoldInit(expr())))); 2099 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { " 2100 "return (args + ... + 0); }", 2101 cxxFoldExpr(hasFoldInit(expr())))); 2102 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { " 2103 "return (... + args); };", 2104 cxxFoldExpr(hasFoldInit(expr())))); 2105 } 2106 2107 TEST_P(ASTMatchersTest, HasPattern) { 2108 if (!GetParam().isCXX17OrLater()) { 2109 return; 2110 } 2111 2112 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { " 2113 "return (0 + ... + args); }", 2114 cxxFoldExpr(hasPattern(expr())))); 2115 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { " 2116 "return (args + ... + 0); }", 2117 cxxFoldExpr(hasPattern(expr())))); 2118 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { " 2119 "return (... + args); };", 2120 cxxFoldExpr(hasPattern(expr())))); 2121 } 2122 2123 TEST_P(ASTMatchersTest, HasLHSAndHasRHS) { 2124 if (!GetParam().isCXX17OrLater()) { 2125 return; 2126 } 2127 2128 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { " 2129 "return (0 + ... + args); }", 2130 cxxFoldExpr(hasLHS(expr())))); 2131 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { " 2132 "return (args + ... + 0); }", 2133 cxxFoldExpr(hasLHS(expr())))); 2134 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { " 2135 "return (... + args); };", 2136 cxxFoldExpr(hasLHS(expr())))); 2137 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { " 2138 "return (args + ...); };", 2139 cxxFoldExpr(hasLHS(expr())))); 2140 2141 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { " 2142 "return (0 + ... + args); }", 2143 cxxFoldExpr(hasRHS(expr())))); 2144 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { " 2145 "return (args + ... + 0); }", 2146 cxxFoldExpr(hasRHS(expr())))); 2147 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { " 2148 "return (... + args); };", 2149 cxxFoldExpr(hasRHS(expr())))); 2150 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { " 2151 "return (args + ...); };", 2152 cxxFoldExpr(hasRHS(expr())))); 2153 } 2154 2155 TEST_P(ASTMatchersTest, HasEitherOperandAndHasOperands) { 2156 if (!GetParam().isCXX17OrLater()) { 2157 return; 2158 } 2159 2160 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { " 2161 "return (0 + ... + args); }", 2162 cxxFoldExpr(hasEitherOperand(integerLiteral())))); 2163 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { " 2164 "return (args + ... + 0); }", 2165 cxxFoldExpr(hasEitherOperand(integerLiteral())))); 2166 2167 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { " 2168 "return (0 + ... + args); }", 2169 cxxFoldExpr(hasEitherOperand( 2170 declRefExpr(to(namedDecl(hasName("args")))))))); 2171 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { " 2172 "return (args + ... + 0); }", 2173 cxxFoldExpr(hasEitherOperand( 2174 declRefExpr(to(namedDecl(hasName("args")))))))); 2175 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { " 2176 "return (... + args); };", 2177 cxxFoldExpr(hasEitherOperand( 2178 declRefExpr(to(namedDecl(hasName("args")))))))); 2179 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { " 2180 "return (args + ...); };", 2181 cxxFoldExpr(hasEitherOperand( 2182 declRefExpr(to(namedDecl(hasName("args")))))))); 2183 2184 EXPECT_TRUE(matches( 2185 "template <typename... Args> auto sum(Args... args) { " 2186 "return (0 + ... + args); }", 2187 cxxFoldExpr(hasOperands(declRefExpr(to(namedDecl(hasName("args")))), 2188 integerLiteral())))); 2189 EXPECT_TRUE(matches( 2190 "template <typename... Args> auto sum(Args... args) { " 2191 "return (args + ... + 0); }", 2192 cxxFoldExpr(hasOperands(declRefExpr(to(namedDecl(hasName("args")))), 2193 integerLiteral())))); 2194 EXPECT_FALSE(matches( 2195 "template <typename... Args> auto sum(Args... args) { " 2196 "return (... + args); };", 2197 cxxFoldExpr(hasOperands(declRefExpr(to(namedDecl(hasName("args")))), 2198 integerLiteral())))); 2199 EXPECT_FALSE(matches( 2200 "template <typename... Args> auto sum(Args... args) { " 2201 "return (args + ...); };", 2202 cxxFoldExpr(hasOperands(declRefExpr(to(namedDecl(hasName("args")))), 2203 integerLiteral())))); 2204 } 2205 2206 TEST_P(ASTMatchersTest, Callee) { 2207 if (!GetParam().isCXX17OrLater()) { 2208 return; 2209 } 2210 2211 EXPECT_TRUE(matches( 2212 "struct Dummy {}; Dummy operator+(Dummy, Dummy); template " 2213 "<typename... Args> auto sum(Args... args) { return (0 + ... + args); }", 2214 cxxFoldExpr(callee(expr())))); 2215 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { " 2216 "return (0 + ... + args); }", 2217 cxxFoldExpr(callee(expr())))); 2218 } 2219 2220 TEST(ArraySubscriptMatchers, ArrayIndex) { 2221 EXPECT_TRUE(matches( 2222 "int i[2]; void f() { i[1] = 1; }", 2223 arraySubscriptExpr(hasIndex(integerLiteral(equals(1)))))); 2224 EXPECT_TRUE(matches( 2225 "int i[2]; void f() { 1[i] = 1; }", 2226 arraySubscriptExpr(hasIndex(integerLiteral(equals(1)))))); 2227 EXPECT_TRUE(notMatches( 2228 "int i[2]; void f() { i[1] = 1; }", 2229 arraySubscriptExpr(hasIndex(integerLiteral(equals(0)))))); 2230 } 2231 2232 TEST(ArraySubscriptMatchers, MatchesArrayBase) { 2233 EXPECT_TRUE( 2234 matches("int i[2]; void f() { i[1] = 2; }", 2235 traverse(TK_AsIs, arraySubscriptExpr(hasBase(implicitCastExpr( 2236 hasSourceExpression(declRefExpr()))))))); 2237 } 2238 2239 TEST(Matcher, OfClass) { 2240 StatementMatcher Constructor = cxxConstructExpr(hasDeclaration(cxxMethodDecl( 2241 ofClass(hasName("X"))))); 2242 2243 EXPECT_TRUE( 2244 matches("class X { public: X(); }; void x(int) { X x; }", Constructor)); 2245 EXPECT_TRUE( 2246 matches("class X { public: X(); }; void x(int) { X x = X(); }", 2247 Constructor)); 2248 EXPECT_TRUE( 2249 notMatches("class Y { public: Y(); }; void x(int) { Y y; }", 2250 Constructor)); 2251 } 2252 2253 TEST(Matcher, VisitsTemplateInstantiations) { 2254 EXPECT_TRUE(matches( 2255 "class A { public: void x(); };" 2256 "template <typename T> class B { public: void y() { T t; t.x(); } };" 2257 "void f() { B<A> b; b.y(); }", 2258 callExpr(callee(cxxMethodDecl(hasName("x")))))); 2259 2260 EXPECT_TRUE(matches( 2261 "class A { public: void x(); };" 2262 "class C {" 2263 " public:" 2264 " template <typename T> class B { public: void y() { T t; t.x(); } };" 2265 "};" 2266 "void f() {" 2267 " C::B<A> b; b.y();" 2268 "}", 2269 recordDecl(hasName("C"), hasDescendant(callExpr( 2270 callee(cxxMethodDecl(hasName("x")))))))); 2271 } 2272 2273 TEST(Matcher, HasCondition) { 2274 StatementMatcher IfStmt = 2275 ifStmt(hasCondition(cxxBoolLiteral(equals(true)))); 2276 EXPECT_TRUE(matches("void x() { if (true) {} }", IfStmt)); 2277 EXPECT_TRUE(notMatches("void x() { if (false) {} }", IfStmt)); 2278 2279 StatementMatcher ForStmt = 2280 forStmt(hasCondition(cxxBoolLiteral(equals(true)))); 2281 EXPECT_TRUE(matches("void x() { for (;true;) {} }", ForStmt)); 2282 EXPECT_TRUE(notMatches("void x() { for (;false;) {} }", ForStmt)); 2283 2284 StatementMatcher WhileStmt = 2285 whileStmt(hasCondition(cxxBoolLiteral(equals(true)))); 2286 EXPECT_TRUE(matches("void x() { while (true) {} }", WhileStmt)); 2287 EXPECT_TRUE(notMatches("void x() { while (false) {} }", WhileStmt)); 2288 2289 StatementMatcher SwitchStmt = 2290 switchStmt(hasCondition(integerLiteral(equals(42)))); 2291 EXPECT_TRUE(matches("void x() { switch (42) {case 42:;} }", SwitchStmt)); 2292 EXPECT_TRUE(notMatches("void x() { switch (43) {case 43:;} }", SwitchStmt)); 2293 } 2294 2295 TEST(For, ForLoopInternals) { 2296 EXPECT_TRUE(matches("void f(){ int i; for (; i < 3 ; ); }", 2297 forStmt(hasCondition(anything())))); 2298 EXPECT_TRUE(matches("void f() { for (int i = 0; ;); }", 2299 forStmt(hasLoopInit(anything())))); 2300 } 2301 2302 TEST(For, ForRangeLoopInternals) { 2303 EXPECT_TRUE(matches("void f(){ int a[] {1, 2}; for (int i : a); }", 2304 cxxForRangeStmt(hasLoopVariable(anything())))); 2305 EXPECT_TRUE(matches( 2306 "void f(){ int a[] {1, 2}; for (int i : a); }", 2307 cxxForRangeStmt(hasRangeInit(declRefExpr(to(varDecl(hasName("a")))))))); 2308 } 2309 2310 TEST(For, NegativeForLoopInternals) { 2311 EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }", 2312 forStmt(hasCondition(expr())))); 2313 EXPECT_TRUE(notMatches("void f() {int i; for (; i < 4; ++i) {} }", 2314 forStmt(hasLoopInit(anything())))); 2315 } 2316 2317 TEST(HasBody, FindsBodyOfForWhileDoLoops) { 2318 EXPECT_TRUE(matches("void f() { for(;;) {} }", 2319 forStmt(hasBody(compoundStmt())))); 2320 EXPECT_TRUE(notMatches("void f() { for(;;); }", 2321 forStmt(hasBody(compoundStmt())))); 2322 EXPECT_TRUE(matches("void f() { while(true) {} }", 2323 whileStmt(hasBody(compoundStmt())))); 2324 EXPECT_TRUE(matches("void f() { do {} while(true); }", 2325 doStmt(hasBody(compoundStmt())))); 2326 EXPECT_TRUE(matches("void f() { int p[2]; for (auto x : p) {} }", 2327 cxxForRangeStmt(hasBody(compoundStmt())))); 2328 } 2329 2330 TEST(HasBody, FindsBodyOfFunctions) { 2331 EXPECT_TRUE(matches("void f() {}", functionDecl(hasBody(compoundStmt())))); 2332 EXPECT_TRUE(notMatches("void f();", functionDecl(hasBody(compoundStmt())))); 2333 EXPECT_TRUE(matchAndVerifyResultTrue( 2334 "void f(); void f() {}", 2335 functionDecl(hasBody(compoundStmt())).bind("func"), 2336 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("func", 1))); 2337 EXPECT_TRUE(matchAndVerifyResultTrue( 2338 "class C { void f(); }; void C::f() {}", 2339 cxxMethodDecl(hasBody(compoundStmt())).bind("met"), 2340 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("met", 1))); 2341 EXPECT_TRUE(matchAndVerifyResultTrue( 2342 "class C { C(); }; C::C() {}", 2343 cxxConstructorDecl(hasBody(compoundStmt())).bind("ctr"), 2344 std::make_unique<VerifyIdIsBoundTo<CXXConstructorDecl>>("ctr", 1))); 2345 EXPECT_TRUE(matchAndVerifyResultTrue( 2346 "class C { ~C(); }; C::~C() {}", 2347 cxxDestructorDecl(hasBody(compoundStmt())).bind("dtr"), 2348 std::make_unique<VerifyIdIsBoundTo<CXXDestructorDecl>>("dtr", 1))); 2349 } 2350 2351 TEST(HasAnyBody, FindsAnyBodyOfFunctions) { 2352 EXPECT_TRUE(matches("void f() {}", functionDecl(hasAnyBody(compoundStmt())))); 2353 EXPECT_TRUE(notMatches("void f();", 2354 functionDecl(hasAnyBody(compoundStmt())))); 2355 EXPECT_TRUE(matchAndVerifyResultTrue( 2356 "void f(); void f() {}", 2357 functionDecl(hasAnyBody(compoundStmt())).bind("func"), 2358 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("func", 2))); 2359 EXPECT_TRUE(matchAndVerifyResultTrue( 2360 "class C { void f(); }; void C::f() {}", 2361 cxxMethodDecl(hasAnyBody(compoundStmt())).bind("met"), 2362 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("met", 2))); 2363 EXPECT_TRUE(matchAndVerifyResultTrue( 2364 "class C { C(); }; C::C() {}", 2365 cxxConstructorDecl(hasAnyBody(compoundStmt())).bind("ctr"), 2366 std::make_unique<VerifyIdIsBoundTo<CXXConstructorDecl>>("ctr", 2))); 2367 EXPECT_TRUE(matchAndVerifyResultTrue( 2368 "class C { ~C(); }; C::~C() {}", 2369 cxxDestructorDecl(hasAnyBody(compoundStmt())).bind("dtr"), 2370 std::make_unique<VerifyIdIsBoundTo<CXXDestructorDecl>>("dtr", 2))); 2371 } 2372 2373 TEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) { 2374 // The simplest case: every compound statement is in a function 2375 // definition, and the function body itself must be a compound 2376 // statement. 2377 EXPECT_TRUE(matches("void f() { for (;;); }", 2378 compoundStmt(hasAnySubstatement(forStmt())))); 2379 } 2380 2381 TEST(HasAnySubstatement, IsNotRecursive) { 2382 // It's really "has any immediate substatement". 2383 EXPECT_TRUE(notMatches("void f() { if (true) for (;;); }", 2384 compoundStmt(hasAnySubstatement(forStmt())))); 2385 } 2386 2387 TEST(HasAnySubstatement, MatchesInNestedCompoundStatements) { 2388 EXPECT_TRUE(matches("void f() { if (true) { for (;;); } }", 2389 compoundStmt(hasAnySubstatement(forStmt())))); 2390 } 2391 2392 TEST(HasAnySubstatement, FindsSubstatementBetweenOthers) { 2393 EXPECT_TRUE(matches("void f() { 1; 2; 3; for (;;); 4; 5; 6; }", 2394 compoundStmt(hasAnySubstatement(forStmt())))); 2395 } 2396 2397 TEST(Member, MatchesMemberAllocationFunction) { 2398 // Fails in C++11 mode 2399 EXPECT_TRUE(matchesConditionally( 2400 "namespace std { typedef typeof(sizeof(int)) size_t; }" 2401 "class X { void *operator new(std::size_t); };", 2402 cxxMethodDecl(ofClass(hasName("X"))), true, {"-std=gnu++03"})); 2403 2404 EXPECT_TRUE(matches("class X { void operator delete(void*); };", 2405 cxxMethodDecl(ofClass(hasName("X"))))); 2406 2407 // Fails in C++11 mode 2408 EXPECT_TRUE(matchesConditionally( 2409 "namespace std { typedef typeof(sizeof(int)) size_t; }" 2410 "class X { void operator delete[](void*, std::size_t); };", 2411 cxxMethodDecl(ofClass(hasName("X"))), true, {"-std=gnu++03"})); 2412 } 2413 2414 TEST(HasDestinationType, MatchesSimpleCase) { 2415 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);", 2416 cxxStaticCastExpr(hasDestinationType( 2417 pointsTo(TypeMatcher(anything())))))); 2418 } 2419 2420 TEST(HasImplicitDestinationType, MatchesSimpleCase) { 2421 // This test creates an implicit const cast. 2422 EXPECT_TRUE(matches( 2423 "int x; const int i = x;", 2424 traverse(TK_AsIs, 2425 implicitCastExpr(hasImplicitDestinationType(isInteger()))))); 2426 // This test creates an implicit array-to-pointer cast. 2427 EXPECT_TRUE( 2428 matches("int arr[3]; int *p = arr;", 2429 traverse(TK_AsIs, implicitCastExpr(hasImplicitDestinationType( 2430 pointsTo(TypeMatcher(anything()))))))); 2431 } 2432 2433 TEST(HasImplicitDestinationType, DoesNotMatchIncorrectly) { 2434 // This test creates an implicit cast from int to char. 2435 EXPECT_TRUE(notMatches("char c = 0;", 2436 implicitCastExpr(hasImplicitDestinationType( 2437 unless(anything()))))); 2438 // This test creates an implicit array-to-pointer cast. 2439 EXPECT_TRUE(notMatches("int arr[3]; int *p = arr;", 2440 implicitCastExpr(hasImplicitDestinationType( 2441 unless(anything()))))); 2442 } 2443 2444 TEST(Matcher, IgnoresElidableConstructors) { 2445 EXPECT_TRUE( 2446 matches("struct H {};" 2447 "template<typename T> H B(T A);" 2448 "void f() {" 2449 " H D1;" 2450 " D1 = B(B(1));" 2451 "}", 2452 cxxOperatorCallExpr(hasArgument( 2453 1, callExpr(hasArgument( 2454 0, ignoringElidableConstructorCall(callExpr()))))), 2455 langCxx11OrLater())); 2456 EXPECT_TRUE( 2457 matches("struct H {};" 2458 "template<typename T> H B(T A);" 2459 "void f() {" 2460 " H D1;" 2461 " D1 = B(1);" 2462 "}", 2463 cxxOperatorCallExpr(hasArgument( 2464 1, callExpr(hasArgument(0, ignoringElidableConstructorCall( 2465 integerLiteral()))))), 2466 langCxx11OrLater())); 2467 EXPECT_TRUE(matches( 2468 "struct H {};" 2469 "H G();" 2470 "void f() {" 2471 " H D = G();" 2472 "}", 2473 varDecl(hasInitializer(anyOf( 2474 ignoringElidableConstructorCall(callExpr()), 2475 exprWithCleanups(has(ignoringElidableConstructorCall(callExpr())))))), 2476 langCxx11OrLater())); 2477 } 2478 2479 TEST(Matcher, IgnoresElidableInReturn) { 2480 auto matcher = expr(ignoringElidableConstructorCall(declRefExpr())); 2481 EXPECT_TRUE(matches("struct H {};" 2482 "H f() {" 2483 " H g;" 2484 " return g;" 2485 "}", 2486 matcher, langCxx11OrLater())); 2487 EXPECT_TRUE(notMatches("struct H {};" 2488 "H f() {" 2489 " return H();" 2490 "}", 2491 matcher, langCxx11OrLater())); 2492 } 2493 2494 TEST(Matcher, IgnoreElidableConstructorDoesNotMatchConstructors) { 2495 EXPECT_TRUE(matches("struct H {};" 2496 "void f() {" 2497 " H D;" 2498 "}", 2499 varDecl(hasInitializer( 2500 ignoringElidableConstructorCall(cxxConstructExpr()))), 2501 langCxx11OrLater())); 2502 } 2503 2504 TEST(Matcher, IgnoresElidableDoesNotPreventMatches) { 2505 EXPECT_TRUE(matches("void f() {" 2506 " int D = 10;" 2507 "}", 2508 expr(ignoringElidableConstructorCall(integerLiteral())), 2509 langCxx11OrLater())); 2510 } 2511 2512 TEST(Matcher, IgnoresElidableInVarInit) { 2513 auto matcher = 2514 varDecl(hasInitializer(ignoringElidableConstructorCall(callExpr()))); 2515 EXPECT_TRUE(matches("struct H {};" 2516 "H G();" 2517 "void f(H D = G()) {" 2518 " return;" 2519 "}", 2520 matcher, langCxx11OrLater())); 2521 EXPECT_TRUE(matches("struct H {};" 2522 "H G();" 2523 "void f() {" 2524 " H D = G();" 2525 "}", 2526 matcher, langCxx11OrLater())); 2527 } 2528 2529 TEST(IgnoringImplicit, MatchesImplicit) { 2530 EXPECT_TRUE(matches("class C {}; C a = C();", 2531 varDecl(has(ignoringImplicit(cxxConstructExpr()))))); 2532 } 2533 2534 TEST(IgnoringImplicit, MatchesNestedImplicit) { 2535 StringRef Code = R"( 2536 2537 struct OtherType; 2538 2539 struct SomeType 2540 { 2541 SomeType() {} 2542 SomeType(const OtherType&) {} 2543 SomeType& operator=(OtherType const&) { return *this; } 2544 }; 2545 2546 struct OtherType 2547 { 2548 OtherType() {} 2549 ~OtherType() {} 2550 }; 2551 2552 OtherType something() 2553 { 2554 return {}; 2555 } 2556 2557 int main() 2558 { 2559 SomeType i = something(); 2560 } 2561 )"; 2562 EXPECT_TRUE(matches( 2563 Code, 2564 traverse(TK_AsIs, 2565 varDecl(hasName("i"), 2566 hasInitializer(exprWithCleanups(has(cxxConstructExpr( 2567 has(expr(ignoringImplicit(cxxConstructExpr(has( 2568 expr(ignoringImplicit(callExpr()))))))))))))))); 2569 } 2570 2571 TEST(IgnoringImplicit, DoesNotMatchIncorrectly) { 2572 EXPECT_TRUE(notMatches("class C {}; C a = C();", 2573 traverse(TK_AsIs, varDecl(has(cxxConstructExpr()))))); 2574 } 2575 2576 TEST(Traversal, traverseMatcher) { 2577 2578 StringRef VarDeclCode = R"cpp( 2579 void foo() 2580 { 2581 int i = 3.0; 2582 } 2583 )cpp"; 2584 2585 auto Matcher = varDecl(hasInitializer(floatLiteral())); 2586 2587 EXPECT_TRUE(notMatches(VarDeclCode, traverse(TK_AsIs, Matcher))); 2588 EXPECT_TRUE( 2589 matches(VarDeclCode, traverse(TK_IgnoreUnlessSpelledInSource, Matcher))); 2590 2591 auto ParentMatcher = floatLiteral(hasParent(varDecl(hasName("i")))); 2592 2593 EXPECT_TRUE(notMatches(VarDeclCode, traverse(TK_AsIs, ParentMatcher))); 2594 EXPECT_TRUE(matches(VarDeclCode, 2595 traverse(TK_IgnoreUnlessSpelledInSource, ParentMatcher))); 2596 2597 EXPECT_TRUE(matches( 2598 VarDeclCode, decl(traverse(TK_AsIs, anyOf(cxxRecordDecl(), varDecl()))))); 2599 2600 EXPECT_TRUE( 2601 matches(VarDeclCode, 2602 floatLiteral(traverse(TK_AsIs, hasParent(implicitCastExpr()))))); 2603 2604 EXPECT_TRUE( 2605 matches(VarDeclCode, floatLiteral(traverse(TK_IgnoreUnlessSpelledInSource, 2606 hasParent(varDecl()))))); 2607 2608 EXPECT_TRUE( 2609 matches(VarDeclCode, varDecl(traverse(TK_IgnoreUnlessSpelledInSource, 2610 unless(parmVarDecl()))))); 2611 2612 EXPECT_TRUE( 2613 notMatches(VarDeclCode, varDecl(traverse(TK_IgnoreUnlessSpelledInSource, 2614 has(implicitCastExpr()))))); 2615 2616 EXPECT_TRUE(matches(VarDeclCode, 2617 varDecl(traverse(TK_AsIs, has(implicitCastExpr()))))); 2618 2619 EXPECT_TRUE(matches( 2620 VarDeclCode, traverse(TK_IgnoreUnlessSpelledInSource, 2621 // The has() below strips away the ImplicitCastExpr 2622 // before the traverse(AsIs) gets to process it. 2623 varDecl(has(traverse(TK_AsIs, floatLiteral())))))); 2624 2625 EXPECT_TRUE( 2626 matches(VarDeclCode, functionDecl(traverse(TK_AsIs, hasName("foo"))))); 2627 2628 EXPECT_TRUE(matches( 2629 VarDeclCode, 2630 functionDecl(traverse(TK_IgnoreUnlessSpelledInSource, hasName("foo"))))); 2631 2632 EXPECT_TRUE(matches( 2633 VarDeclCode, functionDecl(traverse(TK_AsIs, hasAnyName("foo", "bar"))))); 2634 2635 EXPECT_TRUE( 2636 matches(VarDeclCode, functionDecl(traverse(TK_IgnoreUnlessSpelledInSource, 2637 hasAnyName("foo", "bar"))))); 2638 2639 StringRef Code = R"cpp( 2640 void foo(int a) 2641 { 2642 int i = 3.0 + a; 2643 } 2644 void bar() 2645 { 2646 foo(7.0); 2647 } 2648 )cpp"; 2649 EXPECT_TRUE( 2650 matches(Code, callExpr(traverse(TK_IgnoreUnlessSpelledInSource, 2651 hasArgument(0, floatLiteral()))))); 2652 2653 EXPECT_TRUE( 2654 matches(Code, callExpr(traverse(TK_IgnoreUnlessSpelledInSource, 2655 hasAnyArgument(floatLiteral()))))); 2656 2657 EXPECT_TRUE(matches( 2658 R"cpp( 2659 void takesBool(bool){} 2660 2661 template <typename T> 2662 void neverInstantiatedTemplate() { 2663 takesBool(T{}); 2664 } 2665 )cpp", 2666 traverse(TK_IgnoreUnlessSpelledInSource, 2667 callExpr(unless(callExpr(hasDeclaration(functionDecl()))))))); 2668 2669 EXPECT_TRUE( 2670 matches(VarDeclCode, varDecl(traverse(TK_IgnoreUnlessSpelledInSource, 2671 hasType(builtinType()))))); 2672 2673 EXPECT_TRUE( 2674 matches(VarDeclCode, 2675 functionDecl(hasName("foo"), 2676 traverse(TK_AsIs, hasDescendant(floatLiteral()))))); 2677 2678 EXPECT_TRUE(notMatches( 2679 Code, traverse(TK_AsIs, floatLiteral(hasParent(callExpr( 2680 callee(functionDecl(hasName("foo"))))))))); 2681 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, 2682 floatLiteral(hasParent(callExpr(callee( 2683 functionDecl(hasName("foo"))))))))); 2684 2685 Code = R"cpp( 2686 void foo() 2687 { 2688 int i = (3); 2689 } 2690 )cpp"; 2691 EXPECT_TRUE(matches( 2692 Code, traverse(TK_IgnoreUnlessSpelledInSource, 2693 varDecl(hasInitializer(integerLiteral(equals(3))))))); 2694 EXPECT_TRUE(matches( 2695 Code, 2696 traverse(TK_IgnoreUnlessSpelledInSource, 2697 integerLiteral(equals(3), hasParent(varDecl(hasName("i"))))))); 2698 2699 Code = R"cpp( 2700 const char *SomeString{"str"}; 2701 )cpp"; 2702 EXPECT_TRUE( 2703 matches(Code, traverse(TK_AsIs, stringLiteral(hasParent(implicitCastExpr( 2704 hasParent(initListExpr()))))))); 2705 EXPECT_TRUE( 2706 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, 2707 stringLiteral(hasParent(initListExpr()))))); 2708 2709 Code = R"cpp( 2710 struct String 2711 { 2712 String(const char*, int = -1) {} 2713 }; 2714 2715 void stringConstruct() 2716 { 2717 String s = "foo"; 2718 s = "bar"; 2719 } 2720 )cpp"; 2721 EXPECT_TRUE(matches( 2722 Code, 2723 traverse( 2724 TK_AsIs, 2725 functionDecl( 2726 hasName("stringConstruct"), 2727 hasDescendant(varDecl( 2728 hasName("s"), 2729 hasInitializer(ignoringImplicit(cxxConstructExpr(hasArgument( 2730 0, ignoringImplicit(cxxConstructExpr(hasArgument( 2731 0, ignoringImplicit(stringLiteral())))))))))))))); 2732 2733 EXPECT_TRUE(matches( 2734 Code, 2735 traverse( 2736 TK_AsIs, 2737 functionDecl(hasName("stringConstruct"), 2738 hasDescendant(cxxOperatorCallExpr( 2739 isAssignmentOperator(), 2740 hasArgument(1, ignoringImplicit( 2741 cxxConstructExpr(hasArgument( 2742 0, ignoringImplicit(stringLiteral()))))) 2743 )))))); 2744 2745 EXPECT_TRUE(matches( 2746 Code, traverse(TK_IgnoreUnlessSpelledInSource, 2747 functionDecl(hasName("stringConstruct"), 2748 hasDescendant(varDecl( 2749 hasName("s"), 2750 hasInitializer(stringLiteral()))))))); 2751 2752 EXPECT_TRUE( 2753 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, 2754 functionDecl(hasName("stringConstruct"), 2755 hasDescendant(cxxOperatorCallExpr( 2756 isAssignmentOperator(), 2757 hasArgument(1, stringLiteral()))))))); 2758 2759 Code = R"cpp( 2760 2761 struct C1 {}; 2762 struct C2 { operator C1(); }; 2763 2764 void conversionOperator() 2765 { 2766 C2* c2; 2767 C1 c1 = (*c2); 2768 } 2769 2770 )cpp"; 2771 EXPECT_TRUE(matches( 2772 Code, 2773 traverse( 2774 TK_AsIs, 2775 functionDecl( 2776 hasName("conversionOperator"), 2777 hasDescendant( 2778 varDecl( 2779 hasName("c1"), 2780 hasInitializer( 2781 ignoringImplicit(cxxConstructExpr(hasArgument( 2782 0, ignoringImplicit( 2783 cxxMemberCallExpr(onImplicitObjectArgument( 2784 ignoringParenImpCasts(unaryOperator( 2785 hasOperatorName("*"))))))))))) 2786 .bind("c1")))))); 2787 2788 EXPECT_TRUE(matches( 2789 Code, 2790 traverse(TK_IgnoreUnlessSpelledInSource, 2791 functionDecl(hasName("conversionOperator"), 2792 hasDescendant(varDecl( 2793 hasName("c1"), hasInitializer(unaryOperator( 2794 hasOperatorName("*"))))))))); 2795 2796 Code = R"cpp( 2797 2798 template <unsigned alignment> 2799 void template_test() { 2800 static_assert(alignment, ""); 2801 } 2802 void actual_template_test() { 2803 template_test<4>(); 2804 } 2805 2806 )cpp"; 2807 EXPECT_TRUE(matches( 2808 Code, 2809 traverse(TK_AsIs, 2810 staticAssertDecl(has(implicitCastExpr(has( 2811 substNonTypeTemplateParmExpr(has(integerLiteral()))))))))); 2812 EXPECT_TRUE(matches( 2813 Code, traverse(TK_IgnoreUnlessSpelledInSource, 2814 staticAssertDecl(has(declRefExpr( 2815 to(nonTypeTemplateParmDecl(hasName("alignment"))), 2816 hasType(asString("unsigned int")))))))); 2817 2818 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, staticAssertDecl(hasDescendant( 2819 integerLiteral()))))); 2820 EXPECT_FALSE(matches( 2821 Code, traverse(TK_IgnoreUnlessSpelledInSource, 2822 staticAssertDecl(hasDescendant(integerLiteral()))))); 2823 2824 Code = R"cpp( 2825 2826 struct OneParamCtor { 2827 explicit OneParamCtor(int); 2828 }; 2829 struct TwoParamCtor { 2830 explicit TwoParamCtor(int, int); 2831 }; 2832 2833 void varDeclCtors() { 2834 { 2835 auto var1 = OneParamCtor(5); 2836 auto var2 = TwoParamCtor(6, 7); 2837 } 2838 { 2839 OneParamCtor var3(5); 2840 TwoParamCtor var4(6, 7); 2841 } 2842 int i = 0; 2843 { 2844 auto var5 = OneParamCtor(i); 2845 auto var6 = TwoParamCtor(i, 7); 2846 } 2847 { 2848 OneParamCtor var7(i); 2849 TwoParamCtor var8(i, 7); 2850 } 2851 } 2852 2853 )cpp"; 2854 EXPECT_TRUE(matches( 2855 Code, 2856 traverse(TK_AsIs, varDecl(hasName("var1"), hasInitializer(hasDescendant( 2857 cxxConstructExpr())))))); 2858 EXPECT_TRUE(matches( 2859 Code, 2860 traverse(TK_AsIs, varDecl(hasName("var2"), hasInitializer(hasDescendant( 2861 cxxConstructExpr())))))); 2862 EXPECT_TRUE(matches( 2863 Code, traverse(TK_AsIs, varDecl(hasName("var3"), 2864 hasInitializer(cxxConstructExpr()))))); 2865 EXPECT_TRUE(matches( 2866 Code, traverse(TK_AsIs, varDecl(hasName("var4"), 2867 hasInitializer(cxxConstructExpr()))))); 2868 EXPECT_TRUE(matches( 2869 Code, 2870 traverse(TK_AsIs, varDecl(hasName("var5"), hasInitializer(hasDescendant( 2871 cxxConstructExpr())))))); 2872 EXPECT_TRUE(matches( 2873 Code, 2874 traverse(TK_AsIs, varDecl(hasName("var6"), hasInitializer(hasDescendant( 2875 cxxConstructExpr())))))); 2876 EXPECT_TRUE(matches( 2877 Code, traverse(TK_AsIs, varDecl(hasName("var7"), 2878 hasInitializer(cxxConstructExpr()))))); 2879 EXPECT_TRUE(matches( 2880 Code, traverse(TK_AsIs, varDecl(hasName("var8"), 2881 hasInitializer(cxxConstructExpr()))))); 2882 2883 EXPECT_TRUE(matches( 2884 Code, 2885 traverse(TK_IgnoreUnlessSpelledInSource, 2886 varDecl(hasName("var1"), hasInitializer(cxxConstructExpr()))))); 2887 EXPECT_TRUE(matches( 2888 Code, 2889 traverse(TK_IgnoreUnlessSpelledInSource, 2890 varDecl(hasName("var2"), hasInitializer(cxxConstructExpr()))))); 2891 EXPECT_TRUE(matches( 2892 Code, 2893 traverse(TK_IgnoreUnlessSpelledInSource, 2894 varDecl(hasName("var3"), hasInitializer(cxxConstructExpr()))))); 2895 EXPECT_TRUE(matches( 2896 Code, 2897 traverse(TK_IgnoreUnlessSpelledInSource, 2898 varDecl(hasName("var4"), hasInitializer(cxxConstructExpr()))))); 2899 EXPECT_TRUE(matches( 2900 Code, 2901 traverse(TK_IgnoreUnlessSpelledInSource, 2902 varDecl(hasName("var5"), hasInitializer(cxxConstructExpr()))))); 2903 EXPECT_TRUE(matches( 2904 Code, 2905 traverse(TK_IgnoreUnlessSpelledInSource, 2906 varDecl(hasName("var6"), hasInitializer(cxxConstructExpr()))))); 2907 EXPECT_TRUE(matches( 2908 Code, 2909 traverse(TK_IgnoreUnlessSpelledInSource, 2910 varDecl(hasName("var7"), hasInitializer(cxxConstructExpr()))))); 2911 EXPECT_TRUE(matches( 2912 Code, 2913 traverse(TK_IgnoreUnlessSpelledInSource, 2914 varDecl(hasName("var8"), hasInitializer(cxxConstructExpr()))))); 2915 2916 Code = R"cpp( 2917 2918 template<typename T> 2919 struct TemplStruct { 2920 TemplStruct() {} 2921 ~TemplStruct() {} 2922 2923 void outOfLine(T); 2924 2925 private: 2926 T m_t; 2927 }; 2928 2929 template<typename T> 2930 void TemplStruct<T>::outOfLine(T) 2931 { 2932 2933 } 2934 2935 template<typename T> 2936 T timesTwo(T input) 2937 { 2938 return input * 2; 2939 } 2940 2941 void instantiate() 2942 { 2943 TemplStruct<int> ti; 2944 TemplStruct<double> td; 2945 (void)timesTwo<int>(2); 2946 (void)timesTwo<double>(2); 2947 } 2948 2949 template class TemplStruct<float>; 2950 2951 extern template class TemplStruct<long>; 2952 2953 template<> class TemplStruct<bool> { 2954 TemplStruct() {} 2955 ~TemplStruct() {} 2956 2957 void boolSpecializationMethodOnly() {} 2958 private: 2959 bool m_t; 2960 }; 2961 2962 template float timesTwo(float); 2963 template<> bool timesTwo<bool>(bool){ 2964 return true; 2965 } 2966 )cpp"; 2967 { 2968 auto M = cxxRecordDecl(hasName("TemplStruct"), 2969 has(fieldDecl(hasType(asString("int"))))); 2970 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 2971 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 2972 } 2973 { 2974 auto M = cxxRecordDecl(hasName("TemplStruct"), 2975 has(fieldDecl(hasType(asString("double"))))); 2976 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 2977 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 2978 } 2979 { 2980 auto M = 2981 functionDecl(hasName("timesTwo"), 2982 hasParameter(0, parmVarDecl(hasType(asString("int"))))); 2983 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 2984 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 2985 } 2986 { 2987 auto M = 2988 functionDecl(hasName("timesTwo"), 2989 hasParameter(0, parmVarDecl(hasType(asString("double"))))); 2990 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 2991 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 2992 } 2993 { 2994 // Match on the integer literal in the explicit instantiation: 2995 auto MDef = 2996 functionDecl(hasName("timesTwo"), 2997 hasParameter(0, parmVarDecl(hasType(asString("float")))), 2998 hasDescendant(integerLiteral(equals(2)))); 2999 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MDef))); 3000 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MDef))); 3001 3002 auto MTempl = 3003 functionDecl(hasName("timesTwo"), 3004 hasTemplateArgument(0, refersToType(asString("float")))); 3005 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MTempl))); 3006 // TODO: If we could match on explicit instantiations of function templates, 3007 // this would be EXPECT_TRUE. See Sema::ActOnExplicitInstantiation. 3008 EXPECT_FALSE( 3009 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MTempl))); 3010 } 3011 { 3012 auto M = functionDecl(hasName("timesTwo"), 3013 hasParameter(0, parmVarDecl(hasType(booleanType())))); 3014 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3015 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3016 } 3017 { 3018 // Match on the field within the explicit instantiation: 3019 auto MRecord = cxxRecordDecl(hasName("TemplStruct"), 3020 has(fieldDecl(hasType(asString("float"))))); 3021 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MRecord))); 3022 EXPECT_FALSE( 3023 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MRecord))); 3024 3025 // Match on the explicit template instantiation itself: 3026 auto MTempl = classTemplateSpecializationDecl( 3027 hasName("TemplStruct"), 3028 hasTemplateArgument(0, 3029 templateArgument(refersToType(asString("float"))))); 3030 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MTempl))); 3031 EXPECT_TRUE( 3032 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MTempl))); 3033 } 3034 { 3035 // The template argument is matchable, but the instantiation is not: 3036 auto M = classTemplateSpecializationDecl( 3037 hasName("TemplStruct"), 3038 hasTemplateArgument(0, 3039 templateArgument(refersToType(asString("float")))), 3040 has(cxxConstructorDecl(hasName("TemplStruct")))); 3041 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3042 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3043 } 3044 { 3045 // The template argument is matchable, but the instantiation is not: 3046 auto M = classTemplateSpecializationDecl( 3047 hasName("TemplStruct"), 3048 hasTemplateArgument(0, 3049 templateArgument(refersToType(asString("long")))), 3050 has(cxxConstructorDecl(hasName("TemplStruct")))); 3051 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3052 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3053 } 3054 { 3055 // Instantiated, out-of-line methods are not matchable. 3056 auto M = 3057 cxxMethodDecl(hasName("outOfLine"), isDefinition(), 3058 hasParameter(0, parmVarDecl(hasType(asString("float"))))); 3059 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3060 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3061 } 3062 { 3063 // Explicit specialization is written in source and it matches: 3064 auto M = classTemplateSpecializationDecl( 3065 hasName("TemplStruct"), 3066 hasTemplateArgument(0, templateArgument(refersToType(booleanType()))), 3067 has(cxxConstructorDecl(hasName("TemplStruct"))), 3068 has(cxxMethodDecl(hasName("boolSpecializationMethodOnly")))); 3069 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3070 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3071 } 3072 3073 Code = R"cpp( 3074 struct B { 3075 B(int); 3076 }; 3077 3078 B func1() { return 42; } 3079 )cpp"; 3080 { 3081 auto M = expr(ignoringImplicit(integerLiteral(equals(42)).bind("intLit"))); 3082 EXPECT_TRUE(matchAndVerifyResultTrue( 3083 Code, traverse(TK_AsIs, M), 3084 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1))); 3085 EXPECT_TRUE(matchAndVerifyResultTrue( 3086 Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 3087 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1))); 3088 } 3089 { 3090 auto M = expr(unless(integerLiteral(equals(24)))).bind("intLit"); 3091 EXPECT_TRUE(matchAndVerifyResultTrue( 3092 Code, traverse(TK_AsIs, M), 3093 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 6), 3094 {"-std=c++11"})); 3095 3096 EXPECT_TRUE(matchAndVerifyResultTrue( 3097 Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 3098 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1), 3099 {"-std=c++11"})); 3100 } 3101 { 3102 auto M = 3103 expr(anyOf(integerLiteral(equals(42)).bind("intLit"), unless(expr()))); 3104 EXPECT_TRUE(matchAndVerifyResultTrue( 3105 Code, traverse(TK_AsIs, M), 3106 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1))); 3107 EXPECT_TRUE(matchAndVerifyResultTrue( 3108 Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 3109 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1))); 3110 } 3111 { 3112 auto M = expr(allOf(integerLiteral(equals(42)).bind("intLit"), expr())); 3113 EXPECT_TRUE(matchAndVerifyResultTrue( 3114 Code, traverse(TK_AsIs, M), 3115 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1))); 3116 EXPECT_TRUE(matchAndVerifyResultTrue( 3117 Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 3118 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1))); 3119 } 3120 { 3121 auto M = expr(integerLiteral(equals(42)).bind("intLit"), expr()); 3122 EXPECT_TRUE(matchAndVerifyResultTrue( 3123 Code, traverse(TK_AsIs, M), 3124 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1))); 3125 EXPECT_TRUE(matchAndVerifyResultTrue( 3126 Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 3127 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1))); 3128 } 3129 { 3130 auto M = expr(optionally(integerLiteral(equals(42)).bind("intLit"))); 3131 EXPECT_TRUE(matchAndVerifyResultTrue( 3132 Code, traverse(TK_AsIs, M), 3133 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1))); 3134 EXPECT_TRUE(matchAndVerifyResultTrue( 3135 Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 3136 std::make_unique<VerifyIdIsBoundTo<Expr>>("intLit", 1))); 3137 } 3138 { 3139 auto M = expr().bind("allExprs"); 3140 EXPECT_TRUE(matchAndVerifyResultTrue( 3141 Code, traverse(TK_AsIs, M), 3142 std::make_unique<VerifyIdIsBoundTo<Expr>>("allExprs", 6), 3143 {"-std=c++11"})); 3144 EXPECT_TRUE(matchAndVerifyResultTrue( 3145 Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 3146 std::make_unique<VerifyIdIsBoundTo<Expr>>("allExprs", 1))); 3147 } 3148 3149 Code = R"cpp( 3150 void foo() 3151 { 3152 int arr[3]; 3153 auto &[f, s, t] = arr; 3154 3155 f = 42; 3156 } 3157 )cpp"; 3158 { 3159 auto M = bindingDecl(hasName("f")); 3160 EXPECT_TRUE( 3161 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++17"})); 3162 EXPECT_TRUE( 3163 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 3164 true, {"-std=c++17"})); 3165 } 3166 { 3167 auto M = bindingDecl(hasName("f"), has(expr())); 3168 EXPECT_TRUE( 3169 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++17"})); 3170 EXPECT_FALSE( 3171 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 3172 true, {"-std=c++17"})); 3173 } 3174 { 3175 auto M = integerLiteral(hasAncestor(bindingDecl(hasName("f")))); 3176 EXPECT_TRUE( 3177 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++17"})); 3178 EXPECT_FALSE( 3179 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 3180 true, {"-std=c++17"})); 3181 } 3182 { 3183 auto M = declRefExpr(hasAncestor(bindingDecl(hasName("f")))); 3184 EXPECT_TRUE( 3185 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++17"})); 3186 EXPECT_FALSE( 3187 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 3188 true, {"-std=c++17"})); 3189 } 3190 } 3191 3192 TEST(Traversal, traverseNoImplicit) { 3193 StringRef Code = R"cpp( 3194 struct NonTrivial { 3195 NonTrivial() {} 3196 NonTrivial(const NonTrivial&) {} 3197 NonTrivial& operator=(const NonTrivial&) { return *this; } 3198 3199 ~NonTrivial() {} 3200 }; 3201 3202 struct NoSpecialMethods { 3203 NonTrivial nt; 3204 }; 3205 3206 struct ContainsArray { 3207 NonTrivial arr[2]; 3208 ContainsArray& operator=(const ContainsArray &other) = default; 3209 }; 3210 3211 void copyIt() 3212 { 3213 NoSpecialMethods nc1; 3214 NoSpecialMethods nc2(nc1); 3215 nc2 = nc1; 3216 3217 ContainsArray ca; 3218 ContainsArray ca2; 3219 ca2 = ca; 3220 } 3221 3222 struct HasCtorInits : NoSpecialMethods, NonTrivial 3223 { 3224 int m_i; 3225 NonTrivial m_nt; 3226 HasCtorInits() : NoSpecialMethods(), m_i(42) {} 3227 }; 3228 3229 struct CtorInitsNonTrivial : NonTrivial 3230 { 3231 int m_i; 3232 NonTrivial m_nt; 3233 CtorInitsNonTrivial() : NonTrivial(), m_i(42) {} 3234 }; 3235 3236 )cpp"; 3237 { 3238 auto M = cxxRecordDecl(hasName("NoSpecialMethods"), 3239 has(cxxRecordDecl(hasName("NoSpecialMethods")))); 3240 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3241 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3242 3243 M = cxxRecordDecl(hasName("NoSpecialMethods"), 3244 has(cxxConstructorDecl(isCopyConstructor()))); 3245 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3246 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3247 3248 M = cxxRecordDecl(hasName("NoSpecialMethods"), 3249 has(cxxMethodDecl(isCopyAssignmentOperator()))); 3250 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3251 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3252 3253 M = cxxRecordDecl(hasName("NoSpecialMethods"), 3254 has(cxxConstructorDecl(isDefaultConstructor()))); 3255 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3256 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3257 3258 M = cxxRecordDecl(hasName("NoSpecialMethods"), has(cxxDestructorDecl())); 3259 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3260 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3261 3262 M = cxxRecordDecl(hasName("NoSpecialMethods"), 3263 hasMethod(cxxConstructorDecl(isCopyConstructor()))); 3264 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3265 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3266 3267 M = cxxRecordDecl(hasName("NoSpecialMethods"), 3268 hasMethod(cxxMethodDecl(isCopyAssignmentOperator()))); 3269 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3270 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3271 3272 M = cxxRecordDecl(hasName("NoSpecialMethods"), 3273 hasMethod(cxxConstructorDecl(isDefaultConstructor()))); 3274 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3275 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3276 3277 M = cxxRecordDecl(hasName("NoSpecialMethods"), 3278 hasMethod(cxxDestructorDecl())); 3279 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3280 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3281 } 3282 { 3283 // Because the copy-assignment operator is not spelled in the 3284 // source (ie, isImplicit()), we don't match it 3285 auto M = 3286 cxxOperatorCallExpr(hasType(cxxRecordDecl(hasName("NoSpecialMethods"))), 3287 callee(cxxMethodDecl(isCopyAssignmentOperator()))); 3288 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3289 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3290 } 3291 { 3292 // Compiler generates a forStmt to copy the array 3293 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, forStmt()))); 3294 EXPECT_FALSE( 3295 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, forStmt()))); 3296 } 3297 { 3298 // The defaulted method declaration can be matched, but not its 3299 // definition, in IgnoreUnlessSpelledInSource mode 3300 auto MDecl = cxxMethodDecl(ofClass(cxxRecordDecl(hasName("ContainsArray"))), 3301 isCopyAssignmentOperator(), isDefaulted()); 3302 3303 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MDecl))); 3304 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MDecl))); 3305 3306 auto MDef = cxxMethodDecl(MDecl, has(compoundStmt())); 3307 3308 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MDef))); 3309 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MDef))); 3310 3311 auto MBody = cxxMethodDecl(MDecl, hasBody(compoundStmt())); 3312 3313 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MBody))); 3314 EXPECT_FALSE( 3315 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MBody))); 3316 3317 auto MIsDefn = cxxMethodDecl(MDecl, isDefinition()); 3318 3319 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MIsDefn))); 3320 EXPECT_TRUE( 3321 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MIsDefn))); 3322 3323 auto MIsInline = cxxMethodDecl(MDecl, isInline()); 3324 3325 EXPECT_FALSE(matches(Code, traverse(TK_AsIs, MIsInline))); 3326 EXPECT_FALSE( 3327 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MIsInline))); 3328 3329 // The parameter of the defaulted method can still be matched. 3330 auto MParm = 3331 cxxMethodDecl(MDecl, hasParameter(0, parmVarDecl(hasName("other")))); 3332 3333 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, MParm))); 3334 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, MParm))); 3335 } 3336 { 3337 auto M = 3338 cxxConstructorDecl(hasName("HasCtorInits"), 3339 has(cxxCtorInitializer(forField(hasName("m_i"))))); 3340 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3341 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3342 } 3343 { 3344 auto M = 3345 cxxConstructorDecl(hasName("HasCtorInits"), 3346 has(cxxCtorInitializer(forField(hasName("m_nt"))))); 3347 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3348 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3349 } 3350 { 3351 auto M = cxxConstructorDecl(hasName("HasCtorInits"), 3352 hasAnyConstructorInitializer(cxxCtorInitializer( 3353 forField(hasName("m_nt"))))); 3354 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3355 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3356 } 3357 { 3358 auto M = 3359 cxxConstructorDecl(hasName("HasCtorInits"), 3360 forEachConstructorInitializer( 3361 cxxCtorInitializer(forField(hasName("m_nt"))))); 3362 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3363 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3364 } 3365 { 3366 auto M = cxxConstructorDecl( 3367 hasName("CtorInitsNonTrivial"), 3368 has(cxxCtorInitializer(withInitializer(cxxConstructExpr( 3369 hasDeclaration(cxxConstructorDecl(hasName("NonTrivial")))))))); 3370 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3371 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3372 } 3373 { 3374 auto M = cxxConstructorDecl( 3375 hasName("HasCtorInits"), 3376 has(cxxCtorInitializer(withInitializer(cxxConstructExpr(hasDeclaration( 3377 cxxConstructorDecl(hasName("NoSpecialMethods")))))))); 3378 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3379 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3380 } 3381 { 3382 auto M = cxxCtorInitializer(forField(hasName("m_nt"))); 3383 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3384 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3385 } 3386 3387 Code = R"cpp( 3388 void rangeFor() 3389 { 3390 int arr[2]; 3391 for (auto i : arr) 3392 { 3393 if (true) 3394 { 3395 } 3396 } 3397 } 3398 )cpp"; 3399 { 3400 auto M = cxxForRangeStmt(has(binaryOperator(hasOperatorName("!=")))); 3401 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3402 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3403 } 3404 { 3405 auto M = 3406 cxxForRangeStmt(hasDescendant(binaryOperator(hasOperatorName("+")))); 3407 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3408 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3409 } 3410 { 3411 auto M = 3412 cxxForRangeStmt(hasDescendant(unaryOperator(hasOperatorName("++")))); 3413 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3414 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3415 } 3416 { 3417 auto M = cxxForRangeStmt(has(declStmt())); 3418 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3419 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3420 } 3421 { 3422 auto M = 3423 cxxForRangeStmt(hasLoopVariable(varDecl(hasName("i"))), 3424 hasRangeInit(declRefExpr(to(varDecl(hasName("arr")))))); 3425 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3426 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3427 } 3428 { 3429 auto M = cxxForRangeStmt(unless(hasInitStatement(stmt()))); 3430 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3431 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3432 } 3433 { 3434 auto M = cxxForRangeStmt(hasBody(stmt())); 3435 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3436 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3437 } 3438 { 3439 auto M = cxxForRangeStmt(hasDescendant(ifStmt())); 3440 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3441 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3442 } 3443 { 3444 EXPECT_TRUE(matches( 3445 Code, traverse(TK_AsIs, cxxForRangeStmt(has(declStmt( 3446 hasSingleDecl(varDecl(hasName("i"))))))))); 3447 EXPECT_TRUE( 3448 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, 3449 cxxForRangeStmt(has(varDecl(hasName("i"))))))); 3450 } 3451 { 3452 EXPECT_TRUE(matches( 3453 Code, traverse(TK_AsIs, cxxForRangeStmt(has(declStmt(hasSingleDecl( 3454 varDecl(hasInitializer(declRefExpr( 3455 to(varDecl(hasName("arr"))))))))))))); 3456 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, 3457 cxxForRangeStmt(has(declRefExpr( 3458 to(varDecl(hasName("arr"))))))))); 3459 } 3460 { 3461 auto M = cxxForRangeStmt(has(compoundStmt())); 3462 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3463 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3464 } 3465 { 3466 auto M = binaryOperator(hasOperatorName("!=")); 3467 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3468 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3469 } 3470 { 3471 auto M = unaryOperator(hasOperatorName("++")); 3472 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3473 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3474 } 3475 { 3476 auto M = declStmt(hasSingleDecl(varDecl(matchesName("__range")))); 3477 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3478 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3479 } 3480 { 3481 auto M = declStmt(hasSingleDecl(varDecl(matchesName("__begin")))); 3482 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3483 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3484 } 3485 { 3486 auto M = declStmt(hasSingleDecl(varDecl(matchesName("__end")))); 3487 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3488 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3489 } 3490 { 3491 auto M = ifStmt(hasParent(compoundStmt(hasParent(cxxForRangeStmt())))); 3492 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3493 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3494 } 3495 { 3496 auto M = cxxForRangeStmt( 3497 has(varDecl(hasName("i"), hasParent(cxxForRangeStmt())))); 3498 EXPECT_FALSE(matches(Code, traverse(TK_AsIs, M))); 3499 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3500 } 3501 { 3502 auto M = cxxForRangeStmt(hasDescendant(varDecl( 3503 hasName("i"), hasParent(declStmt(hasParent(cxxForRangeStmt())))))); 3504 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3505 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3506 } 3507 { 3508 auto M = cxxForRangeStmt(hasRangeInit(declRefExpr( 3509 to(varDecl(hasName("arr"))), hasParent(cxxForRangeStmt())))); 3510 EXPECT_FALSE(matches(Code, traverse(TK_AsIs, M))); 3511 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3512 } 3513 3514 { 3515 auto M = cxxForRangeStmt(hasRangeInit(declRefExpr( 3516 to(varDecl(hasName("arr"))), hasParent(varDecl(hasParent(declStmt( 3517 hasParent(cxxForRangeStmt())))))))); 3518 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3519 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3520 } 3521 3522 Code = R"cpp( 3523 struct Range { 3524 int* begin() const; 3525 int* end() const; 3526 }; 3527 Range getRange(int); 3528 3529 void rangeFor() 3530 { 3531 for (auto i : getRange(42)) 3532 { 3533 } 3534 } 3535 )cpp"; 3536 { 3537 auto M = integerLiteral(equals(42)); 3538 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3539 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3540 } 3541 { 3542 auto M = callExpr(hasDescendant(integerLiteral(equals(42)))); 3543 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3544 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3545 } 3546 { 3547 auto M = compoundStmt(hasDescendant(integerLiteral(equals(42)))); 3548 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3549 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3550 } 3551 3552 Code = R"cpp( 3553 void rangeFor() 3554 { 3555 int arr[2]; 3556 for (auto& a = arr; auto i : a) 3557 { 3558 3559 } 3560 } 3561 )cpp"; 3562 { 3563 auto M = cxxForRangeStmt(has(binaryOperator(hasOperatorName("!=")))); 3564 EXPECT_TRUE( 3565 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 3566 EXPECT_FALSE( 3567 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 3568 true, {"-std=c++20"})); 3569 } 3570 { 3571 auto M = 3572 cxxForRangeStmt(hasDescendant(binaryOperator(hasOperatorName("+")))); 3573 EXPECT_TRUE( 3574 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 3575 EXPECT_FALSE( 3576 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 3577 true, {"-std=c++20"})); 3578 } 3579 { 3580 auto M = 3581 cxxForRangeStmt(hasDescendant(unaryOperator(hasOperatorName("++")))); 3582 EXPECT_TRUE( 3583 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 3584 EXPECT_FALSE( 3585 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 3586 true, {"-std=c++20"})); 3587 } 3588 { 3589 auto M = 3590 cxxForRangeStmt(has(declStmt(hasSingleDecl(varDecl(hasName("i")))))); 3591 EXPECT_TRUE( 3592 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 3593 EXPECT_FALSE( 3594 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 3595 true, {"-std=c++20"})); 3596 } 3597 { 3598 auto M = cxxForRangeStmt( 3599 hasInitStatement(declStmt(hasSingleDecl(varDecl( 3600 hasName("a"), 3601 hasInitializer(declRefExpr(to(varDecl(hasName("arr"))))))))), 3602 hasLoopVariable(varDecl(hasName("i"))), 3603 hasRangeInit(declRefExpr(to(varDecl(hasName("a")))))); 3604 EXPECT_TRUE( 3605 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 3606 EXPECT_TRUE( 3607 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 3608 true, {"-std=c++20"})); 3609 } 3610 { 3611 auto M = cxxForRangeStmt( 3612 has(declStmt(hasSingleDecl(varDecl( 3613 hasName("a"), 3614 hasInitializer(declRefExpr(to(varDecl(hasName("arr"))))))))), 3615 hasLoopVariable(varDecl(hasName("i"))), 3616 hasRangeInit(declRefExpr(to(varDecl(hasName("a")))))); 3617 EXPECT_TRUE( 3618 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 3619 EXPECT_TRUE( 3620 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 3621 true, {"-std=c++20"})); 3622 } 3623 { 3624 auto M = cxxForRangeStmt(hasInitStatement(declStmt( 3625 hasSingleDecl(varDecl(hasName("a"))), hasParent(cxxForRangeStmt())))); 3626 EXPECT_TRUE( 3627 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 3628 EXPECT_TRUE( 3629 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 3630 true, {"-std=c++20"})); 3631 } 3632 3633 Code = R"cpp( 3634 struct Range { 3635 int* begin() const; 3636 int* end() const; 3637 }; 3638 Range getRange(int); 3639 3640 int getNum(int); 3641 3642 void rangeFor() 3643 { 3644 for (auto j = getNum(42); auto i : getRange(j)) 3645 { 3646 } 3647 } 3648 )cpp"; 3649 { 3650 auto M = integerLiteral(equals(42)); 3651 EXPECT_TRUE( 3652 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 3653 EXPECT_TRUE( 3654 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 3655 true, {"-std=c++20"})); 3656 } 3657 { 3658 auto M = compoundStmt(hasDescendant(integerLiteral(equals(42)))); 3659 EXPECT_TRUE( 3660 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 3661 EXPECT_TRUE( 3662 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 3663 true, {"-std=c++20"})); 3664 } 3665 3666 Code = R"cpp( 3667 void hasDefaultArg(int i, int j = 0) 3668 { 3669 } 3670 void callDefaultArg() 3671 { 3672 hasDefaultArg(42); 3673 } 3674 )cpp"; 3675 auto hasDefaultArgCall = [](auto InnerMatcher) { 3676 return callExpr(callee(functionDecl(hasName("hasDefaultArg"))), 3677 InnerMatcher); 3678 }; 3679 { 3680 auto M = hasDefaultArgCall(has(integerLiteral(equals(42)))); 3681 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3682 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3683 } 3684 { 3685 auto M = hasDefaultArgCall(has(cxxDefaultArgExpr())); 3686 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3687 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3688 } 3689 { 3690 auto M = hasDefaultArgCall(argumentCountIs(2)); 3691 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3692 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3693 } 3694 { 3695 auto M = hasDefaultArgCall(argumentCountIs(1)); 3696 EXPECT_FALSE(matches(Code, traverse(TK_AsIs, M))); 3697 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3698 } 3699 { 3700 auto M = hasDefaultArgCall(hasArgument(1, cxxDefaultArgExpr())); 3701 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3702 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3703 } 3704 { 3705 auto M = hasDefaultArgCall(hasAnyArgument(cxxDefaultArgExpr())); 3706 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3707 EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3708 } 3709 Code = R"cpp( 3710 struct A 3711 { 3712 ~A(); 3713 private: 3714 int i; 3715 }; 3716 3717 A::~A() = default; 3718 )cpp"; 3719 { 3720 auto M = cxxDestructorDecl(isDefaulted(), 3721 ofClass(cxxRecordDecl(has(fieldDecl())))); 3722 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); 3723 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); 3724 } 3725 Code = R"cpp( 3726 struct S 3727 { 3728 static constexpr bool getTrue() { return true; } 3729 }; 3730 3731 struct A 3732 { 3733 explicit(S::getTrue()) A(); 3734 }; 3735 3736 A::A() = default; 3737 )cpp"; 3738 { 3739 EXPECT_TRUE(matchesConditionally( 3740 Code, 3741 traverse(TK_AsIs, 3742 cxxConstructorDecl( 3743 isDefaulted(), 3744 hasExplicitSpecifier(expr(ignoringImplicit( 3745 callExpr(has(ignoringImplicit(declRefExpr())))))))), 3746 true, {"-std=c++20"})); 3747 EXPECT_TRUE(matchesConditionally( 3748 Code, 3749 traverse(TK_IgnoreUnlessSpelledInSource, 3750 cxxConstructorDecl( 3751 isDefaulted(), 3752 hasExplicitSpecifier(callExpr(has(declRefExpr()))))), 3753 true, {"-std=c++20"})); 3754 } 3755 } 3756 3757 template <typename MatcherT> 3758 bool matcherTemplateWithBinding(StringRef Code, const MatcherT &M) { 3759 return matchAndVerifyResultTrue( 3760 Code, M.bind("matchedStmt"), 3761 std::make_unique<VerifyIdIsBoundTo<ReturnStmt>>("matchedStmt", 1)); 3762 } 3763 3764 TEST(Traversal, traverseWithBinding) { 3765 // Some existing matcher code expects to take a matcher as a 3766 // template arg and bind to it. Verify that that works. 3767 3768 llvm::StringRef Code = R"cpp( 3769 int foo() 3770 { 3771 return 42.0; 3772 } 3773 )cpp"; 3774 EXPECT_TRUE(matcherTemplateWithBinding( 3775 Code, traverse(TK_AsIs, 3776 returnStmt(has(implicitCastExpr(has(floatLiteral()))))))); 3777 } 3778 3779 TEST(Traversal, traverseMatcherNesting) { 3780 3781 StringRef Code = R"cpp( 3782 float bar(int i) 3783 { 3784 return i; 3785 } 3786 3787 void foo() 3788 { 3789 bar(bar(3.0)); 3790 } 3791 )cpp"; 3792 3793 EXPECT_TRUE( 3794 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, 3795 callExpr(has(callExpr(traverse( 3796 TK_AsIs, callExpr(has(implicitCastExpr( 3797 has(floatLiteral()))))))))))); 3798 3799 EXPECT_TRUE(matches( 3800 Code, 3801 traverse(TK_IgnoreUnlessSpelledInSource, 3802 traverse(TK_AsIs, implicitCastExpr(has(floatLiteral())))))); 3803 } 3804 3805 TEST(Traversal, traverseMatcherThroughImplicit) { 3806 StringRef Code = R"cpp( 3807 struct S { 3808 S(int x); 3809 }; 3810 3811 void constructImplicit() { 3812 int a = 8; 3813 S s(a); 3814 } 3815 )cpp"; 3816 3817 auto Matcher = traverse(TK_IgnoreUnlessSpelledInSource, implicitCastExpr()); 3818 3819 // Verfiy that it does not segfault 3820 EXPECT_FALSE(matches(Code, Matcher)); 3821 } 3822 3823 TEST(Traversal, traverseMatcherThroughMemoization) { 3824 3825 StringRef Code = R"cpp( 3826 void foo() 3827 { 3828 int i = 3.0; 3829 } 3830 )cpp"; 3831 3832 auto Matcher = varDecl(hasInitializer(floatLiteral())); 3833 3834 // Matchers such as hasDescendant memoize their result regarding AST 3835 // nodes. In the matcher below, the first use of hasDescendant(Matcher) 3836 // fails, and the use of it inside the traverse() matcher should pass 3837 // causing the overall matcher to be a true match. 3838 // This test verifies that the first false result is not re-used, which 3839 // would cause the overall matcher to be incorrectly false. 3840 3841 EXPECT_TRUE(matches( 3842 Code, 3843 functionDecl(anyOf(hasDescendant(Matcher), 3844 traverse(TK_IgnoreUnlessSpelledInSource, 3845 functionDecl(hasDescendant(Matcher))))))); 3846 } 3847 3848 TEST(Traversal, traverseUnlessSpelledInSource) { 3849 3850 StringRef Code = R"cpp( 3851 3852 struct A 3853 { 3854 }; 3855 3856 struct B 3857 { 3858 B(int); 3859 B(A const& a); 3860 B(); 3861 }; 3862 3863 struct C 3864 { 3865 operator B(); 3866 }; 3867 3868 B func1() { 3869 return 42; 3870 } 3871 3872 B func2() { 3873 return B{42}; 3874 } 3875 3876 B func3() { 3877 return B(42); 3878 } 3879 3880 B func4() { 3881 return B(); 3882 } 3883 3884 B func5() { 3885 return B{}; 3886 } 3887 3888 B func6() { 3889 return C(); 3890 } 3891 3892 B func7() { 3893 return A(); 3894 } 3895 3896 B func8() { 3897 return C{}; 3898 } 3899 3900 B func9() { 3901 return A{}; 3902 } 3903 3904 B func10() { 3905 A a; 3906 return a; 3907 } 3908 3909 B func11() { 3910 B b; 3911 return b; 3912 } 3913 3914 B func12() { 3915 C c; 3916 return c; 3917 } 3918 3919 void func13() { 3920 int a = 0; 3921 int c = 0; 3922 3923 [a, b = c](int d) { int e = d; }; 3924 } 3925 3926 void func14() { 3927 [] <typename TemplateType> (TemplateType t, TemplateType u) { int e = t + u; }; 3928 float i = 42.0; 3929 } 3930 3931 void func15() { 3932 int count = 0; 3933 auto l = [&] { ++count; }; 3934 (void)l; 3935 } 3936 3937 )cpp"; 3938 3939 EXPECT_TRUE( 3940 matches(Code, 3941 traverse(TK_IgnoreUnlessSpelledInSource, 3942 returnStmt(forFunction(functionDecl(hasName("func1"))), 3943 hasReturnValue(integerLiteral(equals(42))))), 3944 langCxx20OrLater())); 3945 3946 EXPECT_TRUE( 3947 matches(Code, 3948 traverse(TK_IgnoreUnlessSpelledInSource, 3949 integerLiteral(equals(42), 3950 hasParent(returnStmt(forFunction( 3951 functionDecl(hasName("func1"))))))), 3952 langCxx20OrLater())); 3953 3954 EXPECT_TRUE(matches( 3955 Code, 3956 traverse(TK_IgnoreUnlessSpelledInSource, 3957 returnStmt(forFunction(functionDecl(hasName("func2"))), 3958 hasReturnValue(cxxTemporaryObjectExpr( 3959 hasArgument(0, integerLiteral(equals(42))))))), 3960 langCxx20OrLater())); 3961 EXPECT_TRUE(matches( 3962 Code, 3963 traverse( 3964 TK_IgnoreUnlessSpelledInSource, 3965 integerLiteral(equals(42), 3966 hasParent(cxxTemporaryObjectExpr(hasParent(returnStmt( 3967 forFunction(functionDecl(hasName("func2"))))))))), 3968 langCxx20OrLater())); 3969 3970 EXPECT_TRUE( 3971 matches(Code, 3972 traverse(TK_IgnoreUnlessSpelledInSource, 3973 returnStmt(forFunction(functionDecl(hasName("func3"))), 3974 hasReturnValue(cxxConstructExpr(hasArgument( 3975 0, integerLiteral(equals(42))))))), 3976 langCxx20OrLater())); 3977 3978 EXPECT_TRUE(matches( 3979 Code, 3980 traverse( 3981 TK_IgnoreUnlessSpelledInSource, 3982 integerLiteral(equals(42), 3983 hasParent(cxxConstructExpr(hasParent(returnStmt( 3984 forFunction(functionDecl(hasName("func3"))))))))), 3985 langCxx20OrLater())); 3986 3987 EXPECT_TRUE( 3988 matches(Code, 3989 traverse(TK_IgnoreUnlessSpelledInSource, 3990 returnStmt(forFunction(functionDecl(hasName("func4"))), 3991 hasReturnValue(cxxTemporaryObjectExpr()))), 3992 langCxx20OrLater())); 3993 3994 EXPECT_TRUE( 3995 matches(Code, 3996 traverse(TK_IgnoreUnlessSpelledInSource, 3997 returnStmt(forFunction(functionDecl(hasName("func5"))), 3998 hasReturnValue(cxxTemporaryObjectExpr()))), 3999 langCxx20OrLater())); 4000 4001 EXPECT_TRUE( 4002 matches(Code, 4003 traverse(TK_IgnoreUnlessSpelledInSource, 4004 returnStmt(forFunction(functionDecl(hasName("func6"))), 4005 hasReturnValue(cxxTemporaryObjectExpr()))), 4006 langCxx20OrLater())); 4007 4008 EXPECT_TRUE( 4009 matches(Code, 4010 traverse(TK_IgnoreUnlessSpelledInSource, 4011 returnStmt(forFunction(functionDecl(hasName("func7"))), 4012 hasReturnValue(cxxTemporaryObjectExpr()))), 4013 langCxx20OrLater())); 4014 4015 EXPECT_TRUE( 4016 matches(Code, 4017 traverse(TK_IgnoreUnlessSpelledInSource, 4018 returnStmt(forFunction(functionDecl(hasName("func8"))), 4019 hasReturnValue(cxxFunctionalCastExpr( 4020 hasSourceExpression(initListExpr()))))), 4021 langCxx20OrLater())); 4022 4023 EXPECT_TRUE( 4024 matches(Code, 4025 traverse(TK_IgnoreUnlessSpelledInSource, 4026 returnStmt(forFunction(functionDecl(hasName("func9"))), 4027 hasReturnValue(cxxFunctionalCastExpr( 4028 hasSourceExpression(initListExpr()))))), 4029 langCxx20OrLater())); 4030 4031 EXPECT_TRUE(matches( 4032 Code, 4033 traverse( 4034 TK_IgnoreUnlessSpelledInSource, 4035 returnStmt(forFunction(functionDecl(hasName("func10"))), 4036 hasReturnValue(declRefExpr(to(varDecl(hasName("a"))))))), 4037 langCxx20OrLater())); 4038 4039 EXPECT_TRUE( 4040 matches(Code, 4041 traverse(TK_IgnoreUnlessSpelledInSource, 4042 declRefExpr(to(varDecl(hasName("a"))), 4043 hasParent(returnStmt(forFunction( 4044 functionDecl(hasName("func10"))))))), 4045 langCxx20OrLater())); 4046 4047 EXPECT_TRUE(matches( 4048 Code, 4049 traverse( 4050 TK_IgnoreUnlessSpelledInSource, 4051 returnStmt(forFunction(functionDecl(hasName("func11"))), 4052 hasReturnValue(declRefExpr(to(varDecl(hasName("b"))))))), 4053 langCxx20OrLater())); 4054 4055 EXPECT_TRUE( 4056 matches(Code, 4057 traverse(TK_IgnoreUnlessSpelledInSource, 4058 declRefExpr(to(varDecl(hasName("b"))), 4059 hasParent(returnStmt(forFunction( 4060 functionDecl(hasName("func11"))))))), 4061 langCxx20OrLater())); 4062 4063 EXPECT_TRUE(matches( 4064 Code, 4065 traverse( 4066 TK_IgnoreUnlessSpelledInSource, 4067 returnStmt(forFunction(functionDecl(hasName("func12"))), 4068 hasReturnValue(declRefExpr(to(varDecl(hasName("c"))))))), 4069 langCxx20OrLater())); 4070 4071 EXPECT_TRUE( 4072 matches(Code, 4073 traverse(TK_IgnoreUnlessSpelledInSource, 4074 declRefExpr(to(varDecl(hasName("c"))), 4075 hasParent(returnStmt(forFunction( 4076 functionDecl(hasName("func12"))))))), 4077 langCxx20OrLater())); 4078 4079 EXPECT_TRUE(matches( 4080 Code, 4081 traverse( 4082 TK_IgnoreUnlessSpelledInSource, 4083 lambdaExpr(forFunction(functionDecl(hasName("func13"))), 4084 has(compoundStmt(hasDescendant(varDecl(hasName("e"))))), 4085 has(declRefExpr(to(varDecl(hasName("a"))))), 4086 has(varDecl(hasName("b"), hasInitializer(declRefExpr(to( 4087 varDecl(hasName("c"))))))), 4088 has(parmVarDecl(hasName("d"))))), 4089 langCxx20OrLater())); 4090 4091 EXPECT_TRUE( 4092 matches(Code, 4093 traverse(TK_IgnoreUnlessSpelledInSource, 4094 declRefExpr(to(varDecl(hasName("a"))), 4095 hasParent(lambdaExpr(forFunction( 4096 functionDecl(hasName("func13"))))))), 4097 langCxx20OrLater())); 4098 4099 EXPECT_TRUE(matches( 4100 Code, 4101 traverse(TK_IgnoreUnlessSpelledInSource, 4102 varDecl(hasName("b"), 4103 hasInitializer(declRefExpr(to(varDecl(hasName("c"))))), 4104 hasParent(lambdaExpr( 4105 forFunction(functionDecl(hasName("func13"))))))), 4106 langCxx20OrLater())); 4107 4108 EXPECT_TRUE(matches(Code, 4109 traverse(TK_IgnoreUnlessSpelledInSource, 4110 compoundStmt(hasParent(lambdaExpr(forFunction( 4111 functionDecl(hasName("func13"))))))), 4112 langCxx20OrLater())); 4113 4114 EXPECT_TRUE(matches( 4115 Code, 4116 traverse(TK_IgnoreUnlessSpelledInSource, 4117 templateTypeParmDecl(hasName("TemplateType"), 4118 hasParent(lambdaExpr(forFunction( 4119 functionDecl(hasName("func14"))))))), 4120 langCxx20OrLater())); 4121 4122 EXPECT_TRUE(matches( 4123 Code, 4124 traverse(TK_IgnoreUnlessSpelledInSource, 4125 lambdaExpr(forFunction(functionDecl(hasName("func14"))), 4126 has(templateTypeParmDecl(hasName("TemplateType"))))), 4127 langCxx20OrLater())); 4128 4129 EXPECT_TRUE(matches( 4130 Code, 4131 traverse(TK_IgnoreUnlessSpelledInSource, 4132 functionDecl(hasName("func14"), hasDescendant(floatLiteral()))), 4133 langCxx20OrLater())); 4134 4135 EXPECT_TRUE(matches( 4136 Code, 4137 traverse(TK_IgnoreUnlessSpelledInSource, 4138 compoundStmt( 4139 hasDescendant(varDecl(hasName("count")).bind("countVar")), 4140 hasDescendant( 4141 declRefExpr(to(varDecl(equalsBoundNode("countVar"))))))), 4142 langCxx20OrLater())); 4143 4144 Code = R"cpp( 4145 void foo() { 4146 int explicit_captured = 0; 4147 int implicit_captured = 0; 4148 auto l = [&, explicit_captured](int i) { 4149 if (i || explicit_captured || implicit_captured) return; 4150 }; 4151 } 4152 )cpp"; 4153 4154 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, ifStmt()))); 4155 EXPECT_TRUE( 4156 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, ifStmt()))); 4157 4158 auto lambdaExplicitCapture = declRefExpr( 4159 to(varDecl(hasName("explicit_captured"))), unless(hasAncestor(ifStmt()))); 4160 auto lambdaImplicitCapture = declRefExpr( 4161 to(varDecl(hasName("implicit_captured"))), unless(hasAncestor(ifStmt()))); 4162 4163 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, lambdaExplicitCapture))); 4164 EXPECT_TRUE(matches( 4165 Code, traverse(TK_IgnoreUnlessSpelledInSource, lambdaExplicitCapture))); 4166 4167 EXPECT_TRUE(matches(Code, traverse(TK_AsIs, lambdaImplicitCapture))); 4168 EXPECT_FALSE(matches( 4169 Code, traverse(TK_IgnoreUnlessSpelledInSource, lambdaImplicitCapture))); 4170 4171 Code = R"cpp( 4172 struct S {}; 4173 4174 struct HasOpEq 4175 { 4176 bool operator==(const S& other) 4177 { 4178 return true; 4179 } 4180 }; 4181 4182 void binop() 4183 { 4184 HasOpEq s1; 4185 S s2; 4186 if (s1 != s2) 4187 return; 4188 } 4189 )cpp"; 4190 { 4191 auto M = unaryOperator( 4192 hasOperatorName("!"), 4193 has(cxxOperatorCallExpr(hasOverloadedOperatorName("==")))); 4194 EXPECT_TRUE( 4195 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 4196 EXPECT_FALSE( 4197 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 4198 true, {"-std=c++20"})); 4199 } 4200 { 4201 auto M = declRefExpr(to(varDecl(hasName("s1")))); 4202 EXPECT_TRUE( 4203 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 4204 EXPECT_TRUE( 4205 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 4206 true, {"-std=c++20"})); 4207 } 4208 { 4209 auto M = cxxOperatorCallExpr(hasOverloadedOperatorName("==")); 4210 EXPECT_TRUE( 4211 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 4212 EXPECT_FALSE( 4213 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 4214 true, {"-std=c++20"})); 4215 } 4216 { 4217 auto M = cxxOperatorCallExpr(hasOverloadedOperatorName("!=")); 4218 EXPECT_FALSE( 4219 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 4220 EXPECT_FALSE( 4221 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 4222 true, {"-std=c++20"})); 4223 } 4224 auto withDescendants = [](StringRef lName, StringRef rName) { 4225 return stmt(hasDescendant(declRefExpr(to(varDecl(hasName(lName))))), 4226 hasDescendant(declRefExpr(to(varDecl(hasName(rName)))))); 4227 }; 4228 { 4229 auto M = cxxRewrittenBinaryOperator(withDescendants("s1", "s2")); 4230 EXPECT_TRUE( 4231 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 4232 EXPECT_TRUE( 4233 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 4234 true, {"-std=c++20"})); 4235 } 4236 { 4237 auto M = cxxRewrittenBinaryOperator( 4238 has(declRefExpr(to(varDecl(hasName("s1"))))), 4239 has(declRefExpr(to(varDecl(hasName("s2")))))); 4240 EXPECT_FALSE( 4241 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 4242 EXPECT_TRUE( 4243 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 4244 true, {"-std=c++20"})); 4245 } 4246 { 4247 auto M = cxxRewrittenBinaryOperator( 4248 hasLHS(expr(hasParent(cxxRewrittenBinaryOperator()))), 4249 hasRHS(expr(hasParent(cxxRewrittenBinaryOperator())))); 4250 EXPECT_FALSE( 4251 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 4252 EXPECT_TRUE( 4253 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 4254 true, {"-std=c++20"})); 4255 } 4256 { 4257 EXPECT_TRUE(matchesConditionally( 4258 Code, 4259 traverse(TK_AsIs, 4260 cxxRewrittenBinaryOperator( 4261 hasOperatorName("!="), hasAnyOperatorName("<", "!="), 4262 isComparisonOperator(), 4263 hasLHS(ignoringImplicit( 4264 declRefExpr(to(varDecl(hasName("s1")))))), 4265 hasRHS(ignoringImplicit( 4266 declRefExpr(to(varDecl(hasName("s2")))))), 4267 hasEitherOperand(ignoringImplicit( 4268 declRefExpr(to(varDecl(hasName("s2")))))), 4269 hasOperands(ignoringImplicit( 4270 declRefExpr(to(varDecl(hasName("s1"))))), 4271 ignoringImplicit(declRefExpr( 4272 to(varDecl(hasName("s2")))))))), 4273 true, {"-std=c++20"})); 4274 EXPECT_TRUE(matchesConditionally( 4275 Code, 4276 traverse(TK_IgnoreUnlessSpelledInSource, 4277 cxxRewrittenBinaryOperator( 4278 hasOperatorName("!="), hasAnyOperatorName("<", "!="), 4279 isComparisonOperator(), 4280 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))), 4281 hasRHS(declRefExpr(to(varDecl(hasName("s2"))))), 4282 hasEitherOperand(declRefExpr(to(varDecl(hasName("s2"))))), 4283 hasOperands(declRefExpr(to(varDecl(hasName("s1")))), 4284 declRefExpr(to(varDecl(hasName("s2"))))))), 4285 true, {"-std=c++20"})); 4286 } 4287 4288 Code = R"cpp( 4289 namespace std { 4290 struct strong_ordering { 4291 int n; 4292 constexpr operator int() const { return n; } 4293 static const strong_ordering equal, greater, less; 4294 }; 4295 constexpr strong_ordering strong_ordering::equal = {0}; 4296 constexpr strong_ordering strong_ordering::greater = {1}; 4297 constexpr strong_ordering strong_ordering::less = {-1}; 4298 } 4299 4300 struct HasSpaceshipMem { 4301 int a; 4302 constexpr auto operator<=>(const HasSpaceshipMem&) const = default; 4303 }; 4304 4305 void binop() 4306 { 4307 HasSpaceshipMem hs1, hs2; 4308 if (hs1 == hs2) 4309 return; 4310 4311 HasSpaceshipMem hs3, hs4; 4312 if (hs3 != hs4) 4313 return; 4314 4315 HasSpaceshipMem hs5, hs6; 4316 if (hs5 < hs6) 4317 return; 4318 4319 HasSpaceshipMem hs7, hs8; 4320 if (hs7 > hs8) 4321 return; 4322 4323 HasSpaceshipMem hs9, hs10; 4324 if (hs9 <= hs10) 4325 return; 4326 4327 HasSpaceshipMem hs11, hs12; 4328 if (hs11 >= hs12) 4329 return; 4330 } 4331 )cpp"; 4332 auto withArgs = [](StringRef lName, StringRef rName) { 4333 return cxxOperatorCallExpr( 4334 hasArgument(0, declRefExpr(to(varDecl(hasName(lName))))), 4335 hasArgument(1, declRefExpr(to(varDecl(hasName(rName)))))); 4336 }; 4337 { 4338 auto M = ifStmt(hasCondition(cxxOperatorCallExpr( 4339 hasOverloadedOperatorName("=="), withArgs("hs1", "hs2")))); 4340 EXPECT_TRUE( 4341 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 4342 EXPECT_TRUE( 4343 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 4344 true, {"-std=c++20"})); 4345 } 4346 { 4347 auto M = 4348 unaryOperator(hasOperatorName("!"), 4349 has(cxxOperatorCallExpr(hasOverloadedOperatorName("=="), 4350 withArgs("hs3", "hs4")))); 4351 EXPECT_TRUE( 4352 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 4353 EXPECT_FALSE( 4354 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 4355 true, {"-std=c++20"})); 4356 } 4357 { 4358 auto M = 4359 unaryOperator(hasOperatorName("!"), 4360 has(cxxOperatorCallExpr(hasOverloadedOperatorName("=="), 4361 withArgs("hs3", "hs4")))); 4362 EXPECT_TRUE( 4363 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 4364 EXPECT_FALSE( 4365 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 4366 true, {"-std=c++20"})); 4367 } 4368 { 4369 auto M = binaryOperator( 4370 hasOperatorName("<"), 4371 hasLHS(hasDescendant(cxxOperatorCallExpr( 4372 hasOverloadedOperatorName("<=>"), withArgs("hs5", "hs6")))), 4373 hasRHS(integerLiteral(equals(0)))); 4374 EXPECT_TRUE( 4375 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 4376 EXPECT_FALSE( 4377 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 4378 true, {"-std=c++20"})); 4379 } 4380 { 4381 auto M = cxxRewrittenBinaryOperator(withDescendants("hs3", "hs4")); 4382 EXPECT_TRUE( 4383 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 4384 EXPECT_TRUE( 4385 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 4386 true, {"-std=c++20"})); 4387 } 4388 { 4389 auto M = declRefExpr(to(varDecl(hasName("hs3")))); 4390 EXPECT_TRUE( 4391 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 4392 EXPECT_TRUE( 4393 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 4394 true, {"-std=c++20"})); 4395 } 4396 { 4397 auto M = cxxRewrittenBinaryOperator(has( 4398 unaryOperator(hasOperatorName("!"), withDescendants("hs3", "hs4")))); 4399 EXPECT_TRUE( 4400 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 4401 EXPECT_FALSE( 4402 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 4403 true, {"-std=c++20"})); 4404 } 4405 { 4406 auto M = cxxRewrittenBinaryOperator( 4407 has(declRefExpr(to(varDecl(hasName("hs3"))))), 4408 has(declRefExpr(to(varDecl(hasName("hs4")))))); 4409 EXPECT_FALSE( 4410 matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); 4411 EXPECT_TRUE( 4412 matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), 4413 true, {"-std=c++20"})); 4414 } 4415 { 4416 EXPECT_TRUE(matchesConditionally( 4417 Code, 4418 traverse(TK_AsIs, 4419 cxxRewrittenBinaryOperator( 4420 hasOperatorName("!="), hasAnyOperatorName("<", "!="), 4421 isComparisonOperator(), 4422 hasLHS(ignoringImplicit( 4423 declRefExpr(to(varDecl(hasName("hs3")))))), 4424 hasRHS(ignoringImplicit( 4425 declRefExpr(to(varDecl(hasName("hs4")))))), 4426 hasEitherOperand(ignoringImplicit( 4427 declRefExpr(to(varDecl(hasName("hs3")))))), 4428 hasOperands(ignoringImplicit( 4429 declRefExpr(to(varDecl(hasName("hs3"))))), 4430 ignoringImplicit(declRefExpr( 4431 to(varDecl(hasName("hs4")))))))), 4432 true, {"-std=c++20"})); 4433 EXPECT_TRUE(matchesConditionally( 4434 Code, 4435 traverse(TK_IgnoreUnlessSpelledInSource, 4436 cxxRewrittenBinaryOperator( 4437 hasOperatorName("!="), hasAnyOperatorName("<", "!="), 4438 isComparisonOperator(), 4439 hasLHS(declRefExpr(to(varDecl(hasName("hs3"))))), 4440 hasRHS(declRefExpr(to(varDecl(hasName("hs4"))))), 4441 hasEitherOperand(declRefExpr(to(varDecl(hasName("hs3"))))), 4442 hasOperands(declRefExpr(to(varDecl(hasName("hs3")))), 4443 declRefExpr(to(varDecl(hasName("hs4"))))))), 4444 true, {"-std=c++20"})); 4445 } 4446 { 4447 EXPECT_TRUE(matchesConditionally( 4448 Code, 4449 traverse(TK_AsIs, 4450 cxxRewrittenBinaryOperator( 4451 hasOperatorName("<"), hasAnyOperatorName("<", "!="), 4452 isComparisonOperator(), 4453 hasLHS(ignoringImplicit( 4454 declRefExpr(to(varDecl(hasName("hs5")))))), 4455 hasRHS(ignoringImplicit( 4456 declRefExpr(to(varDecl(hasName("hs6")))))), 4457 hasEitherOperand(ignoringImplicit( 4458 declRefExpr(to(varDecl(hasName("hs5")))))), 4459 hasOperands(ignoringImplicit( 4460 declRefExpr(to(varDecl(hasName("hs5"))))), 4461 ignoringImplicit(declRefExpr( 4462 to(varDecl(hasName("hs6")))))))), 4463 true, {"-std=c++20"})); 4464 EXPECT_TRUE(matchesConditionally( 4465 Code, 4466 traverse(TK_IgnoreUnlessSpelledInSource, 4467 cxxRewrittenBinaryOperator( 4468 hasOperatorName("<"), hasAnyOperatorName("<", "!="), 4469 isComparisonOperator(), 4470 hasLHS(declRefExpr(to(varDecl(hasName("hs5"))))), 4471 hasRHS(declRefExpr(to(varDecl(hasName("hs6"))))), 4472 hasEitherOperand(declRefExpr(to(varDecl(hasName("hs5"))))), 4473 hasOperands(declRefExpr(to(varDecl(hasName("hs5")))), 4474 declRefExpr(to(varDecl(hasName("hs6"))))))), 4475 true, {"-std=c++20"})); 4476 } 4477 { 4478 EXPECT_TRUE(matchesConditionally( 4479 Code, 4480 traverse(TK_AsIs, 4481 cxxRewrittenBinaryOperator( 4482 hasOperatorName(">"), hasAnyOperatorName("<", ">"), 4483 isComparisonOperator(), 4484 hasLHS(ignoringImplicit( 4485 declRefExpr(to(varDecl(hasName("hs7")))))), 4486 hasRHS(ignoringImplicit( 4487 declRefExpr(to(varDecl(hasName("hs8")))))), 4488 hasEitherOperand(ignoringImplicit( 4489 declRefExpr(to(varDecl(hasName("hs7")))))), 4490 hasOperands(ignoringImplicit( 4491 declRefExpr(to(varDecl(hasName("hs7"))))), 4492 ignoringImplicit(declRefExpr( 4493 to(varDecl(hasName("hs8")))))))), 4494 true, {"-std=c++20"})); 4495 EXPECT_TRUE(matchesConditionally( 4496 Code, 4497 traverse(TK_IgnoreUnlessSpelledInSource, 4498 cxxRewrittenBinaryOperator( 4499 hasOperatorName(">"), hasAnyOperatorName("<", ">"), 4500 isComparisonOperator(), 4501 hasLHS(declRefExpr(to(varDecl(hasName("hs7"))))), 4502 hasRHS(declRefExpr(to(varDecl(hasName("hs8"))))), 4503 hasEitherOperand(declRefExpr(to(varDecl(hasName("hs7"))))), 4504 hasOperands(declRefExpr(to(varDecl(hasName("hs7")))), 4505 declRefExpr(to(varDecl(hasName("hs8"))))))), 4506 true, {"-std=c++20"})); 4507 } 4508 { 4509 EXPECT_TRUE(matchesConditionally( 4510 Code, 4511 traverse(TK_AsIs, 4512 cxxRewrittenBinaryOperator( 4513 hasOperatorName("<="), hasAnyOperatorName("<", "<="), 4514 isComparisonOperator(), 4515 hasLHS(ignoringImplicit( 4516 declRefExpr(to(varDecl(hasName("hs9")))))), 4517 hasRHS(ignoringImplicit( 4518 declRefExpr(to(varDecl(hasName("hs10")))))), 4519 hasEitherOperand(ignoringImplicit( 4520 declRefExpr(to(varDecl(hasName("hs9")))))), 4521 hasOperands(ignoringImplicit( 4522 declRefExpr(to(varDecl(hasName("hs9"))))), 4523 ignoringImplicit(declRefExpr( 4524 to(varDecl(hasName("hs10")))))))), 4525 true, {"-std=c++20"})); 4526 EXPECT_TRUE(matchesConditionally( 4527 Code, 4528 traverse(TK_IgnoreUnlessSpelledInSource, 4529 cxxRewrittenBinaryOperator( 4530 hasOperatorName("<="), hasAnyOperatorName("<", "<="), 4531 isComparisonOperator(), 4532 hasLHS(declRefExpr(to(varDecl(hasName("hs9"))))), 4533 hasRHS(declRefExpr(to(varDecl(hasName("hs10"))))), 4534 hasEitherOperand(declRefExpr(to(varDecl(hasName("hs9"))))), 4535 hasOperands(declRefExpr(to(varDecl(hasName("hs9")))), 4536 declRefExpr(to(varDecl(hasName("hs10"))))))), 4537 true, {"-std=c++20"})); 4538 } 4539 { 4540 EXPECT_TRUE(matchesConditionally( 4541 Code, 4542 traverse(TK_AsIs, 4543 cxxRewrittenBinaryOperator( 4544 hasOperatorName(">="), hasAnyOperatorName("<", ">="), 4545 isComparisonOperator(), 4546 hasLHS(ignoringImplicit( 4547 declRefExpr(to(varDecl(hasName("hs11")))))), 4548 hasRHS(ignoringImplicit( 4549 declRefExpr(to(varDecl(hasName("hs12")))))), 4550 hasEitherOperand(ignoringImplicit( 4551 declRefExpr(to(varDecl(hasName("hs11")))))), 4552 hasOperands(ignoringImplicit( 4553 declRefExpr(to(varDecl(hasName("hs11"))))), 4554 ignoringImplicit(declRefExpr( 4555 to(varDecl(hasName("hs12")))))))), 4556 true, {"-std=c++20"})); 4557 EXPECT_TRUE(matchesConditionally( 4558 Code, 4559 traverse( 4560 TK_IgnoreUnlessSpelledInSource, 4561 cxxRewrittenBinaryOperator( 4562 hasOperatorName(">="), hasAnyOperatorName("<", ">="), 4563 isComparisonOperator(), 4564 hasLHS(declRefExpr(to(varDecl(hasName("hs11"))))), 4565 hasRHS(declRefExpr(to(varDecl(hasName("hs12"))))), 4566 hasEitherOperand(declRefExpr(to(varDecl(hasName("hs11"))))), 4567 hasOperands(declRefExpr(to(varDecl(hasName("hs11")))), 4568 declRefExpr(to(varDecl(hasName("hs12"))))))), 4569 true, {"-std=c++20"})); 4570 } 4571 4572 Code = R"cpp( 4573 struct S {}; 4574 4575 struct HasOpEq 4576 { 4577 bool operator==(const S& other) const 4578 { 4579 return true; 4580 } 4581 }; 4582 4583 struct HasOpEqMem { 4584 bool operator==(const HasOpEqMem&) const { return true; } 4585 }; 4586 4587 struct HasOpEqFree { 4588 }; 4589 bool operator==(const HasOpEqFree&, const HasOpEqFree&) { return true; } 4590 4591 void binop() 4592 { 4593 { 4594 HasOpEq s1; 4595 S s2; 4596 if (s1 != s2) 4597 return; 4598 } 4599 4600 { 4601 int i1; 4602 int i2; 4603 if (i1 != i2) 4604 return; 4605 } 4606 4607 { 4608 HasOpEqMem M1; 4609 HasOpEqMem M2; 4610 if (M1 == M2) 4611 return; 4612 } 4613 4614 { 4615 HasOpEqFree F1; 4616 HasOpEqFree F2; 4617 if (F1 == F2) 4618 return; 4619 } 4620 } 4621 )cpp"; 4622 { 4623 EXPECT_TRUE(matchesConditionally( 4624 Code, 4625 traverse(TK_AsIs, 4626 binaryOperation( 4627 hasOperatorName("!="), hasAnyOperatorName("<", "!="), 4628 isComparisonOperator(), 4629 hasLHS(ignoringImplicit( 4630 declRefExpr(to(varDecl(hasName("s1")))))), 4631 hasRHS(ignoringImplicit( 4632 declRefExpr(to(varDecl(hasName("s2")))))), 4633 hasEitherOperand(ignoringImplicit( 4634 declRefExpr(to(varDecl(hasName("s2")))))), 4635 hasOperands(ignoringImplicit( 4636 declRefExpr(to(varDecl(hasName("s1"))))), 4637 ignoringImplicit(declRefExpr( 4638 to(varDecl(hasName("s2")))))))), 4639 true, {"-std=c++20"})); 4640 EXPECT_TRUE(matchesConditionally( 4641 Code, 4642 traverse(TK_AsIs, binaryOperation(hasOperatorName("!="), 4643 hasLHS(ignoringImplicit(declRefExpr( 4644 to(varDecl(hasName("i1")))))), 4645 hasRHS(ignoringImplicit(declRefExpr( 4646 to(varDecl(hasName("i2")))))))), 4647 true, {"-std=c++20"})); 4648 EXPECT_TRUE(matchesConditionally( 4649 Code, 4650 traverse(TK_AsIs, binaryOperation(hasOperatorName("=="), 4651 hasLHS(ignoringImplicit(declRefExpr( 4652 to(varDecl(hasName("M1")))))), 4653 hasRHS(ignoringImplicit(declRefExpr( 4654 to(varDecl(hasName("M2")))))))), 4655 true, {"-std=c++20"})); 4656 EXPECT_TRUE(matchesConditionally( 4657 Code, 4658 traverse(TK_AsIs, binaryOperation(hasOperatorName("=="), 4659 hasLHS(ignoringImplicit(declRefExpr( 4660 to(varDecl(hasName("F1")))))), 4661 hasRHS(ignoringImplicit(declRefExpr( 4662 to(varDecl(hasName("F2")))))))), 4663 true, {"-std=c++20"})); 4664 EXPECT_TRUE(matchesConditionally( 4665 Code, 4666 traverse(TK_IgnoreUnlessSpelledInSource, 4667 binaryOperation( 4668 hasOperatorName("!="), hasAnyOperatorName("<", "!="), 4669 isComparisonOperator(), 4670 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))), 4671 hasRHS(declRefExpr(to(varDecl(hasName("s2"))))), 4672 hasEitherOperand(declRefExpr(to(varDecl(hasName("s2"))))), 4673 hasOperands(declRefExpr(to(varDecl(hasName("s1")))), 4674 declRefExpr(to(varDecl(hasName("s2"))))))), 4675 true, {"-std=c++20"})); 4676 EXPECT_TRUE(matchesConditionally( 4677 Code, 4678 traverse( 4679 TK_IgnoreUnlessSpelledInSource, 4680 binaryOperation(hasOperatorName("!="), 4681 hasLHS(declRefExpr(to(varDecl(hasName("i1"))))), 4682 hasRHS(declRefExpr(to(varDecl(hasName("i2"))))))), 4683 true, {"-std=c++20"})); 4684 EXPECT_TRUE(matchesConditionally( 4685 Code, 4686 traverse( 4687 TK_IgnoreUnlessSpelledInSource, 4688 binaryOperation(hasOperatorName("=="), 4689 hasLHS(declRefExpr(to(varDecl(hasName("M1"))))), 4690 hasRHS(declRefExpr(to(varDecl(hasName("M2"))))))), 4691 true, {"-std=c++20"})); 4692 EXPECT_TRUE(matchesConditionally( 4693 Code, 4694 traverse( 4695 TK_IgnoreUnlessSpelledInSource, 4696 binaryOperation(hasOperatorName("=="), 4697 hasLHS(declRefExpr(to(varDecl(hasName("F1"))))), 4698 hasRHS(declRefExpr(to(varDecl(hasName("F2"))))))), 4699 true, {"-std=c++20"})); 4700 } 4701 } 4702 4703 TEST(IgnoringImpCasts, PathologicalLambda) { 4704 4705 // Test that deeply nested lambdas are not a performance penalty 4706 StringRef Code = R"cpp( 4707 void f() { 4708 [] { 4709 [] { 4710 [] { 4711 [] { 4712 [] { 4713 [] { 4714 [] { 4715 [] { 4716 [] { 4717 [] { 4718 [] { 4719 [] { 4720 [] { 4721 [] { 4722 [] { 4723 [] { 4724 [] { 4725 [] { 4726 [] { 4727 [] { 4728 [] { 4729 [] { 4730 [] { 4731 [] { 4732 [] { 4733 [] { 4734 [] { 4735 [] { 4736 [] { 4737 int i = 42; 4738 (void)i; 4739 }(); 4740 }(); 4741 }(); 4742 }(); 4743 }(); 4744 }(); 4745 }(); 4746 }(); 4747 }(); 4748 }(); 4749 }(); 4750 }(); 4751 }(); 4752 }(); 4753 }(); 4754 }(); 4755 }(); 4756 }(); 4757 }(); 4758 }(); 4759 }(); 4760 }(); 4761 }(); 4762 }(); 4763 }(); 4764 }(); 4765 }(); 4766 }(); 4767 }(); 4768 } 4769 )cpp"; 4770 4771 EXPECT_TRUE(matches(Code, integerLiteral(equals(42)))); 4772 EXPECT_TRUE(matches(Code, functionDecl(hasDescendant(integerLiteral(equals(42)))))); 4773 } 4774 4775 TEST(IgnoringImpCasts, MatchesImpCasts) { 4776 // This test checks that ignoringImpCasts matches when implicit casts are 4777 // present and its inner matcher alone does not match. 4778 // Note that this test creates an implicit const cast. 4779 EXPECT_TRUE(matches("int x = 0; const int y = x;", 4780 varDecl(hasInitializer(ignoringImpCasts( 4781 declRefExpr(to(varDecl(hasName("x"))))))))); 4782 // This test creates an implict cast from int to char. 4783 EXPECT_TRUE(matches("char x = 0;", 4784 varDecl(hasInitializer(ignoringImpCasts( 4785 integerLiteral(equals(0))))))); 4786 } 4787 4788 TEST(IgnoringImpCasts, DoesNotMatchIncorrectly) { 4789 // These tests verify that ignoringImpCasts does not match if the inner 4790 // matcher does not match. 4791 // Note that the first test creates an implicit const cast. 4792 EXPECT_TRUE(notMatches("int x; const int y = x;", 4793 varDecl(hasInitializer(ignoringImpCasts( 4794 unless(anything())))))); 4795 EXPECT_TRUE(notMatches("int x; int y = x;", 4796 varDecl(hasInitializer(ignoringImpCasts( 4797 unless(anything())))))); 4798 4799 // These tests verify that ignoringImplictCasts does not look through explicit 4800 // casts or parentheses. 4801 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);", 4802 varDecl(hasInitializer(ignoringImpCasts( 4803 integerLiteral()))))); 4804 EXPECT_TRUE(notMatches( 4805 "int i = (0);", 4806 traverse(TK_AsIs, 4807 varDecl(hasInitializer(ignoringImpCasts(integerLiteral())))))); 4808 EXPECT_TRUE(notMatches("float i = (float)0;", 4809 varDecl(hasInitializer(ignoringImpCasts( 4810 integerLiteral()))))); 4811 EXPECT_TRUE(notMatches("float i = float(0);", 4812 varDecl(hasInitializer(ignoringImpCasts( 4813 integerLiteral()))))); 4814 } 4815 4816 TEST(IgnoringImpCasts, MatchesWithoutImpCasts) { 4817 // This test verifies that expressions that do not have implicit casts 4818 // still match the inner matcher. 4819 EXPECT_TRUE(matches("int x = 0; int &y = x;", 4820 varDecl(hasInitializer(ignoringImpCasts( 4821 declRefExpr(to(varDecl(hasName("x"))))))))); 4822 } 4823 4824 TEST(IgnoringParenCasts, MatchesParenCasts) { 4825 // This test checks that ignoringParenCasts matches when parentheses and/or 4826 // casts are present and its inner matcher alone does not match. 4827 EXPECT_TRUE(matches("int x = (0);", 4828 varDecl(hasInitializer(ignoringParenCasts( 4829 integerLiteral(equals(0))))))); 4830 EXPECT_TRUE(matches("int x = (((((0)))));", 4831 varDecl(hasInitializer(ignoringParenCasts( 4832 integerLiteral(equals(0))))))); 4833 4834 // This test creates an implict cast from int to char in addition to the 4835 // parentheses. 4836 EXPECT_TRUE(matches("char x = (0);", 4837 varDecl(hasInitializer(ignoringParenCasts( 4838 integerLiteral(equals(0))))))); 4839 4840 EXPECT_TRUE(matches("char x = (char)0;", 4841 varDecl(hasInitializer(ignoringParenCasts( 4842 integerLiteral(equals(0))))))); 4843 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);", 4844 varDecl(hasInitializer(ignoringParenCasts( 4845 integerLiteral(equals(0))))))); 4846 } 4847 4848 TEST(IgnoringParenCasts, MatchesWithoutParenCasts) { 4849 // This test verifies that expressions that do not have any casts still match. 4850 EXPECT_TRUE(matches("int x = 0;", 4851 varDecl(hasInitializer(ignoringParenCasts( 4852 integerLiteral(equals(0))))))); 4853 } 4854 4855 TEST(IgnoringParenCasts, DoesNotMatchIncorrectly) { 4856 // These tests verify that ignoringImpCasts does not match if the inner 4857 // matcher does not match. 4858 EXPECT_TRUE(notMatches("int x = ((0));", 4859 varDecl(hasInitializer(ignoringParenCasts( 4860 unless(anything())))))); 4861 4862 // This test creates an implicit cast from int to char in addition to the 4863 // parentheses. 4864 EXPECT_TRUE(notMatches("char x = ((0));", 4865 varDecl(hasInitializer(ignoringParenCasts( 4866 unless(anything())))))); 4867 4868 EXPECT_TRUE(notMatches("char *x = static_cast<char *>((0));", 4869 varDecl(hasInitializer(ignoringParenCasts( 4870 unless(anything())))))); 4871 } 4872 4873 TEST(IgnoringParenAndImpCasts, MatchesParenImpCasts) { 4874 // This test checks that ignoringParenAndImpCasts matches when 4875 // parentheses and/or implicit casts are present and its inner matcher alone 4876 // does not match. 4877 // Note that this test creates an implicit const cast. 4878 EXPECT_TRUE(matches("int x = 0; const int y = x;", 4879 varDecl(hasInitializer(ignoringParenImpCasts( 4880 declRefExpr(to(varDecl(hasName("x"))))))))); 4881 // This test creates an implicit cast from int to char. 4882 EXPECT_TRUE(matches("const char x = (0);", 4883 varDecl(hasInitializer(ignoringParenImpCasts( 4884 integerLiteral(equals(0))))))); 4885 } 4886 4887 TEST(IgnoringParenAndImpCasts, MatchesWithoutParenImpCasts) { 4888 // This test verifies that expressions that do not have parentheses or 4889 // implicit casts still match. 4890 EXPECT_TRUE(matches("int x = 0; int &y = x;", 4891 varDecl(hasInitializer(ignoringParenImpCasts( 4892 declRefExpr(to(varDecl(hasName("x"))))))))); 4893 EXPECT_TRUE(matches("int x = 0;", 4894 varDecl(hasInitializer(ignoringParenImpCasts( 4895 integerLiteral(equals(0))))))); 4896 } 4897 4898 TEST(IgnoringParenAndImpCasts, DoesNotMatchIncorrectly) { 4899 // These tests verify that ignoringParenImpCasts does not match if 4900 // the inner matcher does not match. 4901 // This test creates an implicit cast. 4902 EXPECT_TRUE(notMatches("char c = ((3));", 4903 varDecl(hasInitializer(ignoringParenImpCasts( 4904 unless(anything())))))); 4905 // These tests verify that ignoringParenAndImplictCasts does not look 4906 // through explicit casts. 4907 EXPECT_TRUE(notMatches("float y = (float(0));", 4908 varDecl(hasInitializer(ignoringParenImpCasts( 4909 integerLiteral()))))); 4910 EXPECT_TRUE(notMatches("float y = (float)0;", 4911 varDecl(hasInitializer(ignoringParenImpCasts( 4912 integerLiteral()))))); 4913 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);", 4914 varDecl(hasInitializer(ignoringParenImpCasts( 4915 integerLiteral()))))); 4916 } 4917 4918 TEST(HasSourceExpression, MatchesImplicitCasts) { 4919 EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };" 4920 "void r() {string a_string; URL url = a_string; }", 4921 traverse(TK_AsIs, implicitCastExpr(hasSourceExpression( 4922 cxxConstructExpr()))))); 4923 } 4924 4925 TEST(HasSourceExpression, MatchesExplicitCasts) { 4926 EXPECT_TRUE( 4927 matches("float x = static_cast<float>(42);", 4928 traverse(TK_AsIs, explicitCastExpr(hasSourceExpression( 4929 hasDescendant(expr(integerLiteral()))))))); 4930 } 4931 4932 TEST(UsingDeclaration, MatchesSpecificTarget) { 4933 EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;", 4934 usingDecl(hasAnyUsingShadowDecl( 4935 hasTargetDecl(functionDecl()))))); 4936 EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;", 4937 usingDecl(hasAnyUsingShadowDecl( 4938 hasTargetDecl(functionDecl()))))); 4939 } 4940 4941 TEST(UsingDeclaration, ThroughUsingDeclaration) { 4942 EXPECT_TRUE(matches( 4943 "namespace a { void f(); } using a::f; void g() { f(); }", 4944 declRefExpr(throughUsingDecl(anything())))); 4945 EXPECT_TRUE(notMatches( 4946 "namespace a { void f(); } using a::f; void g() { a::f(); }", 4947 declRefExpr(throughUsingDecl(anything())))); 4948 } 4949 4950 TEST(SingleDecl, IsSingleDecl) { 4951 StatementMatcher SingleDeclStmt = 4952 declStmt(hasSingleDecl(varDecl(hasInitializer(anything())))); 4953 EXPECT_TRUE(matches("void f() {int a = 4;}", SingleDeclStmt)); 4954 EXPECT_TRUE(notMatches("void f() {int a;}", SingleDeclStmt)); 4955 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}", 4956 SingleDeclStmt)); 4957 } 4958 4959 TEST(DeclStmt, ContainsDeclaration) { 4960 DeclarationMatcher MatchesInit = varDecl(hasInitializer(anything())); 4961 4962 EXPECT_TRUE(matches("void f() {int a = 4;}", 4963 declStmt(containsDeclaration(0, MatchesInit)))); 4964 EXPECT_TRUE(matches("void f() {int a = 4, b = 3;}", 4965 declStmt(containsDeclaration(0, MatchesInit), 4966 containsDeclaration(1, MatchesInit)))); 4967 unsigned WrongIndex = 42; 4968 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}", 4969 declStmt(containsDeclaration(WrongIndex, 4970 MatchesInit)))); 4971 } 4972 4973 TEST(SwitchCase, MatchesEachCase) { 4974 EXPECT_TRUE(notMatches("void x() { switch(42); }", 4975 switchStmt(forEachSwitchCase(caseStmt())))); 4976 EXPECT_TRUE(matches("void x() { switch(42) case 42:; }", 4977 switchStmt(forEachSwitchCase(caseStmt())))); 4978 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", 4979 switchStmt(forEachSwitchCase(caseStmt())))); 4980 EXPECT_TRUE(notMatches( 4981 "void x() { if (1) switch(42) { case 42: switch (42) { default:; } } }", 4982 ifStmt(has(switchStmt(forEachSwitchCase(defaultStmt())))))); 4983 EXPECT_TRUE(matches( 4984 "void x() { switch(42) { case 1+1: case 4:; } }", 4985 traverse(TK_AsIs, switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant( 4986 constantExpr(has(integerLiteral()))))))))); 4987 EXPECT_TRUE(notMatches( 4988 "void x() { switch(42) { case 1+1: case 2+2:; } }", 4989 traverse(TK_AsIs, switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant( 4990 constantExpr(has(integerLiteral()))))))))); 4991 EXPECT_TRUE(notMatches( 4992 "void x() { switch(42) { case 1 ... 2:; } }", 4993 traverse(TK_AsIs, switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant( 4994 constantExpr(has(integerLiteral()))))))))); 4995 EXPECT_TRUE(matchAndVerifyResultTrue( 4996 "void x() { switch (42) { case 1: case 2: case 3: default:; } }", 4997 switchStmt(forEachSwitchCase(caseStmt().bind("x"))), 4998 std::make_unique<VerifyIdIsBoundTo<CaseStmt>>("x", 3))); 4999 } 5000 5001 TEST(Declaration, HasExplicitSpecifier) { 5002 5003 EXPECT_TRUE(notMatches("void f();", 5004 functionDecl(hasExplicitSpecifier(constantExpr())), 5005 langCxx20OrLater())); 5006 EXPECT_TRUE( 5007 notMatches("template<bool b> struct S { explicit operator int(); };", 5008 cxxConversionDecl( 5009 hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))), 5010 langCxx20OrLater())); 5011 EXPECT_TRUE( 5012 notMatches("template<bool b> struct S { explicit(b) operator int(); };", 5013 cxxConversionDecl( 5014 hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))), 5015 langCxx20OrLater())); 5016 EXPECT_TRUE( 5017 matches("struct S { explicit(true) operator int(); };", 5018 traverse(TK_AsIs, cxxConversionDecl(hasExplicitSpecifier( 5019 constantExpr(has(cxxBoolLiteral()))))), 5020 langCxx20OrLater())); 5021 EXPECT_TRUE( 5022 matches("struct S { explicit(false) operator int(); };", 5023 traverse(TK_AsIs, cxxConversionDecl(hasExplicitSpecifier( 5024 constantExpr(has(cxxBoolLiteral()))))), 5025 langCxx20OrLater())); 5026 EXPECT_TRUE( 5027 notMatches("template<bool b> struct S { explicit(b) S(int); };", 5028 traverse(TK_AsIs, cxxConstructorDecl(hasExplicitSpecifier( 5029 constantExpr(has(cxxBoolLiteral()))))), 5030 langCxx20OrLater())); 5031 EXPECT_TRUE( 5032 matches("struct S { explicit(true) S(int); };", 5033 traverse(TK_AsIs, cxxConstructorDecl(hasExplicitSpecifier( 5034 constantExpr(has(cxxBoolLiteral()))))), 5035 langCxx20OrLater())); 5036 EXPECT_TRUE( 5037 matches("struct S { explicit(false) S(int); };", 5038 traverse(TK_AsIs, cxxConstructorDecl(hasExplicitSpecifier( 5039 constantExpr(has(cxxBoolLiteral()))))), 5040 langCxx20OrLater())); 5041 EXPECT_TRUE( 5042 notMatches("template<typename T> struct S { S(int); };" 5043 "template<bool b = true> explicit(b) S(int) -> S<int>;", 5044 traverse(TK_AsIs, cxxDeductionGuideDecl(hasExplicitSpecifier( 5045 constantExpr(has(cxxBoolLiteral()))))), 5046 langCxx20OrLater())); 5047 EXPECT_TRUE( 5048 matches("template<typename T> struct S { S(int); };" 5049 "explicit(true) S(int) -> S<int>;", 5050 traverse(TK_AsIs, cxxDeductionGuideDecl(hasExplicitSpecifier( 5051 constantExpr(has(cxxBoolLiteral()))))), 5052 langCxx20OrLater())); 5053 EXPECT_TRUE( 5054 matches("template<typename T> struct S { S(int); };" 5055 "explicit(false) S(int) -> S<int>;", 5056 traverse(TK_AsIs, cxxDeductionGuideDecl(hasExplicitSpecifier( 5057 constantExpr(has(cxxBoolLiteral()))))), 5058 langCxx20OrLater())); 5059 } 5060 5061 TEST(ForEachConstructorInitializer, MatchesInitializers) { 5062 EXPECT_TRUE(matches( 5063 "struct X { X() : i(42), j(42) {} int i, j; };", 5064 cxxConstructorDecl(forEachConstructorInitializer(cxxCtorInitializer())))); 5065 } 5066 5067 TEST(LambdaCapture, InvalidLambdaCapture) { 5068 // not crash 5069 EXPECT_FALSE(matches( 5070 R"(int main() { 5071 struct A { A()=default; A(A const&)=delete; }; 5072 A a; [a]() -> void {}(); 5073 return 0; 5074 })", 5075 traverse(TK_IgnoreUnlessSpelledInSource, 5076 lambdaExpr(has(lambdaCapture()))), 5077 langCxx11OrLater())); 5078 } 5079 5080 TEST(ForEachLambdaCapture, MatchesCaptures) { 5081 EXPECT_TRUE(matches( 5082 "int main() { int x, y; auto f = [x, y]() { return x + y; }; }", 5083 lambdaExpr(forEachLambdaCapture(lambdaCapture())), langCxx11OrLater())); 5084 auto matcher = lambdaExpr(forEachLambdaCapture( 5085 lambdaCapture(capturesVar(varDecl(hasType(isInteger())))).bind("LC"))); 5086 EXPECT_TRUE(matchAndVerifyResultTrue( 5087 "int main() { int x, y; float z; auto f = [=]() { return x + y + z; }; }", 5088 matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 2))); 5089 EXPECT_TRUE(matchAndVerifyResultTrue( 5090 "int main() { int x, y; float z; auto f = [x, y, z]() { return x + y + " 5091 "z; }; }", 5092 matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 2))); 5093 } 5094 5095 TEST(ForEachLambdaCapture, IgnoreUnlessSpelledInSource) { 5096 auto matcher = 5097 traverse(TK_IgnoreUnlessSpelledInSource, 5098 lambdaExpr(forEachLambdaCapture( 5099 lambdaCapture(capturesVar(varDecl(hasType(isInteger())))) 5100 .bind("LC")))); 5101 EXPECT_TRUE( 5102 notMatches("int main() { int x, y; auto f = [=]() { return x + y; }; }", 5103 matcher, langCxx11OrLater())); 5104 EXPECT_TRUE( 5105 notMatches("int main() { int x, y; auto f = [&]() { return x + y; }; }", 5106 matcher, langCxx11OrLater())); 5107 EXPECT_TRUE(matchAndVerifyResultTrue( 5108 R"cc( 5109 int main() { 5110 int x, y; 5111 float z; 5112 auto f = [=, &y]() { return x + y + z; }; 5113 } 5114 )cc", 5115 matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 1))); 5116 } 5117 5118 TEST(ForEachLambdaCapture, MatchImplicitCapturesOnly) { 5119 auto matcher = 5120 lambdaExpr(forEachLambdaCapture(lambdaCapture(isImplicit()).bind("LC"))); 5121 EXPECT_TRUE(matchAndVerifyResultTrue( 5122 "int main() { int x, y, z; auto f = [=, &z]() { return x + y + z; }; }", 5123 matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 2))); 5124 EXPECT_TRUE(matchAndVerifyResultTrue( 5125 "int main() { int x, y, z; auto f = [&, z]() { return x + y + z; }; }", 5126 matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 2))); 5127 } 5128 5129 TEST(ForEachLambdaCapture, MatchExplicitCapturesOnly) { 5130 auto matcher = lambdaExpr( 5131 forEachLambdaCapture(lambdaCapture(unless(isImplicit())).bind("LC"))); 5132 EXPECT_TRUE(matchAndVerifyResultTrue( 5133 "int main() { int x, y, z; auto f = [=, &z]() { return x + y + z; }; }", 5134 matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 1))); 5135 EXPECT_TRUE(matchAndVerifyResultTrue( 5136 "int main() { int x, y, z; auto f = [&, z]() { return x + y + z; }; }", 5137 matcher, std::make_unique<VerifyIdIsBoundTo<LambdaCapture>>("LC", 1))); 5138 } 5139 5140 TEST(HasConditionVariableStatement, DoesNotMatchCondition) { 5141 EXPECT_TRUE(notMatches( 5142 "void x() { if(true) {} }", 5143 ifStmt(hasConditionVariableStatement(declStmt())))); 5144 EXPECT_TRUE(notMatches( 5145 "void x() { int x; if((x = 42)) {} }", 5146 ifStmt(hasConditionVariableStatement(declStmt())))); 5147 } 5148 5149 TEST(HasConditionVariableStatement, MatchesConditionVariables) { 5150 EXPECT_TRUE(matches( 5151 "void x() { if(int* a = 0) {} }", 5152 ifStmt(hasConditionVariableStatement(declStmt())))); 5153 } 5154 5155 TEST(ForEach, BindsOneNode) { 5156 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };", 5157 recordDecl(hasName("C"), forEach(fieldDecl(hasName("x")).bind("x"))), 5158 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("x", 1))); 5159 } 5160 5161 TEST(ForEach, BindsMultipleNodes) { 5162 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };", 5163 recordDecl(hasName("C"), forEach(fieldDecl().bind("f"))), 5164 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 3))); 5165 } 5166 5167 TEST(ForEach, BindsRecursiveCombinations) { 5168 EXPECT_TRUE(matchAndVerifyResultTrue( 5169 "class C { class D { int x; int y; }; class E { int y; int z; }; };", 5170 recordDecl(hasName("C"), 5171 forEach(recordDecl(forEach(fieldDecl().bind("f"))))), 5172 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 4))); 5173 } 5174 5175 TEST(ForEach, DoesNotIgnoreImplicit) { 5176 StringRef Code = R"cpp( 5177 void foo() 5178 { 5179 int i = 0; 5180 int b = 4; 5181 i < b; 5182 } 5183 )cpp"; 5184 EXPECT_TRUE(matchAndVerifyResultFalse( 5185 Code, binaryOperator(forEach(declRefExpr().bind("dre"))), 5186 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 0))); 5187 5188 EXPECT_TRUE(matchAndVerifyResultTrue( 5189 Code, 5190 binaryOperator(forEach( 5191 implicitCastExpr(hasSourceExpression(declRefExpr().bind("dre"))))), 5192 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 2))); 5193 5194 EXPECT_TRUE(matchAndVerifyResultTrue( 5195 Code, 5196 binaryOperator( 5197 forEach(expr(ignoringImplicit(declRefExpr().bind("dre"))))), 5198 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 2))); 5199 5200 EXPECT_TRUE(matchAndVerifyResultTrue( 5201 Code, 5202 traverse(TK_IgnoreUnlessSpelledInSource, 5203 binaryOperator(forEach(declRefExpr().bind("dre")))), 5204 std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("dre", 2))); 5205 } 5206 5207 TEST(ForEachDescendant, BindsOneNode) { 5208 EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };", 5209 recordDecl(hasName("C"), 5210 forEachDescendant(fieldDecl(hasName("x")).bind("x"))), 5211 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("x", 1))); 5212 } 5213 5214 TEST(ForEachDescendant, NestedForEachDescendant) { 5215 DeclarationMatcher m = recordDecl( 5216 isDefinition(), decl().bind("x"), hasName("C")); 5217 EXPECT_TRUE(matchAndVerifyResultTrue( 5218 "class A { class B { class C {}; }; };", 5219 recordDecl(hasName("A"), anyOf(m, forEachDescendant(m))), 5220 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", "C"))); 5221 5222 // Check that a partial match of 'm' that binds 'x' in the 5223 // first part of anyOf(m, anything()) will not overwrite the 5224 // binding created by the earlier binding in the hasDescendant. 5225 EXPECT_TRUE(matchAndVerifyResultTrue( 5226 "class A { class B { class C {}; }; };", 5227 recordDecl(hasName("A"), allOf(hasDescendant(m), anyOf(m, anything()))), 5228 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", "C"))); 5229 } 5230 5231 TEST(ForEachDescendant, BindsMultipleNodes) { 5232 EXPECT_TRUE(matchAndVerifyResultTrue( 5233 "class C { class D { int x; int y; }; " 5234 " class E { class F { int y; int z; }; }; };", 5235 recordDecl(hasName("C"), forEachDescendant(fieldDecl().bind("f"))), 5236 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 4))); 5237 } 5238 5239 TEST(ForEachDescendant, BindsRecursiveCombinations) { 5240 EXPECT_TRUE(matchAndVerifyResultTrue( 5241 "class C { class D { " 5242 " class E { class F { class G { int y; int z; }; }; }; }; };", 5243 recordDecl(hasName("C"), forEachDescendant(recordDecl( 5244 forEachDescendant(fieldDecl().bind("f"))))), 5245 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("f", 8))); 5246 } 5247 5248 TEST(ForEachDescendant, BindsCombinations) { 5249 EXPECT_TRUE(matchAndVerifyResultTrue( 5250 "void f() { if(true) {} if (true) {} while (true) {} if (true) {} while " 5251 "(true) {} }", 5252 compoundStmt(forEachDescendant(ifStmt().bind("if")), 5253 forEachDescendant(whileStmt().bind("while"))), 5254 std::make_unique<VerifyIdIsBoundTo<IfStmt>>("if", 6))); 5255 } 5256 5257 TEST(ForEachTemplateArgument, OnFunctionDecl) { 5258 const std::string Code = R"( 5259 template <typename T, typename U> void f(T, U) {} 5260 void test() { 5261 int I = 1; 5262 bool B = false; 5263 f(I, B); 5264 })"; 5265 EXPECT_TRUE(matches( 5266 Code, functionDecl(forEachTemplateArgument(refersToType(builtinType()))), 5267 langCxx11OrLater())); 5268 auto matcher = 5269 functionDecl(forEachTemplateArgument( 5270 templateArgument(refersToType(builtinType().bind("BT"))) 5271 .bind("TA"))) 5272 .bind("FN"); 5273 5274 EXPECT_TRUE(matchAndVerifyResultTrue( 5275 Code, matcher, 5276 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("FN", 2))); 5277 EXPECT_TRUE(matchAndVerifyResultTrue( 5278 Code, matcher, 5279 std::make_unique<VerifyIdIsBoundTo<TemplateArgument>>("TA", 2))); 5280 EXPECT_TRUE(matchAndVerifyResultTrue( 5281 Code, matcher, 5282 std::make_unique<VerifyIdIsBoundTo<BuiltinType>>("BT", 2))); 5283 } 5284 5285 TEST(ForEachTemplateArgument, OnClassTemplateSpecialization) { 5286 const std::string Code = R"( 5287 template <typename T, unsigned N, unsigned M> 5288 struct Matrix {}; 5289 5290 static constexpr unsigned R = 2; 5291 5292 Matrix<int, R * 2, R * 4> M; 5293 )"; 5294 EXPECT_TRUE(matches( 5295 Code, templateSpecializationType(forEachTemplateArgument(isExpr(expr()))), 5296 langCxx11OrLater())); 5297 auto matcher = templateSpecializationType( 5298 forEachTemplateArgument( 5299 templateArgument(isExpr(expr().bind("E"))).bind("TA"))) 5300 .bind("TST"); 5301 5302 EXPECT_TRUE(matchAndVerifyResultTrue( 5303 Code, matcher, 5304 std::make_unique<VerifyIdIsBoundTo<TemplateSpecializationType>>("TST", 5305 2))); 5306 EXPECT_TRUE(matchAndVerifyResultTrue( 5307 Code, matcher, 5308 std::make_unique<VerifyIdIsBoundTo<TemplateArgument>>("TA", 2))); 5309 EXPECT_TRUE(matchAndVerifyResultTrue( 5310 Code, matcher, std::make_unique<VerifyIdIsBoundTo<Expr>>("E", 2))); 5311 } 5312 5313 TEST(Has, DoesNotDeleteBindings) { 5314 EXPECT_TRUE(matchAndVerifyResultTrue( 5315 "class X { int a; };", recordDecl(decl().bind("x"), has(fieldDecl())), 5316 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1))); 5317 } 5318 5319 TEST(TemplateArgumentLoc, Matches) { 5320 EXPECT_TRUE(matchAndVerifyResultTrue( 5321 R"cpp( 5322 template <typename A, int B, template <typename> class C> class X {}; 5323 class A {}; 5324 const int B = 42; 5325 template <typename> class C {}; 5326 X<A, B, C> x; 5327 )cpp", 5328 templateArgumentLoc().bind("x"), 5329 std::make_unique<VerifyIdIsBoundTo<TemplateArgumentLoc>>("x", 3))); 5330 } 5331 5332 TEST(LoopingMatchers, DoNotOverwritePreviousMatchResultOnFailure) { 5333 // Those matchers cover all the cases where an inner matcher is called 5334 // and there is not a 1:1 relationship between the match of the outer 5335 // matcher and the match of the inner matcher. 5336 // The pattern to look for is: 5337 // ... return InnerMatcher.matches(...); ... 5338 // In which case no special handling is needed. 5339 // 5340 // On the other hand, if there are multiple alternative matches 5341 // (for example forEach*) or matches might be discarded (for example has*) 5342 // the implementation must make sure that the discarded matches do not 5343 // affect the bindings. 5344 // When new such matchers are added, add a test here that: 5345 // - matches a simple node, and binds it as the first thing in the matcher: 5346 // recordDecl(decl().bind("x"), hasName("X"))) 5347 // - uses the matcher under test afterwards in a way that not the first 5348 // alternative is matched; for anyOf, that means the first branch 5349 // would need to return false; for hasAncestor, it means that not 5350 // the direct parent matches the inner matcher. 5351 5352 EXPECT_TRUE(matchAndVerifyResultTrue( 5353 "class X { int y; };", 5354 recordDecl( 5355 recordDecl().bind("x"), hasName("::X"), 5356 anyOf(forEachDescendant(recordDecl(hasName("Y"))), anything())), 5357 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("x", 1))); 5358 EXPECT_TRUE(matchAndVerifyResultTrue( 5359 "class X {};", recordDecl(recordDecl().bind("x"), hasName("::X"), 5360 anyOf(unless(anything()), anything())), 5361 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("x", 1))); 5362 EXPECT_TRUE(matchAndVerifyResultTrue( 5363 "template<typename T1, typename T2> class X {}; X<float, int> x;", 5364 classTemplateSpecializationDecl( 5365 decl().bind("x"), 5366 hasAnyTemplateArgument(refersToType(asString("int")))), 5367 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1))); 5368 EXPECT_TRUE(matchAndVerifyResultTrue( 5369 "class X { void f(); void g(); };", 5370 cxxRecordDecl(decl().bind("x"), hasMethod(hasName("g"))), 5371 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1))); 5372 EXPECT_TRUE(matchAndVerifyResultTrue( 5373 "class X { X() : a(1), b(2) {} double a; int b; };", 5374 recordDecl(decl().bind("x"), 5375 has(cxxConstructorDecl( 5376 hasAnyConstructorInitializer(forField(hasName("b")))))), 5377 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1))); 5378 EXPECT_TRUE(matchAndVerifyResultTrue( 5379 "void x(int, int) { x(0, 42); }", 5380 callExpr(expr().bind("x"), hasAnyArgument(integerLiteral(equals(42)))), 5381 std::make_unique<VerifyIdIsBoundTo<Expr>>("x", 1))); 5382 EXPECT_TRUE(matchAndVerifyResultTrue( 5383 "void x(int, int y) {}", 5384 functionDecl(decl().bind("x"), hasAnyParameter(hasName("y"))), 5385 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1))); 5386 EXPECT_TRUE(matchAndVerifyResultTrue( 5387 "void x() { return; if (true) {} }", 5388 functionDecl(decl().bind("x"), 5389 has(compoundStmt(hasAnySubstatement(ifStmt())))), 5390 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1))); 5391 EXPECT_TRUE(matchAndVerifyResultTrue( 5392 "namespace X { void b(int); void b(); }" 5393 "using X::b;", 5394 usingDecl(decl().bind("x"), hasAnyUsingShadowDecl(hasTargetDecl( 5395 functionDecl(parameterCountIs(1))))), 5396 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1))); 5397 EXPECT_TRUE(matchAndVerifyResultTrue( 5398 "class A{}; class B{}; class C : B, A {};", 5399 cxxRecordDecl(decl().bind("x"), isDerivedFrom("::A")), 5400 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1))); 5401 EXPECT_TRUE(matchAndVerifyResultTrue( 5402 "class A{}; typedef A B; typedef A C; typedef A D;" 5403 "class E : A {};", 5404 cxxRecordDecl(decl().bind("x"), isDerivedFrom("C")), 5405 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1))); 5406 EXPECT_TRUE(matchAndVerifyResultTrue( 5407 "class A { class B { void f() {} }; };", 5408 functionDecl(decl().bind("x"), hasAncestor(recordDecl(hasName("::A")))), 5409 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1))); 5410 EXPECT_TRUE(matchAndVerifyResultTrue( 5411 "template <typename T> struct A { struct B {" 5412 " void f() { if(true) {} }" 5413 "}; };" 5414 "void t() { A<int>::B b; b.f(); }", 5415 ifStmt(stmt().bind("x"), hasAncestor(recordDecl(hasName("::A")))), 5416 std::make_unique<VerifyIdIsBoundTo<Stmt>>("x", 2))); 5417 EXPECT_TRUE(matchAndVerifyResultTrue( 5418 "class A {};", 5419 recordDecl(hasName("::A"), decl().bind("x"), unless(hasName("fooble"))), 5420 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1))); 5421 EXPECT_TRUE(matchAndVerifyResultTrue( 5422 "class A { A() : s(), i(42) {} const char *s; int i; };", 5423 cxxConstructorDecl(hasName("::A::A"), decl().bind("x"), 5424 forEachConstructorInitializer(forField(hasName("i")))), 5425 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1))); 5426 } 5427 5428 TEST(ForEachDescendant, BindsCorrectNodes) { 5429 EXPECT_TRUE(matchAndVerifyResultTrue( 5430 "class C { void f(); int i; };", 5431 recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))), 5432 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("decl", 1))); 5433 EXPECT_TRUE(matchAndVerifyResultTrue( 5434 "class C { void f() {} int i; };", 5435 recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))), 5436 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("decl", 1))); 5437 } 5438 5439 TEST(FindAll, BindsNodeOnMatch) { 5440 EXPECT_TRUE(matchAndVerifyResultTrue( 5441 "class A {};", 5442 recordDecl(hasName("::A"), findAll(recordDecl(hasName("::A")).bind("v"))), 5443 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("v", 1))); 5444 } 5445 5446 TEST(FindAll, BindsDescendantNodeOnMatch) { 5447 EXPECT_TRUE(matchAndVerifyResultTrue( 5448 "class A { int a; int b; };", 5449 recordDecl(hasName("::A"), findAll(fieldDecl().bind("v"))), 5450 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 2))); 5451 } 5452 5453 TEST(FindAll, BindsNodeAndDescendantNodesOnOneMatch) { 5454 EXPECT_TRUE(matchAndVerifyResultTrue( 5455 "class A { int a; int b; };", 5456 recordDecl(hasName("::A"), 5457 findAll(decl(anyOf(recordDecl(hasName("::A")).bind("v"), 5458 fieldDecl().bind("v"))))), 5459 std::make_unique<VerifyIdIsBoundTo<Decl>>("v", 3))); 5460 5461 EXPECT_TRUE(matchAndVerifyResultTrue( 5462 "class A { class B {}; class C {}; };", 5463 recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("v"))), 5464 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("v", 3))); 5465 } 5466 5467 TEST(HasAncenstor, MatchesDeclarationAncestors) { 5468 EXPECT_TRUE(matches( 5469 "class A { class B { class C {}; }; };", 5470 recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("A")))))); 5471 } 5472 5473 TEST(HasAncenstor, FailsIfNoAncestorMatches) { 5474 EXPECT_TRUE(notMatches( 5475 "class A { class B { class C {}; }; };", 5476 recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("X")))))); 5477 } 5478 5479 TEST(HasAncestor, MatchesDeclarationsThatGetVisitedLater) { 5480 EXPECT_TRUE(matches( 5481 "class A { class B { void f() { C c; } class C {}; }; };", 5482 varDecl(hasName("c"), hasType(recordDecl(hasName("C"), 5483 hasAncestor(recordDecl(hasName("A")))))))); 5484 } 5485 5486 TEST(HasAncenstor, MatchesStatementAncestors) { 5487 EXPECT_TRUE(matches( 5488 "void f() { if (true) { while (false) { 42; } } }", 5489 integerLiteral(equals(42), hasAncestor(ifStmt())))); 5490 } 5491 5492 TEST(HasAncestor, DrillsThroughDifferentHierarchies) { 5493 EXPECT_TRUE(matches( 5494 "void f() { if (true) { int x = 42; } }", 5495 integerLiteral(equals(42), hasAncestor(functionDecl(hasName("f")))))); 5496 } 5497 5498 TEST(HasAncestor, BindsRecursiveCombinations) { 5499 EXPECT_TRUE(matchAndVerifyResultTrue( 5500 "class C { class D { class E { class F { int y; }; }; }; };", 5501 fieldDecl(hasAncestor(recordDecl(hasAncestor(recordDecl().bind("r"))))), 5502 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("r", 1))); 5503 } 5504 5505 TEST(HasAncestor, BindsCombinationsWithHasDescendant) { 5506 EXPECT_TRUE(matchAndVerifyResultTrue( 5507 "class C { class D { class E { class F { int y; }; }; }; };", 5508 fieldDecl(hasAncestor( 5509 decl( 5510 hasDescendant(recordDecl(isDefinition(), 5511 hasAncestor(recordDecl()))) 5512 ).bind("d") 5513 )), 5514 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("d", "E"))); 5515 } 5516 5517 TEST(HasAncestor, MatchesClosestAncestor) { 5518 EXPECT_TRUE(matchAndVerifyResultTrue( 5519 "template <typename T> struct C {" 5520 " void f(int) {" 5521 " struct I { void g(T) { int x; } } i; i.g(42);" 5522 " }" 5523 "};" 5524 "template struct C<int>;", 5525 varDecl(hasName("x"), 5526 hasAncestor(functionDecl(hasParameter( 5527 0, varDecl(hasType(asString("int"))))).bind("f"))).bind("v"), 5528 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("f", "g", 2))); 5529 } 5530 5531 TEST(HasAncestor, MatchesInTemplateInstantiations) { 5532 EXPECT_TRUE(matches( 5533 "template <typename T> struct A { struct B { struct C { T t; }; }; }; " 5534 "A<int>::B::C a;", 5535 fieldDecl(hasType(asString("int")), 5536 hasAncestor(recordDecl(hasName("A")))))); 5537 } 5538 5539 TEST(HasAncestor, MatchesInImplicitCode) { 5540 EXPECT_TRUE(matches( 5541 "struct X {}; struct A { A() {} X x; };", 5542 cxxConstructorDecl( 5543 hasAnyConstructorInitializer(withInitializer(expr( 5544 hasAncestor(recordDecl(hasName("A"))))))))); 5545 } 5546 5547 TEST(HasParent, MatchesOnlyParent) { 5548 EXPECT_TRUE(matches( 5549 "void f() { if (true) { int x = 42; } }", 5550 compoundStmt(hasParent(ifStmt())))); 5551 EXPECT_TRUE(notMatches( 5552 "void f() { for (;;) { int x = 42; } }", 5553 compoundStmt(hasParent(ifStmt())))); 5554 EXPECT_TRUE(notMatches( 5555 "void f() { if (true) for (;;) { int x = 42; } }", 5556 compoundStmt(hasParent(ifStmt())))); 5557 } 5558 5559 TEST(MatcherMemoize, HasParentDiffersFromHas) { 5560 // Test introduced after detecting a bug in memoization 5561 constexpr auto code = "void f() { throw 1; }"; 5562 EXPECT_TRUE(notMatches( 5563 code, 5564 cxxThrowExpr(hasParent(expr())))); 5565 EXPECT_TRUE(matches( 5566 code, 5567 cxxThrowExpr(has(expr())))); 5568 EXPECT_TRUE(matches( 5569 code, 5570 cxxThrowExpr(anyOf(hasParent(expr()), has(expr()))))); 5571 } 5572 5573 TEST(MatcherMemoize, HasDiffersFromHasDescendant) { 5574 // Test introduced after detecting a bug in memoization 5575 constexpr auto code = "void f() { throw 1+1; }"; 5576 EXPECT_TRUE(notMatches( 5577 code, 5578 cxxThrowExpr(has(integerLiteral())))); 5579 EXPECT_TRUE(matches( 5580 code, 5581 cxxThrowExpr(hasDescendant(integerLiteral())))); 5582 EXPECT_TRUE( 5583 notMatches(code, cxxThrowExpr(allOf(hasDescendant(integerLiteral()), 5584 has(integerLiteral()))))); 5585 } 5586 TEST(HasAncestor, MatchesAllAncestors) { 5587 EXPECT_TRUE(matches( 5588 "template <typename T> struct C { static void f() { 42; } };" 5589 "void t() { C<int>::f(); }", 5590 integerLiteral( 5591 equals(42), 5592 allOf( 5593 hasAncestor(cxxRecordDecl(isTemplateInstantiation())), 5594 hasAncestor(cxxRecordDecl(unless(isTemplateInstantiation()))))))); 5595 } 5596 5597 TEST(HasAncestor, ImplicitArrayCopyCtorDeclRefExpr) { 5598 EXPECT_TRUE(matches("struct MyClass {\n" 5599 " int c[1];\n" 5600 " static MyClass Create() { return MyClass(); }\n" 5601 "};", 5602 declRefExpr(to(decl(hasAncestor(decl())))))); 5603 } 5604 5605 TEST(HasAncestor, AnonymousUnionMemberExpr) { 5606 EXPECT_TRUE(matches("int F() {\n" 5607 " union { int i; };\n" 5608 " return i;\n" 5609 "}\n", 5610 memberExpr(member(hasAncestor(decl()))))); 5611 EXPECT_TRUE(matches("void f() {\n" 5612 " struct {\n" 5613 " struct { int a; int b; };\n" 5614 " } s;\n" 5615 " s.a = 4;\n" 5616 "}\n", 5617 memberExpr(member(hasAncestor(decl()))))); 5618 EXPECT_TRUE(matches("void f() {\n" 5619 " struct {\n" 5620 " struct { int a; int b; };\n" 5621 " } s;\n" 5622 " s.a = 4;\n" 5623 "}\n", 5624 declRefExpr(to(decl(hasAncestor(decl())))))); 5625 } 5626 TEST(HasAncestor, NonParmDependentTemplateParmVarDeclRefExpr) { 5627 EXPECT_TRUE(matches("struct PartitionAllocator {\n" 5628 " template<typename T>\n" 5629 " static int quantizedSize(int count) {\n" 5630 " return count;\n" 5631 " }\n" 5632 " void f() { quantizedSize<int>(10); }\n" 5633 "};", 5634 declRefExpr(to(decl(hasAncestor(decl())))))); 5635 } 5636 5637 TEST(HasAncestor, AddressOfExplicitSpecializationFunction) { 5638 EXPECT_TRUE(matches("template <class T> void f();\n" 5639 "template <> void f<int>();\n" 5640 "void (*get_f())() { return f<int>; }\n", 5641 declRefExpr(to(decl(hasAncestor(decl())))))); 5642 } 5643 5644 TEST(HasParent, MatchesAllParents) { 5645 EXPECT_TRUE(matches( 5646 "template <typename T> struct C { static void f() { 42; } };" 5647 "void t() { C<int>::f(); }", 5648 integerLiteral( 5649 equals(42), 5650 hasParent(compoundStmt(hasParent(functionDecl( 5651 hasParent(cxxRecordDecl(isTemplateInstantiation()))))))))); 5652 EXPECT_TRUE( 5653 matches("template <typename T> struct C { static void f() { 42; } };" 5654 "void t() { C<int>::f(); }", 5655 integerLiteral( 5656 equals(42), 5657 hasParent(compoundStmt(hasParent(functionDecl(hasParent( 5658 cxxRecordDecl(unless(isTemplateInstantiation())))))))))); 5659 EXPECT_TRUE(matches( 5660 "template <typename T> struct C { static void f() { 42; } };" 5661 "void t() { C<int>::f(); }", 5662 integerLiteral(equals(42), 5663 hasParent(compoundStmt( 5664 allOf(hasParent(functionDecl(hasParent( 5665 cxxRecordDecl(isTemplateInstantiation())))), 5666 hasParent(functionDecl(hasParent(cxxRecordDecl( 5667 unless(isTemplateInstantiation()))))))))))); 5668 EXPECT_TRUE( 5669 notMatches("template <typename T> struct C { static void f() {} };" 5670 "void t() { C<int>::f(); }", 5671 compoundStmt(hasParent(recordDecl())))); 5672 } 5673 5674 TEST(HasParent, NoDuplicateParents) { 5675 class HasDuplicateParents : public BoundNodesCallback { 5676 public: 5677 bool run(const BoundNodes *Nodes, ASTContext *Context) override { 5678 const Stmt *Node = Nodes->getNodeAs<Stmt>("node"); 5679 std::set<const void *> Parents; 5680 for (const auto &Parent : Context->getParents(*Node)) { 5681 if (!Parents.insert(Parent.getMemoizationData()).second) { 5682 return true; 5683 } 5684 } 5685 return false; 5686 } 5687 }; 5688 EXPECT_FALSE(matchAndVerifyResultTrue( 5689 "template <typename T> int Foo() { return 1 + 2; }\n" 5690 "int x = Foo<int>() + Foo<unsigned>();", 5691 stmt().bind("node"), std::make_unique<HasDuplicateParents>())); 5692 } 5693 5694 TEST(HasAnyBase, BindsInnerBoundNodes) { 5695 EXPECT_TRUE(matchAndVerifyResultTrue( 5696 "struct Inner {}; struct Proxy : Inner {}; struct Main : public " 5697 "Proxy {};", 5698 cxxRecordDecl(hasName("Main"), 5699 hasAnyBase(cxxBaseSpecifier(hasType( 5700 cxxRecordDecl(hasName("Inner")).bind("base-class"))))) 5701 .bind("class"), 5702 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("base-class", 5703 "Inner"))); 5704 } 5705 5706 TEST(TypeMatching, PointeeTypes) { 5707 EXPECT_TRUE(matches("int b; int &a = b;", 5708 referenceType(pointee(builtinType())))); 5709 EXPECT_TRUE(matches("int *a;", pointerType(pointee(builtinType())))); 5710 5711 EXPECT_TRUE(matches("int *a;", 5712 loc(pointerType(pointee(builtinType()))))); 5713 5714 EXPECT_TRUE(matches( 5715 "int const *A;", 5716 pointerType(pointee(isConstQualified(), builtinType())))); 5717 EXPECT_TRUE(notMatches( 5718 "int *A;", 5719 pointerType(pointee(isConstQualified(), builtinType())))); 5720 } 5721 5722 TEST(ElaboratedTypeNarrowing, hasQualifier) { 5723 EXPECT_TRUE(matches( 5724 "namespace N {" 5725 " namespace M {" 5726 " class D {};" 5727 " }" 5728 "}" 5729 "N::M::D d;", 5730 elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N"))))))); 5731 EXPECT_TRUE(notMatches( 5732 "namespace M {" 5733 " class D {};" 5734 "}" 5735 "M::D d;", 5736 elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N"))))))); 5737 EXPECT_TRUE(notMatches( 5738 "struct D {" 5739 "} d;", 5740 elaboratedType(hasQualifier(nestedNameSpecifier())))); 5741 } 5742 5743 TEST(ElaboratedTypeNarrowing, namesType) { 5744 EXPECT_TRUE(matches( 5745 "namespace N {" 5746 " namespace M {" 5747 " class D {};" 5748 " }" 5749 "}" 5750 "N::M::D d;", 5751 elaboratedType(elaboratedType(namesType(recordType( 5752 hasDeclaration(namedDecl(hasName("D"))))))))); 5753 EXPECT_TRUE(notMatches( 5754 "namespace M {" 5755 " class D {};" 5756 "}" 5757 "M::D d;", 5758 elaboratedType(elaboratedType(namesType(typedefType()))))); 5759 } 5760 5761 TEST(NNS, BindsNestedNameSpecifiers) { 5762 EXPECT_TRUE(matchAndVerifyResultTrue( 5763 "namespace ns { struct E { struct B {}; }; } ns::E::B b;", 5764 nestedNameSpecifier(specifiesType(asString("struct ns::E"))).bind("nns"), 5765 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>( 5766 "nns", "ns::struct E::"))); 5767 } 5768 5769 TEST(NNS, BindsNestedNameSpecifierLocs) { 5770 EXPECT_TRUE(matchAndVerifyResultTrue( 5771 "namespace ns { struct B {}; } ns::B b;", 5772 loc(nestedNameSpecifier()).bind("loc"), 5773 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifierLoc>>("loc", 1))); 5774 } 5775 5776 TEST(NNS, DescendantsOfNestedNameSpecifiers) { 5777 StringRef Fragment = 5778 "namespace a { struct A { struct B { struct C {}; }; }; };" 5779 "void f() { a::A::B::C c; }"; 5780 EXPECT_TRUE(matches( 5781 Fragment, 5782 nestedNameSpecifier(specifiesType(asString("struct a::A::B")), 5783 hasDescendant(nestedNameSpecifier( 5784 specifiesNamespace(hasName("a"))))))); 5785 EXPECT_TRUE(notMatches( 5786 Fragment, 5787 nestedNameSpecifier(specifiesType(asString("struct a::A::B")), 5788 has(nestedNameSpecifier( 5789 specifiesNamespace(hasName("a"))))))); 5790 EXPECT_TRUE(matches( 5791 Fragment, 5792 nestedNameSpecifier(specifiesType(asString("struct a::A")), 5793 has(nestedNameSpecifier( 5794 specifiesNamespace(hasName("a"))))))); 5795 5796 // Not really useful because a NestedNameSpecifier can af at most one child, 5797 // but to complete the interface. 5798 EXPECT_TRUE(matchAndVerifyResultTrue( 5799 Fragment, 5800 nestedNameSpecifier(specifiesType(asString("struct a::A::B")), 5801 forEach(nestedNameSpecifier().bind("x"))), 5802 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>("x", 1))); 5803 } 5804 5805 TEST(NNS, NestedNameSpecifiersAsDescendants) { 5806 StringRef Fragment = 5807 "namespace a { struct A { struct B { struct C {}; }; }; };" 5808 "void f() { a::A::B::C c; }"; 5809 EXPECT_TRUE(matches( 5810 Fragment, 5811 decl(hasDescendant(nestedNameSpecifier(specifiesType( 5812 asString("struct a::A"))))))); 5813 EXPECT_TRUE(matchAndVerifyResultTrue( 5814 Fragment, 5815 functionDecl(hasName("f"), 5816 forEachDescendant(nestedNameSpecifier().bind("x"))), 5817 // Nested names: a, a::A and a::A::B. 5818 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>("x", 3))); 5819 } 5820 5821 TEST(NNSLoc, DescendantsOfNestedNameSpecifierLocs) { 5822 StringRef Fragment = 5823 "namespace a { struct A { struct B { struct C {}; }; }; };" 5824 "void f() { a::A::B::C c; }"; 5825 EXPECT_TRUE(matches( 5826 Fragment, 5827 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))), 5828 hasDescendant(loc(nestedNameSpecifier( 5829 specifiesNamespace(hasName("a")))))))); 5830 EXPECT_TRUE(notMatches( 5831 Fragment, 5832 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))), 5833 has(loc(nestedNameSpecifier( 5834 specifiesNamespace(hasName("a")))))))); 5835 EXPECT_TRUE(matches( 5836 Fragment, 5837 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A"))), 5838 has(loc(nestedNameSpecifier( 5839 specifiesNamespace(hasName("a")))))))); 5840 5841 EXPECT_TRUE(matchAndVerifyResultTrue( 5842 Fragment, 5843 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))), 5844 forEach(nestedNameSpecifierLoc().bind("x"))), 5845 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifierLoc>>("x", 1))); 5846 } 5847 5848 TEST(NNSLoc, NestedNameSpecifierLocsAsDescendants) { 5849 StringRef Fragment = 5850 "namespace a { struct A { struct B { struct C {}; }; }; };" 5851 "void f() { a::A::B::C c; }"; 5852 EXPECT_TRUE(matches( 5853 Fragment, 5854 decl(hasDescendant(loc(nestedNameSpecifier(specifiesType( 5855 asString("struct a::A")))))))); 5856 EXPECT_TRUE(matchAndVerifyResultTrue( 5857 Fragment, 5858 functionDecl(hasName("f"), 5859 forEachDescendant(nestedNameSpecifierLoc().bind("x"))), 5860 // Nested names: a, a::A and a::A::B. 5861 std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifierLoc>>("x", 3))); 5862 } 5863 5864 TEST(Attr, AttrsAsDescendants) { 5865 StringRef Fragment = "namespace a { struct [[clang::warn_unused_result]] " 5866 "F{}; [[noreturn]] void foo(); }"; 5867 EXPECT_TRUE(matches(Fragment, namespaceDecl(hasDescendant(attr())))); 5868 EXPECT_TRUE(matchAndVerifyResultTrue( 5869 Fragment, 5870 namespaceDecl(hasName("a"), 5871 forEachDescendant(attr(unless(isImplicit())).bind("x"))), 5872 std::make_unique<VerifyIdIsBoundTo<Attr>>("x", 2))); 5873 } 5874 5875 TEST(Attr, ParentsOfAttrs) { 5876 StringRef Fragment = 5877 "namespace a { struct [[clang::warn_unused_result]] F{}; }"; 5878 EXPECT_TRUE(matches(Fragment, attr(hasAncestor(namespaceDecl())))); 5879 } 5880 5881 template <typename T> class VerifyMatchOnNode : public BoundNodesCallback { 5882 public: 5883 VerifyMatchOnNode(StringRef Id, const internal::Matcher<T> &InnerMatcher, 5884 StringRef InnerId) 5885 : Id(Id), InnerMatcher(InnerMatcher), InnerId(InnerId) {} 5886 5887 bool run(const BoundNodes *Nodes, ASTContext *Context) override { 5888 const T *Node = Nodes->getNodeAs<T>(Id); 5889 return selectFirst<T>(InnerId, match(InnerMatcher, *Node, *Context)) != 5890 nullptr; 5891 } 5892 5893 private: 5894 std::string Id; 5895 internal::Matcher<T> InnerMatcher; 5896 std::string InnerId; 5897 }; 5898 5899 TEST(MatchFinder, CanMatchDeclarationsRecursively) { 5900 EXPECT_TRUE(matchAndVerifyResultTrue( 5901 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"), 5902 std::make_unique<VerifyMatchOnNode<Decl>>( 5903 "X", decl(hasDescendant(recordDecl(hasName("X::Y")).bind("Y"))), 5904 "Y"))); 5905 EXPECT_TRUE(matchAndVerifyResultFalse( 5906 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"), 5907 std::make_unique<VerifyMatchOnNode<Decl>>( 5908 "X", decl(hasDescendant(recordDecl(hasName("X::Z")).bind("Z"))), 5909 "Z"))); 5910 } 5911 5912 TEST(MatchFinder, CanMatchStatementsRecursively) { 5913 EXPECT_TRUE(matchAndVerifyResultTrue( 5914 "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"), 5915 std::make_unique<VerifyMatchOnNode<Stmt>>( 5916 "if", stmt(hasDescendant(forStmt().bind("for"))), "for"))); 5917 EXPECT_TRUE(matchAndVerifyResultFalse( 5918 "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"), 5919 std::make_unique<VerifyMatchOnNode<Stmt>>( 5920 "if", stmt(hasDescendant(declStmt().bind("decl"))), "decl"))); 5921 } 5922 5923 TEST(MatchFinder, CanMatchSingleNodesRecursively) { 5924 EXPECT_TRUE(matchAndVerifyResultTrue( 5925 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"), 5926 std::make_unique<VerifyMatchOnNode<Decl>>( 5927 "X", recordDecl(has(recordDecl(hasName("X::Y")).bind("Y"))), "Y"))); 5928 EXPECT_TRUE(matchAndVerifyResultFalse( 5929 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"), 5930 std::make_unique<VerifyMatchOnNode<Decl>>( 5931 "X", recordDecl(has(recordDecl(hasName("X::Z")).bind("Z"))), "Z"))); 5932 } 5933 5934 TEST(StatementMatcher, HasReturnValue) { 5935 StatementMatcher RetVal = returnStmt(hasReturnValue(binaryOperator())); 5936 EXPECT_TRUE(matches("int F() { int a, b; return a + b; }", RetVal)); 5937 EXPECT_FALSE(matches("int F() { int a; return a; }", RetVal)); 5938 EXPECT_FALSE(matches("void F() { return; }", RetVal)); 5939 } 5940 5941 TEST(StatementMatcher, ForFunction) { 5942 StringRef CppString1 = "struct PosVec {" 5943 " PosVec& operator=(const PosVec&) {" 5944 " auto x = [] { return 1; };" 5945 " return *this;" 5946 " }" 5947 "};"; 5948 StringRef CppString2 = "void F() {" 5949 " struct S {" 5950 " void F2() {" 5951 " return;" 5952 " }" 5953 " };" 5954 "}"; 5955 EXPECT_TRUE( 5956 matches( 5957 CppString1, 5958 returnStmt(forFunction(hasName("operator=")), 5959 has(unaryOperator(hasOperatorName("*")))))); 5960 EXPECT_TRUE( 5961 notMatches( 5962 CppString1, 5963 returnStmt(forFunction(hasName("operator=")), 5964 has(integerLiteral())))); 5965 EXPECT_TRUE( 5966 matches( 5967 CppString1, 5968 returnStmt(forFunction(hasName("operator()")), 5969 has(integerLiteral())))); 5970 EXPECT_TRUE(matches(CppString2, returnStmt(forFunction(hasName("F2"))))); 5971 EXPECT_TRUE(notMatches(CppString2, returnStmt(forFunction(hasName("F"))))); 5972 } 5973 5974 TEST(StatementMatcher, ForCallable) { 5975 // These tests are copied over from the forFunction() test above. 5976 StringRef CppString1 = "struct PosVec {" 5977 " PosVec& operator=(const PosVec&) {" 5978 " auto x = [] { return 1; };" 5979 " return *this;" 5980 " }" 5981 "};"; 5982 StringRef CppString2 = "void F() {" 5983 " struct S {" 5984 " void F2() {" 5985 " return;" 5986 " }" 5987 " };" 5988 "}"; 5989 5990 EXPECT_TRUE( 5991 matches( 5992 CppString1, 5993 returnStmt(forCallable(functionDecl(hasName("operator="))), 5994 has(unaryOperator(hasOperatorName("*")))))); 5995 EXPECT_TRUE( 5996 notMatches( 5997 CppString1, 5998 returnStmt(forCallable(functionDecl(hasName("operator="))), 5999 has(integerLiteral())))); 6000 EXPECT_TRUE( 6001 matches( 6002 CppString1, 6003 returnStmt(forCallable(functionDecl(hasName("operator()"))), 6004 has(integerLiteral())))); 6005 EXPECT_TRUE(matches(CppString2, 6006 returnStmt(forCallable(functionDecl(hasName("F2")))))); 6007 EXPECT_TRUE(notMatches(CppString2, 6008 returnStmt(forCallable(functionDecl(hasName("F")))))); 6009 6010 StringRef CodeWithDeepCallExpr = R"cpp( 6011 void Other(); 6012 void Function() { 6013 { 6014 ( 6015 Other() 6016 ); 6017 } 6018 } 6019 )cpp"; 6020 auto ForCallableFirst = 6021 callExpr(forCallable(functionDecl(hasName("Function"))), 6022 callee(functionDecl(hasName("Other")).bind("callee"))) 6023 .bind("call"); 6024 auto ForCallableSecond = 6025 callExpr(callee(functionDecl(hasName("Other")).bind("callee")), 6026 forCallable(functionDecl(hasName("Function")))) 6027 .bind("call"); 6028 EXPECT_TRUE(matchAndVerifyResultTrue( 6029 CodeWithDeepCallExpr, ForCallableFirst, 6030 std::make_unique<VerifyIdIsBoundTo<CallExpr>>("call"))); 6031 EXPECT_TRUE(matchAndVerifyResultTrue( 6032 CodeWithDeepCallExpr, ForCallableFirst, 6033 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("callee"))); 6034 EXPECT_TRUE(matchAndVerifyResultTrue( 6035 CodeWithDeepCallExpr, ForCallableSecond, 6036 std::make_unique<VerifyIdIsBoundTo<CallExpr>>("call"))); 6037 EXPECT_TRUE(matchAndVerifyResultTrue( 6038 CodeWithDeepCallExpr, ForCallableSecond, 6039 std::make_unique<VerifyIdIsBoundTo<FunctionDecl>>("callee"))); 6040 6041 // These tests are specific to forCallable(). 6042 StringRef ObjCString1 = "@interface I" 6043 "-(void) foo;" 6044 "@end" 6045 "@implementation I" 6046 "-(void) foo {" 6047 " void (^block)() = ^{ 0x2b | ~0x2b; };" 6048 "}" 6049 "@end"; 6050 6051 EXPECT_TRUE( 6052 matchesObjC( 6053 ObjCString1, 6054 binaryOperator(forCallable(blockDecl())))); 6055 6056 EXPECT_TRUE( 6057 notMatchesObjC( 6058 ObjCString1, 6059 binaryOperator(forCallable(objcMethodDecl())))); 6060 6061 StringRef ObjCString2 = "@interface I" 6062 "-(void) foo;" 6063 "@end" 6064 "@implementation I" 6065 "-(void) foo {" 6066 " 0x2b | ~0x2b;" 6067 " void (^block)() = ^{};" 6068 "}" 6069 "@end"; 6070 6071 EXPECT_TRUE( 6072 matchesObjC( 6073 ObjCString2, 6074 binaryOperator(forCallable(objcMethodDecl())))); 6075 6076 EXPECT_TRUE( 6077 notMatchesObjC( 6078 ObjCString2, 6079 binaryOperator(forCallable(blockDecl())))); 6080 } 6081 6082 namespace { 6083 class ForCallablePreservesBindingWithMultipleParentsTestCallback 6084 : public BoundNodesCallback { 6085 public: 6086 bool run(const BoundNodes *BoundNodes, ASTContext *Context) override { 6087 FunctionDecl const *FunDecl = 6088 BoundNodes->getNodeAs<FunctionDecl>("funDecl"); 6089 // Validate test assumptions. This would be expressed as ASSERT_* in 6090 // a TEST(). 6091 if (!FunDecl) { 6092 EXPECT_TRUE(false && "Incorrect test setup"); 6093 return false; 6094 } 6095 auto const *FunDef = FunDecl->getDefinition(); 6096 if (!FunDef || !FunDef->getBody() || 6097 FunDef->getNameAsString() != "Function") { 6098 EXPECT_TRUE(false && "Incorrect test setup"); 6099 return false; 6100 } 6101 6102 ExpectCorrectResult( 6103 "Baseline", 6104 callExpr(callee(cxxMethodDecl().bind("callee"))).bind("call"), // 6105 FunDecl); 6106 6107 ExpectCorrectResult("ForCallable first", 6108 callExpr(forCallable(equalsNode(FunDecl)), 6109 callee(cxxMethodDecl().bind("callee"))) 6110 .bind("call"), 6111 FunDecl); 6112 6113 ExpectCorrectResult("ForCallable second", 6114 callExpr(callee(cxxMethodDecl().bind("callee")), 6115 forCallable(equalsNode(FunDecl))) 6116 .bind("call"), 6117 FunDecl); 6118 6119 // This value does not really matter: the EXPECT_* will set the exit code. 6120 return true; 6121 } 6122 6123 private: 6124 void ExpectCorrectResult(StringRef LogInfo, 6125 ArrayRef<BoundNodes> Results) const { 6126 EXPECT_EQ(Results.size(), 1u) << LogInfo; 6127 if (Results.empty()) 6128 return; 6129 auto const &R = Results.front(); 6130 EXPECT_TRUE(R.getNodeAs<CallExpr>("call")) << LogInfo; 6131 EXPECT_TRUE(R.getNodeAs<CXXMethodDecl>("callee")) << LogInfo; 6132 } 6133 6134 template <typename MatcherT> 6135 void ExpectCorrectResult(StringRef LogInfo, MatcherT Matcher, 6136 FunctionDecl const *FunDef) const { 6137 auto &Context = FunDef->getASTContext(); 6138 auto const &Results = match(findAll(Matcher), *FunDef->getBody(), Context); 6139 ExpectCorrectResult(LogInfo, Results); 6140 } 6141 }; 6142 } // namespace 6143 6144 TEST(StatementMatcher, ForCallablePreservesBindingWithMultipleParents) { 6145 // Tests in this file are fairly simple and therefore can rely on matches, 6146 // matchAndVerifyResultTrue, etc. This test, however, needs a FunctionDecl* in 6147 // order to call equalsNode in order to reproduce the observed issue (bindings 6148 // being removed despite forCallable matching the node). 6149 // 6150 // Because of this and because the machinery to compile the code into an 6151 // ASTUnit is not exposed outside matchAndVerifyResultConditionally, it is 6152 // cheaper to have a custom BoundNodesCallback for the purpose of this test. 6153 StringRef codeWithTemplateFunction = R"cpp( 6154 struct Klass { 6155 void Method(); 6156 template <typename T> 6157 void Function(T t); // Declaration 6158 }; 6159 6160 void Instantiate(Klass k) { 6161 k.Function(0); 6162 } 6163 6164 template <typename T> 6165 void Klass::Function(T t) { // Definition 6166 // Compound statement has two parents: the declaration and the definition. 6167 Method(); 6168 } 6169 )cpp"; 6170 EXPECT_TRUE(matchAndVerifyResultTrue( 6171 codeWithTemplateFunction, 6172 callExpr(callee(functionDecl(hasName("Function")).bind("funDecl"))), 6173 std::make_unique< 6174 ForCallablePreservesBindingWithMultipleParentsTestCallback>())); 6175 } 6176 6177 TEST(Matcher, ForEachOverriden) { 6178 const auto ForEachOverriddenInClass = [](const char *ClassName) { 6179 return cxxMethodDecl(ofClass(hasName(ClassName)), isVirtual(), 6180 forEachOverridden(cxxMethodDecl().bind("overridden"))) 6181 .bind("override"); 6182 }; 6183 static const char Code1[] = "class A { virtual void f(); };" 6184 "class B : public A { void f(); };" 6185 "class C : public B { void f(); };"; 6186 // C::f overrides A::f. 6187 EXPECT_TRUE(matchAndVerifyResultTrue( 6188 Code1, ForEachOverriddenInClass("C"), 6189 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("override", "f", 1))); 6190 EXPECT_TRUE(matchAndVerifyResultTrue( 6191 Code1, ForEachOverriddenInClass("C"), 6192 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("overridden", "f", 6193 1))); 6194 // B::f overrides A::f. 6195 EXPECT_TRUE(matchAndVerifyResultTrue( 6196 Code1, ForEachOverriddenInClass("B"), 6197 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("override", "f", 1))); 6198 EXPECT_TRUE(matchAndVerifyResultTrue( 6199 Code1, ForEachOverriddenInClass("B"), 6200 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("overridden", "f", 6201 1))); 6202 // A::f overrides nothing. 6203 EXPECT_TRUE(notMatches(Code1, ForEachOverriddenInClass("A"))); 6204 6205 static const char Code2[] = 6206 "class A1 { virtual void f(); };" 6207 "class A2 { virtual void f(); };" 6208 "class B : public A1, public A2 { void f(); };"; 6209 // B::f overrides A1::f and A2::f. This produces two matches. 6210 EXPECT_TRUE(matchAndVerifyResultTrue( 6211 Code2, ForEachOverriddenInClass("B"), 6212 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("override", "f", 2))); 6213 EXPECT_TRUE(matchAndVerifyResultTrue( 6214 Code2, ForEachOverriddenInClass("B"), 6215 std::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("overridden", "f", 6216 2))); 6217 // A1::f overrides nothing. 6218 EXPECT_TRUE(notMatches(Code2, ForEachOverriddenInClass("A1"))); 6219 } 6220 6221 TEST(Matcher, HasAnyDeclaration) { 6222 StringRef Fragment = "void foo(int p1);" 6223 "void foo(int *p2);" 6224 "void bar(int p3);" 6225 "template <typename T> void baz(T t) { foo(t); }"; 6226 6227 EXPECT_TRUE( 6228 matches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(functionDecl( 6229 hasParameter(0, parmVarDecl(hasName("p1")))))))); 6230 EXPECT_TRUE( 6231 matches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(functionDecl( 6232 hasParameter(0, parmVarDecl(hasName("p2")))))))); 6233 EXPECT_TRUE( 6234 notMatches(Fragment, unresolvedLookupExpr(hasAnyDeclaration(functionDecl( 6235 hasParameter(0, parmVarDecl(hasName("p3")))))))); 6236 EXPECT_TRUE(notMatches(Fragment, unresolvedLookupExpr(hasAnyDeclaration( 6237 functionDecl(hasName("bar")))))); 6238 } 6239 6240 TEST(SubstTemplateTypeParmType, HasReplacementType) { 6241 StringRef Fragment = "template<typename T>" 6242 "double F(T t);" 6243 "int i;" 6244 "double j = F(i);"; 6245 EXPECT_TRUE(matches(Fragment, substTemplateTypeParmType(hasReplacementType( 6246 qualType(asString("int")))))); 6247 EXPECT_TRUE(notMatches(Fragment, substTemplateTypeParmType(hasReplacementType( 6248 qualType(asString("double")))))); 6249 EXPECT_TRUE( 6250 notMatches("template<int N>" 6251 "double F();" 6252 "double j = F<5>();", 6253 substTemplateTypeParmType(hasReplacementType(qualType())))); 6254 } 6255 6256 TEST(ClassTemplateSpecializationDecl, HasSpecializedTemplate) { 6257 auto Matcher = classTemplateSpecializationDecl( 6258 hasSpecializedTemplate(classTemplateDecl())); 6259 EXPECT_TRUE( 6260 matches("template<typename T> class A {}; typedef A<int> B;", Matcher)); 6261 EXPECT_TRUE(notMatches("template<typename T> class A {};", Matcher)); 6262 } 6263 6264 TEST(CXXNewExpr, Array) { 6265 StatementMatcher NewArray = cxxNewExpr(isArray()); 6266 6267 EXPECT_TRUE(matches("void foo() { int *Ptr = new int[10]; }", NewArray)); 6268 EXPECT_TRUE(notMatches("void foo() { int *Ptr = new int; }", NewArray)); 6269 6270 StatementMatcher NewArraySize10 = 6271 cxxNewExpr(hasArraySize(integerLiteral(equals(10)))); 6272 EXPECT_TRUE( 6273 matches("void foo() { int *Ptr = new int[10]; }", NewArraySize10)); 6274 EXPECT_TRUE( 6275 notMatches("void foo() { int *Ptr = new int[20]; }", NewArraySize10)); 6276 } 6277 6278 TEST(CXXNewExpr, PlacementArgs) { 6279 StatementMatcher IsPlacementNew = cxxNewExpr(hasAnyPlacementArg(anything())); 6280 6281 EXPECT_TRUE(matches(R"( 6282 void* operator new(decltype(sizeof(void*)), void*); 6283 int *foo(void* Storage) { 6284 return new (Storage) int; 6285 })", 6286 IsPlacementNew)); 6287 6288 EXPECT_TRUE(matches(R"( 6289 void* operator new(decltype(sizeof(void*)), void*, unsigned); 6290 int *foo(void* Storage) { 6291 return new (Storage, 16) int; 6292 })", 6293 cxxNewExpr(hasPlacementArg( 6294 1, ignoringImpCasts(integerLiteral(equals(16))))))); 6295 6296 EXPECT_TRUE(notMatches(R"( 6297 void* operator new(decltype(sizeof(void*)), void*); 6298 int *foo(void* Storage) { 6299 return new int; 6300 })", 6301 IsPlacementNew)); 6302 } 6303 6304 TEST(HasUnqualifiedLoc, BindsToConstIntVarDecl) { 6305 EXPECT_TRUE(matches( 6306 "const int x = 0;", 6307 varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc( 6308 hasUnqualifiedLoc(loc(asString("int")))))))); 6309 } 6310 6311 TEST(HasUnqualifiedLoc, BindsToVolatileIntVarDecl) { 6312 EXPECT_TRUE(matches( 6313 "volatile int x = 0;", 6314 varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc( 6315 hasUnqualifiedLoc(loc(asString("int")))))))); 6316 } 6317 6318 TEST(HasUnqualifiedLoc, BindsToConstVolatileIntVarDecl) { 6319 EXPECT_TRUE(matches( 6320 "const volatile int x = 0;", 6321 varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc( 6322 hasUnqualifiedLoc(loc(asString("int")))))))); 6323 } 6324 6325 TEST(HasUnqualifiedLoc, BindsToConstPointerVarDecl) { 6326 auto matcher = varDecl( 6327 hasName("x"), 6328 hasTypeLoc(qualifiedTypeLoc(hasUnqualifiedLoc(pointerTypeLoc())))); 6329 EXPECT_TRUE(matches("int* const x = 0;", matcher)); 6330 EXPECT_TRUE(notMatches("int const x = 0;", matcher)); 6331 } 6332 6333 TEST(HasUnqualifiedLoc, BindsToPointerToConstVolatileIntVarDecl) { 6334 EXPECT_TRUE( 6335 matches("const volatile int* x = 0;", 6336 varDecl(hasName("x"), 6337 hasTypeLoc(pointerTypeLoc(hasPointeeLoc(qualifiedTypeLoc( 6338 hasUnqualifiedLoc(loc(asString("int")))))))))); 6339 } 6340 6341 TEST(HasUnqualifiedLoc, BindsToConstIntFunctionDecl) { 6342 EXPECT_TRUE( 6343 matches("const int f() { return 5; }", 6344 functionDecl(hasName("f"), 6345 hasReturnTypeLoc(qualifiedTypeLoc( 6346 hasUnqualifiedLoc(loc(asString("int")))))))); 6347 } 6348 6349 TEST(HasUnqualifiedLoc, FloatBindsToConstFloatVarDecl) { 6350 EXPECT_TRUE(matches( 6351 "const float x = 0;", 6352 varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc( 6353 hasUnqualifiedLoc(loc(asString("float")))))))); 6354 } 6355 6356 TEST(HasUnqualifiedLoc, FloatDoesNotBindToIntVarDecl) { 6357 EXPECT_TRUE(notMatches( 6358 "int x = 0;", 6359 varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc( 6360 hasUnqualifiedLoc(loc(asString("float")))))))); 6361 } 6362 6363 TEST(HasUnqualifiedLoc, FloatDoesNotBindToConstIntVarDecl) { 6364 EXPECT_TRUE(notMatches( 6365 "const int x = 0;", 6366 varDecl(hasName("x"), hasTypeLoc(qualifiedTypeLoc( 6367 hasUnqualifiedLoc(loc(asString("float")))))))); 6368 } 6369 6370 TEST(HasReturnTypeLoc, BindsToIntReturnTypeLoc) { 6371 EXPECT_TRUE(matches( 6372 "int f() { return 5; }", 6373 functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("int")))))); 6374 } 6375 6376 TEST(HasReturnTypeLoc, BindsToFloatReturnTypeLoc) { 6377 EXPECT_TRUE(matches( 6378 "float f() { return 5.0; }", 6379 functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("float")))))); 6380 } 6381 6382 TEST(HasReturnTypeLoc, BindsToVoidReturnTypeLoc) { 6383 EXPECT_TRUE(matches( 6384 "void f() {}", 6385 functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("void")))))); 6386 } 6387 6388 TEST(HasReturnTypeLoc, FloatDoesNotBindToIntReturnTypeLoc) { 6389 EXPECT_TRUE(notMatches( 6390 "int f() { return 5; }", 6391 functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("float")))))); 6392 } 6393 6394 TEST(HasReturnTypeLoc, IntDoesNotBindToFloatReturnTypeLoc) { 6395 EXPECT_TRUE(notMatches( 6396 "float f() { return 5.0; }", 6397 functionDecl(hasName("f"), hasReturnTypeLoc(loc(asString("int")))))); 6398 } 6399 6400 TEST(HasPointeeLoc, BindsToAnyPointeeTypeLoc) { 6401 auto matcher = varDecl(hasName("x"), 6402 hasTypeLoc(pointerTypeLoc(hasPointeeLoc(typeLoc())))); 6403 EXPECT_TRUE(matches("int* x;", matcher)); 6404 EXPECT_TRUE(matches("float* x;", matcher)); 6405 EXPECT_TRUE(matches("char* x;", matcher)); 6406 EXPECT_TRUE(matches("void* x;", matcher)); 6407 } 6408 6409 TEST(HasPointeeLoc, DoesNotBindToTypeLocWithoutPointee) { 6410 auto matcher = varDecl(hasName("x"), 6411 hasTypeLoc(pointerTypeLoc(hasPointeeLoc(typeLoc())))); 6412 EXPECT_TRUE(notMatches("int x;", matcher)); 6413 EXPECT_TRUE(notMatches("float x;", matcher)); 6414 EXPECT_TRUE(notMatches("char x;", matcher)); 6415 } 6416 6417 TEST(HasPointeeLoc, BindsToTypeLocPointingToInt) { 6418 EXPECT_TRUE( 6419 matches("int* x;", pointerTypeLoc(hasPointeeLoc(loc(asString("int")))))); 6420 } 6421 6422 TEST(HasPointeeLoc, BindsToTypeLocPointingToIntPointer) { 6423 EXPECT_TRUE(matches("int** x;", 6424 pointerTypeLoc(hasPointeeLoc(loc(asString("int *")))))); 6425 } 6426 6427 TEST(HasPointeeLoc, BindsToTypeLocPointingToTypeLocPointingToInt) { 6428 EXPECT_TRUE(matches("int** x;", pointerTypeLoc(hasPointeeLoc(pointerTypeLoc( 6429 hasPointeeLoc(loc(asString("int")))))))); 6430 } 6431 6432 TEST(HasPointeeLoc, BindsToTypeLocPointingToFloat) { 6433 EXPECT_TRUE(matches("float* x;", 6434 pointerTypeLoc(hasPointeeLoc(loc(asString("float")))))); 6435 } 6436 6437 TEST(HasPointeeLoc, IntPointeeDoesNotBindToTypeLocPointingToFloat) { 6438 EXPECT_TRUE(notMatches("float* x;", 6439 pointerTypeLoc(hasPointeeLoc(loc(asString("int")))))); 6440 } 6441 6442 TEST(HasPointeeLoc, FloatPointeeDoesNotBindToTypeLocPointingToInt) { 6443 EXPECT_TRUE(notMatches( 6444 "int* x;", pointerTypeLoc(hasPointeeLoc(loc(asString("float")))))); 6445 } 6446 6447 TEST(HasReferentLoc, BindsToAnyReferentTypeLoc) { 6448 auto matcher = varDecl( 6449 hasName("r"), hasTypeLoc(referenceTypeLoc(hasReferentLoc(typeLoc())))); 6450 EXPECT_TRUE(matches("int rr = 3; int& r = rr;", matcher)); 6451 EXPECT_TRUE(matches("int rr = 3; auto& r = rr;", matcher)); 6452 EXPECT_TRUE(matches("int rr = 3; const int& r = rr;", matcher)); 6453 EXPECT_TRUE(matches("float rr = 3.0; float& r = rr;", matcher)); 6454 EXPECT_TRUE(matches("char rr = 'a'; char& r = rr;", matcher)); 6455 } 6456 6457 TEST(HasReferentLoc, DoesNotBindToTypeLocWithoutReferent) { 6458 auto matcher = varDecl( 6459 hasName("r"), hasTypeLoc(referenceTypeLoc(hasReferentLoc(typeLoc())))); 6460 EXPECT_TRUE(notMatches("int r;", matcher)); 6461 EXPECT_TRUE(notMatches("int r = 3;", matcher)); 6462 EXPECT_TRUE(notMatches("const int r = 3;", matcher)); 6463 EXPECT_TRUE(notMatches("int* r;", matcher)); 6464 EXPECT_TRUE(notMatches("float r;", matcher)); 6465 EXPECT_TRUE(notMatches("char r;", matcher)); 6466 } 6467 6468 TEST(HasReferentLoc, BindsToAnyRvalueReference) { 6469 auto matcher = varDecl( 6470 hasName("r"), hasTypeLoc(referenceTypeLoc(hasReferentLoc(typeLoc())))); 6471 EXPECT_TRUE(matches("int&& r = 3;", matcher)); 6472 EXPECT_TRUE(matches("auto&& r = 3;", matcher)); 6473 EXPECT_TRUE(matches("float&& r = 3.0;", matcher)); 6474 } 6475 6476 TEST(HasReferentLoc, BindsToIntReferenceTypeLoc) { 6477 EXPECT_TRUE(matches("int rr = 3; int& r = rr;", 6478 referenceTypeLoc(hasReferentLoc(loc(asString("int")))))); 6479 } 6480 6481 TEST(HasReferentLoc, BindsToIntRvalueReferenceTypeLoc) { 6482 EXPECT_TRUE(matches("int&& r = 3;", 6483 referenceTypeLoc(hasReferentLoc(loc(asString("int")))))); 6484 } 6485 6486 TEST(HasReferentLoc, BindsToFloatReferenceTypeLoc) { 6487 EXPECT_TRUE( 6488 matches("float rr = 3.0; float& r = rr;", 6489 referenceTypeLoc(hasReferentLoc(loc(asString("float")))))); 6490 } 6491 6492 TEST(HasReferentLoc, BindsToParameterWithIntReferenceTypeLoc) { 6493 EXPECT_TRUE(matches( 6494 "int f(int& r) { return r; }", 6495 parmVarDecl(hasName("r"), hasTypeLoc(referenceTypeLoc( 6496 hasReferentLoc(loc(asString("int")))))))); 6497 } 6498 6499 TEST(HasReferentLoc, IntReferenceDoesNotBindToFloatReferenceTypeLoc) { 6500 EXPECT_TRUE( 6501 notMatches("float rr = 3.0; float& r = rr;", 6502 referenceTypeLoc(hasReferentLoc(loc(asString("int")))))); 6503 } 6504 6505 TEST(HasReferentLoc, FloatReferenceDoesNotBindToIntReferenceTypeLoc) { 6506 EXPECT_TRUE( 6507 notMatches("int rr = 3; int& r = rr;", 6508 referenceTypeLoc(hasReferentLoc(loc(asString("float")))))); 6509 } 6510 6511 TEST(HasReferentLoc, DoesNotBindToParameterWithoutIntReferenceTypeLoc) { 6512 EXPECT_TRUE(notMatches( 6513 "int f(int r) { return r; }", 6514 parmVarDecl(hasName("r"), hasTypeLoc(referenceTypeLoc( 6515 hasReferentLoc(loc(asString("int")))))))); 6516 } 6517 6518 TEST(HasAnyTemplateArgumentLoc, BindsToSpecializationWithIntArgument) { 6519 EXPECT_TRUE(matches( 6520 "template<typename T> class A {}; A<int> a;", 6521 varDecl(hasName("a"), 6522 hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc( 6523 templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc( 6524 hasTypeLoc(loc(asString("int"))))))))))); 6525 } 6526 6527 TEST(HasAnyTemplateArgumentLoc, BindsToSpecializationWithDoubleArgument) { 6528 EXPECT_TRUE(matches( 6529 "template<typename T> class A {}; A<double> a;", 6530 varDecl(hasName("a"), 6531 hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc( 6532 templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc( 6533 hasTypeLoc(loc(asString("double"))))))))))); 6534 } 6535 6536 TEST(HasAnyTemplateArgumentLoc, BindsToExplicitSpecializationWithIntArgument) { 6537 EXPECT_TRUE(matches( 6538 "template<typename T> class A {}; template<> class A<int> {};", 6539 classTemplateSpecializationDecl( 6540 hasName("A"), 6541 hasAnyTemplateArgumentLoc(hasTypeLoc(loc(asString("int"))))))); 6542 } 6543 6544 TEST(HasAnyTemplateArgumentLoc, 6545 BindsToExplicitSpecializationWithDoubleArgument) { 6546 EXPECT_TRUE(matches( 6547 "template<typename T> class A {}; template<> class A<double> {};", 6548 classTemplateSpecializationDecl( 6549 hasName("A"), 6550 hasAnyTemplateArgumentLoc(hasTypeLoc(loc(asString("double"))))))); 6551 } 6552 6553 TEST(HasAnyTemplateArgumentLoc, BindsToSpecializationWithMultipleArguments) { 6554 auto code = R"( 6555 template<typename T, typename U> class A {}; 6556 template<> class A<double, int> {}; 6557 )"; 6558 EXPECT_TRUE( 6559 matches(code, classTemplateSpecializationDecl( 6560 hasName("A"), hasAnyTemplateArgumentLoc(hasTypeLoc( 6561 loc(asString("double"))))))); 6562 6563 EXPECT_TRUE(matches( 6564 code, classTemplateSpecializationDecl( 6565 hasName("A"), 6566 hasAnyTemplateArgumentLoc(hasTypeLoc(loc(asString("int"))))))); 6567 } 6568 6569 TEST(HasAnyTemplateArgumentLoc, DoesNotBindToSpecializationWithIntArgument) { 6570 EXPECT_TRUE(notMatches("template<typename T> class A {}; A<int> a;", 6571 classTemplateSpecializationDecl( 6572 hasName("A"), hasAnyTemplateArgumentLoc(hasTypeLoc( 6573 loc(asString("double"))))))); 6574 } 6575 6576 TEST(HasAnyTemplateArgumentLoc, 6577 DoesNotBindToExplicitSpecializationWithIntArgument) { 6578 EXPECT_TRUE(notMatches( 6579 "template<typename T> class A {}; template<> class A<int> {};", 6580 classTemplateSpecializationDecl( 6581 hasName("A"), 6582 hasAnyTemplateArgumentLoc(hasTypeLoc(loc(asString("double"))))))); 6583 } 6584 6585 TEST(HasTemplateArgumentLoc, BindsToSpecializationWithIntArgument) { 6586 EXPECT_TRUE( 6587 matches("template<typename T> class A {}; A<int> a;", 6588 varDecl(hasName("a"), 6589 hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc( 6590 templateSpecializationTypeLoc(hasTemplateArgumentLoc( 6591 0, hasTypeLoc(loc(asString("int"))))))))))); 6592 } 6593 6594 TEST(HasTemplateArgumentLoc, BindsToSpecializationWithDoubleArgument) { 6595 EXPECT_TRUE( 6596 matches("template<typename T> class A {}; A<double> a;", 6597 varDecl(hasName("a"), 6598 hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc( 6599 templateSpecializationTypeLoc(hasTemplateArgumentLoc( 6600 0, hasTypeLoc(loc(asString("double"))))))))))); 6601 } 6602 6603 TEST(HasTemplateArgumentLoc, DoesNotBindToSpecializationWithIntArgument) { 6604 EXPECT_TRUE(notMatches( 6605 "template<typename T> class A {}; A<int> a;", 6606 varDecl(hasName("a"), 6607 hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc( 6608 templateSpecializationTypeLoc(hasTemplateArgumentLoc( 6609 0, hasTypeLoc(loc(asString("double"))))))))))); 6610 } 6611 6612 TEST(HasTemplateArgumentLoc, BindsToExplicitSpecializationWithIntArgument) { 6613 EXPECT_TRUE(matches( 6614 "template<typename T> class A {}; template<> class A<int> {};", 6615 classTemplateSpecializationDecl( 6616 hasName("A"), 6617 hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("int"))))))); 6618 } 6619 6620 TEST(HasTemplateArgumentLoc, BindsToExplicitSpecializationWithDoubleArgument) { 6621 EXPECT_TRUE(matches( 6622 "template<typename T> class A {}; template<> class A<double> {};", 6623 classTemplateSpecializationDecl( 6624 hasName("A"), 6625 hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("double"))))))); 6626 } 6627 6628 TEST(HasTemplateArgumentLoc, BindsToSpecializationWithMultipleArguments) { 6629 auto code = R"( 6630 template<typename T, typename U> class A {}; 6631 template<> class A<double, int> {}; 6632 )"; 6633 EXPECT_TRUE(matches( 6634 code, classTemplateSpecializationDecl( 6635 hasName("A"), hasTemplateArgumentLoc( 6636 0, hasTypeLoc(loc(asString("double"))))))); 6637 EXPECT_TRUE(matches( 6638 code, classTemplateSpecializationDecl( 6639 hasName("A"), 6640 hasTemplateArgumentLoc(1, hasTypeLoc(loc(asString("int"))))))); 6641 } 6642 6643 TEST(HasTemplateArgumentLoc, 6644 DoesNotBindToExplicitSpecializationWithIntArgument) { 6645 EXPECT_TRUE(notMatches( 6646 "template<typename T> class A {}; template<> class A<int> {};", 6647 classTemplateSpecializationDecl( 6648 hasName("A"), 6649 hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("double"))))))); 6650 } 6651 6652 TEST(HasTemplateArgumentLoc, 6653 DoesNotBindToSpecializationWithMisplacedArguments) { 6654 auto code = R"( 6655 template<typename T, typename U> class A {}; 6656 template<> class A<double, int> {}; 6657 )"; 6658 EXPECT_TRUE(notMatches( 6659 code, classTemplateSpecializationDecl( 6660 hasName("A"), hasTemplateArgumentLoc( 6661 1, hasTypeLoc(loc(asString("double"))))))); 6662 EXPECT_TRUE(notMatches( 6663 code, classTemplateSpecializationDecl( 6664 hasName("A"), 6665 hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("int"))))))); 6666 } 6667 6668 TEST(HasTemplateArgumentLoc, DoesNotBindWithBadIndex) { 6669 auto code = R"( 6670 template<typename T, typename U> class A {}; 6671 template<> class A<double, int> {}; 6672 )"; 6673 EXPECT_TRUE(notMatches( 6674 code, classTemplateSpecializationDecl( 6675 hasName("A"), hasTemplateArgumentLoc( 6676 -1, hasTypeLoc(loc(asString("double"))))))); 6677 EXPECT_TRUE(notMatches( 6678 code, classTemplateSpecializationDecl( 6679 hasName("A"), hasTemplateArgumentLoc( 6680 100, hasTypeLoc(loc(asString("int"))))))); 6681 } 6682 6683 TEST(HasTemplateArgumentLoc, BindsToDeclRefExprWithIntArgument) { 6684 EXPECT_TRUE(matches(R"( 6685 template<typename T> T f(T t) { return t; } 6686 int g() { int i = f<int>(3); return i; } 6687 )", 6688 declRefExpr(to(functionDecl(hasName("f"))), 6689 hasTemplateArgumentLoc( 6690 0, hasTypeLoc(loc(asString("int"))))))); 6691 } 6692 6693 TEST(HasTemplateArgumentLoc, BindsToDeclRefExprWithDoubleArgument) { 6694 EXPECT_TRUE(matches( 6695 R"( 6696 template<typename T> T f(T t) { return t; } 6697 double g() { double i = f<double>(3.0); return i; } 6698 )", 6699 declRefExpr( 6700 to(functionDecl(hasName("f"))), 6701 hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("double"))))))); 6702 } 6703 6704 TEST(HasTemplateArgumentLoc, DoesNotBindToDeclRefExprWithDoubleArgument) { 6705 EXPECT_TRUE(notMatches( 6706 R"( 6707 template<typename T> T f(T t) { return t; } 6708 double g() { double i = f<double>(3.0); return i; } 6709 )", 6710 declRefExpr( 6711 to(functionDecl(hasName("f"))), 6712 hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("int"))))))); 6713 } 6714 6715 TEST(HasNamedTypeLoc, BindsToElaboratedObjectDeclaration) { 6716 EXPECT_TRUE(matches( 6717 R"( 6718 template <typename T> 6719 class C {}; 6720 class C<int> c; 6721 )", 6722 varDecl(hasName("c"), 6723 hasTypeLoc(elaboratedTypeLoc( 6724 hasNamedTypeLoc(templateSpecializationTypeLoc( 6725 hasAnyTemplateArgumentLoc(templateArgumentLoc())))))))); 6726 } 6727 6728 TEST(HasNamedTypeLoc, DoesNotBindToNonElaboratedObjectDeclaration) { 6729 EXPECT_TRUE(matches( 6730 R"( 6731 template <typename T> 6732 class C {}; 6733 C<int> c; 6734 )", 6735 varDecl(hasName("c"), 6736 hasTypeLoc(elaboratedTypeLoc( 6737 hasNamedTypeLoc(templateSpecializationTypeLoc( 6738 hasAnyTemplateArgumentLoc(templateArgumentLoc())))))))); 6739 } 6740 6741 } // namespace ast_matchers 6742 } // namespace clang 6743