5017 lines · cpp
1// unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp - AST matcher unit tests//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "ASTMatchersTest.h"10#include "clang/AST/PrettyPrinter.h"11#include "clang/ASTMatchers/ASTMatchFinder.h"12#include "clang/ASTMatchers/ASTMatchers.h"13#include "clang/Tooling/Tooling.h"14#include "llvm/TargetParser/Host.h"15#include "llvm/TargetParser/Triple.h"16#include "gtest/gtest.h"17 18namespace clang {19namespace ast_matchers {20 21TEST_P(ASTMatchersTest, IsExpandedFromMacro_MatchesInFile) {22 StringRef input = R"cc(23#define MY_MACRO(a) (4 + (a))24 void Test() { MY_MACRO(4); }25 )cc";26 EXPECT_TRUE(matches(input, binaryOperator(isExpandedFromMacro("MY_MACRO"))));27}28 29static std::string constructMacroName(llvm::StringRef A, llvm::StringRef B) {30 return (A + "_" + B).str();31}32 33TEST_P(ASTMatchersTest, IsExpandedFromMacro_ConstructedMacroName) {34 StringRef input = R"cc(35#define MY_MACRO(a) (4 + (a))36 void Test() { MY_MACRO(4); }37 )cc";38 auto matcher = isExpandedFromMacro(constructMacroName("MY", "MACRO"));39 EXPECT_TRUE(matches(input, binaryOperator(matcher)));40}41 42TEST_P(ASTMatchersTest, IsExpandedFromMacro_MatchesNested) {43 StringRef input = R"cc(44#define MY_MACRO(a) (4 + (a))45#define WRAPPER(a) MY_MACRO(a)46 void Test() { WRAPPER(4); }47 )cc";48 EXPECT_TRUE(matches(input, binaryOperator(isExpandedFromMacro("MY_MACRO"))));49}50 51TEST_P(ASTMatchersTest, IsExpandedFromMacro_MatchesIntermediate) {52 StringRef input = R"cc(53#define IMPL(a) (4 + (a))54#define MY_MACRO(a) IMPL(a)55#define WRAPPER(a) MY_MACRO(a)56 void Test() { WRAPPER(4); }57 )cc";58 EXPECT_TRUE(matches(input, binaryOperator(isExpandedFromMacro("MY_MACRO"))));59}60 61TEST_P(ASTMatchersTest, IsExpandedFromMacro_MatchesTransitive) {62 StringRef input = R"cc(63#define MY_MACRO(a) (4 + (a))64#define WRAPPER(a) MY_MACRO(a)65 void Test() { WRAPPER(4); }66 )cc";67 EXPECT_TRUE(matches(input, binaryOperator(isExpandedFromMacro("WRAPPER"))));68}69 70TEST_P(ASTMatchersTest, IsExpandedFromMacro_MatchesArgument) {71 StringRef input = R"cc(72#define MY_MACRO(a) (4 + (a))73 void Test() {74 int x = 5;75 MY_MACRO(x);76 }77 )cc";78 EXPECT_TRUE(matches(input, declRefExpr(isExpandedFromMacro("MY_MACRO"))));79}80 81// Like IsExpandedFromMacro_MatchesArgument, but the argument is itself a82// macro.83TEST_P(ASTMatchersTest, IsExpandedFromMacro_MatchesArgumentMacroExpansion) {84 StringRef input = R"cc(85#define MY_MACRO(a) (4 + (a))86#define IDENTITY(a) (a)87 void Test() {88 IDENTITY(MY_MACRO(2));89 }90 )cc";91 EXPECT_TRUE(matches(input, binaryOperator(isExpandedFromMacro("IDENTITY"))));92}93 94TEST_P(ASTMatchersTest, IsExpandedFromMacro_MatchesWhenInArgument) {95 StringRef input = R"cc(96#define MY_MACRO(a) (4 + (a))97#define IDENTITY(a) (a)98 void Test() {99 IDENTITY(MY_MACRO(2));100 }101 )cc";102 EXPECT_TRUE(matches(input, binaryOperator(isExpandedFromMacro("MY_MACRO"))));103}104 105TEST_P(ASTMatchersTest, IsExpandedFromMacro_MatchesObjectMacro) {106 StringRef input = R"cc(107#define PLUS (2 + 2)108 void Test() {109 PLUS;110 }111 )cc";112 EXPECT_TRUE(matches(input, binaryOperator(isExpandedFromMacro("PLUS"))));113}114 115TEST(IsExpandedFromMacro, MatchesFromCommandLine) {116 StringRef input = R"cc(117 void Test() { FOUR_PLUS_FOUR; }118 )cc";119 EXPECT_TRUE(matchesConditionally(120 input, binaryOperator(isExpandedFromMacro("FOUR_PLUS_FOUR")), true,121 {"-std=c++11", "-DFOUR_PLUS_FOUR=4+4"}));122}123 124TEST_P(ASTMatchersTest, IsExpandedFromMacro_NotMatchesBeginOnly) {125 StringRef input = R"cc(126#define ONE_PLUS 1+127 void Test() { ONE_PLUS 4; }128 )cc";129 EXPECT_TRUE(130 notMatches(input, binaryOperator(isExpandedFromMacro("ONE_PLUS"))));131}132 133TEST_P(ASTMatchersTest, IsExpandedFromMacro_NotMatchesEndOnly) {134 StringRef input = R"cc(135#define PLUS_ONE +1136 void Test() { 4 PLUS_ONE; }137 )cc";138 EXPECT_TRUE(139 notMatches(input, binaryOperator(isExpandedFromMacro("PLUS_ONE"))));140}141 142TEST_P(ASTMatchersTest, IsExpandedFromMacro_NotMatchesDifferentMacro) {143 StringRef input = R"cc(144#define MY_MACRO(a) (4 + (a))145 void Test() { MY_MACRO(4); }146 )cc";147 EXPECT_TRUE(notMatches(input, binaryOperator(isExpandedFromMacro("OTHER"))));148}149 150TEST_P(ASTMatchersTest, IsExpandedFromMacro_NotMatchesDifferentInstances) {151 StringRef input = R"cc(152#define FOUR 4153 void Test() { FOUR + FOUR; }154 )cc";155 EXPECT_TRUE(notMatches(input, binaryOperator(isExpandedFromMacro("FOUR"))));156}157 158TEST(IsExpandedFromMacro, IsExpandedFromMacro_MatchesDecls) {159 StringRef input = R"cc(160#define MY_MACRO(a) int i = a;161 void Test() { MY_MACRO(4); }162 )cc";163 EXPECT_TRUE(matches(input, varDecl(isExpandedFromMacro("MY_MACRO"))));164}165 166TEST(IsExpandedFromMacro, IsExpandedFromMacro_MatchesTypelocs) {167 StringRef input = R"cc(168#define MY_TYPE int169 void Test() { MY_TYPE i = 4; }170 )cc";171 EXPECT_TRUE(matches(input, typeLoc(isExpandedFromMacro("MY_TYPE"))));172}173 174TEST_P(ASTMatchersTest, AllOf) {175 const char Program[] = "struct T { };"176 "int f(int, struct T*, int, int);"177 "void g(int x) { struct T t; f(x, &t, 3, 4); }";178 EXPECT_TRUE(matches(179 Program, callExpr(allOf(callee(functionDecl(hasName("f"))),180 hasArgument(0, declRefExpr(to(varDecl())))))));181 EXPECT_TRUE(matches(182 Program,183 callExpr(184 allOf(callee(functionDecl(hasName("f"))),185 hasArgument(0, declRefExpr(to(varDecl()))),186 hasArgument(1, hasType(pointsTo(recordDecl(hasName("T")))))))));187 EXPECT_TRUE(matches(188 Program, callExpr(allOf(189 callee(functionDecl(hasName("f"))),190 hasArgument(0, declRefExpr(to(varDecl()))),191 hasArgument(1, hasType(pointsTo(recordDecl(hasName("T"))))),192 hasArgument(2, integerLiteral(equals(3)))))));193 EXPECT_TRUE(matches(194 Program, callExpr(allOf(195 callee(functionDecl(hasName("f"))),196 hasArgument(0, declRefExpr(to(varDecl()))),197 hasArgument(1, hasType(pointsTo(recordDecl(hasName("T"))))),198 hasArgument(2, integerLiteral(equals(3))),199 hasArgument(3, integerLiteral(equals(4)))))));200}201 202TEST_P(ASTMatchersTest, Has) {203 if (!GetParam().isCXX()) {204 // FIXME: Add a test for `has()` that does not depend on C++.205 return;206 }207 208 DeclarationMatcher HasClassX = recordDecl(has(recordDecl(hasName("X"))));209 EXPECT_TRUE(matches("class Y { class X {}; };", HasClassX));210 EXPECT_TRUE(matches("class X {};", HasClassX));211 212 DeclarationMatcher YHasClassX =213 recordDecl(hasName("Y"), has(recordDecl(hasName("X"))));214 EXPECT_TRUE(matches("class Y { class X {}; };", YHasClassX));215 EXPECT_TRUE(notMatches("class X {};", YHasClassX));216 EXPECT_TRUE(notMatches("class Y { class Z { class X {}; }; };", YHasClassX));217}218 219TEST_P(ASTMatchersTest, Has_RecursiveAllOf) {220 if (!GetParam().isCXX()) {221 return;222 }223 224 DeclarationMatcher Recursive =225 recordDecl(has(recordDecl(has(recordDecl(hasName("X"))),226 has(recordDecl(hasName("Y"))), hasName("Z"))),227 has(recordDecl(has(recordDecl(hasName("A"))),228 has(recordDecl(hasName("B"))), hasName("C"))),229 hasName("F"));230 231 EXPECT_TRUE(matches("class F {"232 " class Z {"233 " class X {};"234 " class Y {};"235 " };"236 " class C {"237 " class A {};"238 " class B {};"239 " };"240 "};",241 Recursive));242 243 EXPECT_TRUE(matches("class F {"244 " class Z {"245 " class A {};"246 " class X {};"247 " class Y {};"248 " };"249 " class C {"250 " class X {};"251 " class A {};"252 " class B {};"253 " };"254 "};",255 Recursive));256 257 EXPECT_TRUE(matches("class O1 {"258 " class O2 {"259 " class F {"260 " class Z {"261 " class A {};"262 " class X {};"263 " class Y {};"264 " };"265 " class C {"266 " class X {};"267 " class A {};"268 " class B {};"269 " };"270 " };"271 " };"272 "};",273 Recursive));274}275 276TEST_P(ASTMatchersTest, Has_RecursiveAnyOf) {277 if (!GetParam().isCXX()) {278 return;279 }280 281 DeclarationMatcher Recursive = recordDecl(282 anyOf(has(recordDecl(anyOf(has(recordDecl(hasName("X"))),283 has(recordDecl(hasName("Y"))), hasName("Z")))),284 has(recordDecl(anyOf(hasName("C"), has(recordDecl(hasName("A"))),285 has(recordDecl(hasName("B")))))),286 hasName("F")));287 288 EXPECT_TRUE(matches("class F {};", Recursive));289 EXPECT_TRUE(matches("class Z {};", Recursive));290 EXPECT_TRUE(matches("class C {};", Recursive));291 EXPECT_TRUE(matches("class M { class N { class X {}; }; };", Recursive));292 EXPECT_TRUE(matches("class M { class N { class B {}; }; };", Recursive));293 EXPECT_TRUE(matches("class O1 { class O2 {"294 " class M { class N { class B {}; }; }; "295 "}; };",296 Recursive));297}298 299TEST_P(ASTMatchersTest, Unless) {300 if (!GetParam().isCXX()) {301 // FIXME: Add a test for `unless()` that does not depend on C++.302 return;303 }304 305 DeclarationMatcher NotClassX =306 cxxRecordDecl(isDerivedFrom("Y"), unless(hasName("X")));307 EXPECT_TRUE(notMatches("", NotClassX));308 EXPECT_TRUE(notMatches("class Y {};", NotClassX));309 EXPECT_TRUE(matches("class Y {}; class Z : public Y {};", NotClassX));310 EXPECT_TRUE(notMatches("class Y {}; class X : public Y {};", NotClassX));311 EXPECT_TRUE(312 notMatches("class Y {}; class Z {}; class X : public Y {};", NotClassX));313 314 DeclarationMatcher ClassXHasNotClassY =315 recordDecl(hasName("X"), has(recordDecl(hasName("Z"))),316 unless(has(recordDecl(hasName("Y")))));317 EXPECT_TRUE(matches("class X { class Z {}; };", ClassXHasNotClassY));318 EXPECT_TRUE(319 notMatches("class X { class Y {}; class Z {}; };", ClassXHasNotClassY));320 321 DeclarationMatcher NamedNotRecord =322 namedDecl(hasName("Foo"), unless(recordDecl()));323 EXPECT_TRUE(matches("void Foo(){}", NamedNotRecord));324 EXPECT_TRUE(notMatches("struct Foo {};", NamedNotRecord));325}326 327TEST_P(ASTMatchersTest, HasCastKind) {328 EXPECT_TRUE(329 matches("char *p = 0;",330 traverse(TK_AsIs,331 varDecl(has(castExpr(hasCastKind(CK_NullToPointer)))))));332 EXPECT_TRUE(notMatches(333 "char *p = 0;",334 traverse(TK_AsIs,335 varDecl(has(castExpr(hasCastKind(CK_DerivedToBase)))))));336 EXPECT_TRUE(matches("char *p = 0;",337 traverse(TK_AsIs, varDecl(has(implicitCastExpr(338 hasCastKind(CK_NullToPointer)))))));339}340 341TEST_P(ASTMatchersTest, HasDescendant) {342 if (!GetParam().isCXX()) {343 // FIXME: Add a test for `hasDescendant()` that does not depend on C++.344 return;345 }346 347 DeclarationMatcher ZDescendantClassX =348 recordDecl(hasDescendant(recordDecl(hasName("X"))), hasName("Z"));349 EXPECT_TRUE(matches("class Z { class X {}; };", ZDescendantClassX));350 EXPECT_TRUE(351 matches("class Z { class Y { class X {}; }; };", ZDescendantClassX));352 EXPECT_TRUE(matches("class Z { class A { class Y { class X {}; }; }; };",353 ZDescendantClassX));354 EXPECT_TRUE(355 matches("class Z { class A { class B { class Y { class X {}; }; }; }; };",356 ZDescendantClassX));357 EXPECT_TRUE(notMatches("class Z {};", ZDescendantClassX));358 359 DeclarationMatcher ZDescendantClassXHasClassY = recordDecl(360 hasDescendant(recordDecl(has(recordDecl(hasName("Y"))), hasName("X"))),361 hasName("Z"));362 EXPECT_TRUE(matches("class Z { class X { class Y {}; }; };",363 ZDescendantClassXHasClassY));364 EXPECT_TRUE(365 matches("class Z { class A { class B { class X { class Y {}; }; }; }; };",366 ZDescendantClassXHasClassY));367 EXPECT_TRUE(notMatches("class Z {"368 " class A {"369 " class B {"370 " class X {"371 " class C {"372 " class Y {};"373 " };"374 " };"375 " }; "376 " };"377 "};",378 ZDescendantClassXHasClassY));379 380 DeclarationMatcher ZDescendantClassXDescendantClassY =381 recordDecl(hasDescendant(recordDecl(382 hasDescendant(recordDecl(hasName("Y"))), hasName("X"))),383 hasName("Z"));384 EXPECT_TRUE(385 matches("class Z { class A { class X { class B { class Y {}; }; }; }; };",386 ZDescendantClassXDescendantClassY));387 EXPECT_TRUE(matches("class Z {"388 " class A {"389 " class X {"390 " class B {"391 " class Y {};"392 " };"393 " class Y {};"394 " };"395 " };"396 "};",397 ZDescendantClassXDescendantClassY));398}399 400TEST_P(ASTMatchersTest, HasDescendant_Memoization) {401 DeclarationMatcher CannotMemoize =402 decl(hasDescendant(typeLoc().bind("x")), has(decl()));403 EXPECT_TRUE(matches("void f() { int i; }", CannotMemoize));404}405 406TEST_P(ASTMatchersTest, HasDescendant_MemoizationUsesRestrictKind) {407 auto Name = hasName("i");408 auto VD = internal::Matcher<VarDecl>(Name).dynCastTo<Decl>();409 auto RD = internal::Matcher<RecordDecl>(Name).dynCastTo<Decl>();410 // Matching VD first should not make a cache hit for RD.411 EXPECT_TRUE(notMatches("void f() { int i; }",412 decl(hasDescendant(VD), hasDescendant(RD))));413 EXPECT_TRUE(notMatches("void f() { int i; }",414 decl(hasDescendant(RD), hasDescendant(VD))));415 // Not matching RD first should not make a cache hit for VD either.416 EXPECT_TRUE(matches("void f() { int i; }",417 decl(anyOf(hasDescendant(RD), hasDescendant(VD)))));418}419 420TEST_P(ASTMatchersTest, HasAncestor_Memoization) {421 if (!GetParam().isCXX()) {422 return;423 }424 425 // This triggers an hasAncestor with a TemplateArgument in the bound nodes.426 // That node can't be memoized so we have to check for it before trying to put427 // it on the cache.428 DeclarationMatcher CannotMemoize = classTemplateSpecializationDecl(429 hasAnyTemplateArgument(templateArgument().bind("targ")),430 forEach(fieldDecl(hasAncestor(forStmt()))));431 432 EXPECT_TRUE(notMatches("template <typename T> struct S;"433 "template <> struct S<int>{ int i; int j; };",434 CannotMemoize));435}436 437TEST_P(ASTMatchersTest, HasAttr) {438 EXPECT_TRUE(matches("struct __attribute__((warn_unused)) X {};",439 decl(hasAttr(clang::attr::WarnUnused))));440 EXPECT_FALSE(matches("struct X {};", decl(hasAttr(clang::attr::WarnUnused))));441}442 443TEST_P(ASTMatchersTest, AnyOf) {444 if (!GetParam().isCXX()) {445 // FIXME: Add a test for `anyOf()` that does not depend on C++.446 return;447 }448 449 DeclarationMatcher YOrZDerivedFromX = cxxRecordDecl(450 anyOf(hasName("Y"), allOf(isDerivedFrom("X"), hasName("Z"))));451 EXPECT_TRUE(matches("class X {}; class Z : public X {};", YOrZDerivedFromX));452 EXPECT_TRUE(matches("class Y {};", YOrZDerivedFromX));453 EXPECT_TRUE(454 notMatches("class X {}; class W : public X {};", YOrZDerivedFromX));455 EXPECT_TRUE(notMatches("class Z {};", YOrZDerivedFromX));456 457 DeclarationMatcher XOrYOrZOrU =458 recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U")));459 EXPECT_TRUE(matches("class X {};", XOrYOrZOrU));460 EXPECT_TRUE(notMatches("class V {};", XOrYOrZOrU));461 462 DeclarationMatcher XOrYOrZOrUOrV = recordDecl(anyOf(463 hasName("X"), hasName("Y"), hasName("Z"), hasName("U"), hasName("V")));464 EXPECT_TRUE(matches("class X {};", XOrYOrZOrUOrV));465 EXPECT_TRUE(matches("class Y {};", XOrYOrZOrUOrV));466 EXPECT_TRUE(matches("class Z {};", XOrYOrZOrUOrV));467 EXPECT_TRUE(matches("class U {};", XOrYOrZOrUOrV));468 EXPECT_TRUE(matches("class V {};", XOrYOrZOrUOrV));469 EXPECT_TRUE(notMatches("class A {};", XOrYOrZOrUOrV));470 471 StatementMatcher MixedTypes = stmt(anyOf(ifStmt(), binaryOperator()));472 EXPECT_TRUE(matches("int F() { return 1 + 2; }", MixedTypes));473 EXPECT_TRUE(matches("int F() { if (true) return 1; }", MixedTypes));474 EXPECT_TRUE(notMatches("int F() { return 1; }", MixedTypes));475 476 EXPECT_TRUE(477 matches("void f() try { } catch (int) { } catch (...) { }",478 cxxCatchStmt(anyOf(hasDescendant(varDecl()), isCatchAll()))));479}480 481TEST_P(ASTMatchersTest, MapAnyOf) {482 if (!GetParam().isCXX()) {483 return;484 }485 486 if (GetParam().hasDelayedTemplateParsing()) {487 return;488 }489 490 StringRef Code = R"cpp(491void F() {492 if (true) {}493 for ( ; false; ) {}494}495)cpp";496 497 auto trueExpr = cxxBoolLiteral(equals(true));498 auto falseExpr = cxxBoolLiteral(equals(false));499 500 EXPECT_TRUE(matches(501 Code, traverse(TK_IgnoreUnlessSpelledInSource,502 mapAnyOf(ifStmt, forStmt).with(hasCondition(trueExpr)))));503 EXPECT_TRUE(matches(504 Code, traverse(TK_IgnoreUnlessSpelledInSource,505 mapAnyOf(ifStmt, forStmt).with(hasCondition(falseExpr)))));506 507 EXPECT_TRUE(508 matches(Code, cxxBoolLiteral(equals(true),509 hasAncestor(mapAnyOf(ifStmt, forStmt)))));510 511 EXPECT_TRUE(512 matches(Code, cxxBoolLiteral(equals(false),513 hasAncestor(mapAnyOf(ifStmt, forStmt)))));514 515 EXPECT_TRUE(516 notMatches(Code, floatLiteral(hasAncestor(mapAnyOf(ifStmt, forStmt)))));517 518 Code = R"cpp(519void func(bool b) {}520struct S {521 S(bool b) {}522};523void F() {524 func(false);525 S s(true);526}527)cpp";528 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,529 mapAnyOf(callExpr, cxxConstructExpr)530 .with(hasArgument(0, trueExpr)))));531 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,532 mapAnyOf(callExpr, cxxConstructExpr)533 .with(hasArgument(0, falseExpr)))));534 535 EXPECT_TRUE(536 matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,537 mapAnyOf(callExpr, cxxConstructExpr)538 .with(hasArgument(0, expr()),539 hasDeclaration(functionDecl())))));540 541 EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,542 mapAnyOf(callExpr, cxxConstructExpr))));543 544 EXPECT_TRUE(matches(545 Code, traverse(TK_IgnoreUnlessSpelledInSource,546 mapAnyOf(callExpr, cxxConstructExpr).bind("call"))));547 548 Code = R"cpp(549struct HasOpNeqMem550{551 bool operator!=(const HasOpNeqMem& other) const552 {553 return true;554 }555};556struct HasOpFree557{558};559bool operator!=(const HasOpFree& lhs, const HasOpFree& rhs)560{561 return true;562}563 564void binop()565{566 int s1;567 int s2;568 if (s1 != s2)569 return;570}571 572void opMem()573{574 HasOpNeqMem s1;575 HasOpNeqMem s2;576 if (s1 != s2)577 return;578}579 580void opFree()581{582 HasOpFree s1;583 HasOpFree s2;584 if (s1 != s2)585 return;586}587 588template<typename T>589void templ()590{591 T s1;592 T s2;593 if (s1 != s2)594 return;595}596)cpp";597 598 EXPECT_TRUE(matches(599 Code,600 traverse(TK_IgnoreUnlessSpelledInSource,601 mapAnyOf(binaryOperator, cxxOperatorCallExpr)602 .with(hasOperatorName("!="),603 forFunction(functionDecl(hasName("binop"))),604 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),605 hasRHS(declRefExpr(to(varDecl(hasName("s2")))))))));606 607 EXPECT_TRUE(matches(608 Code,609 traverse(TK_IgnoreUnlessSpelledInSource,610 mapAnyOf(binaryOperator, cxxOperatorCallExpr)611 .with(hasOperatorName("!="),612 forFunction(functionDecl(hasName("opMem"))),613 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),614 hasRHS(declRefExpr(to(varDecl(hasName("s2")))))))));615 616 EXPECT_TRUE(matches(617 Code,618 traverse(TK_IgnoreUnlessSpelledInSource,619 mapAnyOf(binaryOperator, cxxOperatorCallExpr)620 .with(hasOperatorName("!="),621 forFunction(functionDecl(hasName("opFree"))),622 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),623 hasRHS(declRefExpr(to(varDecl(hasName("s2")))))))));624 625 EXPECT_TRUE(matches(626 Code, traverse(TK_IgnoreUnlessSpelledInSource,627 mapAnyOf(binaryOperator, cxxOperatorCallExpr)628 .with(hasOperatorName("!="),629 forFunction(functionDecl(hasName("binop"))),630 hasEitherOperand(631 declRefExpr(to(varDecl(hasName("s1"))))),632 hasEitherOperand(633 declRefExpr(to(varDecl(hasName("s2")))))))));634 635 EXPECT_TRUE(matches(636 Code, traverse(TK_IgnoreUnlessSpelledInSource,637 mapAnyOf(binaryOperator, cxxOperatorCallExpr)638 .with(hasOperatorName("!="),639 forFunction(functionDecl(hasName("opMem"))),640 hasEitherOperand(641 declRefExpr(to(varDecl(hasName("s1"))))),642 hasEitherOperand(643 declRefExpr(to(varDecl(hasName("s2")))))))));644 645 EXPECT_TRUE(matches(646 Code, traverse(TK_IgnoreUnlessSpelledInSource,647 mapAnyOf(binaryOperator, cxxOperatorCallExpr)648 .with(hasOperatorName("!="),649 forFunction(functionDecl(hasName("opFree"))),650 hasEitherOperand(651 declRefExpr(to(varDecl(hasName("s1"))))),652 hasEitherOperand(653 declRefExpr(to(varDecl(hasName("s2")))))))));654 655 EXPECT_TRUE(matches(656 Code,657 traverse(658 TK_IgnoreUnlessSpelledInSource,659 mapAnyOf(binaryOperator, cxxOperatorCallExpr)660 .with(hasOperatorName("!="),661 forFunction(functionDecl(hasName("binop"))),662 hasOperands(declRefExpr(to(varDecl(hasName("s1")))),663 declRefExpr(to(varDecl(hasName("s2"))))),664 hasOperands(declRefExpr(to(varDecl(hasName("s2")))),665 declRefExpr(to(varDecl(hasName("s1")))))))));666 667 EXPECT_TRUE(matches(668 Code,669 traverse(670 TK_IgnoreUnlessSpelledInSource,671 mapAnyOf(binaryOperator, cxxOperatorCallExpr)672 .with(hasOperatorName("!="),673 forFunction(functionDecl(hasName("opMem"))),674 hasOperands(declRefExpr(to(varDecl(hasName("s1")))),675 declRefExpr(to(varDecl(hasName("s2"))))),676 hasOperands(declRefExpr(to(varDecl(hasName("s2")))),677 declRefExpr(to(varDecl(hasName("s1")))))))));678 679 EXPECT_TRUE(matches(680 Code,681 traverse(682 TK_IgnoreUnlessSpelledInSource,683 mapAnyOf(binaryOperator, cxxOperatorCallExpr)684 .with(hasOperatorName("!="),685 forFunction(functionDecl(hasName("opFree"))),686 hasOperands(declRefExpr(to(varDecl(hasName("s1")))),687 declRefExpr(to(varDecl(hasName("s2"))))),688 hasOperands(declRefExpr(to(varDecl(hasName("s2")))),689 declRefExpr(to(varDecl(hasName("s1")))))))));690 691 EXPECT_TRUE(matches(692 Code, traverse(TK_IgnoreUnlessSpelledInSource,693 mapAnyOf(binaryOperator, cxxOperatorCallExpr)694 .with(hasAnyOperatorName("==", "!="),695 forFunction(functionDecl(hasName("binop")))))));696 697 EXPECT_TRUE(matches(698 Code, traverse(TK_IgnoreUnlessSpelledInSource,699 mapAnyOf(binaryOperator, cxxOperatorCallExpr)700 .with(hasAnyOperatorName("==", "!="),701 forFunction(functionDecl(hasName("opMem")))))));702 703 EXPECT_TRUE(matches(704 Code, traverse(TK_IgnoreUnlessSpelledInSource,705 mapAnyOf(binaryOperator, cxxOperatorCallExpr)706 .with(hasAnyOperatorName("==", "!="),707 forFunction(functionDecl(hasName("opFree")))))));708 709 EXPECT_TRUE(matches(710 Code, traverse(TK_IgnoreUnlessSpelledInSource,711 binaryOperation(712 hasOperatorName("!="),713 forFunction(functionDecl(hasName("binop"))),714 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),715 hasRHS(declRefExpr(to(varDecl(hasName("s2")))))))));716 717 EXPECT_TRUE(matches(718 Code, traverse(TK_IgnoreUnlessSpelledInSource,719 binaryOperation(720 hasOperatorName("!="),721 forFunction(functionDecl(hasName("opMem"))),722 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),723 hasRHS(declRefExpr(to(varDecl(hasName("s2")))))))));724 725 EXPECT_TRUE(matches(726 Code, traverse(TK_IgnoreUnlessSpelledInSource,727 binaryOperation(728 hasOperatorName("!="),729 forFunction(functionDecl(hasName("opFree"))),730 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),731 hasRHS(declRefExpr(to(varDecl(hasName("s2")))))))));732 733 EXPECT_TRUE(matches(734 Code, traverse(TK_IgnoreUnlessSpelledInSource,735 binaryOperation(736 hasOperatorName("!="),737 forFunction(functionDecl(hasName("templ"))),738 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),739 hasRHS(declRefExpr(to(varDecl(hasName("s2")))))))));740 741 Code = R"cpp(742struct HasOpEq743{744 bool operator==(const HasOpEq &) const;745};746 747void inverse()748{749 HasOpEq s1;750 HasOpEq s2;751 if (s1 != s2)752 return;753}754 755namespace std {756struct strong_ordering {757 int n;758 constexpr operator int() const { return n; }759 static const strong_ordering equal, greater, less;760};761constexpr strong_ordering strong_ordering::equal = {0};762constexpr strong_ordering strong_ordering::greater = {1};763constexpr strong_ordering strong_ordering::less = {-1};764}765 766struct HasSpaceshipMem {767 int a;768 constexpr auto operator<=>(const HasSpaceshipMem&) const = default;769};770 771void rewritten()772{773 HasSpaceshipMem s1;774 HasSpaceshipMem s2;775 if (s1 != s2)776 return;777}778)cpp";779 780 EXPECT_TRUE(matchesConditionally(781 Code,782 traverse(783 TK_IgnoreUnlessSpelledInSource,784 binaryOperation(hasOperatorName("!="),785 forFunction(functionDecl(hasName("inverse"))),786 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),787 hasRHS(declRefExpr(to(varDecl(hasName("s2"))))))),788 true, {"-std=c++20"}));789 790 EXPECT_TRUE(matchesConditionally(791 Code,792 traverse(793 TK_IgnoreUnlessSpelledInSource,794 binaryOperation(hasOperatorName("!="),795 forFunction(functionDecl(hasName("rewritten"))),796 hasLHS(declRefExpr(to(varDecl(hasName("s1"))))),797 hasRHS(declRefExpr(to(varDecl(hasName("s2"))))))),798 true, {"-std=c++20"}));799 800 Code = R"cpp(801struct HasOpBangMem802{803 bool operator!() const804 {805 return false;806 }807};808struct HasOpBangFree809{810};811bool operator!(HasOpBangFree const&)812{813 return false;814}815 816void unop()817{818 int s1;819 if (!s1)820 return;821}822 823void opMem()824{825 HasOpBangMem s1;826 if (!s1)827 return;828}829 830void opFree()831{832 HasOpBangFree s1;833 if (!s1)834 return;835}836)cpp";837 838 EXPECT_TRUE(matches(839 Code, traverse(TK_IgnoreUnlessSpelledInSource,840 mapAnyOf(unaryOperator, cxxOperatorCallExpr)841 .with(hasOperatorName("!"),842 forFunction(functionDecl(hasName("unop"))),843 hasUnaryOperand(844 declRefExpr(to(varDecl(hasName("s1")))))))));845 846 EXPECT_TRUE(matches(847 Code, traverse(TK_IgnoreUnlessSpelledInSource,848 mapAnyOf(unaryOperator, cxxOperatorCallExpr)849 .with(hasOperatorName("!"),850 forFunction(functionDecl(hasName("opMem"))),851 hasUnaryOperand(852 declRefExpr(to(varDecl(hasName("s1")))))))));853 854 EXPECT_TRUE(matches(855 Code, traverse(TK_IgnoreUnlessSpelledInSource,856 mapAnyOf(unaryOperator, cxxOperatorCallExpr)857 .with(hasOperatorName("!"),858 forFunction(functionDecl(hasName("opFree"))),859 hasUnaryOperand(860 declRefExpr(to(varDecl(hasName("s1")))))))));861 862 EXPECT_TRUE(matches(863 Code, traverse(TK_IgnoreUnlessSpelledInSource,864 mapAnyOf(unaryOperator, cxxOperatorCallExpr)865 .with(hasAnyOperatorName("+", "!"),866 forFunction(functionDecl(hasName("unop")))))));867 868 EXPECT_TRUE(matches(869 Code, traverse(TK_IgnoreUnlessSpelledInSource,870 mapAnyOf(unaryOperator, cxxOperatorCallExpr)871 .with(hasAnyOperatorName("+", "!"),872 forFunction(functionDecl(hasName("opMem")))))));873 874 EXPECT_TRUE(matches(875 Code, traverse(TK_IgnoreUnlessSpelledInSource,876 mapAnyOf(unaryOperator, cxxOperatorCallExpr)877 .with(hasAnyOperatorName("+", "!"),878 forFunction(functionDecl(hasName("opFree")))))));879 880 Code = R"cpp(881struct ConstructorTakesInt882{883 ConstructorTakesInt(int i) {}884};885 886void callTakesInt(int i)887{888 889}890 891void doCall()892{893 callTakesInt(42);894}895 896void doConstruct()897{898 ConstructorTakesInt cti(42);899}900)cpp";901 902 EXPECT_TRUE(matches(903 Code, traverse(TK_IgnoreUnlessSpelledInSource,904 invocation(forFunction(functionDecl(hasName("doCall"))),905 hasArgument(0, integerLiteral(equals(42))),906 hasAnyArgument(integerLiteral(equals(42))),907 forEachArgumentWithParam(908 integerLiteral(equals(42)),909 parmVarDecl(hasName("i")))))));910 911 EXPECT_TRUE(matches(912 Code,913 traverse(914 TK_IgnoreUnlessSpelledInSource,915 invocation(forFunction(functionDecl(hasName("doConstruct"))),916 hasArgument(0, integerLiteral(equals(42))),917 hasAnyArgument(integerLiteral(equals(42))),918 forEachArgumentWithParam(integerLiteral(equals(42)),919 parmVarDecl(hasName("i")))))));920}921 922TEST_P(ASTMatchersTest, IsDerivedFrom) {923 if (!GetParam().isCXX()) {924 return;925 }926 927 DeclarationMatcher IsDerivedFromX = cxxRecordDecl(isDerivedFrom("X"));928 929 EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsDerivedFromX));930 EXPECT_TRUE(notMatches("class X {};", IsDerivedFromX));931 EXPECT_TRUE(notMatches("class X;", IsDerivedFromX));932 EXPECT_TRUE(notMatches("class Y;", IsDerivedFromX));933 EXPECT_TRUE(notMatches("", IsDerivedFromX));934 EXPECT_TRUE(matches("class X {}; template<int N> class Y : Y<N-1>, X {};",935 IsDerivedFromX));936 EXPECT_TRUE(matches("class X {}; template<int N> class Y : X, Y<N-1> {};",937 IsDerivedFromX));938 939 DeclarationMatcher IsZDerivedFromX =940 cxxRecordDecl(hasName("Z"), isDerivedFrom("X"));941 EXPECT_TRUE(matches("class X {};"942 "template<int N> class Y : Y<N-1> {};"943 "template<> class Y<0> : X {};"944 "class Z : Y<1> {};",945 IsZDerivedFromX));946 947 DeclarationMatcher IsDirectlyDerivedFromX =948 cxxRecordDecl(isDirectlyDerivedFrom("X"));949 950 EXPECT_TRUE(951 matches("class X {}; class Y : public X {};", IsDirectlyDerivedFromX));952 EXPECT_TRUE(notMatches("class X {};", IsDirectlyDerivedFromX));953 EXPECT_TRUE(notMatches("class X;", IsDirectlyDerivedFromX));954 EXPECT_TRUE(notMatches("class Y;", IsDirectlyDerivedFromX));955 EXPECT_TRUE(notMatches("", IsDirectlyDerivedFromX));956 957 DeclarationMatcher IsAX = cxxRecordDecl(isSameOrDerivedFrom("X"));958 959 EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsAX));960 EXPECT_TRUE(matches("class X {};", IsAX));961 EXPECT_TRUE(matches("class X;", IsAX));962 EXPECT_TRUE(notMatches("class Y;", IsAX));963 EXPECT_TRUE(notMatches("", IsAX));964 965 DeclarationMatcher ZIsDerivedFromX =966 cxxRecordDecl(hasName("Z"), isDerivedFrom("X"));967 DeclarationMatcher ZIsDirectlyDerivedFromX =968 cxxRecordDecl(hasName("Z"), isDirectlyDerivedFrom("X"));969 EXPECT_TRUE(970 matches("class X {}; class Y : public X {}; class Z : public Y {};",971 ZIsDerivedFromX));972 EXPECT_TRUE(973 notMatches("class X {}; class Y : public X {}; class Z : public Y {};",974 ZIsDirectlyDerivedFromX));975 EXPECT_TRUE(matches("class X {};"976 "template<class T> class Y : public X {};"977 "class Z : public Y<int> {};",978 ZIsDerivedFromX));979 EXPECT_TRUE(notMatches("class X {};"980 "template<class T> class Y : public X {};"981 "class Z : public Y<int> {};",982 ZIsDirectlyDerivedFromX));983 EXPECT_TRUE(matches("class X {}; template<class T> class Z : public X {};",984 ZIsDerivedFromX));985 EXPECT_TRUE(matches("template<class T> class X {}; "986 "template<class T> class Z : public X<T> {};",987 ZIsDerivedFromX));988 EXPECT_TRUE(matches("template<class T, class U=T> class X {}; "989 "template<class T> class Z : public X<T> {};",990 ZIsDerivedFromX));991 EXPECT_TRUE(992 notMatches("template<class X> class A { class Z : public X {}; };",993 ZIsDerivedFromX));994 EXPECT_TRUE(995 matches("template<class X> class A { public: class Z : public X {}; }; "996 "class X{}; void y() { A<X>::Z z; }",997 ZIsDerivedFromX));998 EXPECT_TRUE(999 matches("template <class T> class X {}; "1000 "template<class Y> class A { class Z : public X<Y> {}; };",1001 ZIsDerivedFromX));1002 EXPECT_TRUE(notMatches("template<template<class T> class X> class A { "1003 " class Z : public X<int> {}; };",1004 ZIsDerivedFromX));1005 EXPECT_TRUE(matches("template<template<class T> class X> class A { "1006 " public: class Z : public X<int> {}; }; "1007 "template<class T> class X {}; void y() { A<X>::Z z; }",1008 ZIsDerivedFromX));1009 EXPECT_TRUE(1010 notMatches("template<class X> class A { class Z : public X::D {}; };",1011 ZIsDerivedFromX));1012 EXPECT_TRUE(matches("template<class X> class A { public: "1013 " class Z : public X::D {}; }; "1014 "class Y { public: class X {}; typedef X D; }; "1015 "void y() { A<Y>::Z z; }",1016 ZIsDerivedFromX));1017 EXPECT_TRUE(matches("class X {}; typedef X Y; class Z : public Y {};",1018 ZIsDerivedFromX));1019 EXPECT_TRUE(matches("template<class T> class Y { typedef typename T::U X; "1020 " class Z : public X {}; };",1021 ZIsDerivedFromX));1022 EXPECT_TRUE(matches("class X {}; class Z : public ::X {};", ZIsDerivedFromX));1023 EXPECT_TRUE(1024 notMatches("template<class T> class X {}; "1025 "template<class T> class A { class Z : public X<T>::D {}; };",1026 ZIsDerivedFromX));1027 EXPECT_TRUE(1028 matches("template<class T> class X { public: typedef X<T> D; }; "1029 "template<class T> class A { public: "1030 " class Z : public X<T>::D {}; }; void y() { A<int>::Z z; }",1031 ZIsDerivedFromX));1032 EXPECT_TRUE(1033 notMatches("template<class X> class A { class Z : public X::D::E {}; };",1034 ZIsDerivedFromX));1035 EXPECT_TRUE(1036 matches("class X {}; typedef X V; typedef V W; class Z : public W {};",1037 ZIsDerivedFromX));1038 EXPECT_TRUE(matches("class X {}; class Y : public X {}; "1039 "typedef Y V; typedef V W; class Z : public W {};",1040 ZIsDerivedFromX));1041 EXPECT_TRUE(notMatches("class X {}; class Y : public X {}; "1042 "typedef Y V; typedef V W; class Z : public W {};",1043 ZIsDirectlyDerivedFromX));1044 EXPECT_TRUE(1045 matches("template<class T, class U> class X {}; "1046 "template<class T> class A { class Z : public X<T, int> {}; };",1047 ZIsDerivedFromX));1048 EXPECT_TRUE(1049 notMatches("template<class X> class D { typedef X A; typedef A B; "1050 " typedef B C; class Z : public C {}; };",1051 ZIsDerivedFromX));1052 EXPECT_TRUE(matches("class X {}; typedef X A; typedef A B; "1053 "class Z : public B {};",1054 ZIsDerivedFromX));1055 EXPECT_TRUE(matches("class X {}; typedef X A; typedef A B; typedef B C; "1056 "class Z : public C {};",1057 ZIsDerivedFromX));1058 EXPECT_TRUE(matches("class U {}; typedef U X; typedef X V; "1059 "class Z : public V {};",1060 ZIsDerivedFromX));1061 EXPECT_TRUE(matches("class Base {}; typedef Base X; "1062 "class Z : public Base {};",1063 ZIsDerivedFromX));1064 EXPECT_TRUE(matches("class Base {}; typedef Base Base2; typedef Base2 X; "1065 "class Z : public Base {};",1066 ZIsDerivedFromX));1067 EXPECT_TRUE(notMatches("class Base {}; class Base2 {}; typedef Base2 X; "1068 "class Z : public Base {};",1069 ZIsDerivedFromX));1070 EXPECT_TRUE(matches("class A {}; typedef A X; typedef A Y; "1071 "class Z : public Y {};",1072 ZIsDerivedFromX));1073 EXPECT_TRUE(notMatches("template <typename T> class Z;"1074 "template <> class Z<void> {};"1075 "template <typename T> class Z : public Z<void> {};",1076 IsDerivedFromX));1077 EXPECT_TRUE(matches("template <typename T> class X;"1078 "template <> class X<void> {};"1079 "template <typename T> class X : public X<void> {};",1080 IsDerivedFromX));1081 EXPECT_TRUE(1082 matches("class X {};"1083 "template <typename T> class Z;"1084 "template <> class Z<void> {};"1085 "template <typename T> class Z : public Z<void>, public X {};",1086 ZIsDerivedFromX));1087 EXPECT_TRUE(1088 notMatches("template<int> struct X;"1089 "template<int i> struct X : public X<i-1> {};",1090 cxxRecordDecl(isDerivedFrom(recordDecl(hasName("Some"))))));1091 EXPECT_TRUE(matches(1092 "struct A {};"1093 "template<int> struct X;"1094 "template<int i> struct X : public X<i-1> {};"1095 "template<> struct X<0> : public A {};"1096 "struct B : public X<42> {};",1097 cxxRecordDecl(hasName("B"), isDerivedFrom(recordDecl(hasName("A"))))));1098 EXPECT_TRUE(notMatches(1099 "struct A {};"1100 "template<int> struct X;"1101 "template<int i> struct X : public X<i-1> {};"1102 "template<> struct X<0> : public A {};"1103 "struct B : public X<42> {};",1104 cxxRecordDecl(hasName("B"),1105 isDirectlyDerivedFrom(recordDecl(hasName("A"))))));1106 1107 // FIXME: Once we have better matchers for template type matching,1108 // get rid of the Variable(...) matching and match the right template1109 // declarations directly.1110 const char *RecursiveTemplateOneParameter =1111 "class Base1 {}; class Base2 {};"1112 "template <typename T> class Z;"1113 "template <> class Z<void> : public Base1 {};"1114 "template <> class Z<int> : public Base2 {};"1115 "template <> class Z<float> : public Z<void> {};"1116 "template <> class Z<double> : public Z<int> {};"1117 "template <typename T> class Z : public Z<float>, public Z<double> {};"1118 "void f() { Z<float> z_float; Z<double> z_double; Z<char> z_char; }";1119 EXPECT_TRUE(matches(1120 RecursiveTemplateOneParameter,1121 varDecl(hasName("z_float"),1122 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1")))))));1123 EXPECT_TRUE(notMatches(1124 RecursiveTemplateOneParameter,1125 varDecl(hasName("z_float"),1126 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2")))))));1127 EXPECT_TRUE(1128 matches(RecursiveTemplateOneParameter,1129 varDecl(hasName("z_char"),1130 hasInitializer(hasType(cxxRecordDecl(1131 isDerivedFrom("Base1"), isDerivedFrom("Base2")))))));1132 1133 const char *RecursiveTemplateTwoParameters =1134 "class Base1 {}; class Base2 {};"1135 "template <typename T1, typename T2> class Z;"1136 "template <typename T> class Z<void, T> : public Base1 {};"1137 "template <typename T> class Z<int, T> : public Base2 {};"1138 "template <typename T> class Z<float, T> : public Z<void, T> {};"1139 "template <typename T> class Z<double, T> : public Z<int, T> {};"1140 "template <typename T1, typename T2> class Z : "1141 " public Z<float, T2>, public Z<double, T2> {};"1142 "void f() { Z<float, void> z_float; Z<double, void> z_double; "1143 " Z<char, void> z_char; }";1144 EXPECT_TRUE(matches(1145 RecursiveTemplateTwoParameters,1146 varDecl(hasName("z_float"),1147 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1")))))));1148 EXPECT_TRUE(notMatches(1149 RecursiveTemplateTwoParameters,1150 varDecl(hasName("z_float"),1151 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2")))))));1152 EXPECT_TRUE(1153 matches(RecursiveTemplateTwoParameters,1154 varDecl(hasName("z_char"),1155 hasInitializer(hasType(cxxRecordDecl(1156 isDerivedFrom("Base1"), isDerivedFrom("Base2")))))));1157 EXPECT_TRUE(matches("namespace ns { class X {}; class Y : public X {}; }",1158 cxxRecordDecl(isDerivedFrom("::ns::X"))));1159 EXPECT_TRUE(notMatches("class X {}; class Y : public X {};",1160 cxxRecordDecl(isDerivedFrom("::ns::X"))));1161 1162 EXPECT_TRUE(matches(1163 "class X {}; class Y : public X {};",1164 cxxRecordDecl(isDerivedFrom(recordDecl(hasName("X")).bind("test")))));1165 1166 EXPECT_TRUE(matches("template<typename T> class X {};"1167 "template<typename T> using Z = X<T>;"1168 "template <typename T> class Y : Z<T> {};",1169 cxxRecordDecl(isDerivedFrom(namedDecl(hasName("X"))))));1170}1171 1172TEST_P(ASTMatchersTest, IsDerivedFrom_EmptyName) {1173 if (!GetParam().isCXX()) {1174 return;1175 }1176 1177 const char *const Code = "class X {}; class Y : public X {};";1178 EXPECT_TRUE(notMatches(Code, cxxRecordDecl(isDerivedFrom(""))));1179 EXPECT_TRUE(notMatches(Code, cxxRecordDecl(isDirectlyDerivedFrom(""))));1180 EXPECT_TRUE(notMatches(Code, cxxRecordDecl(isSameOrDerivedFrom(""))));1181}1182 1183TEST_P(ASTMatchersTest, IsDerivedFrom_ElaboratedType) {1184 if (!GetParam().isCXX()) {1185 return;1186 }1187 1188 DeclarationMatcher IsDerivenFromBase = cxxRecordDecl(1189 isDerivedFrom(decl().bind("typedef")), unless(isImplicit()));1190 1191 EXPECT_TRUE(matchAndVerifyResultTrue(1192 "struct AnInterface {};"1193 "typedef AnInterface UnusedTypedef;"1194 "typedef AnInterface Base;"1195 "class AClass : public Base {};",1196 IsDerivenFromBase,1197 std::make_unique<VerifyIdIsBoundTo<TypedefDecl>>("typedef", "Base")));1198}1199 1200TEST_P(ASTMatchersTest, IsDerivedFrom_ObjC) {1201 DeclarationMatcher IsDerivedFromX = objcInterfaceDecl(isDerivedFrom("X"));1202 EXPECT_TRUE(1203 matchesObjC("@interface X @end @interface Y : X @end", IsDerivedFromX));1204 EXPECT_TRUE(matchesObjC(1205 "@interface X @end @interface Y<__covariant ObjectType> : X @end",1206 IsDerivedFromX));1207 EXPECT_TRUE(matchesObjC(1208 "@interface X @end @compatibility_alias Y X; @interface Z : Y @end",1209 IsDerivedFromX));1210 EXPECT_TRUE(matchesObjC(1211 "@interface X @end typedef X Y; @interface Z : Y @end", IsDerivedFromX));1212 EXPECT_TRUE(notMatchesObjC("@interface X @end", IsDerivedFromX));1213 EXPECT_TRUE(notMatchesObjC("@class X;", IsDerivedFromX));1214 EXPECT_TRUE(notMatchesObjC("@class Y;", IsDerivedFromX));1215 EXPECT_TRUE(notMatchesObjC("@interface X @end @compatibility_alias Y X;",1216 IsDerivedFromX));1217 EXPECT_TRUE(notMatchesObjC("@interface X @end typedef X Y;", IsDerivedFromX));1218 1219 DeclarationMatcher IsDirectlyDerivedFromX =1220 objcInterfaceDecl(isDirectlyDerivedFrom("X"));1221 EXPECT_TRUE(matchesObjC("@interface X @end @interface Y : X @end",1222 IsDirectlyDerivedFromX));1223 EXPECT_TRUE(matchesObjC(1224 "@interface X @end @interface Y<__covariant ObjectType> : X @end",1225 IsDirectlyDerivedFromX));1226 EXPECT_TRUE(matchesObjC(1227 "@interface X @end @compatibility_alias Y X; @interface Z : Y @end",1228 IsDirectlyDerivedFromX));1229 EXPECT_TRUE(1230 matchesObjC("@interface X @end typedef X Y; @interface Z : Y @end",1231 IsDirectlyDerivedFromX));1232 EXPECT_TRUE(notMatchesObjC("@interface X @end", IsDirectlyDerivedFromX));1233 EXPECT_TRUE(notMatchesObjC("@class X;", IsDirectlyDerivedFromX));1234 EXPECT_TRUE(notMatchesObjC("@class Y;", IsDirectlyDerivedFromX));1235 EXPECT_TRUE(notMatchesObjC("@interface X @end @compatibility_alias Y X;",1236 IsDirectlyDerivedFromX));1237 EXPECT_TRUE(1238 notMatchesObjC("@interface X @end typedef X Y;", IsDirectlyDerivedFromX));1239 1240 DeclarationMatcher IsAX = objcInterfaceDecl(isSameOrDerivedFrom("X"));1241 EXPECT_TRUE(matchesObjC("@interface X @end @interface Y : X @end", IsAX));1242 EXPECT_TRUE(matchesObjC("@interface X @end", IsAX));1243 EXPECT_TRUE(matchesObjC("@class X;", IsAX));1244 EXPECT_TRUE(notMatchesObjC("@interface Y @end", IsAX));1245 EXPECT_TRUE(notMatchesObjC("@class Y;", IsAX));1246 1247 DeclarationMatcher ZIsDerivedFromX =1248 objcInterfaceDecl(hasName("Z"), isDerivedFrom("X"));1249 DeclarationMatcher ZIsDirectlyDerivedFromX =1250 objcInterfaceDecl(hasName("Z"), isDirectlyDerivedFrom("X"));1251 EXPECT_TRUE(matchesObjC(1252 "@interface X @end @interface Y : X @end @interface Z : Y @end",1253 ZIsDerivedFromX));1254 EXPECT_TRUE(matchesObjC("@interface X @end @interface Y : X @end typedef Y "1255 "V; typedef V W; @interface Z : W @end",1256 ZIsDerivedFromX));1257 EXPECT_TRUE(matchesObjC(1258 "@interface X @end typedef X Y; @interface Z : Y @end", ZIsDerivedFromX));1259 EXPECT_TRUE(1260 matchesObjC("@interface X @end typedef X Y; @interface Z : Y @end",1261 ZIsDirectlyDerivedFromX));1262 EXPECT_TRUE(matchesObjC(1263 "@interface A @end typedef A X; typedef A Y; @interface Z : Y @end",1264 ZIsDerivedFromX));1265 EXPECT_TRUE(matchesObjC(1266 "@interface A @end typedef A X; typedef A Y; @interface Z : Y @end",1267 ZIsDirectlyDerivedFromX));1268 EXPECT_TRUE(matchesObjC(1269 "@interface X @end @compatibility_alias Y X; @interface Z : Y @end",1270 ZIsDerivedFromX));1271 EXPECT_TRUE(matchesObjC(1272 "@interface X @end @compatibility_alias Y X; @interface Z : Y @end",1273 ZIsDirectlyDerivedFromX));1274 EXPECT_TRUE(matchesObjC(1275 "@interface Y @end @compatibility_alias X Y; @interface Z : Y @end",1276 ZIsDerivedFromX));1277 EXPECT_TRUE(matchesObjC(1278 "@interface Y @end @compatibility_alias X Y; @interface Z : Y @end",1279 ZIsDirectlyDerivedFromX));1280 EXPECT_TRUE(matchesObjC(1281 "@interface A @end @compatibility_alias X A; @compatibility_alias Y A;"1282 "@interface Z : Y @end",1283 ZIsDerivedFromX));1284 EXPECT_TRUE(matchesObjC(1285 "@interface A @end @compatibility_alias X A; @compatibility_alias Y A;"1286 "@interface Z : Y @end",1287 ZIsDirectlyDerivedFromX));1288 EXPECT_TRUE(matchesObjC(1289 "@interface Y @end typedef Y X; @interface Z : X @end", ZIsDerivedFromX));1290 EXPECT_TRUE(1291 matchesObjC("@interface Y @end typedef Y X; @interface Z : X @end",1292 ZIsDirectlyDerivedFromX));1293 EXPECT_TRUE(1294 matchesObjC("@interface A @end @compatibility_alias Y A; typedef Y X;"1295 "@interface Z : A @end",1296 ZIsDerivedFromX));1297 EXPECT_TRUE(1298 matchesObjC("@interface A @end @compatibility_alias Y A; typedef Y X;"1299 "@interface Z : A @end",1300 ZIsDirectlyDerivedFromX));1301 EXPECT_TRUE(1302 matchesObjC("@interface A @end typedef A Y; @compatibility_alias X Y;"1303 "@interface Z : A @end",1304 ZIsDerivedFromX));1305 EXPECT_TRUE(1306 matchesObjC("@interface A @end typedef A Y; @compatibility_alias X Y;"1307 "@interface Z : A @end",1308 ZIsDirectlyDerivedFromX));1309}1310 1311TEST_P(ASTMatchersTest, IsLambda) {1312 if (!GetParam().isCXX11OrLater()) {1313 return;1314 }1315 1316 const auto IsLambda = cxxMethodDecl(ofClass(cxxRecordDecl(isLambda())));1317 EXPECT_TRUE(matches("auto x = []{};", IsLambda));1318 EXPECT_TRUE(notMatches("struct S { void operator()() const; };", IsLambda));1319}1320 1321TEST_P(ASTMatchersTest, Bind) {1322 DeclarationMatcher ClassX = has(recordDecl(hasName("::X")).bind("x"));1323 1324 EXPECT_TRUE(matchAndVerifyResultTrue(1325 "class X {};", ClassX,1326 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("x")));1327 1328 EXPECT_TRUE(matchAndVerifyResultFalse(1329 "class X {};", ClassX,1330 std::make_unique<VerifyIdIsBoundTo<CXXRecordDecl>>("other-id")));1331 1332 TypeMatcher TypeAHasClassB = hasDeclaration(1333 recordDecl(hasName("A"), has(recordDecl(hasName("B")).bind("b"))));1334 1335 EXPECT_TRUE(matchAndVerifyResultTrue(1336 "class A { public: A *a; class B {}; };", TypeAHasClassB,1337 std::make_unique<VerifyIdIsBoundTo<Decl>>("b")));1338 1339 StatementMatcher MethodX =1340 callExpr(callee(cxxMethodDecl(hasName("x")))).bind("x");1341 1342 EXPECT_TRUE(matchAndVerifyResultTrue(1343 "class A { void x() { x(); } };", MethodX,1344 std::make_unique<VerifyIdIsBoundTo<CXXMemberCallExpr>>("x")));1345}1346 1347TEST_P(ASTMatchersTest, Bind_SameNameInAlternatives) {1348 StatementMatcher matcher = anyOf(1349 binaryOperator(hasOperatorName("+"), hasLHS(expr().bind("x")),1350 hasRHS(integerLiteral(equals(0)))),1351 binaryOperator(hasOperatorName("+"), hasLHS(integerLiteral(equals(0))),1352 hasRHS(expr().bind("x"))));1353 1354 EXPECT_TRUE(matchAndVerifyResultTrue(1355 // The first branch of the matcher binds x to 0 but then fails.1356 // The second branch binds x to f() and succeeds.1357 "int f() { return 0 + f(); }", matcher,1358 std::make_unique<VerifyIdIsBoundTo<CallExpr>>("x")));1359}1360 1361TEST_P(ASTMatchersTest, Bind_BindsIDForMemoizedResults) {1362 // Using the same matcher in two match expressions will make memoization1363 // kick in.1364 DeclarationMatcher ClassX = recordDecl(hasName("X")).bind("x");1365 EXPECT_TRUE(matchAndVerifyResultTrue(1366 "class A { class B { class X {}; }; };",1367 DeclarationMatcher(1368 anyOf(recordDecl(hasName("A"), hasDescendant(ClassX)),1369 recordDecl(hasName("B"), hasDescendant(ClassX)))),1370 std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 2)));1371}1372 1373TEST_P(ASTMatchersTest, HasType_MatchesAsString) {1374 if (!GetParam().isCXX()) {1375 // FIXME: Add a test for `hasType()` that does not depend on C++.1376 return;1377 }1378 1379 EXPECT_TRUE(1380 matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }",1381 cxxMemberCallExpr(on(hasType(asString("Y *"))))));1382 EXPECT_TRUE(1383 matches("class X { void x(int x) {} };",1384 cxxMethodDecl(hasParameter(0, hasType(asString("int"))))));1385 EXPECT_TRUE(matches("namespace ns { struct A {}; } struct B { ns::A a; };",1386 fieldDecl(hasType(asString("ns::A")))));1387 EXPECT_TRUE(matches("namespace { struct A {}; } struct B { A a; };",1388 fieldDecl(hasType(asString("A")))));1389}1390 1391TEST_P(ASTMatchersTest, HasOverloadedOperatorName) {1392 if (!GetParam().isCXX()) {1393 return;1394 }1395 1396 StatementMatcher OpCallAndAnd =1397 cxxOperatorCallExpr(hasOverloadedOperatorName("&&"));1398 EXPECT_TRUE(matches("class Y { }; "1399 "bool operator&&(Y x, Y y) { return true; }; "1400 "Y a; Y b; bool c = a && b;",1401 OpCallAndAnd));1402 StatementMatcher OpCallLessLess =1403 cxxOperatorCallExpr(hasOverloadedOperatorName("<<"));1404 EXPECT_TRUE(notMatches("class Y { }; "1405 "bool operator&&(Y x, Y y) { return true; }; "1406 "Y a; Y b; bool c = a && b;",1407 OpCallLessLess));1408 StatementMatcher OpStarCall =1409 cxxOperatorCallExpr(hasOverloadedOperatorName("*"));1410 EXPECT_TRUE(1411 matches("class Y; int operator*(Y &); void f(Y &y) { *y; }", OpStarCall));1412 DeclarationMatcher ClassWithOpStar =1413 cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*")));1414 EXPECT_TRUE(matches("class Y { int operator*(); };", ClassWithOpStar));1415 EXPECT_TRUE(notMatches("class Y { void myOperator(); };", ClassWithOpStar));1416 DeclarationMatcher AnyOpStar = functionDecl(hasOverloadedOperatorName("*"));1417 EXPECT_TRUE(matches("class Y; int operator*(Y &);", AnyOpStar));1418 EXPECT_TRUE(matches("class Y { int operator*(); };", AnyOpStar));1419 DeclarationMatcher AnyAndOp =1420 functionDecl(hasAnyOverloadedOperatorName("&", "&&"));1421 EXPECT_TRUE(matches("class Y; Y operator&(Y &, Y &);", AnyAndOp));1422 EXPECT_TRUE(matches("class Y; Y operator&&(Y &, Y &);", AnyAndOp));1423 EXPECT_TRUE(matches("class Y { Y operator&(Y &); };", AnyAndOp));1424 EXPECT_TRUE(matches("class Y { Y operator&&(Y &); };", AnyAndOp));1425}1426 1427TEST_P(ASTMatchersTest, HasOverloadedOperatorName_MatchesNestedCalls) {1428 if (!GetParam().isCXX()) {1429 return;1430 }1431 1432 EXPECT_TRUE(matchAndVerifyResultTrue(1433 "class Y { }; "1434 "Y& operator&&(Y& x, Y& y) { return x; }; "1435 "Y a; Y b; Y c; Y d = a && b && c;",1436 cxxOperatorCallExpr(hasOverloadedOperatorName("&&")).bind("x"),1437 std::make_unique<VerifyIdIsBoundTo<CXXOperatorCallExpr>>("x", 2)));1438 EXPECT_TRUE(matches("class Y { }; "1439 "Y& operator&&(Y& x, Y& y) { return x; }; "1440 "Y a; Y b; Y c; Y d = a && b && c;",1441 cxxOperatorCallExpr(hasParent(cxxOperatorCallExpr()))));1442 EXPECT_TRUE(1443 matches("class Y { }; "1444 "Y& operator&&(Y& x, Y& y) { return x; }; "1445 "Y a; Y b; Y c; Y d = a && b && c;",1446 cxxOperatorCallExpr(hasDescendant(cxxOperatorCallExpr()))));1447}1448 1449TEST_P(ASTMatchersTest, HasLocalStorage) {1450 auto M = varDecl(hasName("X"), hasLocalStorage());1451 EXPECT_TRUE(matches("void f() { int X; }", M));1452 EXPECT_TRUE(notMatches("int X;", M));1453 EXPECT_TRUE(notMatches("void f() { static int X; }", M));1454}1455 1456TEST_P(ASTMatchersTest, HasGlobalStorage) {1457 auto M = varDecl(hasName("X"), hasGlobalStorage());1458 EXPECT_TRUE(notMatches("void f() { int X; }", M));1459 EXPECT_TRUE(matches("int X;", M));1460 EXPECT_TRUE(matches("void f() { static int X; }", M));1461}1462 1463TEST_P(ASTMatchersTest, IsStaticLocal) {1464 auto M = varDecl(isStaticLocal());1465 EXPECT_TRUE(matches("void f() { static int X; }", M));1466 EXPECT_TRUE(notMatches("static int X;", M));1467 EXPECT_TRUE(notMatches("void f() { int X; }", M));1468 EXPECT_TRUE(notMatches("int X;", M));1469}1470 1471TEST_P(ASTMatchersTest, IsInitCapture) {1472 if (!GetParam().isCXX11OrLater()) {1473 return;1474 }1475 auto M = varDecl(hasName("vd"), isInitCapture());1476 EXPECT_TRUE(notMatches(1477 "int main() { int vd = 3; auto f = [vd]() { return vd; }; }", M));1478 1479 if (!GetParam().isCXX14OrLater()) {1480 return;1481 }1482 EXPECT_TRUE(matches("int main() { auto f = [vd=3]() { return vd; }; }", M));1483 EXPECT_TRUE(matches(1484 "int main() { int x = 3; auto f = [vd=x]() { return vd; }; }", M));1485}1486 1487TEST_P(ASTMatchersTest, StorageDuration) {1488 StringRef T =1489 "void f() { int x; static int y; } int a;static int b;extern int c;";1490 1491 EXPECT_TRUE(matches(T, varDecl(hasName("x"), hasAutomaticStorageDuration())));1492 EXPECT_TRUE(1493 notMatches(T, varDecl(hasName("y"), hasAutomaticStorageDuration())));1494 EXPECT_TRUE(1495 notMatches(T, varDecl(hasName("a"), hasAutomaticStorageDuration())));1496 1497 EXPECT_TRUE(matches(T, varDecl(hasName("y"), hasStaticStorageDuration())));1498 EXPECT_TRUE(matches(T, varDecl(hasName("a"), hasStaticStorageDuration())));1499 EXPECT_TRUE(matches(T, varDecl(hasName("b"), hasStaticStorageDuration())));1500 EXPECT_TRUE(matches(T, varDecl(hasName("c"), hasStaticStorageDuration())));1501 EXPECT_TRUE(notMatches(T, varDecl(hasName("x"), hasStaticStorageDuration())));1502 1503 // FIXME: Add thread_local variables to the source code snippet.1504 EXPECT_TRUE(notMatches(T, varDecl(hasName("x"), hasThreadStorageDuration())));1505 EXPECT_TRUE(notMatches(T, varDecl(hasName("y"), hasThreadStorageDuration())));1506 EXPECT_TRUE(notMatches(T, varDecl(hasName("a"), hasThreadStorageDuration())));1507}1508 1509TEST_P(ASTMatchersTest, VarDecl_MatchesFunctionParameter) {1510 EXPECT_TRUE(matches("void f(int i) {}", varDecl(hasName("i"))));1511}1512 1513TEST_P(ASTMatchersTest, SizeOfExpr_MatchesCorrectType) {1514 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }",1515 sizeOfExpr(hasArgumentOfType(asString("int")))));1516 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }",1517 sizeOfExpr(hasArgumentOfType(asString("float")))));1518 EXPECT_TRUE(matches(1519 "struct A {}; void x() { struct A a; int b = sizeof(a); }",1520 sizeOfExpr(hasArgumentOfType(hasDeclaration(recordDecl(hasName("A")))))));1521 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }",1522 sizeOfExpr(hasArgumentOfType(1523 hasDeclaration(recordDecl(hasName("string")))))));1524}1525 1526TEST_P(ASTMatchersTest, IsInteger_MatchesIntegers) {1527 EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isInteger()))));1528 EXPECT_TRUE(1529 matches("long long i = 0; void f(long long) { }; void g() {f(i);}",1530 callExpr(hasArgument(1531 0, declRefExpr(to(varDecl(hasType(isInteger()))))))));1532}1533 1534TEST_P(ASTMatchersTest, IsInteger_ReportsNoFalsePositives) {1535 if (!GetParam().isCXX()) {1536 // FIXME: Add a similar negative test for `isInteger()` that does not depend1537 // on C++.1538 return;1539 }1540 1541 EXPECT_TRUE(notMatches("int *i;", varDecl(hasType(isInteger()))));1542 EXPECT_TRUE(1543 notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}",1544 callExpr(hasArgument(1545 0, declRefExpr(to(varDecl(hasType(isInteger()))))))));1546}1547 1548TEST_P(ASTMatchersTest, IsSignedInteger_MatchesSignedIntegers) {1549 EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isSignedInteger()))));1550 EXPECT_TRUE(1551 notMatches("unsigned i = 0;", varDecl(hasType(isSignedInteger()))));1552}1553 1554TEST_P(ASTMatchersTest, IsUnsignedInteger_MatchesUnsignedIntegers) {1555 EXPECT_TRUE(notMatches("int i = 0;", varDecl(hasType(isUnsignedInteger()))));1556 EXPECT_TRUE(1557 matches("unsigned i = 0;", varDecl(hasType(isUnsignedInteger()))));1558}1559 1560TEST_P(ASTMatchersTest, IsAnyPointer_MatchesPointers) {1561 if (!GetParam().isCXX11OrLater()) {1562 // FIXME: Add a test for `isAnyPointer()` that does not depend on C++.1563 return;1564 }1565 1566 EXPECT_TRUE(matches("int* i = nullptr;", varDecl(hasType(isAnyPointer()))));1567}1568 1569TEST_P(ASTMatchersTest, IsAnyPointer_MatchesObjcPointer) {1570 EXPECT_TRUE(matchesObjC("@interface Foo @end Foo *f;",1571 varDecl(hasType(isAnyPointer()))));1572}1573 1574TEST_P(ASTMatchersTest, IsAnyPointer_ReportsNoFalsePositives) {1575 EXPECT_TRUE(notMatches("int i = 0;", varDecl(hasType(isAnyPointer()))));1576}1577 1578TEST_P(ASTMatchersTest, IsAnyCharacter_MatchesCharacters) {1579 EXPECT_TRUE(matches("char i = 0;", varDecl(hasType(isAnyCharacter()))));1580}1581 1582TEST_P(ASTMatchersTest, IsAnyCharacter_ReportsNoFalsePositives) {1583 EXPECT_TRUE(notMatches("int i;", varDecl(hasType(isAnyCharacter()))));1584}1585 1586TEST_P(ASTMatchersTest, IsArrow_MatchesMemberVariablesViaArrow) {1587 if (!GetParam().isCXX()) {1588 // FIXME: Add a test for `isArrow()` that does not depend on C++.1589 return;1590 }1591 if (GetParam().hasDelayedTemplateParsing()) {1592 // FIXME: Fix this test to work with delayed template parsing.1593 return;1594 }1595 1596 EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };",1597 memberExpr(isArrow())));1598 EXPECT_TRUE(1599 matches("class Y { void x() { y; } int y; };", memberExpr(isArrow())));1600 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };",1601 memberExpr(isArrow())));1602 EXPECT_TRUE(1603 matches("template <class T> class Y { void x() { this->m; } int m; };",1604 memberExpr(isArrow())));1605 EXPECT_TRUE(notMatches(1606 "template <class T> class Y { void x() { (*this).m; } int m; };",1607 memberExpr(isArrow())));1608}1609 1610TEST_P(ASTMatchersTest, IsArrow_MatchesStaticMemberVariablesViaArrow) {1611 if (!GetParam().isCXX()) {1612 // FIXME: Add a test for `isArrow()` that does not depend on C++.1613 return;1614 }1615 1616 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",1617 memberExpr(isArrow())));1618 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",1619 memberExpr(isArrow())));1620 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } static int y; };",1621 memberExpr(isArrow())));1622}1623 1624TEST_P(ASTMatchersTest, IsArrow_MatchesMemberCallsViaArrow) {1625 if (!GetParam().isCXX()) {1626 // FIXME: Add a test for `isArrow()` that does not depend on C++.1627 return;1628 }1629 if (GetParam().hasDelayedTemplateParsing()) {1630 // FIXME: Fix this test to work with delayed template parsing.1631 return;1632 }1633 1634 EXPECT_TRUE(1635 matches("class Y { void x() { this->x(); } };", memberExpr(isArrow())));1636 EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpr(isArrow())));1637 EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",1638 memberExpr(isArrow())));1639 EXPECT_TRUE(1640 matches("class Y { template <class T> void x() { this->x<T>(); } };",1641 unresolvedMemberExpr(isArrow())));1642 EXPECT_TRUE(matches("class Y { template <class T> void x() { x<T>(); } };",1643 unresolvedMemberExpr(isArrow())));1644 EXPECT_TRUE(1645 notMatches("class Y { template <class T> void x() { (*this).x<T>(); } };",1646 unresolvedMemberExpr(isArrow())));1647}1648 1649TEST_P(ASTMatchersTest, IsExplicit_CXXConversionDecl) {1650 if (!GetParam().isCXX11OrLater()) {1651 return;1652 }1653 1654 EXPECT_TRUE(matches("struct S { explicit operator int(); };",1655 cxxConversionDecl(isExplicit())));1656 EXPECT_TRUE(notMatches("struct S { operator int(); };",1657 cxxConversionDecl(isExplicit())));1658}1659 1660TEST_P(ASTMatchersTest, IsExplicit_CXXConversionDecl_CXX20) {1661 if (!GetParam().isCXX20OrLater()) {1662 return;1663 }1664 1665 EXPECT_TRUE(1666 notMatches("template<bool b> struct S { explicit(b) operator int(); };",1667 cxxConversionDecl(isExplicit())));1668 EXPECT_TRUE(matches("struct S { explicit(true) operator int(); };",1669 cxxConversionDecl(isExplicit())));1670 EXPECT_TRUE(notMatches("struct S { explicit(false) operator int(); };",1671 cxxConversionDecl(isExplicit())));1672}1673 1674TEST_P(ASTMatchersTest, ArgumentCountAtLeast_CallExpr) {1675 StatementMatcher Call2PlusArgs = callExpr(argumentCountAtLeast(2));1676 1677 EXPECT_TRUE(notMatches("void x(void) { x(); }", Call2PlusArgs));1678 EXPECT_TRUE(notMatches("void x(int) { x(0); }", Call2PlusArgs));1679 EXPECT_TRUE(matches("void x(int, int) { x(0, 0); }", Call2PlusArgs));1680 EXPECT_TRUE(matches("void x(int, int, int) { x(0, 0, 0); }", Call2PlusArgs));1681 1682 if (!GetParam().isCXX()) {1683 return;1684 }1685 1686 EXPECT_TRUE(1687 notMatches("void x(int = 1) { x(); }", traverse(TK_AsIs, Call2PlusArgs)));1688 EXPECT_TRUE(matches("void x(int, int = 1) { x(0); }",1689 traverse(TK_AsIs, Call2PlusArgs)));1690 EXPECT_TRUE(matches("void x(int, int = 1, int = 1) { x(0); }",1691 traverse(TK_AsIs, Call2PlusArgs)));1692 EXPECT_TRUE(matches("void x(int, int, int = 1) { x(0, 0); }",1693 traverse(TK_AsIs, Call2PlusArgs)));1694 EXPECT_TRUE(matches("void x(int, int, int, int = 1) { x(0, 0, 0); }",1695 traverse(TK_AsIs, Call2PlusArgs)));1696 1697 EXPECT_TRUE(1698 notMatches("void x(int = 1) { x(); }",1699 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));1700 EXPECT_TRUE(1701 notMatches("void x(int, int = 1) { x(0); }",1702 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));1703 EXPECT_TRUE(1704 notMatches("void x(int, int = 1, int = 1) { x(0); }",1705 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));1706 EXPECT_TRUE(matches("void x(int, int, int = 1) { x(0, 0); }",1707 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));1708 EXPECT_TRUE(matches("void x(int, int, int, int = 1) { x(0, 0, 0); }",1709 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));1710}1711 1712TEST_P(ASTMatchersTest, ArgumentCountAtLeast_CallExpr_CXX) {1713 if (!GetParam().isCXX()) {1714 return;1715 }1716 1717 StatementMatcher Call2PlusArgs = callExpr(argumentCountAtLeast(2));1718 EXPECT_TRUE(notMatches("class X { void x() { x(); } };", Call2PlusArgs));1719 EXPECT_TRUE(notMatches("class X { void x(int) { x(0); } };", Call2PlusArgs));1720 EXPECT_TRUE(1721 matches("class X { void x(int, int) { x(0, 0); } };", Call2PlusArgs));1722 EXPECT_TRUE(matches("class X { void x(int, int, int) { x(0, 0, 0); } };",1723 Call2PlusArgs));1724 1725 EXPECT_TRUE(notMatches("class X { void x(int = 1) { x(0); } };",1726 traverse(TK_AsIs, Call2PlusArgs)));1727 EXPECT_TRUE(matches("class X { void x(int, int = 1) { x(0); } };",1728 traverse(TK_AsIs, Call2PlusArgs)));1729 EXPECT_TRUE(matches("class X { void x(int, int = 1, int = 1) { x(0); } };",1730 traverse(TK_AsIs, Call2PlusArgs)));1731 EXPECT_TRUE(matches("class X { void x(int, int, int = 1) { x(0, 0); } };",1732 traverse(TK_AsIs, Call2PlusArgs)));1733 EXPECT_TRUE(1734 matches("class X { void x(int, int, int, int = 1) { x(0, 0, 0); } };",1735 traverse(TK_AsIs, Call2PlusArgs)));1736 1737 EXPECT_TRUE(1738 notMatches("class X { void x(int = 1) { x(0); } };",1739 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));1740 EXPECT_TRUE(1741 notMatches("class X { void x(int, int = 1) { x(0); } };",1742 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));1743 EXPECT_TRUE(1744 notMatches("class X { void x(int, int = 1, int = 1) { x(0); } };",1745 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));1746 EXPECT_TRUE(matches("class X { void x(int, int, int = 1) { x(0, 0); } };",1747 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));1748 EXPECT_TRUE(1749 matches("class X { void x(int, int, int, int = 1) { x(0, 0, 0); } };",1750 traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs)));1751 1752 EXPECT_TRUE(1753 notMatches("class X { static void x() { x(); } };", Call2PlusArgs));1754 EXPECT_TRUE(1755 notMatches("class X { static void x(int) { x(0); } };", Call2PlusArgs));1756 EXPECT_TRUE(matches("class X { static void x(int, int) { x(0, 0); } };",1757 Call2PlusArgs));1758 EXPECT_TRUE(1759 matches("class X { static void x(int, int, int) { x(0, 0, 0); } };",1760 Call2PlusArgs));1761}1762 1763TEST_P(ASTMatchersTest, ArgumentCountIs_CallExpr) {1764 StatementMatcher Call1Arg = callExpr(argumentCountIs(1));1765 1766 EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg));1767 EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg));1768}1769 1770TEST_P(ASTMatchersTest, ArgumentCountIs_CallExpr_CXX) {1771 if (!GetParam().isCXX()) {1772 return;1773 }1774 1775 StatementMatcher Call1Arg = callExpr(argumentCountIs(1));1776 EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg));1777}1778 1779TEST_P(ASTMatchersTest, ParameterCountIs) {1780 DeclarationMatcher Function1Arg = functionDecl(parameterCountIs(1));1781 EXPECT_TRUE(matches("void f(int i) {}", Function1Arg));1782 EXPECT_TRUE(notMatches("void f() {}", Function1Arg));1783 EXPECT_TRUE(notMatches("void f(int i, int j, int k) {}", Function1Arg));1784 EXPECT_TRUE(matches("void f(int i, ...) {};", Function1Arg));1785}1786 1787TEST_P(ASTMatchersTest, ParameterCountIs_CXX) {1788 if (!GetParam().isCXX()) {1789 return;1790 }1791 1792 DeclarationMatcher Function1Arg = functionDecl(parameterCountIs(1));1793 EXPECT_TRUE(matches("class X { void f(int i) {} };", Function1Arg));1794}1795 1796TEST_P(ASTMatchersTest, References) {1797 if (!GetParam().isCXX()) {1798 // FIXME: Add a test for `references()` that does not depend on C++.1799 return;1800 }1801 1802 DeclarationMatcher ReferenceClassX =1803 varDecl(hasType(references(recordDecl(hasName("X")))));1804 EXPECT_TRUE(1805 matches("class X {}; void y(X y) { X &x = y; }", ReferenceClassX));1806 EXPECT_TRUE(1807 matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));1808 // The match here is on the implicit copy constructor code for1809 // class X, not on code 'X x = y'.1810 EXPECT_TRUE(matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));1811 EXPECT_TRUE(notMatches("class X {}; extern X x;", ReferenceClassX));1812 EXPECT_TRUE(1813 notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));1814}1815 1816TEST_P(ASTMatchersTest, HasLocalQualifiers) {1817 if (!GetParam().isCXX11OrLater()) {1818 // FIXME: Add a test for `hasLocalQualifiers()` that does not depend on C++.1819 return;1820 }1821 1822 EXPECT_TRUE(notMatches("typedef const int const_int; const_int i = 1;",1823 varDecl(hasType(hasLocalQualifiers()))));1824 EXPECT_TRUE(matches("int *const j = nullptr;",1825 varDecl(hasType(hasLocalQualifiers()))));1826 EXPECT_TRUE(1827 matches("int *volatile k;", varDecl(hasType(hasLocalQualifiers()))));1828 EXPECT_TRUE(notMatches("int m;", varDecl(hasType(hasLocalQualifiers()))));1829}1830 1831TEST_P(ASTMatchersTest, IsExternC_MatchesExternCFunctionDeclarations) {1832 if (!GetParam().isCXX()) {1833 return;1834 }1835 1836 EXPECT_TRUE(matches("extern \"C\" void f() {}", functionDecl(isExternC())));1837 EXPECT_TRUE(1838 matches("extern \"C\" { void f() {} }", functionDecl(isExternC())));1839 EXPECT_TRUE(notMatches("void f() {}", functionDecl(isExternC())));1840}1841 1842TEST_P(ASTMatchersTest, IsExternC_MatchesExternCVariableDeclarations) {1843 if (!GetParam().isCXX()) {1844 return;1845 }1846 1847 EXPECT_TRUE(matches("extern \"C\" int i;", varDecl(isExternC())));1848 EXPECT_TRUE(matches("extern \"C\" { int i; }", varDecl(isExternC())));1849 EXPECT_TRUE(notMatches("int i;", varDecl(isExternC())));1850}1851 1852TEST_P(ASTMatchersTest, IsStaticStorageClass) {1853 EXPECT_TRUE(1854 matches("static void f() {}", functionDecl(isStaticStorageClass())));1855 EXPECT_TRUE(matches("static int i = 1;", varDecl(isStaticStorageClass())));1856 EXPECT_TRUE(notMatches("int i = 1;", varDecl(isStaticStorageClass())));1857 EXPECT_TRUE(notMatches("extern int i;", varDecl(isStaticStorageClass())));1858 EXPECT_TRUE(notMatches("void f() {}", functionDecl(isStaticStorageClass())));1859}1860 1861TEST_P(ASTMatchersTest, IsDefaulted) {1862 if (!GetParam().isCXX()) {1863 return;1864 }1865 1866 EXPECT_TRUE(notMatches("class A { ~A(); };",1867 functionDecl(hasName("~A"), isDefaulted())));1868 EXPECT_TRUE(matches("class B { ~B() = default; };",1869 functionDecl(hasName("~B"), isDefaulted())));1870}1871 1872TEST_P(ASTMatchersTest, IsDeleted) {1873 if (!GetParam().isCXX()) {1874 return;1875 }1876 1877 EXPECT_TRUE(1878 notMatches("void Func();", functionDecl(hasName("Func"), isDeleted())));1879 EXPECT_TRUE(matches("void Func() = delete;",1880 functionDecl(hasName("Func"), isDeleted())));1881}1882 1883TEST_P(ASTMatchersTest, IsNoThrow_DynamicExceptionSpec) {1884 if (!GetParam().supportsCXXDynamicExceptionSpecification()) {1885 return;1886 }1887 1888 EXPECT_TRUE(notMatches("void f();", functionDecl(isNoThrow())));1889 EXPECT_TRUE(notMatches("void f() throw(int);", functionDecl(isNoThrow())));1890 EXPECT_TRUE(matches("void f() throw();", functionDecl(isNoThrow())));1891 1892 EXPECT_TRUE(notMatches("void f();", functionProtoType(isNoThrow())));1893 EXPECT_TRUE(1894 notMatches("void f() throw(int);", functionProtoType(isNoThrow())));1895 EXPECT_TRUE(matches("void f() throw();", functionProtoType(isNoThrow())));1896}1897 1898TEST_P(ASTMatchersTest, IsNoThrow_CXX11) {1899 if (!GetParam().isCXX11OrLater()) {1900 return;1901 }1902 1903 EXPECT_TRUE(1904 notMatches("void f() noexcept(false);", functionDecl(isNoThrow())));1905 EXPECT_TRUE(matches("void f() noexcept;", functionDecl(isNoThrow())));1906 1907 EXPECT_TRUE(1908 notMatches("void f() noexcept(false);", functionProtoType(isNoThrow())));1909 EXPECT_TRUE(matches("void f() noexcept;", functionProtoType(isNoThrow())));1910}1911 1912TEST_P(ASTMatchersTest, IsConsteval) {1913 if (!GetParam().isCXX20OrLater())1914 return;1915 1916 EXPECT_TRUE(matches("consteval int bar();",1917 functionDecl(hasName("bar"), isConsteval())));1918 EXPECT_TRUE(notMatches("constexpr int bar();",1919 functionDecl(hasName("bar"), isConsteval())));1920 EXPECT_TRUE(1921 notMatches("int bar();", functionDecl(hasName("bar"), isConsteval())));1922}1923 1924TEST_P(ASTMatchersTest, IsConsteval_MatchesIfConsteval) {1925 if (!GetParam().isCXX20OrLater())1926 return;1927 1928 EXPECT_TRUE(matches("void baz() { if consteval {} }", ifStmt(isConsteval())));1929 EXPECT_TRUE(1930 matches("void baz() { if ! consteval {} }", ifStmt(isConsteval())));1931 EXPECT_TRUE(matches("void baz() { if ! consteval {} else {} }",1932 ifStmt(isConsteval())));1933 EXPECT_TRUE(1934 matches("void baz() { if not consteval {} }", ifStmt(isConsteval())));1935 EXPECT_TRUE(notMatches("void baz() { if constexpr(1 > 0) {} }",1936 ifStmt(isConsteval())));1937 EXPECT_TRUE(1938 notMatches("void baz() { if (1 > 0) {} }", ifStmt(isConsteval())));1939}1940 1941TEST_P(ASTMatchersTest, IsConstexpr) {1942 if (!GetParam().isCXX11OrLater()) {1943 return;1944 }1945 1946 EXPECT_TRUE(matches("constexpr int foo = 42;",1947 varDecl(hasName("foo"), isConstexpr())));1948 EXPECT_TRUE(matches("constexpr int bar();",1949 functionDecl(hasName("bar"), isConstexpr())));1950}1951 1952TEST_P(ASTMatchersTest, IsConstexpr_MatchesIfConstexpr) {1953 if (!GetParam().isCXX17OrLater()) {1954 return;1955 }1956 1957 EXPECT_TRUE(1958 matches("void baz() { if constexpr(1 > 0) {} }", ifStmt(isConstexpr())));1959 EXPECT_TRUE(1960 notMatches("void baz() { if (1 > 0) {} }", ifStmt(isConstexpr())));1961}1962 1963TEST_P(ASTMatchersTest, IsConstinit) {1964 if (!GetParam().isCXX20OrLater())1965 return;1966 1967 EXPECT_TRUE(matches("constinit int foo = 1;",1968 varDecl(hasName("foo"), isConstinit())));1969 EXPECT_TRUE(matches("extern constinit int foo;",1970 varDecl(hasName("foo"), isConstinit())));1971 EXPECT_TRUE(matches("constinit const char* foo = \"bar\";",1972 varDecl(hasName("foo"), isConstinit())));1973 EXPECT_TRUE(1974 notMatches("[[clang::require_constant_initialization]] int foo = 1;",1975 varDecl(hasName("foo"), isConstinit())));1976 EXPECT_TRUE(notMatches("constexpr int foo = 1;",1977 varDecl(hasName("foo"), isConstinit())));1978 EXPECT_TRUE(notMatches("static inline int foo = 1;",1979 varDecl(hasName("foo"), isConstinit())));1980}1981 1982TEST_P(ASTMatchersTest, HasInitStatement_MatchesSelectionInitializers) {1983 EXPECT_TRUE(notMatches("void baz() { if (1 > 0) {} }",1984 ifStmt(hasInitStatement(anything()))));1985 EXPECT_TRUE(notMatches("void baz(int i) { switch (i) { default: break; } }",1986 switchStmt(hasInitStatement(anything()))));1987}1988 1989TEST_P(ASTMatchersTest, HasInitStatement_MatchesSelectionInitializers_CXX) {1990 if (!GetParam().isCXX()) {1991 return;1992 }1993 1994 EXPECT_TRUE(notMatches("void baz() { if (int i = 1) {} }",1995 ifStmt(hasInitStatement(anything()))));1996}1997 1998TEST_P(ASTMatchersTest, HasInitStatement_MatchesSelectionInitializers_CXX17) {1999 if (!GetParam().isCXX17OrLater()) {2000 return;2001 }2002 2003 EXPECT_TRUE(matches("void baz() { if (int i = 1; i > 0) {} }",2004 ifStmt(hasInitStatement(anything()))));2005 EXPECT_TRUE(2006 matches("void baz(int i) { switch (int j = i; j) { default: break; } }",2007 switchStmt(hasInitStatement(anything()))));2008}2009 2010TEST_P(ASTMatchersTest, HasInitStatement_MatchesRangeForInitializers) {2011 if (!GetParam().isCXX20OrLater()) {2012 return;2013 }2014 2015 EXPECT_TRUE(matches("void baz() {"2016 "int items[] = {};"2017 "for (auto &arr = items; auto &item : arr) {}"2018 "}",2019 cxxForRangeStmt(hasInitStatement(anything()))));2020 EXPECT_TRUE(notMatches("void baz() {"2021 "int items[] = {};"2022 "for (auto &item : items) {}"2023 "}",2024 cxxForRangeStmt(hasInitStatement(anything()))));2025}2026 2027TEST_P(ASTMatchersTest, TemplateArgumentCountIs) {2028 if (!GetParam().isCXX()) {2029 return;2030 }2031 2032 EXPECT_TRUE(2033 matches("template<typename T> struct C {}; C<int> c;",2034 classTemplateSpecializationDecl(templateArgumentCountIs(1))));2035 EXPECT_TRUE(2036 notMatches("template<typename T> struct C {}; C<int> c;",2037 classTemplateSpecializationDecl(templateArgumentCountIs(2))));2038 2039 EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",2040 templateSpecializationType(templateArgumentCountIs(1))));2041 EXPECT_TRUE(2042 notMatches("template<typename T> struct C {}; C<int> c;",2043 templateSpecializationType(templateArgumentCountIs(2))));2044 2045 const char *FuncTemplateCode =2046 "template<typename T> T f(); auto v = f<int>();";2047 EXPECT_TRUE(2048 matches(FuncTemplateCode, functionDecl(templateArgumentCountIs(1))));2049 EXPECT_TRUE(2050 notMatches(FuncTemplateCode, functionDecl(templateArgumentCountIs(2))));2051}2052 2053TEST_P(ASTMatchersTest, IsIntegral) {2054 if (!GetParam().isCXX()) {2055 return;2056 }2057 2058 EXPECT_TRUE(matches(2059 "template<int T> struct C {}; C<42> c;",2060 classTemplateSpecializationDecl(hasAnyTemplateArgument(isIntegral()))));2061 EXPECT_TRUE(notMatches("template<typename T> struct C {}; C<int> c;",2062 classTemplateSpecializationDecl(hasAnyTemplateArgument(2063 templateArgument(isIntegral())))));2064}2065 2066TEST_P(ASTMatchersTest, EqualsIntegralValue) {2067 if (!GetParam().isCXX()) {2068 return;2069 }2070 2071 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",2072 classTemplateSpecializationDecl(2073 hasAnyTemplateArgument(equalsIntegralValue("42")))));2074 EXPECT_TRUE(matches("template<int T> struct C {}; C<-42> c;",2075 classTemplateSpecializationDecl(2076 hasAnyTemplateArgument(equalsIntegralValue("-42")))));2077 EXPECT_TRUE(matches("template<int T> struct C {}; C<-0042> c;",2078 classTemplateSpecializationDecl(2079 hasAnyTemplateArgument(equalsIntegralValue("-34")))));2080 EXPECT_TRUE(notMatches("template<int T> struct C {}; C<42> c;",2081 classTemplateSpecializationDecl(hasAnyTemplateArgument(2082 equalsIntegralValue("0042")))));2083}2084 2085TEST_P(ASTMatchersTest, AccessSpecDecl) {2086 if (!GetParam().isCXX()) {2087 return;2088 }2089 2090 EXPECT_TRUE(matches("class C { public: int i; };", accessSpecDecl()));2091 EXPECT_TRUE(2092 matches("class C { public: int i; };", accessSpecDecl(isPublic())));2093 EXPECT_TRUE(2094 notMatches("class C { public: int i; };", accessSpecDecl(isProtected())));2095 EXPECT_TRUE(2096 notMatches("class C { public: int i; };", accessSpecDecl(isPrivate())));2097 2098 EXPECT_TRUE(notMatches("class C { int i; };", accessSpecDecl()));2099}2100 2101TEST_P(ASTMatchersTest, IsFinal) {2102 if (!GetParam().isCXX11OrLater()) {2103 return;2104 }2105 2106 EXPECT_TRUE(matches("class X final {};", cxxRecordDecl(isFinal())));2107 EXPECT_TRUE(matches("class X { virtual void f() final; };",2108 cxxMethodDecl(isFinal())));2109 EXPECT_TRUE(notMatches("class X {};", cxxRecordDecl(isFinal())));2110 EXPECT_TRUE(2111 notMatches("class X { virtual void f(); };", cxxMethodDecl(isFinal())));2112}2113 2114TEST_P(ASTMatchersTest, IsVirtual) {2115 if (!GetParam().isCXX()) {2116 return;2117 }2118 2119 EXPECT_TRUE(matches("class X { virtual int f(); };",2120 cxxMethodDecl(isVirtual(), hasName("::X::f"))));2121 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isVirtual())));2122}2123 2124TEST_P(ASTMatchersTest, IsVirtualAsWritten) {2125 if (!GetParam().isCXX()) {2126 return;2127 }2128 2129 EXPECT_TRUE(matches("class A { virtual int f(); };"2130 "class B : public A { int f(); };",2131 cxxMethodDecl(isVirtualAsWritten(), hasName("::A::f"))));2132 EXPECT_TRUE(2133 notMatches("class A { virtual int f(); };"2134 "class B : public A { int f(); };",2135 cxxMethodDecl(isVirtualAsWritten(), hasName("::B::f"))));2136}2137 2138TEST_P(ASTMatchersTest, IsPure) {2139 if (!GetParam().isCXX()) {2140 return;2141 }2142 2143 EXPECT_TRUE(matches("class X { virtual int f() = 0; };",2144 cxxMethodDecl(isPure(), hasName("::X::f"))));2145 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isPure())));2146}2147 2148TEST_P(ASTMatchersTest, IsExplicitObjectMemberFunction) {2149 if (!GetParam().isCXX23OrLater()) {2150 return;2151 }2152 2153 auto ExpObjParamFn = cxxMethodDecl(isExplicitObjectMemberFunction());2154 EXPECT_TRUE(2155 notMatches("struct A { static int operator()(int); };", ExpObjParamFn));2156 EXPECT_TRUE(notMatches("struct A { int operator+(int); };", ExpObjParamFn));2157 EXPECT_TRUE(2158 matches("struct A { int operator-(this A, int); };", ExpObjParamFn));2159 EXPECT_TRUE(matches("struct A { void fun(this A &&self); };", ExpObjParamFn));2160}2161 2162TEST_P(ASTMatchersTest, IsCopyAssignmentOperator) {2163 if (!GetParam().isCXX()) {2164 return;2165 }2166 2167 auto CopyAssignment =2168 cxxMethodDecl(isCopyAssignmentOperator(), unless(isImplicit()));2169 EXPECT_TRUE(matches("class X { X &operator=(X); };", CopyAssignment));2170 EXPECT_TRUE(matches("class X { X &operator=(X &); };", CopyAssignment));2171 EXPECT_TRUE(matches("class X { X &operator=(const X &); };", CopyAssignment));2172 EXPECT_TRUE(matches("class X { X &operator=(volatile X &); };", //2173 CopyAssignment));2174 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &); };",2175 CopyAssignment));2176 EXPECT_TRUE(notMatches("class X { X &operator=(X &&); };", CopyAssignment));2177}2178 2179TEST_P(ASTMatchersTest, IsMoveAssignmentOperator) {2180 if (!GetParam().isCXX()) {2181 return;2182 }2183 2184 auto MoveAssignment =2185 cxxMethodDecl(isMoveAssignmentOperator(), unless(isImplicit()));2186 EXPECT_TRUE(notMatches("class X { X &operator=(X); };", MoveAssignment));2187 EXPECT_TRUE(matches("class X { X &operator=(X &&); };", MoveAssignment));2188 EXPECT_TRUE(matches("class X { X &operator=(const X &&); };", //2189 MoveAssignment));2190 EXPECT_TRUE(matches("class X { X &operator=(volatile X &&); };", //2191 MoveAssignment));2192 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &&); };",2193 MoveAssignment));2194 EXPECT_TRUE(notMatches("class X { X &operator=(X &); };", MoveAssignment));2195}2196 2197TEST_P(ASTMatchersTest, IsConst) {2198 if (!GetParam().isCXX()) {2199 return;2200 }2201 2202 EXPECT_TRUE(2203 matches("struct A { void foo() const; };", cxxMethodDecl(isConst())));2204 EXPECT_TRUE(2205 notMatches("struct A { void foo(); };", cxxMethodDecl(isConst())));2206}2207 2208TEST_P(ASTMatchersTest, IsOverride) {2209 if (!GetParam().isCXX()) {2210 return;2211 }2212 2213 EXPECT_TRUE(matches("class X { virtual int f(); }; "2214 "class Y : public X { int f(); };",2215 cxxMethodDecl(isOverride(), hasName("::Y::f"))));2216 EXPECT_TRUE(notMatches("class X { virtual int f(); }; "2217 "class Y : public X { int f(); };",2218 cxxMethodDecl(isOverride(), hasName("::X::f"))));2219 EXPECT_TRUE(notMatches("class X { int f(); }; "2220 "class Y : public X { int f(); };",2221 cxxMethodDecl(isOverride())));2222 EXPECT_TRUE(notMatches("class X { int f(); int f(int); }; ",2223 cxxMethodDecl(isOverride())));2224 EXPECT_TRUE(2225 matches("template <typename Base> struct Y : Base { void f() override;};",2226 cxxMethodDecl(isOverride(), hasName("::Y::f"))));2227}2228 2229TEST_P(ASTMatchersTest, HasArgument_CXXConstructorDecl) {2230 if (!GetParam().isCXX()) {2231 return;2232 }2233 2234 auto Constructor = traverse(2235 TK_AsIs,2236 cxxConstructExpr(hasArgument(0, declRefExpr(to(varDecl(hasName("y")))))));2237 2238 EXPECT_TRUE(matches(2239 "class X { public: X(int); }; void x() { int y; X x(y); }", Constructor));2240 EXPECT_TRUE(2241 matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",2242 Constructor));2243 EXPECT_TRUE(2244 matches("class X { public: X(int); }; void x() { int y; X x = y; }",2245 Constructor));2246 EXPECT_TRUE(notMatches(2247 "class X { public: X(int); }; void x() { int z; X x(z); }", Constructor));2248 2249 StatementMatcher WrongIndex =2250 traverse(TK_AsIs, cxxConstructExpr(hasArgument(2251 42, declRefExpr(to(varDecl(hasName("y")))))));2252 EXPECT_TRUE(notMatches(2253 "class X { public: X(int); }; void x() { int y; X x(y); }", WrongIndex));2254}2255 2256TEST_P(ASTMatchersTest, ArgumentCountIs_CXXConstructExpr) {2257 if (!GetParam().isCXX()) {2258 return;2259 }2260 2261 auto Constructor1Arg =2262 traverse(TK_AsIs, cxxConstructExpr(argumentCountIs(1)));2263 2264 EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x(0); }",2265 Constructor1Arg));2266 EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x = X(0); }",2267 Constructor1Arg));2268 EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x = 0; }",2269 Constructor1Arg));2270 EXPECT_TRUE(2271 notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",2272 Constructor1Arg));2273}2274 2275TEST_P(ASTMatchersTest, HasDependentName_DependentScopeDeclRefExpr) {2276 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {2277 // FIXME: Fix this test to work with delayed template parsing.2278 return;2279 }2280 2281 EXPECT_TRUE(matches("template <class T> class X : T { void f() { T::v; } };",2282 dependentScopeDeclRefExpr(hasDependentName("v"))));2283 2284 EXPECT_TRUE(matches("template <typename T> struct S { static T Foo; };"2285 "template <typename T> void x() { (void)S<T>::Foo; }",2286 dependentScopeDeclRefExpr(hasDependentName("Foo"))));2287 2288 EXPECT_TRUE(matches("template <typename T> struct S { static T foo(); };"2289 "template <typename T> void x() { S<T>::foo(); }",2290 dependentScopeDeclRefExpr(hasDependentName("foo"))));2291}2292 2293TEST_P(ASTMatchersTest, HasDependentName_DependentNameType) {2294 if (!GetParam().isCXX()) {2295 // FIXME: Fix this test to work with delayed template parsing.2296 return;2297 }2298 2299 EXPECT_TRUE(matches(2300 R"(2301 template <typename T> struct declToImport {2302 typedef typename T::type dependent_name;2303 };2304 )",2305 dependentNameType(hasDependentName("type"))));2306}2307 2308TEST(ASTMatchersTest, NamesMember_CXXDependentScopeMemberExpr) {2309 2310 // Member functions:2311 {2312 auto Code = "template <typename T> struct S{ void mem(); }; template "2313 "<typename T> void x() { S<T> s; s.mem(); }";2314 2315 EXPECT_TRUE(matches(2316 Code,2317 cxxDependentScopeMemberExpr(2318 hasObjectExpression(declRefExpr(hasType(templateSpecializationType(2319 hasDeclaration(classTemplateDecl(has(cxxRecordDecl(2320 has(cxxMethodDecl(hasName("mem")).bind("templMem")))))))))),2321 memberHasSameNameAsBoundNode("templMem"))));2322 2323 EXPECT_TRUE(2324 matches(Code, cxxDependentScopeMemberExpr(hasMemberName("mem"))));2325 }2326 2327 // Member variables:2328 {2329 auto Code = "template <typename T> struct S{ int mem; }; template "2330 "<typename T> void x() { S<T> s; s.mem; }";2331 2332 EXPECT_TRUE(2333 matches(Code, cxxDependentScopeMemberExpr(hasMemberName("mem"))));2334 2335 EXPECT_TRUE(matches(2336 Code,2337 cxxDependentScopeMemberExpr(2338 hasObjectExpression(declRefExpr(hasType(templateSpecializationType(2339 hasDeclaration(classTemplateDecl(has(cxxRecordDecl(2340 has(fieldDecl(hasName("mem")).bind("templMem")))))))))),2341 memberHasSameNameAsBoundNode("templMem"))));2342 }2343 2344 // static member variables:2345 {2346 auto Code = "template <typename T> struct S{ static int mem; }; template "2347 "<typename T> void x() { S<T> s; s.mem; }";2348 2349 EXPECT_TRUE(2350 matches(Code, cxxDependentScopeMemberExpr(hasMemberName("mem"))));2351 2352 EXPECT_TRUE(matches(2353 Code,2354 cxxDependentScopeMemberExpr(2355 hasObjectExpression(declRefExpr(hasType(templateSpecializationType(2356 hasDeclaration(classTemplateDecl(has(cxxRecordDecl(2357 has(varDecl(hasName("mem")).bind("templMem")))))))))),2358 memberHasSameNameAsBoundNode("templMem"))));2359 }2360 {2361 auto Code = R"cpp(2362template <typename T>2363struct S {2364 bool operator==(int) const { return true; }2365};2366 2367template <typename T>2368void func(T t) {2369 S<T> s;2370 s.operator==(1);2371}2372)cpp";2373 2374 EXPECT_TRUE(matches(2375 Code, cxxDependentScopeMemberExpr(hasMemberName("operator=="))));2376 }2377 2378 // other named decl:2379 {2380 auto Code = "template <typename T> struct S{ static int mem; }; struct "2381 "mem{}; template "2382 "<typename T> void x() { S<T> s; s.mem; }";2383 2384 EXPECT_TRUE(matches(2385 Code,2386 translationUnitDecl(has(cxxRecordDecl(hasName("mem"))),2387 hasDescendant(cxxDependentScopeMemberExpr()))));2388 2389 EXPECT_FALSE(matches(2390 Code,2391 translationUnitDecl(has(cxxRecordDecl(hasName("mem")).bind("templMem")),2392 hasDescendant(cxxDependentScopeMemberExpr(2393 memberHasSameNameAsBoundNode("templMem"))))));2394 }2395}2396 2397TEST(ASTMatchersTest, ArgumentCountIs_CXXUnresolvedConstructExpr) {2398 const auto *Code =2399 "template <typename T> struct S{}; template <typename T> void "2400 "x() { auto s = S<T>(); }";2401 2402 EXPECT_TRUE(matches(Code, cxxUnresolvedConstructExpr(argumentCountIs(0))));2403 EXPECT_TRUE(notMatches(Code, cxxUnresolvedConstructExpr(argumentCountIs(1))));2404}2405 2406TEST(ASTMatchersTest, HasArgument_CXXUnresolvedConstructExpr) {2407 const auto *Code =2408 "template <typename T> struct S{ S(int){} }; template <typename "2409 "T> void x() { int y; auto s = S<T>(y); }";2410 EXPECT_TRUE(matches(Code, cxxUnresolvedConstructExpr(hasArgument(2411 0, declRefExpr(to(varDecl(hasName("y"))))))));2412 EXPECT_TRUE(2413 notMatches(Code, cxxUnresolvedConstructExpr(hasArgument(2414 0, declRefExpr(to(varDecl(hasName("x"))))))));2415}2416 2417TEST_P(ASTMatchersTest, IsListInitialization) {2418 if (!GetParam().isCXX11OrLater()) {2419 return;2420 }2421 2422 auto ConstructorListInit =2423 traverse(TK_AsIs, varDecl(has(cxxConstructExpr(isListInitialization()))));2424 2425 EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x{0}; }",2426 ConstructorListInit));2427 EXPECT_FALSE(matches("class X { public: X(int); }; void x() { X x(0); }",2428 ConstructorListInit));2429}2430 2431TEST_P(ASTMatchersTest, IsImplicit_CXXConstructorDecl) {2432 if (!GetParam().isCXX()) {2433 return;2434 }2435 2436 // This one doesn't match because the constructor is not added by the2437 // compiler (it is not needed).2438 EXPECT_TRUE(notMatches("class Foo { };", cxxConstructorDecl(isImplicit())));2439 // The compiler added the implicit default constructor.2440 EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",2441 cxxConstructorDecl(isImplicit())));2442 EXPECT_TRUE(matches("class Foo { Foo(){} };",2443 cxxConstructorDecl(unless(isImplicit()))));2444 // The compiler added an implicit assignment operator.2445 EXPECT_TRUE(matches("struct A { int x; } a = {0}, b = a; void f() { a = b; }",2446 cxxMethodDecl(isImplicit(), hasName("operator="))));2447}2448 2449TEST_P(ASTMatchersTest, IsExplicit_CXXConstructorDecl) {2450 if (!GetParam().isCXX()) {2451 return;2452 }2453 2454 EXPECT_TRUE(matches("struct S { explicit S(int); };",2455 cxxConstructorDecl(isExplicit())));2456 EXPECT_TRUE(2457 notMatches("struct S { S(int); };", cxxConstructorDecl(isExplicit())));2458}2459 2460TEST_P(ASTMatchersTest, IsExplicit_CXXConstructorDecl_CXX20) {2461 if (!GetParam().isCXX20OrLater()) {2462 return;2463 }2464 2465 EXPECT_TRUE(notMatches("template<bool b> struct S { explicit(b) S(int);};",2466 cxxConstructorDecl(isExplicit())));2467 EXPECT_TRUE(matches("struct S { explicit(true) S(int);};",2468 cxxConstructorDecl(isExplicit())));2469 EXPECT_TRUE(notMatches("struct S { explicit(false) S(int);};",2470 cxxConstructorDecl(isExplicit())));2471}2472 2473TEST_P(ASTMatchersTest, IsExplicit_CXXDeductionGuideDecl) {2474 if (!GetParam().isCXX17OrLater()) {2475 return;2476 }2477 2478 EXPECT_TRUE(notMatches("template<typename T> struct S { S(int);};"2479 "S(int) -> S<int>;",2480 cxxDeductionGuideDecl(isExplicit())));2481 EXPECT_TRUE(matches("template<typename T> struct S { S(int);};"2482 "explicit S(int) -> S<int>;",2483 cxxDeductionGuideDecl(isExplicit())));2484}2485 2486TEST_P(ASTMatchersTest, IsExplicit_CXXDeductionGuideDecl_CXX20) {2487 if (!GetParam().isCXX20OrLater()) {2488 return;2489 }2490 2491 EXPECT_TRUE(matches("template<typename T> struct S { S(int);};"2492 "explicit(true) S(int) -> S<int>;",2493 cxxDeductionGuideDecl(isExplicit())));2494 EXPECT_TRUE(notMatches("template<typename T> struct S { S(int);};"2495 "explicit(false) S(int) -> S<int>;",2496 cxxDeductionGuideDecl(isExplicit())));2497 EXPECT_TRUE(2498 notMatches("template<typename T> struct S { S(int);};"2499 "template<bool b = true> explicit(b) S(int) -> S<int>;",2500 cxxDeductionGuideDecl(isExplicit())));2501}2502 2503TEST_P(ASTMatchersTest, CXXConstructorDecl_Kinds) {2504 if (!GetParam().isCXX()) {2505 return;2506 }2507 2508 EXPECT_TRUE(2509 matches("struct S { S(); };", cxxConstructorDecl(isDefaultConstructor(),2510 unless(isImplicit()))));2511 EXPECT_TRUE(notMatches(2512 "struct S { S(); };",2513 cxxConstructorDecl(isCopyConstructor(), unless(isImplicit()))));2514 EXPECT_TRUE(notMatches(2515 "struct S { S(); };",2516 cxxConstructorDecl(isMoveConstructor(), unless(isImplicit()))));2517 2518 EXPECT_TRUE(notMatches(2519 "struct S { S(const S&); };",2520 cxxConstructorDecl(isDefaultConstructor(), unless(isImplicit()))));2521 EXPECT_TRUE(2522 matches("struct S { S(const S&); };",2523 cxxConstructorDecl(isCopyConstructor(), unless(isImplicit()))));2524 EXPECT_TRUE(notMatches(2525 "struct S { S(const S&); };",2526 cxxConstructorDecl(isMoveConstructor(), unless(isImplicit()))));2527 2528 EXPECT_TRUE(notMatches(2529 "struct S { S(S&&); };",2530 cxxConstructorDecl(isDefaultConstructor(), unless(isImplicit()))));2531 EXPECT_TRUE(notMatches(2532 "struct S { S(S&&); };",2533 cxxConstructorDecl(isCopyConstructor(), unless(isImplicit()))));2534 EXPECT_TRUE(2535 matches("struct S { S(S&&); };",2536 cxxConstructorDecl(isMoveConstructor(), unless(isImplicit()))));2537}2538 2539TEST_P(ASTMatchersTest, IsUserProvided) {2540 if (!GetParam().isCXX11OrLater()) {2541 return;2542 }2543 2544 EXPECT_TRUE(notMatches("struct S { int X = 0; };",2545 cxxConstructorDecl(isUserProvided())));2546 EXPECT_TRUE(notMatches("struct S { S() = default; };",2547 cxxConstructorDecl(isUserProvided())));2548 EXPECT_TRUE(notMatches("struct S { S() = delete; };",2549 cxxConstructorDecl(isUserProvided())));2550 EXPECT_TRUE(2551 matches("struct S { S(); };", cxxConstructorDecl(isUserProvided())));2552 EXPECT_TRUE(matches("struct S { S(); }; S::S(){}",2553 cxxConstructorDecl(isUserProvided())));2554}2555 2556TEST_P(ASTMatchersTest, IsDelegatingConstructor) {2557 if (!GetParam().isCXX11OrLater()) {2558 return;2559 }2560 2561 EXPECT_TRUE(notMatches("struct S { S(); S(int); int X; };",2562 cxxConstructorDecl(isDelegatingConstructor())));2563 EXPECT_TRUE(notMatches("struct S { S(){} S(int X) : X(X) {} int X; };",2564 cxxConstructorDecl(isDelegatingConstructor())));2565 EXPECT_TRUE(matches(2566 "struct S { S() : S(0) {} S(int X) : X(X) {} int X; };",2567 cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(0))));2568 EXPECT_TRUE(matches(2569 "struct S { S(); S(int X); int X; }; S::S(int X) : S() {}",2570 cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(1))));2571}2572 2573TEST_P(ASTMatchersTest, HasSize) {2574 StatementMatcher Literal = stringLiteral(hasSize(4));2575 EXPECT_TRUE(matches("const char *s = \"abcd\";", Literal));2576 // with escaped characters2577 EXPECT_TRUE(matches("const char *s = \"\x05\x06\x07\x08\";", Literal));2578 // no matching, too small2579 EXPECT_TRUE(notMatches("const char *s = \"ab\";", Literal));2580}2581 2582TEST_P(ASTMatchersTest, HasSize_CXX) {2583 if (!GetParam().isCXX()) {2584 // FIXME: Fix this test to also work in non-C++ language modes.2585 return;2586 }2587 2588 StatementMatcher Literal = stringLiteral(hasSize(4));2589 // wide string2590 EXPECT_TRUE(matches("const wchar_t *s = L\"abcd\";", Literal));2591}2592 2593TEST_P(ASTMatchersTest, HasName_MatchesNamespaces) {2594 if (!GetParam().isCXX()) {2595 return;2596 }2597 2598 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",2599 recordDecl(hasName("a::b::C"))));2600 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",2601 recordDecl(hasName("::a::b::C"))));2602 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",2603 recordDecl(hasName("b::C"))));2604 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",2605 recordDecl(hasName("C"))));2606 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",2607 recordDecl(hasName("c::b::C"))));2608 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",2609 recordDecl(hasName("a::c::C"))));2610 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",2611 recordDecl(hasName("a::b::A"))));2612 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",2613 recordDecl(hasName("::C"))));2614 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",2615 recordDecl(hasName("::b::C"))));2616 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",2617 recordDecl(hasName("z::a::b::C"))));2618 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",2619 recordDecl(hasName("a+b::C"))));2620 EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",2621 recordDecl(hasName("C"))));2622 EXPECT_TRUE(matches("namespace a { inline namespace a { class C; } }",2623 recordDecl(hasName("::a::C"))));2624 EXPECT_TRUE(matches("namespace a { inline namespace a { class C; } }",2625 recordDecl(hasName("::a::a::C"))));2626}2627 2628TEST_P(ASTMatchersTest, HasName_MatchesOuterClasses) {2629 if (!GetParam().isCXX()) {2630 return;2631 }2632 2633 EXPECT_TRUE(matches("class A { class B { class C; }; };",2634 recordDecl(hasName("A::B::C"))));2635 EXPECT_TRUE(matches("class A { class B { class C; }; };",2636 recordDecl(hasName("::A::B::C"))));2637 EXPECT_TRUE(matches("class A { class B { class C; }; };",2638 recordDecl(hasName("B::C"))));2639 EXPECT_TRUE(2640 matches("class A { class B { class C; }; };", recordDecl(hasName("C"))));2641 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",2642 recordDecl(hasName("c::B::C"))));2643 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",2644 recordDecl(hasName("A::c::C"))));2645 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",2646 recordDecl(hasName("A::B::A"))));2647 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",2648 recordDecl(hasName("::C"))));2649 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",2650 recordDecl(hasName("::B::C"))));2651 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",2652 recordDecl(hasName("z::A::B::C"))));2653 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",2654 recordDecl(hasName("A+B::C"))));2655}2656 2657TEST_P(ASTMatchersTest, HasName_MatchesInlinedNamespaces) {2658 if (!GetParam().isCXX()) {2659 return;2660 }2661 2662 StringRef code = "namespace a { inline namespace b { class C; } }";2663 EXPECT_TRUE(matches(code, recordDecl(hasName("a::b::C"))));2664 EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));2665 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::b::C"))));2666 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));2667}2668 2669TEST_P(ASTMatchersTest, HasName_MatchesSpecializedInlinedNamespace) {2670 if (!GetParam().isCXX11OrLater()) {2671 return;2672 }2673 2674 StringRef code = R"(2675namespace a {2676 inline namespace v1 {2677 template<typename T> T foo(T);2678 }2679}2680 2681namespace a {2682 enum Tag{T1, T2};2683 2684 template <Tag, typename T> T foo(T);2685}2686 2687auto v1 = a::foo(1);2688auto v2 = a::foo<a::T1>(1);2689)";2690 EXPECT_TRUE(matches(2691 code, varDecl(hasName("v1"), hasDescendant(callExpr(callee(2692 functionDecl(hasName("::a::foo"))))))));2693 EXPECT_TRUE(matches(2694 code, varDecl(hasName("v2"), hasDescendant(callExpr(callee(2695 functionDecl(hasName("::a::foo"))))))));2696}2697 2698TEST_P(ASTMatchersTest, HasName_MatchesAnonymousNamespaces) {2699 if (!GetParam().isCXX()) {2700 return;2701 }2702 2703 StringRef code = "namespace a { namespace { class C; } }";2704 EXPECT_TRUE(2705 matches(code, recordDecl(hasName("a::(anonymous namespace)::C"))));2706 EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));2707 EXPECT_TRUE(2708 matches(code, recordDecl(hasName("::a::(anonymous namespace)::C"))));2709 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));2710}2711 2712TEST_P(ASTMatchersTest, HasName_MatchesAnonymousOuterClasses) {2713 if (!GetParam().isCXX()) {2714 return;2715 }2716 2717 EXPECT_TRUE(matches("class A { class { class C; } x; };",2718 recordDecl(hasName("A::(anonymous class)::C"))));2719 EXPECT_TRUE(matches("class A { class { class C; } x; };",2720 recordDecl(hasName("::A::(anonymous class)::C"))));2721 EXPECT_FALSE(matches("class A { class { class C; } x; };",2722 recordDecl(hasName("::A::C"))));2723 EXPECT_TRUE(matches("class A { struct { class C; } x; };",2724 recordDecl(hasName("A::(anonymous struct)::C"))));2725 EXPECT_TRUE(matches("class A { struct { class C; } x; };",2726 recordDecl(hasName("::A::(anonymous struct)::C"))));2727 EXPECT_FALSE(matches("class A { struct { class C; } x; };",2728 recordDecl(hasName("::A::C"))));2729}2730 2731TEST_P(ASTMatchersTest, HasName_MatchesFunctionScope) {2732 if (!GetParam().isCXX()) {2733 return;2734 }2735 2736 StringRef code =2737 "namespace a { void F(int a) { struct S { int m; }; int i; } }";2738 EXPECT_TRUE(matches(code, varDecl(hasName("i"))));2739 EXPECT_FALSE(matches(code, varDecl(hasName("F()::i"))));2740 2741 EXPECT_TRUE(matches(code, fieldDecl(hasName("m"))));2742 EXPECT_TRUE(matches(code, fieldDecl(hasName("S::m"))));2743 EXPECT_TRUE(matches(code, fieldDecl(hasName("F(int)::S::m"))));2744 EXPECT_TRUE(matches(code, fieldDecl(hasName("a::F(int)::S::m"))));2745 EXPECT_TRUE(matches(code, fieldDecl(hasName("::a::F(int)::S::m"))));2746}2747 2748TEST_P(ASTMatchersTest, HasName_QualifiedStringMatchesThroughLinkage) {2749 if (!GetParam().isCXX()) {2750 return;2751 }2752 2753 // https://bugs.llvm.org/show_bug.cgi?id=421932754 StringRef code = R"cpp(namespace foo { extern "C" void test(); })cpp";2755 EXPECT_TRUE(matches(code, functionDecl(hasName("test"))));2756 EXPECT_TRUE(matches(code, functionDecl(hasName("foo::test"))));2757 EXPECT_TRUE(matches(code, functionDecl(hasName("::foo::test"))));2758 EXPECT_TRUE(notMatches(code, functionDecl(hasName("::test"))));2759 2760 code = R"cpp(namespace foo { extern "C" { void test(); } })cpp";2761 EXPECT_TRUE(matches(code, functionDecl(hasName("test"))));2762 EXPECT_TRUE(matches(code, functionDecl(hasName("foo::test"))));2763 EXPECT_TRUE(matches(code, functionDecl(hasName("::foo::test"))));2764 EXPECT_TRUE(notMatches(code, functionDecl(hasName("::test"))));2765}2766 2767TEST_P(ASTMatchersTest, HasAnyName) {2768 if (!GetParam().isCXX()) {2769 // FIXME: Add a test for `hasAnyName()` that does not depend on C++.2770 return;2771 }2772 2773 StringRef Code = "namespace a { namespace b { class C; } }";2774 2775 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "a::b::C"))));2776 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("a::b::C", "XX"))));2777 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX::C", "a::b::C"))));2778 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "C"))));2779 2780 EXPECT_TRUE(notMatches(Code, recordDecl(hasAnyName("::C", "::b::C"))));2781 EXPECT_TRUE(2782 matches(Code, recordDecl(hasAnyName("::C", "::b::C", "::a::b::C"))));2783 2784 std::vector<StringRef> Names = {"::C", "::b::C", "::a::b::C"};2785 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName(Names))));2786}2787 2788TEST_P(ASTMatchersTest, IsDefinition) {2789 DeclarationMatcher DefinitionOfClassA =2790 recordDecl(hasName("A"), isDefinition());2791 EXPECT_TRUE(matches("struct A {};", DefinitionOfClassA));2792 EXPECT_TRUE(notMatches("struct A;", DefinitionOfClassA));2793 2794 DeclarationMatcher DefinitionOfVariableA =2795 varDecl(hasName("a"), isDefinition());2796 EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));2797 EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));2798}2799 2800TEST_P(ASTMatchersTest, IsDefinition_CXX) {2801 if (!GetParam().isCXX()) {2802 return;2803 }2804 2805 DeclarationMatcher DefinitionOfMethodA =2806 cxxMethodDecl(hasName("a"), isDefinition());2807 EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));2808 EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));2809 2810 DeclarationMatcher DefinitionOfObjCMethodA =2811 objcMethodDecl(hasName("a"), isDefinition());2812 EXPECT_TRUE(matchesObjC("@interface A @end "2813 "@implementation A; -(void)a {} @end",2814 DefinitionOfObjCMethodA));2815 EXPECT_TRUE(2816 notMatchesObjC("@interface A; - (void)a; @end", DefinitionOfObjCMethodA));2817}2818 2819TEST_P(ASTMatchersTest, HandlesNullQualTypes) {2820 if (!GetParam().isCXX()) {2821 // FIXME: Add an equivalent test that does not depend on C++.2822 return;2823 }2824 2825 // FIXME: Add a Type matcher so we can replace uses of this2826 // variable with Type(True())2827 const TypeMatcher AnyType = anything();2828 2829 // We don't really care whether this matcher succeeds; we're testing that2830 // it completes without crashing.2831 EXPECT_TRUE(matches(2832 "struct A { };"2833 "template <typename T>"2834 "void f(T t) {"2835 " T local_t(t /* this becomes a null QualType in the AST */);"2836 "}"2837 "void g() {"2838 " f(0);"2839 "}",2840 expr(hasType(TypeMatcher(anyOf(TypeMatcher(hasDeclaration(anything())),2841 pointsTo(AnyType), references(AnyType)2842 // Other QualType matchers should go here.2843 ))))));2844}2845 2846TEST_P(ASTMatchersTest, ObjCIvarRefExpr) {2847 StringRef ObjCString =2848 "@interface A @end "2849 "@implementation A { A *x; } - (void) func { x = 0; } @end";2850 EXPECT_TRUE(matchesObjC(ObjCString, objcIvarRefExpr()));2851 EXPECT_TRUE(matchesObjC(2852 ObjCString, objcIvarRefExpr(hasDeclaration(namedDecl(hasName("x"))))));2853 EXPECT_FALSE(matchesObjC(2854 ObjCString, objcIvarRefExpr(hasDeclaration(namedDecl(hasName("y"))))));2855}2856 2857TEST_P(ASTMatchersTest, BlockExpr) {2858 EXPECT_TRUE(matchesObjC("void f() { ^{}(); }", blockExpr()));2859}2860 2861TEST_P(ASTMatchersTest,2862 StatementCountIs_FindsNoStatementsInAnEmptyCompoundStatement) {2863 EXPECT_TRUE(matches("void f() { }", compoundStmt(statementCountIs(0))));2864 EXPECT_TRUE(notMatches("void f() {}", compoundStmt(statementCountIs(1))));2865}2866 2867TEST_P(ASTMatchersTest, StatementCountIs_AppearsToMatchOnlyOneCount) {2868 EXPECT_TRUE(matches("void f() { 1; }", compoundStmt(statementCountIs(1))));2869 EXPECT_TRUE(notMatches("void f() { 1; }", compoundStmt(statementCountIs(0))));2870 EXPECT_TRUE(notMatches("void f() { 1; }", compoundStmt(statementCountIs(2))));2871}2872 2873TEST_P(ASTMatchersTest, StatementCountIs_WorksWithMultipleStatements) {2874 EXPECT_TRUE(2875 matches("void f() { 1; 2; 3; }", compoundStmt(statementCountIs(3))));2876}2877 2878TEST_P(ASTMatchersTest, StatementCountIs_WorksWithNestedCompoundStatements) {2879 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",2880 compoundStmt(statementCountIs(1))));2881 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",2882 compoundStmt(statementCountIs(2))));2883 EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",2884 compoundStmt(statementCountIs(3))));2885 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",2886 compoundStmt(statementCountIs(4))));2887}2888 2889TEST_P(ASTMatchersTest, Member_WorksInSimplestCase) {2890 if (!GetParam().isCXX()) {2891 // FIXME: Add a test for `member()` that does not depend on C++.2892 return;2893 }2894 EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",2895 memberExpr(member(hasName("first")))));2896}2897 2898TEST_P(ASTMatchersTest, Member_DoesNotMatchTheBaseExpression) {2899 if (!GetParam().isCXX()) {2900 // FIXME: Add a test for `member()` that does not depend on C++.2901 return;2902 }2903 2904 // Don't pick out the wrong part of the member expression, this should2905 // be checking the member (name) only.2906 EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",2907 memberExpr(member(hasName("first")))));2908}2909 2910TEST_P(ASTMatchersTest, Member_MatchesInMemberFunctionCall) {2911 if (!GetParam().isCXX()) {2912 return;2913 }2914 2915 EXPECT_TRUE(matches("void f() {"2916 " struct { void first() {}; } s;"2917 " s.first();"2918 "};",2919 memberExpr(member(hasName("first")))));2920}2921 2922TEST_P(ASTMatchersTest, FieldDecl) {2923 EXPECT_TRUE(2924 matches("struct A { int i; }; void f() { struct A a; a.i = 2; }",2925 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));2926 EXPECT_TRUE(2927 notMatches("struct A { float f; }; void f() { struct A a; a.f = 2.0f; }",2928 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));2929}2930 2931TEST_P(ASTMatchersTest, IsBitField) {2932 EXPECT_TRUE(matches("struct C { int a : 2; int b; };",2933 fieldDecl(isBitField(), hasName("a"))));2934 EXPECT_TRUE(notMatches("struct C { int a : 2; int b; };",2935 fieldDecl(isBitField(), hasName("b"))));2936 EXPECT_TRUE(matches("struct C { int a : 2; int b : 4; };",2937 fieldDecl(isBitField(), hasBitWidth(2), hasName("a"))));2938 if (GetParam().isCXX()) {2939 // This test verifies 2 things:2940 // (1) That templates work correctly.2941 // (2) That the matcher does not crash on template-dependent bit widths.2942 EXPECT_TRUE(matches("template<int N> "2943 "struct C { "2944 "explicit C(bool x) : a(x) { } "2945 "int a : N; "2946 "int b : 4; "2947 "}; "2948 "template struct C<2>;",2949 fieldDecl(isBitField(), hasBitWidth(2), hasName("a"))));2950 }2951}2952 2953TEST_P(ASTMatchersTest, HasInClassInitializer) {2954 if (!GetParam().isCXX()) {2955 return;2956 }2957 2958 EXPECT_TRUE(2959 matches("class C { int a = 2; int b; };",2960 fieldDecl(hasInClassInitializer(integerLiteral(equals(2))),2961 hasName("a"))));2962 EXPECT_TRUE(2963 notMatches("class C { int a = 2; int b; };",2964 fieldDecl(hasInClassInitializer(anything()), hasName("b"))));2965}2966 2967TEST_P(ASTMatchersTest, IsPublic_IsProtected_IsPrivate) {2968 if (!GetParam().isCXX()) {2969 return;2970 }2971 2972 EXPECT_TRUE(2973 matches("struct A { int i; };", fieldDecl(isPublic(), hasName("i"))));2974 EXPECT_TRUE(notMatches("struct A { int i; };",2975 fieldDecl(isProtected(), hasName("i"))));2976 EXPECT_TRUE(2977 notMatches("struct A { int i; };", fieldDecl(isPrivate(), hasName("i"))));2978 2979 EXPECT_TRUE(2980 notMatches("class A { int i; };", fieldDecl(isPublic(), hasName("i"))));2981 EXPECT_TRUE(notMatches("class A { int i; };",2982 fieldDecl(isProtected(), hasName("i"))));2983 EXPECT_TRUE(2984 matches("class A { int i; };", fieldDecl(isPrivate(), hasName("i"))));2985 2986 EXPECT_TRUE(notMatches("class A { protected: int i; };",2987 fieldDecl(isPublic(), hasName("i"))));2988 EXPECT_TRUE(matches("class A { protected: int i; };",2989 fieldDecl(isProtected(), hasName("i"))));2990 EXPECT_TRUE(notMatches("class A { protected: int i; };",2991 fieldDecl(isPrivate(), hasName("i"))));2992 2993 // Non-member decls have the AccessSpecifier AS_none and thus aren't matched.2994 EXPECT_TRUE(notMatches("int i;", varDecl(isPublic(), hasName("i"))));2995 EXPECT_TRUE(notMatches("int i;", varDecl(isProtected(), hasName("i"))));2996 EXPECT_TRUE(notMatches("int i;", varDecl(isPrivate(), hasName("i"))));2997}2998 2999TEST_P(ASTMatchersTest,3000 HasDynamicExceptionSpec_MatchesDynamicExceptionSpecifications) {3001 if (!GetParam().supportsCXXDynamicExceptionSpecification()) {3002 return;3003 }3004 3005 EXPECT_TRUE(notMatches("void f();", functionDecl(hasDynamicExceptionSpec())));3006 EXPECT_TRUE(3007 matches("void j() throw();", functionDecl(hasDynamicExceptionSpec())));3008 EXPECT_TRUE(3009 matches("void k() throw(int);", functionDecl(hasDynamicExceptionSpec())));3010 EXPECT_TRUE(3011 matches("void l() throw(...);", functionDecl(hasDynamicExceptionSpec())));3012 3013 EXPECT_TRUE(3014 notMatches("void f();", functionProtoType(hasDynamicExceptionSpec())));3015 EXPECT_TRUE(matches("void j() throw();",3016 functionProtoType(hasDynamicExceptionSpec())));3017 EXPECT_TRUE(matches("void k() throw(int);",3018 functionProtoType(hasDynamicExceptionSpec())));3019 EXPECT_TRUE(matches("void l() throw(...);",3020 functionProtoType(hasDynamicExceptionSpec())));3021}3022 3023TEST_P(ASTMatchersTest,3024 HasDynamicExceptionSpec_MatchesDynamicExceptionSpecifications_CXX11) {3025 if (!GetParam().isCXX11OrLater()) {3026 return;3027 }3028 3029 EXPECT_TRUE(notMatches("void g() noexcept;",3030 functionDecl(hasDynamicExceptionSpec())));3031 EXPECT_TRUE(notMatches("void h() noexcept(true);",3032 functionDecl(hasDynamicExceptionSpec())));3033 EXPECT_TRUE(notMatches("void i() noexcept(false);",3034 functionDecl(hasDynamicExceptionSpec())));3035 3036 EXPECT_TRUE(notMatches("void g() noexcept;",3037 functionProtoType(hasDynamicExceptionSpec())));3038 EXPECT_TRUE(notMatches("void h() noexcept(true);",3039 functionProtoType(hasDynamicExceptionSpec())));3040 EXPECT_TRUE(notMatches("void i() noexcept(false);",3041 functionProtoType(hasDynamicExceptionSpec())));3042}3043 3044TEST_P(ASTMatchersTest, HasObjectExpression_DoesNotMatchMember) {3045 if (!GetParam().isCXX()) {3046 return;3047 }3048 3049 EXPECT_TRUE(notMatches(3050 "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",3051 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));3052}3053 3054TEST_P(ASTMatchersTest, HasObjectExpression_MatchesBaseOfVariable) {3055 EXPECT_TRUE(matches(3056 "struct X { int m; }; void f(struct X x) { x.m; }",3057 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));3058 EXPECT_TRUE(matches("struct X { int m; }; void f(struct X* x) { x->m; }",3059 memberExpr(hasObjectExpression(3060 hasType(pointsTo(recordDecl(hasName("X"))))))));3061}3062 3063TEST_P(ASTMatchersTest, HasObjectExpression_MatchesBaseOfVariable_CXX) {3064 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {3065 // FIXME: Fix this test to work with delayed template parsing.3066 return;3067 }3068 3069 EXPECT_TRUE(matches("template <class T> struct X { void f() { T t; t.m; } };",3070 cxxDependentScopeMemberExpr(hasObjectExpression(3071 declRefExpr(to(namedDecl(hasName("t"))))))));3072 EXPECT_TRUE(3073 matches("template <class T> struct X { void f() { T t; t->m; } };",3074 cxxDependentScopeMemberExpr(hasObjectExpression(3075 declRefExpr(to(namedDecl(hasName("t"))))))));3076}3077 3078TEST_P(ASTMatchersTest, HasObjectExpression_MatchesBaseOfMemberFunc) {3079 if (!GetParam().isCXX()) {3080 return;3081 }3082 3083 EXPECT_TRUE(matches(3084 "struct X { void f(); }; void g(X x) { x.f(); }",3085 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));3086}3087 3088TEST_P(ASTMatchersTest, HasObjectExpression_MatchesBaseOfMemberFunc_Template) {3089 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {3090 // FIXME: Fix this test to work with delayed template parsing.3091 return;3092 }3093 3094 EXPECT_TRUE(matches("struct X { template <class T> void f(); };"3095 "template <class T> void g(X x) { x.f<T>(); }",3096 unresolvedMemberExpr(hasObjectExpression(3097 hasType(recordDecl(hasName("X")))))));3098 EXPECT_TRUE(matches("template <class T> void f(T t) { t.g(); }",3099 cxxDependentScopeMemberExpr(hasObjectExpression(3100 declRefExpr(to(namedDecl(hasName("t"))))))));3101}3102 3103TEST_P(ASTMatchersTest, HasObjectExpression_ImplicitlyFormedMemberExpression) {3104 if (!GetParam().isCXX()) {3105 return;3106 }3107 3108 EXPECT_TRUE(matches("class X {}; struct S { X m; void f() { this->m; } };",3109 memberExpr(hasObjectExpression(3110 hasType(pointsTo(recordDecl(hasName("S"))))))));3111 EXPECT_TRUE(matches("class X {}; struct S { X m; void f() { m; } };",3112 memberExpr(hasObjectExpression(3113 hasType(pointsTo(recordDecl(hasName("S"))))))));3114}3115 3116TEST_P(ASTMatchersTest, FieldDecl_DoesNotMatchNonFieldMembers) {3117 if (!GetParam().isCXX()) {3118 return;3119 }3120 3121 EXPECT_TRUE(notMatches("class X { void m(); };", fieldDecl(hasName("m"))));3122 EXPECT_TRUE(notMatches("class X { class m {}; };", fieldDecl(hasName("m"))));3123 EXPECT_TRUE(notMatches("class X { enum { m }; };", fieldDecl(hasName("m"))));3124 EXPECT_TRUE(notMatches("class X { enum m {}; };", fieldDecl(hasName("m"))));3125}3126 3127TEST_P(ASTMatchersTest, FieldDecl_MatchesField) {3128 EXPECT_TRUE(matches("struct X { int m; };", fieldDecl(hasName("m"))));3129}3130 3131TEST_P(ASTMatchersTest, IsVolatileQualified) {3132 EXPECT_TRUE(3133 matches("volatile int i = 42;", varDecl(hasType(isVolatileQualified()))));3134 EXPECT_TRUE(3135 notMatches("volatile int *i;", varDecl(hasType(isVolatileQualified()))));3136 EXPECT_TRUE(matches("typedef volatile int v_int; v_int i = 42;",3137 varDecl(hasType(isVolatileQualified()))));3138}3139 3140TEST_P(ASTMatchersTest, IsConstQualified_MatchesConstInt) {3141 EXPECT_TRUE(3142 matches("const int i = 42;", varDecl(hasType(isConstQualified()))));3143}3144 3145TEST_P(ASTMatchersTest, IsConstQualified_MatchesConstPointer) {3146 EXPECT_TRUE(matches("int i = 42; int* const p = &i;",3147 varDecl(hasType(isConstQualified()))));3148}3149 3150TEST_P(ASTMatchersTest, IsConstQualified_MatchesThroughTypedef) {3151 EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",3152 varDecl(hasType(isConstQualified()))));3153 EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p = ((int*)0);",3154 varDecl(hasType(isConstQualified()))));3155}3156 3157TEST_P(ASTMatchersTest, IsConstQualified_DoesNotMatchInappropriately) {3158 EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",3159 varDecl(hasType(isConstQualified()))));3160 EXPECT_TRUE(3161 notMatches("int const* p;", varDecl(hasType(isConstQualified()))));3162}3163 3164TEST_P(ASTMatchersTest, DeclCountIs_DeclCountIsCorrect) {3165 EXPECT_TRUE(matches("void f() {int i,j;}", declStmt(declCountIs(2))));3166 EXPECT_TRUE(3167 notMatches("void f() {int i,j; int k;}", declStmt(declCountIs(3))));3168 EXPECT_TRUE(3169 notMatches("void f() {int i,j, k, l;}", declStmt(declCountIs(3))));3170}3171 3172TEST_P(ASTMatchersTest, EachOf_TriggersForEachMatch) {3173 EXPECT_TRUE(matchAndVerifyResultTrue(3174 "class A { int a; int b; };",3175 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),3176 has(fieldDecl(hasName("b")).bind("v")))),3177 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 2)));3178}3179 3180TEST_P(ASTMatchersTest, EachOf_BehavesLikeAnyOfUnlessBothMatch) {3181 EXPECT_TRUE(matchAndVerifyResultTrue(3182 "struct A { int a; int c; };",3183 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),3184 has(fieldDecl(hasName("b")).bind("v")))),3185 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 1)));3186 EXPECT_TRUE(matchAndVerifyResultTrue(3187 "struct A { int c; int b; };",3188 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),3189 has(fieldDecl(hasName("b")).bind("v")))),3190 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v", 1)));3191 EXPECT_TRUE(3192 notMatches("struct A { int c; int d; };",3193 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),3194 has(fieldDecl(hasName("b")).bind("v"))))));3195}3196 3197TEST_P(ASTMatchersTest, Optionally_SubmatchersDoNotMatch) {3198 EXPECT_TRUE(matchAndVerifyResultFalse(3199 "class A { int a; int b; };",3200 recordDecl(optionally(has(fieldDecl(hasName("c")).bind("c")))),3201 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("c")));3202}3203 3204// Regression test.3205TEST_P(ASTMatchersTest, Optionally_SubmatchersDoNotMatchButPreserveBindings) {3206 StringRef Code = "class A { int a; int b; };";3207 auto Matcher = recordDecl(decl().bind("decl"),3208 optionally(has(fieldDecl(hasName("c")).bind("v"))));3209 // "decl" is still bound.3210 EXPECT_TRUE(matchAndVerifyResultTrue(3211 Code, Matcher, std::make_unique<VerifyIdIsBoundTo<RecordDecl>>("decl")));3212 // "v" is not bound, but the match still suceeded.3213 EXPECT_TRUE(matchAndVerifyResultFalse(3214 Code, Matcher, std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v")));3215}3216 3217TEST_P(ASTMatchersTest, Optionally_SubmatchersMatch) {3218 EXPECT_TRUE(matchAndVerifyResultTrue(3219 "class A { int a; int c; };",3220 recordDecl(optionally(has(fieldDecl(hasName("a")).bind("v")))),3221 std::make_unique<VerifyIdIsBoundTo<FieldDecl>>("v")));3222}3223 3224TEST_P(ASTMatchersTest,3225 IsTemplateInstantiation_MatchesImplicitClassTemplateInstantiation) {3226 if (!GetParam().isCXX()) {3227 return;3228 }3229 3230 // Make sure that we can both match the class by name (::X) and by the type3231 // the template was instantiated with (via a field).3232 3233 EXPECT_TRUE(3234 matches("template <typename T> class X {}; class A {}; X<A> x;",3235 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));3236 3237 EXPECT_TRUE(matches(3238 "template <typename T> class X { T t; }; class A {}; X<A> x;",3239 cxxRecordDecl(3240 isTemplateInstantiation(),3241 hasDescendant(fieldDecl(hasType(recordDecl(hasName("A"))))))));3242}3243 3244TEST_P(ASTMatchersTest,3245 IsTemplateInstantiation_MatchesImplicitFunctionTemplateInstantiation) {3246 if (!GetParam().isCXX()) {3247 return;3248 }3249 3250 EXPECT_TRUE(matches(3251 "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",3252 functionDecl(hasParameter(0, hasType(recordDecl(hasName("A")))),3253 isTemplateInstantiation())));3254}3255 3256TEST_P(ASTMatchersTest,3257 IsTemplateInstantiation_MatchesExplicitClassTemplateInstantiation) {3258 if (!GetParam().isCXX()) {3259 return;3260 }3261 3262 EXPECT_TRUE(matches("template <typename T> class X { T t; }; class A {};"3263 "template class X<A>;",3264 cxxRecordDecl(isTemplateInstantiation(),3265 hasDescendant(fieldDecl(3266 hasType(recordDecl(hasName("A"))))))));3267 3268 // Make sure that we match the instantiation instead of the template3269 // definition by checking whether the member function is present.3270 EXPECT_TRUE(3271 matches("template <typename T> class X { void f() { T t; } };"3272 "extern template class X<int>;",3273 cxxRecordDecl(isTemplateInstantiation(),3274 unless(hasDescendant(varDecl(hasName("t")))))));3275}3276 3277TEST_P(3278 ASTMatchersTest,3279 IsTemplateInstantiation_MatchesInstantiationOfPartiallySpecializedClassTemplate) {3280 if (!GetParam().isCXX()) {3281 return;3282 }3283 3284 EXPECT_TRUE(3285 matches("template <typename T> class X {};"3286 "template <typename T> class X<T*> {}; class A {}; X<A*> x;",3287 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));3288}3289 3290TEST_P(3291 ASTMatchersTest,3292 IsTemplateInstantiation_MatchesInstantiationOfClassTemplateNestedInNonTemplate) {3293 if (!GetParam().isCXX()) {3294 return;3295 }3296 3297 EXPECT_TRUE(3298 matches("class A {};"3299 "class X {"3300 " template <typename U> class Y { U u; };"3301 " Y<A> y;"3302 "};",3303 cxxRecordDecl(hasName("::X::Y"), isTemplateInstantiation())));3304}3305 3306TEST_P(3307 ASTMatchersTest,3308 IsTemplateInstantiation_DoesNotMatchInstantiationsInsideOfInstantiation) {3309 if (!GetParam().isCXX()) {3310 return;3311 }3312 3313 // FIXME: Figure out whether this makes sense. It doesn't affect the3314 // normal use case as long as the uppermost instantiation always is marked3315 // as template instantiation, but it might be confusing as a predicate.3316 EXPECT_TRUE(matches(3317 "class A {};"3318 "template <typename T> class X {"3319 " template <typename U> class Y { U u; };"3320 " Y<T> y;"3321 "}; X<A> x;",3322 cxxRecordDecl(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));3323}3324 3325TEST_P(3326 ASTMatchersTest,3327 IsTemplateInstantiation_DoesNotMatchExplicitClassTemplateSpecialization) {3328 if (!GetParam().isCXX()) {3329 return;3330 }3331 3332 EXPECT_TRUE(3333 notMatches("template <typename T> class X {}; class A {};"3334 "template <> class X<A> {}; X<A> x;",3335 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));3336}3337 3338TEST_P(ASTMatchersTest, IsTemplateInstantiation_DoesNotMatchNonTemplate) {3339 if (!GetParam().isCXX()) {3340 return;3341 }3342 3343 EXPECT_TRUE(notMatches("class A {}; class Y { A a; };",3344 cxxRecordDecl(isTemplateInstantiation())));3345}3346 3347TEST_P(ASTMatchersTest, IsInstantiated_MatchesInstantiation) {3348 if (!GetParam().isCXX()) {3349 return;3350 }3351 3352 EXPECT_TRUE(3353 matches("template<typename T> class A { T i; }; class Y { A<int> a; };",3354 cxxRecordDecl(isInstantiated())));3355}3356 3357TEST_P(ASTMatchersTest, IsInstantiated_NotMatchesDefinition) {3358 if (!GetParam().isCXX()) {3359 return;3360 }3361 3362 EXPECT_TRUE(notMatches("template<typename T> class A { T i; };",3363 cxxRecordDecl(isInstantiated())));3364}3365 3366TEST_P(ASTMatchersTest, IsInTemplateInstantiation_MatchesInstantiationStmt) {3367 if (!GetParam().isCXX()) {3368 return;3369 }3370 3371 EXPECT_TRUE(matches("template<typename T> struct A { A() { T i; } };"3372 "class Y { A<int> a; }; Y y;",3373 declStmt(isInTemplateInstantiation())));3374}3375 3376TEST_P(ASTMatchersTest, IsInTemplateInstantiation_NotMatchesDefinitionStmt) {3377 if (!GetParam().isCXX()) {3378 return;3379 }3380 3381 EXPECT_TRUE(notMatches("template<typename T> struct A { void x() { T i; } };",3382 declStmt(isInTemplateInstantiation())));3383}3384 3385TEST_P(ASTMatchersTest, IsInstantiated_MatchesFunctionInstantiation) {3386 if (!GetParam().isCXX()) {3387 return;3388 }3389 3390 EXPECT_TRUE(3391 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",3392 functionDecl(isInstantiated())));3393}3394 3395TEST_P(ASTMatchersTest, IsInstantiated_NotMatchesFunctionDefinition) {3396 if (!GetParam().isCXX()) {3397 return;3398 }3399 3400 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",3401 varDecl(isInstantiated())));3402}3403 3404TEST_P(ASTMatchersTest,3405 IsInTemplateInstantiation_MatchesFunctionInstantiationStmt) {3406 if (!GetParam().isCXX()) {3407 return;3408 }3409 3410 EXPECT_TRUE(3411 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",3412 declStmt(isInTemplateInstantiation())));3413}3414 3415TEST_P(ASTMatchersTest,3416 IsInTemplateInstantiation_NotMatchesFunctionDefinitionStmt) {3417 if (!GetParam().isCXX()) {3418 return;3419 }3420 3421 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",3422 declStmt(isInTemplateInstantiation())));3423}3424 3425TEST_P(ASTMatchersTest, IsInstantiated_MatchesVariableInstantiation) {3426 if (!GetParam().isCXX14OrLater()) {3427 return;3428 }3429 3430 EXPECT_TRUE(matches("template<typename T> int V = 10; void x() { V<int>; }",3431 varDecl(isInstantiated())));3432}3433 3434TEST_P(ASTMatchersTest, IsInstantiated_NotMatchesVariableDefinition) {3435 if (!GetParam().isCXX14OrLater()) {3436 return;3437 }3438 3439 EXPECT_TRUE(notMatches("template<typename T> int V = 10;",3440 varDecl(isInstantiated())));3441}3442 3443TEST_P(ASTMatchersTest,3444 IsInTemplateInstantiation_MatchesVariableInstantiationStmt) {3445 if (!GetParam().isCXX14OrLater()) {3446 return;3447 }3448 3449 EXPECT_TRUE(matches(3450 "template<typename T> auto V = []() { T i; }; void x() { V<int>(); }",3451 declStmt(isInTemplateInstantiation())));3452}3453 3454TEST_P(ASTMatchersTest,3455 IsInTemplateInstantiation_NotMatchesVariableDefinitionStmt) {3456 if (!GetParam().isCXX14OrLater()) {3457 return;3458 }3459 3460 EXPECT_TRUE(notMatches("template<typename T> auto V = []() { T i; };",3461 declStmt(isInTemplateInstantiation())));3462}3463 3464TEST_P(ASTMatchersTest, IsInTemplateInstantiation_Sharing) {3465 if (!GetParam().isCXX()) {3466 return;3467 }3468 3469 auto Matcher = binaryOperator(unless(isInTemplateInstantiation()));3470 // FIXME: Node sharing is an implementation detail, exposing it is ugly3471 // and makes the matcher behave in non-obvious ways.3472 EXPECT_TRUE(notMatches(3473 "int j; template<typename T> void A(T t) { j += 42; } void x() { A(0); }",3474 Matcher));3475 EXPECT_TRUE(matches(3476 "int j; template<typename T> void A(T t) { j += t; } void x() { A(0); }",3477 Matcher));3478}3479 3480TEST_P(ASTMatchersTest, IsInstantiationDependent_MatchesNonValueTypeDependent) {3481 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {3482 // FIXME: Fix this test to work with delayed template parsing.3483 return;3484 }3485 3486 EXPECT_TRUE(matches(3487 "template<typename T> void f() { (void) sizeof(sizeof(T() + T())); }",3488 expr(isInstantiationDependent())));3489}3490 3491TEST_P(ASTMatchersTest, IsInstantiationDependent_MatchesValueDependent) {3492 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {3493 // FIXME: Fix this test to work with delayed template parsing.3494 return;3495 }3496 3497 EXPECT_TRUE(matches("template<int T> int f() { return T; }",3498 expr(isInstantiationDependent())));3499}3500 3501TEST_P(ASTMatchersTest, IsInstantiationDependent_MatchesTypeDependent) {3502 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {3503 // FIXME: Fix this test to work with delayed template parsing.3504 return;3505 }3506 3507 EXPECT_TRUE(matches("template<typename T> T f() { return T(); }",3508 expr(isInstantiationDependent())));3509}3510 3511TEST_P(ASTMatchersTest, IsTypeDependent_MatchesTypeDependent) {3512 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {3513 // FIXME: Fix this test to work with delayed template parsing.3514 return;3515 }3516 3517 EXPECT_TRUE(matches("template<typename T> T f() { return T(); }",3518 expr(isTypeDependent())));3519}3520 3521TEST_P(ASTMatchersTest, IsTypeDependent_NotMatchesValueDependent) {3522 if (!GetParam().isCXX()) {3523 return;3524 }3525 3526 EXPECT_TRUE(notMatches("template<int T> int f() { return T; }",3527 expr(isTypeDependent())));3528}3529 3530TEST_P(ASTMatchersTest, IsValueDependent_MatchesValueDependent) {3531 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {3532 // FIXME: Fix this test to work with delayed template parsing.3533 return;3534 }3535 3536 EXPECT_TRUE(matches("template<int T> int f() { return T; }",3537 expr(isValueDependent())));3538}3539 3540TEST_P(ASTMatchersTest, IsValueDependent_MatchesTypeDependent) {3541 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {3542 // FIXME: Fix this test to work with delayed template parsing.3543 return;3544 }3545 3546 EXPECT_TRUE(matches("template<typename T> T f() { return T(); }",3547 expr(isValueDependent())));3548}3549 3550TEST_P(ASTMatchersTest, IsValueDependent_MatchesInstantiationDependent) {3551 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {3552 // FIXME: Fix this test to work with delayed template parsing.3553 return;3554 }3555 3556 EXPECT_TRUE(matches(3557 "template<typename T> void f() { (void) sizeof(sizeof(T() + T())); }",3558 expr(isValueDependent())));3559}3560 3561TEST_P(ASTMatchersTest,3562 IsExplicitTemplateSpecialization_DoesNotMatchPrimaryTemplate) {3563 if (!GetParam().isCXX()) {3564 return;3565 }3566 3567 EXPECT_TRUE(notMatches("template <typename T> class X {};",3568 cxxRecordDecl(isExplicitTemplateSpecialization())));3569 EXPECT_TRUE(notMatches("template <typename T> void f(T t);",3570 functionDecl(isExplicitTemplateSpecialization())));3571}3572 3573TEST_P(3574 ASTMatchersTest,3575 IsExplicitTemplateSpecialization_DoesNotMatchExplicitTemplateInstantiations) {3576 if (!GetParam().isCXX()) {3577 return;3578 }3579 3580 EXPECT_TRUE(3581 notMatches("template <typename T> class X {};"3582 "template class X<int>; extern template class X<long>;",3583 cxxRecordDecl(isExplicitTemplateSpecialization())));3584 EXPECT_TRUE(3585 notMatches("template <typename T> void f(T t) {}"3586 "template void f(int t); extern template void f(long t);",3587 functionDecl(isExplicitTemplateSpecialization())));3588}3589 3590TEST_P(3591 ASTMatchersTest,3592 IsExplicitTemplateSpecialization_DoesNotMatchImplicitTemplateInstantiations) {3593 if (!GetParam().isCXX()) {3594 return;3595 }3596 3597 EXPECT_TRUE(notMatches("template <typename T> class X {}; X<int> x;",3598 cxxRecordDecl(isExplicitTemplateSpecialization())));3599 EXPECT_TRUE(3600 notMatches("template <typename T> void f(T t); void g() { f(10); }",3601 functionDecl(isExplicitTemplateSpecialization())));3602}3603 3604TEST_P(3605 ASTMatchersTest,3606 IsExplicitTemplateSpecialization_MatchesExplicitTemplateSpecializations) {3607 if (!GetParam().isCXX()) {3608 return;3609 }3610 3611 EXPECT_TRUE(matches("template <typename T> class X {};"3612 "template<> class X<int> {};",3613 cxxRecordDecl(isExplicitTemplateSpecialization())));3614 EXPECT_TRUE(matches("template <typename T> void f(T t) {}"3615 "template<> void f(int t) {}",3616 functionDecl(isExplicitTemplateSpecialization())));3617}3618 3619TEST_P(ASTMatchersTest, IsNoReturn) {3620 EXPECT_TRUE(notMatches("void func();", functionDecl(isNoReturn())));3621 EXPECT_TRUE(notMatches("void func() {}", functionDecl(isNoReturn())));3622 3623 EXPECT_TRUE(matches("__attribute__((noreturn)) void func();",3624 functionDecl(isNoReturn())));3625 EXPECT_TRUE(matches("__attribute__((noreturn)) void func() {}",3626 functionDecl(isNoReturn())));3627 3628 EXPECT_TRUE(matches("_Noreturn void func();", functionDecl(isNoReturn())));3629 EXPECT_TRUE(matches("_Noreturn void func() {}", functionDecl(isNoReturn())));3630}3631 3632TEST_P(ASTMatchersTest, IsNoReturn_CXX) {3633 if (!GetParam().isCXX()) {3634 return;3635 }3636 3637 EXPECT_TRUE(3638 notMatches("struct S { void func(); };", functionDecl(isNoReturn())));3639 EXPECT_TRUE(3640 notMatches("struct S { void func() {} };", functionDecl(isNoReturn())));3641 3642 EXPECT_TRUE(notMatches("struct S { static void func(); };",3643 functionDecl(isNoReturn())));3644 EXPECT_TRUE(notMatches("struct S { static void func() {} };",3645 functionDecl(isNoReturn())));3646 3647 EXPECT_TRUE(notMatches("struct S { S(); };", functionDecl(isNoReturn())));3648 EXPECT_TRUE(notMatches("struct S { S() {} };", functionDecl(isNoReturn())));3649 3650 // ---3651 3652 EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) void func(); };",3653 functionDecl(isNoReturn())));3654 EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) void func() {} };",3655 functionDecl(isNoReturn())));3656 3657 EXPECT_TRUE(3658 matches("struct S { __attribute__((noreturn)) static void func(); };",3659 functionDecl(isNoReturn())));3660 EXPECT_TRUE(3661 matches("struct S { __attribute__((noreturn)) static void func() {} };",3662 functionDecl(isNoReturn())));3663 3664 EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) S(); };",3665 functionDecl(isNoReturn())));3666 EXPECT_TRUE(matches("struct S { __attribute__((noreturn)) S() {} };",3667 functionDecl(isNoReturn())));3668}3669 3670TEST_P(ASTMatchersTest, IsNoReturn_CXX11Attribute) {3671 if (!GetParam().isCXX11OrLater()) {3672 return;3673 }3674 3675 EXPECT_TRUE(matches("[[noreturn]] void func();", functionDecl(isNoReturn())));3676 EXPECT_TRUE(3677 matches("[[noreturn]] void func() {}", functionDecl(isNoReturn())));3678 3679 EXPECT_TRUE(matches("struct S { [[noreturn]] void func(); };",3680 functionDecl(isNoReturn())));3681 EXPECT_TRUE(matches("struct S { [[noreturn]] void func() {} };",3682 functionDecl(isNoReturn())));3683 3684 EXPECT_TRUE(matches("struct S { [[noreturn]] static void func(); };",3685 functionDecl(isNoReturn())));3686 EXPECT_TRUE(matches("struct S { [[noreturn]] static void func() {} };",3687 functionDecl(isNoReturn())));3688 3689 EXPECT_TRUE(3690 matches("struct S { [[noreturn]] S(); };", functionDecl(isNoReturn())));3691 EXPECT_TRUE(3692 matches("struct S { [[noreturn]] S() {} };", functionDecl(isNoReturn())));3693}3694 3695TEST_P(ASTMatchersTest, BooleanType) {3696 if (!GetParam().isCXX()) {3697 // FIXME: Add a test for `booleanType()` that does not depend on C++.3698 return;3699 }3700 3701 EXPECT_TRUE(matches("struct S { bool func(); };",3702 cxxMethodDecl(returns(booleanType()))));3703 EXPECT_TRUE(notMatches("struct S { void func(); };",3704 cxxMethodDecl(returns(booleanType()))));3705}3706 3707TEST_P(ASTMatchersTest, VoidType) {3708 if (!GetParam().isCXX()) {3709 // FIXME: Add a test for `voidType()` that does not depend on C++.3710 return;3711 }3712 3713 EXPECT_TRUE(matches("struct S { void func(); };",3714 cxxMethodDecl(returns(voidType()))));3715}3716 3717TEST_P(ASTMatchersTest, RealFloatingPointType) {3718 if (!GetParam().isCXX()) {3719 // FIXME: Add a test for `realFloatingPointType()` that does not depend on3720 // C++.3721 return;3722 }3723 3724 EXPECT_TRUE(matches("struct S { float func(); };",3725 cxxMethodDecl(returns(realFloatingPointType()))));3726 EXPECT_TRUE(notMatches("struct S { int func(); };",3727 cxxMethodDecl(returns(realFloatingPointType()))));3728 EXPECT_TRUE(matches("struct S { long double func(); };",3729 cxxMethodDecl(returns(realFloatingPointType()))));3730}3731 3732TEST_P(ASTMatchersTest, ArrayType) {3733 EXPECT_TRUE(matches("int a[] = {2,3};", arrayType()));3734 EXPECT_TRUE(matches("int a[42];", arrayType()));3735 EXPECT_TRUE(matches("void f(int b) { int a[b]; }", arrayType()));3736 3737 EXPECT_TRUE(notMatches("struct A {}; struct A a[7];",3738 arrayType(hasElementType(builtinType()))));3739 3740 EXPECT_TRUE(matches("int const a[] = { 2, 3 };",3741 qualType(arrayType(hasElementType(builtinType())))));3742 EXPECT_TRUE(matches(3743 "int const a[] = { 2, 3 };",3744 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));3745 EXPECT_TRUE(matches("typedef const int T; T x[] = { 1, 2 };",3746 qualType(isConstQualified(), arrayType())));3747 3748 EXPECT_TRUE(notMatches(3749 "int a[] = { 2, 3 };",3750 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));3751 EXPECT_TRUE(notMatches(3752 "int a[] = { 2, 3 };",3753 qualType(arrayType(hasElementType(isConstQualified(), builtinType())))));3754 EXPECT_TRUE(notMatches("int const a[] = { 2, 3 };",3755 qualType(arrayType(hasElementType(builtinType())),3756 unless(isConstQualified()))));3757 3758 EXPECT_TRUE(3759 matches("int a[2];", constantArrayType(hasElementType(builtinType()))));3760 EXPECT_TRUE(matches("const int a = 0;", qualType(isInteger())));3761}3762 3763TEST_P(ASTMatchersTest, DecayedType) {3764 EXPECT_TRUE(3765 matches("void f(int i[]);",3766 valueDecl(hasType(decayedType(hasDecayedType(pointerType()))))));3767 EXPECT_TRUE(notMatches("int i[7];", decayedType()));3768}3769 3770TEST_P(ASTMatchersTest, ComplexType) {3771 EXPECT_TRUE(matches("_Complex float f;", complexType()));3772 EXPECT_TRUE(3773 matches("_Complex float f;", complexType(hasElementType(builtinType()))));3774 EXPECT_TRUE(notMatches("_Complex float f;",3775 complexType(hasElementType(isInteger()))));3776}3777 3778TEST_P(ASTMatchersTest, IsAnonymous) {3779 if (!GetParam().isCXX()) {3780 return;3781 }3782 3783 EXPECT_TRUE(notMatches("namespace N {}", namespaceDecl(isAnonymous())));3784 EXPECT_TRUE(matches("namespace {}", namespaceDecl(isAnonymous())));3785}3786 3787TEST_P(ASTMatchersTest, InStdNamespace) {3788 if (!GetParam().isCXX()) {3789 return;3790 }3791 3792 EXPECT_TRUE(notMatches("class vector {};"3793 "namespace foo {"3794 " class vector {};"3795 "}"3796 "namespace foo {"3797 " namespace std {"3798 " class vector {};"3799 " }"3800 "}",3801 cxxRecordDecl(hasName("vector"), isInStdNamespace())));3802 3803 EXPECT_TRUE(matches("namespace std {"3804 " class vector {};"3805 "}",3806 cxxRecordDecl(hasName("vector"), isInStdNamespace())));3807 3808 EXPECT_TRUE(matches("namespace std {"3809 " extern \"C++\" class vector {};"3810 "}",3811 cxxRecordDecl(hasName("vector"), isInStdNamespace())));3812}3813 3814TEST_P(ASTMatchersTest, InAnonymousNamespace) {3815 if (!GetParam().isCXX()) {3816 return;3817 }3818 3819 EXPECT_TRUE(3820 notMatches("class vector {};"3821 "namespace foo {"3822 " class vector {};"3823 "}",3824 cxxRecordDecl(hasName("vector"), isInAnonymousNamespace())));3825 3826 EXPECT_TRUE(3827 matches("namespace {"3828 " class vector {};"3829 "}",3830 cxxRecordDecl(hasName("vector"), isInAnonymousNamespace())));3831 3832 EXPECT_TRUE(3833 matches("namespace foo {"3834 " namespace {"3835 " class vector {};"3836 " }"3837 "}",3838 cxxRecordDecl(hasName("vector"), isInAnonymousNamespace())));3839 3840 EXPECT_TRUE(3841 matches("namespace {"3842 " namespace foo {"3843 " class vector {};"3844 " }"3845 "}",3846 cxxRecordDecl(hasName("vector"), isInAnonymousNamespace())));3847}3848 3849TEST_P(ASTMatchersTest, InStdNamespace_CXX11) {3850 if (!GetParam().isCXX11OrLater()) {3851 return;3852 }3853 3854 EXPECT_TRUE(matches("namespace std {"3855 " inline namespace __1 {"3856 " class vector {};"3857 " }"3858 "}",3859 cxxRecordDecl(hasName("vector"), isInStdNamespace())));3860 EXPECT_TRUE(notMatches("namespace std {"3861 " inline namespace __1 {"3862 " inline namespace __fs {"3863 " namespace filesystem {"3864 " inline namespace v1 {"3865 " class path {};"3866 " }"3867 " }"3868 " }"3869 " }"3870 "}",3871 cxxRecordDecl(hasName("path"), isInStdNamespace())));3872 EXPECT_TRUE(3873 matches("namespace std {"3874 " inline namespace __1 {"3875 " inline namespace __fs {"3876 " namespace filesystem {"3877 " inline namespace v1 {"3878 " class path {};"3879 " }"3880 " }"3881 " }"3882 " }"3883 "}",3884 cxxRecordDecl(hasName("path"),3885 hasAncestor(namespaceDecl(hasName("filesystem"),3886 isInStdNamespace())))));3887}3888 3889TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_QualType) {3890 EXPECT_TRUE(matches(3891 "int i = 1;", varDecl(hasType(qualType().bind("type")),3892 hasInitializer(ignoringParenImpCasts(3893 hasType(qualType(equalsBoundNode("type"))))))));3894 EXPECT_TRUE(notMatches("int i = 1.f;",3895 varDecl(hasType(qualType().bind("type")),3896 hasInitializer(ignoringParenImpCasts(hasType(3897 qualType(equalsBoundNode("type"))))))));3898}3899 3900TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_NonMatchingTypes) {3901 EXPECT_TRUE(notMatches(3902 "int i = 1;", varDecl(namedDecl(hasName("i")).bind("name"),3903 hasInitializer(ignoringParenImpCasts(3904 hasType(qualType(equalsBoundNode("type"))))))));3905}3906 3907TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_Stmt) {3908 EXPECT_TRUE(3909 matches("void f() { if(1) {} }",3910 stmt(allOf(ifStmt().bind("if"),3911 hasParent(stmt(has(stmt(equalsBoundNode("if")))))))));3912 3913 EXPECT_TRUE(notMatches(3914 "void f() { if(1) { if (1) {} } }",3915 stmt(allOf(ifStmt().bind("if"), has(stmt(equalsBoundNode("if")))))));3916}3917 3918TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_Decl) {3919 if (!GetParam().isCXX()) {3920 // FIXME: Add a test for `equalsBoundNode()` for declarations that does not3921 // depend on C++.3922 return;3923 }3924 3925 EXPECT_TRUE(matches(3926 "class X { class Y {}; };",3927 decl(allOf(recordDecl(hasName("::X::Y")).bind("record"),3928 hasParent(decl(has(decl(equalsBoundNode("record")))))))));3929 3930 EXPECT_TRUE(notMatches("class X { class Y {}; };",3931 decl(allOf(recordDecl(hasName("::X")).bind("record"),3932 has(decl(equalsBoundNode("record")))))));3933}3934 3935TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_Type) {3936 if (!GetParam().isCXX()) {3937 // FIXME: Add a test for `equalsBoundNode()` for types that does not depend3938 // on C++.3939 return;3940 }3941 EXPECT_TRUE(matches(3942 "class X { int a; int b; };",3943 recordDecl(3944 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),3945 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));3946 3947 EXPECT_TRUE(notMatches(3948 "class X { int a; double b; };",3949 recordDecl(3950 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),3951 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));3952}3953 3954TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_UsingForEachDescendant) {3955 EXPECT_TRUE(matchAndVerifyResultTrue(3956 "int f() {"3957 " if (1) {"3958 " int i = 9;"3959 " }"3960 " int j = 10;"3961 " {"3962 " float k = 9.0;"3963 " }"3964 " return 0;"3965 "}",3966 // Look for variable declarations within functions whose type is the same3967 // as the function return type.3968 functionDecl(3969 returns(qualType().bind("type")),3970 forEachDescendant(varDecl(hasType(qualType(equalsBoundNode("type"))))3971 .bind("decl"))),3972 // Only i and j should match, not k.3973 std::make_unique<VerifyIdIsBoundTo<VarDecl>>("decl", 2)));3974}3975 3976TEST_P(ASTMatchersTest, EqualsBoundNodeMatcher_FiltersMatchedCombinations) {3977 EXPECT_TRUE(matchAndVerifyResultTrue(3978 "void f() {"3979 " int x;"3980 " double d;"3981 " x = d + x - d + x;"3982 "}",3983 functionDecl(3984 hasName("f"), forEachDescendant(varDecl().bind("d")),3985 forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d")))))),3986 std::make_unique<VerifyIdIsBoundTo<VarDecl>>("d", 5)));3987}3988 3989TEST_P(ASTMatchersTest,3990 EqualsBoundNodeMatcher_UnlessDescendantsOfAncestorsMatch) {3991 EXPECT_TRUE(matchAndVerifyResultTrue(3992 "struct StringRef { int size() const; const char* data() const; };"3993 "void f(StringRef v) {"3994 " v.data();"3995 "}",3996 cxxMemberCallExpr(3997 callee(cxxMethodDecl(hasName("data"))),3998 on(declRefExpr(to(3999 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),4000 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(4001 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),4002 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))4003 .bind("data"),4004 std::make_unique<VerifyIdIsBoundTo<Expr>>("data", 1)));4005 4006 EXPECT_FALSE(matches(4007 "struct StringRef { int size() const; const char* data() const; };"4008 "void f(StringRef v) {"4009 " v.data();"4010 " v.size();"4011 "}",4012 cxxMemberCallExpr(4013 callee(cxxMethodDecl(hasName("data"))),4014 on(declRefExpr(to(4015 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),4016 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(4017 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),4018 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))4019 .bind("data")));4020}4021 4022TEST_P(ASTMatchersTest, NullPointerConstant) {4023 EXPECT_TRUE(matches("#define NULL ((void *)0)\n"4024 "void *v1 = NULL;",4025 expr(nullPointerConstant())));4026 EXPECT_TRUE(matches("char *cp = (char *)0;", expr(nullPointerConstant())));4027 EXPECT_TRUE(matches("int *ip = 0;", expr(nullPointerConstant())));4028 EXPECT_FALSE(matches("int i = 0;", expr(nullPointerConstant())));4029}4030 4031TEST_P(ASTMatchersTest, NullPointerConstant_GNUNull) {4032 if (!GetParam().isCXX()) {4033 return;4034 }4035 4036 EXPECT_TRUE(matches("void *p = __null;", expr(nullPointerConstant())));4037}4038 4039TEST_P(ASTMatchersTest, NullPointerConstant_GNUNullInTemplate) {4040 if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {4041 // FIXME: Fix this test to work with delayed template parsing.4042 return;4043 }4044 4045 const char kTest[] = R"(4046 template <typename T>4047 struct MyTemplate {4048 MyTemplate() : field_(__null) {}4049 T* field_;4050 };4051 )";4052 EXPECT_TRUE(matches(kTest, expr(nullPointerConstant())));4053}4054 4055TEST_P(ASTMatchersTest, NullPointerConstant_CXX11Nullptr) {4056 if (!GetParam().isCXX11OrLater()) {4057 return;4058 }4059 4060 EXPECT_TRUE(matches("void *p = nullptr;", expr(nullPointerConstant())));4061}4062 4063TEST_P(ASTMatchersTest, HasExternalFormalLinkage) {4064 EXPECT_TRUE(matches("int a = 0;",4065 namedDecl(hasName("a"), hasExternalFormalLinkage())));4066 EXPECT_TRUE(notMatches("static int a = 0;",4067 namedDecl(hasName("a"), hasExternalFormalLinkage())));4068 EXPECT_TRUE(notMatches("static void f(void) { int a = 0; }",4069 namedDecl(hasName("a"), hasExternalFormalLinkage())));4070 EXPECT_TRUE(notMatches("void f(void) { int a = 0; }",4071 namedDecl(hasName("a"), hasExternalFormalLinkage())));4072}4073 4074TEST_P(ASTMatchersTest, HasExternalFormalLinkage_CXX) {4075 if (!GetParam().isCXX()) {4076 return;4077 }4078 4079 EXPECT_TRUE(notMatches("namespace { int a = 0; }",4080 namedDecl(hasName("a"), hasExternalFormalLinkage())));4081}4082 4083TEST_P(ASTMatchersTest, HasDefaultArgument) {4084 if (!GetParam().isCXX()) {4085 return;4086 }4087 4088 EXPECT_TRUE(4089 matches("void x(int val = 0) {}", parmVarDecl(hasDefaultArgument())));4090 EXPECT_TRUE(4091 notMatches("void x(int val) {}", parmVarDecl(hasDefaultArgument())));4092}4093 4094TEST_P(ASTMatchersTest, IsAtPosition) {4095 EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1))));4096 EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(0))));4097 EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1))));4098 EXPECT_TRUE(notMatches("void x(int val) {}", parmVarDecl(isAtPosition(1))));4099}4100 4101TEST_P(ASTMatchersTest, IsAtPosition_FunctionDecl) {4102 EXPECT_TRUE(matches("void x(int a);", parmVarDecl(isAtPosition(0))));4103 EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(0))));4104 EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(1))));4105 EXPECT_TRUE(notMatches("void x(int val);", parmVarDecl(isAtPosition(1))));4106}4107 4108TEST_P(ASTMatchersTest, IsAtPosition_Lambda) {4109 if (!GetParam().isCXX11OrLater()) {4110 return;4111 }4112 4113 EXPECT_TRUE(4114 matches("void x() { [](int a) {}; }", parmVarDecl(isAtPosition(0))));4115 EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",4116 parmVarDecl(isAtPosition(0))));4117 EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",4118 parmVarDecl(isAtPosition(1))));4119 EXPECT_TRUE(4120 notMatches("void x() { [](int val) {}; }", parmVarDecl(isAtPosition(1))));4121}4122 4123TEST_P(ASTMatchersTest, IsAtPosition_BlockDecl) {4124 EXPECT_TRUE(matchesObjC(4125 "void func() { void (^my_block)(int arg) = ^void(int arg) {}; } ",4126 parmVarDecl(isAtPosition(0))));4127 4128 EXPECT_TRUE(matchesObjC("void func() { void (^my_block)(int x, int y) = "4129 "^void(int x, int y) {}; } ",4130 parmVarDecl(isAtPosition(1))));4131 4132 EXPECT_TRUE(notMatchesObjC(4133 "void func() { void (^my_block)(int arg) = ^void(int arg) {}; } ",4134 parmVarDecl(isAtPosition(1))));4135}4136 4137TEST_P(ASTMatchersTest, IsArray) {4138 if (!GetParam().isCXX()) {4139 return;4140 }4141 4142 EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",4143 cxxNewExpr(isArray())));4144}4145 4146TEST_P(ASTMatchersTest, HasArraySize) {4147 if (!GetParam().isCXX()) {4148 return;4149 }4150 4151 EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",4152 cxxNewExpr(hasArraySize(4153 ignoringParenImpCasts(integerLiteral(equals(10)))))));4154}4155 4156TEST_P(ASTMatchersTest, HasDefinition_MatchesStructDefinition) {4157 if (!GetParam().isCXX()) {4158 return;4159 }4160 4161 EXPECT_TRUE(matches("struct x {};", cxxRecordDecl(hasDefinition())));4162 EXPECT_TRUE(notMatches("struct x;", cxxRecordDecl(hasDefinition())));4163}4164 4165TEST_P(ASTMatchersTest, HasDefinition_MatchesClassDefinition) {4166 if (!GetParam().isCXX()) {4167 return;4168 }4169 4170 EXPECT_TRUE(matches("class x {};", cxxRecordDecl(hasDefinition())));4171 EXPECT_TRUE(notMatches("class x;", cxxRecordDecl(hasDefinition())));4172}4173 4174TEST_P(ASTMatchersTest, HasDefinition_MatchesUnionDefinition) {4175 if (!GetParam().isCXX()) {4176 return;4177 }4178 4179 EXPECT_TRUE(matches("union x {};", cxxRecordDecl(hasDefinition())));4180 EXPECT_TRUE(notMatches("union x;", cxxRecordDecl(hasDefinition())));4181}4182 4183TEST_P(ASTMatchersTest, IsScoped_MatchesScopedEnum) {4184 if (!GetParam().isCXX11OrLater()) {4185 return;4186 }4187 EXPECT_TRUE(matches("enum class X {};", enumDecl(isScoped())));4188}4189 4190TEST_P(ASTMatchersTest, IsScoped_NotMatchesRegularEnum) {4191 EXPECT_TRUE(notMatches("enum E { E1 };", enumDecl(isScoped())));4192}4193 4194TEST_P(ASTMatchersTest, IsStruct) {4195 EXPECT_TRUE(matches("struct S {};", tagDecl(isStruct())));4196}4197 4198TEST_P(ASTMatchersTest, IsUnion) {4199 EXPECT_TRUE(matches("union U {};", tagDecl(isUnion())));4200}4201 4202TEST_P(ASTMatchersTest, IsEnum) {4203 EXPECT_TRUE(matches("enum E { E1 };", tagDecl(isEnum())));4204}4205 4206TEST_P(ASTMatchersTest, IsClass) {4207 if (!GetParam().isCXX()) {4208 return;4209 }4210 4211 EXPECT_TRUE(matches("class C {};", tagDecl(isClass())));4212}4213 4214TEST_P(ASTMatchersTest, HasTrailingReturn_MatchesTrailingReturn) {4215 if (!GetParam().isCXX11OrLater()) {4216 return;4217 }4218 4219 EXPECT_TRUE(matches("auto Y() -> int { return 0; }",4220 functionDecl(hasTrailingReturn())));4221 EXPECT_TRUE(matches("auto X() -> int;", functionDecl(hasTrailingReturn())));4222 EXPECT_TRUE(4223 notMatches("int X() { return 0; }", functionDecl(hasTrailingReturn())));4224 EXPECT_TRUE(notMatches("int X();", functionDecl(hasTrailingReturn())));4225 EXPECT_TRUE(notMatches("void X();", functionDecl(hasTrailingReturn())));4226}4227 4228TEST_P(ASTMatchersTest, HasTrailingReturn_MatchesLambdaTrailingReturn) {4229 if (!GetParam().isCXX11OrLater()) {4230 return;4231 }4232 4233 EXPECT_TRUE(matches(4234 "auto lambda2 = [](double x, double y) -> double {return x + y;};",4235 functionDecl(hasTrailingReturn())));4236 EXPECT_TRUE(4237 notMatches("auto lambda2 = [](double x, double y) {return x + y;};",4238 functionDecl(hasTrailingReturn())));4239}4240 4241TEST_P(ASTMatchersTest, IsAssignmentOperator) {4242 if (!GetParam().isCXX()) {4243 return;4244 }4245 4246 StatementMatcher BinAsgmtOperator = binaryOperator(isAssignmentOperator());4247 StatementMatcher CXXAsgmtOperator =4248 cxxOperatorCallExpr(isAssignmentOperator());4249 4250 EXPECT_TRUE(matches("void x() { int a; a += 1; }", BinAsgmtOperator));4251 EXPECT_TRUE(matches("void x() { int a; a = 2; }", BinAsgmtOperator));4252 EXPECT_TRUE(matches("void x() { int a; a &= 3; }", BinAsgmtOperator));4253 EXPECT_TRUE(matches("struct S { S& operator=(const S&); };"4254 "void x() { S s1, s2; s1 = s2; }",4255 CXXAsgmtOperator));4256 EXPECT_TRUE(4257 notMatches("void x() { int a; if(a == 0) return; }", BinAsgmtOperator));4258}4259 4260TEST_P(ASTMatchersTest, IsComparisonOperator) {4261 if (!GetParam().isCXX()) {4262 return;4263 }4264 4265 StatementMatcher BinCompOperator = binaryOperator(isComparisonOperator());4266 StatementMatcher CXXCompOperator =4267 cxxOperatorCallExpr(isComparisonOperator());4268 4269 EXPECT_TRUE(matches("void x() { int a; a == 1; }", BinCompOperator));4270 EXPECT_TRUE(matches("void x() { int a; a > 2; }", BinCompOperator));4271 EXPECT_TRUE(matches("struct S { bool operator==(const S&); };"4272 "void x() { S s1, s2; bool b1 = s1 == s2; }",4273 CXXCompOperator));4274 EXPECT_TRUE(4275 notMatches("void x() { int a; if(a = 0) return; }", BinCompOperator));4276}4277 4278TEST_P(ASTMatchersTest, isRightFold) {4279 if (!GetParam().isCXX17OrLater()) {4280 return;4281 }4282 4283 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "4284 "return (0 + ... + args); }",4285 cxxFoldExpr(isRightFold())));4286 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "4287 "return (args + ... + 0); }",4288 cxxFoldExpr(isRightFold())));4289 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "4290 "return (... + args); };",4291 cxxFoldExpr(isRightFold())));4292 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "4293 "return (args + ...); };",4294 cxxFoldExpr(isRightFold())));4295}4296 4297TEST_P(ASTMatchersTest, isLeftFold) {4298 if (!GetParam().isCXX17OrLater()) {4299 return;4300 }4301 4302 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "4303 "return (0 + ... + args); }",4304 cxxFoldExpr(isLeftFold())));4305 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "4306 "return (args + ... + 0); }",4307 cxxFoldExpr(isLeftFold())));4308 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "4309 "return (... + args); };",4310 cxxFoldExpr(isLeftFold())));4311 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "4312 "return (args + ...); };",4313 cxxFoldExpr(isLeftFold())));4314}4315 4316TEST_P(ASTMatchersTest, isUnaryFold) {4317 if (!GetParam().isCXX17OrLater()) {4318 return;4319 }4320 4321 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "4322 "return (0 + ... + args); }",4323 cxxFoldExpr(isUnaryFold())));4324 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "4325 "return (args + ... + 0); }",4326 cxxFoldExpr(isUnaryFold())));4327 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "4328 "return (... + args); };",4329 cxxFoldExpr(isUnaryFold())));4330 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "4331 "return (args + ...); };",4332 cxxFoldExpr(isUnaryFold())));4333}4334 4335TEST_P(ASTMatchersTest, isBinaryFold) {4336 if (!GetParam().isCXX17OrLater()) {4337 return;4338 }4339 4340 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "4341 "return (0 + ... + args); }",4342 cxxFoldExpr(isBinaryFold())));4343 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "4344 "return (args + ... + 0); }",4345 cxxFoldExpr(isBinaryFold())));4346 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "4347 "return (... + args); };",4348 cxxFoldExpr(isBinaryFold())));4349 EXPECT_FALSE(matches("template <typename... Args> auto sum(Args... args) { "4350 "return (args + ...); };",4351 cxxFoldExpr(isBinaryFold())));4352}4353 4354TEST_P(ASTMatchersTest, hasOperator) {4355 if (!GetParam().isCXX17OrLater()) {4356 return;4357 }4358 4359 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "4360 "return (0 + ... + args); }",4361 cxxFoldExpr(hasOperatorName("+"))));4362 EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "4363 "return (... + args); };",4364 cxxFoldExpr(hasOperatorName("+"))));4365 4366 EXPECT_FALSE(4367 matches("template <typename... Args> auto multiply(Args... args) { "4368 "return (0 * ... * args); }",4369 cxxFoldExpr(hasOperatorName("+"))));4370 EXPECT_FALSE(4371 matches("template <typename... Args> auto multiply(Args... args) { "4372 "return (... * args); };",4373 cxxFoldExpr(hasOperatorName("+"))));4374}4375 4376TEST_P(ASTMatchersTest, IsMain) {4377 EXPECT_TRUE(matches("int main() {}", functionDecl(isMain())));4378 4379 EXPECT_TRUE(notMatches("int main2() { return 0; }", functionDecl(isMain())));4380}4381 4382TEST_P(ASTMatchersTest, OMPExecutableDirective_IsStandaloneDirective) {4383 auto Matcher = ompExecutableDirective(isStandaloneDirective());4384 4385 StringRef Source0 = R"(4386void x() {4387#pragma omp parallel4388;4389})";4390 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));4391 4392 StringRef Source1 = R"(4393void x() {4394#pragma omp taskyield4395})";4396 EXPECT_TRUE(matchesWithOpenMP(Source1, Matcher));4397}4398 4399TEST_P(ASTMatchersTest, OMPExecutableDirective_HasStructuredBlock) {4400 StringRef Source0 = R"(4401void x() {4402#pragma omp parallel4403;4404})";4405 EXPECT_TRUE(matchesWithOpenMP(4406 Source0, ompExecutableDirective(hasStructuredBlock(nullStmt()))));4407 4408 StringRef Source1 = R"(4409void x() {4410#pragma omp parallel4411{;}4412})";4413 EXPECT_TRUE(notMatchesWithOpenMP(4414 Source1, ompExecutableDirective(hasStructuredBlock(nullStmt()))));4415 EXPECT_TRUE(matchesWithOpenMP(4416 Source1, ompExecutableDirective(hasStructuredBlock(compoundStmt()))));4417 4418 StringRef Source2 = R"(4419void x() {4420#pragma omp taskyield4421{;}4422})";4423 EXPECT_TRUE(notMatchesWithOpenMP(4424 Source2, ompExecutableDirective(hasStructuredBlock(anything()))));4425}4426 4427TEST_P(ASTMatchersTest, OMPExecutableDirective_HasClause) {4428 auto Matcher = ompExecutableDirective(hasAnyClause(anything()));4429 4430 StringRef Source0 = R"(4431void x() {4432;4433})";4434 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));4435 4436 StringRef Source1 = R"(4437void x() {4438#pragma omp parallel4439;4440})";4441 EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));4442 4443 StringRef Source2 = R"(4444void x() {4445#pragma omp parallel default(none)4446;4447})";4448 EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher));4449 4450 StringRef Source3 = R"(4451void x() {4452#pragma omp parallel default(shared)4453;4454})";4455 EXPECT_TRUE(matchesWithOpenMP(Source3, Matcher));4456 4457 StringRef Source4 = R"(4458void x() {4459#pragma omp parallel default(firstprivate)4460;4461})";4462 EXPECT_TRUE(matchesWithOpenMP51(Source4, Matcher));4463 4464 StringRef Source5 = R"(4465void x(int x) {4466#pragma omp parallel num_threads(x)4467;4468})";4469 EXPECT_TRUE(matchesWithOpenMP(Source5, Matcher));4470}4471 4472TEST_P(ASTMatchersTest, OMPDefaultClause_IsNoneKind) {4473 auto Matcher =4474 ompExecutableDirective(hasAnyClause(ompDefaultClause(isNoneKind())));4475 4476 StringRef Source0 = R"(4477void x() {4478;4479})";4480 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));4481 4482 StringRef Source1 = R"(4483void x() {4484#pragma omp parallel4485;4486})";4487 EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));4488 4489 StringRef Source2 = R"(4490void x() {4491#pragma omp parallel default(none)4492;4493})";4494 EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher));4495 4496 StringRef Source3 = R"(4497void x() {4498#pragma omp parallel default(shared)4499;4500})";4501 EXPECT_TRUE(notMatchesWithOpenMP(Source3, Matcher));4502 4503 StringRef Source4 = R"(4504void x(int x) {4505#pragma omp parallel default(firstprivate)4506;4507})";4508 EXPECT_TRUE(notMatchesWithOpenMP51(Source4, Matcher));4509 4510 StringRef Source5 = R"(4511void x(int x) {4512#pragma omp parallel default(private)4513;4514})";4515 EXPECT_TRUE(notMatchesWithOpenMP51(Source5, Matcher));4516 4517 const std::string Source6 = R"(4518void x(int x) {4519#pragma omp parallel num_threads(x)4520;4521})";4522 EXPECT_TRUE(notMatchesWithOpenMP(Source6, Matcher));4523}4524 4525TEST_P(ASTMatchersTest, OMPDefaultClause_IsSharedKind) {4526 auto Matcher =4527 ompExecutableDirective(hasAnyClause(ompDefaultClause(isSharedKind())));4528 4529 StringRef Source0 = R"(4530void x() {4531;4532})";4533 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));4534 4535 StringRef Source1 = R"(4536void x() {4537#pragma omp parallel4538;4539})";4540 EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));4541 4542 StringRef Source2 = R"(4543void x() {4544#pragma omp parallel default(shared)4545;4546})";4547 EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher));4548 4549 StringRef Source3 = R"(4550void x() {4551#pragma omp parallel default(none)4552;4553})";4554 EXPECT_TRUE(notMatchesWithOpenMP(Source3, Matcher));4555 4556 StringRef Source4 = R"(4557void x(int x) {4558#pragma omp parallel default(firstprivate)4559;4560})";4561 EXPECT_TRUE(notMatchesWithOpenMP51(Source4, Matcher));4562 4563 StringRef Source5 = R"(4564void x(int x) {4565#pragma omp parallel default(private)4566;4567})";4568 EXPECT_TRUE(notMatchesWithOpenMP51(Source5, Matcher));4569 4570 const std::string Source6 = R"(4571void x(int x) {4572#pragma omp parallel num_threads(x)4573;4574})";4575 EXPECT_TRUE(notMatchesWithOpenMP(Source6, Matcher));4576}4577 4578TEST(OMPDefaultClause, isFirstPrivateKind) {4579 auto Matcher = ompExecutableDirective(4580 hasAnyClause(ompDefaultClause(isFirstPrivateKind())));4581 4582 const std::string Source0 = R"(4583void x() {4584;4585})";4586 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));4587 4588 const std::string Source1 = R"(4589void x() {4590#pragma omp parallel4591;4592})";4593 EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));4594 4595 const std::string Source2 = R"(4596void x() {4597#pragma omp parallel default(shared)4598;4599})";4600 EXPECT_TRUE(notMatchesWithOpenMP(Source2, Matcher));4601 4602 const std::string Source3 = R"(4603void x() {4604#pragma omp parallel default(none)4605;4606})";4607 EXPECT_TRUE(notMatchesWithOpenMP(Source3, Matcher));4608 4609 const std::string Source4 = R"(4610void x(int x) {4611#pragma omp parallel default(firstprivate)4612;4613})";4614 EXPECT_TRUE(matchesWithOpenMP51(Source4, Matcher));4615 4616 const std::string Source5 = R"(4617void x(int x) {4618#pragma omp parallel default(private)4619;4620})";4621 EXPECT_TRUE(notMatchesWithOpenMP51(Source5, Matcher));4622 4623 const std::string Source6 = R"(4624void x(int x) {4625#pragma omp parallel num_threads(x)4626;4627})";4628 EXPECT_TRUE(notMatchesWithOpenMP(Source6, Matcher));4629}4630 4631TEST(OMPDefaultClause, istPrivateKind) {4632 auto Matcher =4633 ompExecutableDirective(hasAnyClause(ompDefaultClause(isPrivateKind())));4634 4635 const std::string Source0 = R"(4636void x() {4637;4638})";4639 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));4640 4641 const std::string Source1 = R"(4642void x() {4643#pragma omp parallel4644;4645})";4646 EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));4647 4648 const std::string Source2 = R"(4649void x() {4650#pragma omp parallel default(shared)4651;4652})";4653 EXPECT_TRUE(notMatchesWithOpenMP(Source2, Matcher));4654 4655 const std::string Source3 = R"(4656void x() {4657#pragma omp parallel default(none)4658;4659})";4660 EXPECT_TRUE(notMatchesWithOpenMP(Source3, Matcher));4661 4662 const std::string Source4 = R"(4663void x(int x) {4664#pragma omp parallel default(firstprivate)4665;4666})";4667 EXPECT_TRUE(notMatchesWithOpenMP51(Source4, Matcher));4668 4669 const std::string Source5 = R"(4670void x(int x) {4671#pragma omp parallel default(private)4672;4673})";4674 EXPECT_TRUE(matchesWithOpenMP51(Source5, Matcher));4675 4676 const std::string Source6 = R"(4677void x(int x) {4678#pragma omp parallel num_threads(x)4679;4680})";4681 EXPECT_TRUE(notMatchesWithOpenMP(Source6, Matcher));4682}4683 4684TEST_P(ASTMatchersTest, OMPExecutableDirective_IsAllowedToContainClauseKind) {4685 auto Matcher = ompExecutableDirective(4686 isAllowedToContainClauseKind(llvm::omp::OMPC_default));4687 4688 StringRef Source0 = R"(4689void x() {4690;4691})";4692 EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));4693 4694 StringRef Source1 = R"(4695void x() {4696#pragma omp parallel4697;4698})";4699 EXPECT_TRUE(matchesWithOpenMP(Source1, Matcher));4700 4701 StringRef Source2 = R"(4702void x() {4703#pragma omp parallel default(none)4704;4705})";4706 EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher));4707 4708 StringRef Source3 = R"(4709void x() {4710#pragma omp parallel default(shared)4711;4712})";4713 EXPECT_TRUE(matchesWithOpenMP(Source3, Matcher));4714 4715 StringRef Source4 = R"(4716void x() {4717#pragma omp parallel default(firstprivate)4718;4719})";4720 EXPECT_TRUE(matchesWithOpenMP51(Source4, Matcher));4721 4722 StringRef Source5 = R"(4723void x() {4724#pragma omp parallel default(private)4725;4726})";4727 EXPECT_TRUE(matchesWithOpenMP51(Source5, Matcher));4728 4729 StringRef Source6 = R"(4730void x(int x) {4731#pragma omp parallel num_threads(x)4732;4733})";4734 EXPECT_TRUE(matchesWithOpenMP(Source6, Matcher));4735 4736 StringRef Source7 = R"(4737void x() {4738#pragma omp taskyield4739})";4740 EXPECT_TRUE(notMatchesWithOpenMP(Source7, Matcher));4741 4742 StringRef Source8 = R"(4743void x() {4744#pragma omp task4745;4746})";4747 EXPECT_TRUE(matchesWithOpenMP(Source8, Matcher));4748}4749 4750TEST_P(ASTMatchersTest, HasAnyBase_DirectBase) {4751 if (!GetParam().isCXX()) {4752 return;4753 }4754 EXPECT_TRUE(matches(4755 "struct Base {};"4756 "struct ExpectedMatch : Base {};",4757 cxxRecordDecl(hasName("ExpectedMatch"),4758 hasAnyBase(hasType(cxxRecordDecl(hasName("Base")))))));4759}4760 4761TEST_P(ASTMatchersTest, HasAnyBase_IndirectBase) {4762 if (!GetParam().isCXX()) {4763 return;4764 }4765 EXPECT_TRUE(matches(4766 "struct Base {};"4767 "struct Intermediate : Base {};"4768 "struct ExpectedMatch : Intermediate {};",4769 cxxRecordDecl(hasName("ExpectedMatch"),4770 hasAnyBase(hasType(cxxRecordDecl(hasName("Base")))))));4771}4772 4773TEST_P(ASTMatchersTest, HasAnyBase_NoBase) {4774 if (!GetParam().isCXX()) {4775 return;4776 }4777 EXPECT_TRUE(notMatches("struct Foo {};"4778 "struct Bar {};",4779 cxxRecordDecl(hasAnyBase(hasType(cxxRecordDecl())))));4780}4781 4782TEST_P(ASTMatchersTest, HasAnyBase_IsPublic_Public) {4783 if (!GetParam().isCXX()) {4784 return;4785 }4786 EXPECT_TRUE(matches("class Base {};"4787 "class Derived : public Base {};",4788 cxxRecordDecl(hasAnyBase(isPublic()))));4789}4790 4791TEST_P(ASTMatchersTest, HasAnyBase_IsPublic_DefaultAccessSpecifierPublic) {4792 if (!GetParam().isCXX()) {4793 return;4794 }4795 EXPECT_TRUE(matches("class Base {};"4796 "struct Derived : Base {};",4797 cxxRecordDecl(hasAnyBase(isPublic()))));4798}4799 4800TEST_P(ASTMatchersTest, HasAnyBase_IsPublic_Private) {4801 if (!GetParam().isCXX()) {4802 return;4803 }4804 EXPECT_TRUE(notMatches("class Base {};"4805 "class Derived : private Base {};",4806 cxxRecordDecl(hasAnyBase(isPublic()))));4807}4808 4809TEST_P(ASTMatchersTest, HasAnyBase_IsPublic_DefaultAccessSpecifierPrivate) {4810 if (!GetParam().isCXX()) {4811 return;4812 }4813 EXPECT_TRUE(notMatches("class Base {};"4814 "class Derived : Base {};",4815 cxxRecordDecl(hasAnyBase(isPublic()))));4816}4817 4818TEST_P(ASTMatchersTest, HasAnyBase_IsPublic_Protected) {4819 if (!GetParam().isCXX()) {4820 return;4821 }4822 EXPECT_TRUE(notMatches("class Base {};"4823 "class Derived : protected Base {};",4824 cxxRecordDecl(hasAnyBase(isPublic()))));4825}4826 4827TEST_P(ASTMatchersTest, HasAnyBase_IsPrivate_Private) {4828 if (!GetParam().isCXX()) {4829 return;4830 }4831 EXPECT_TRUE(matches("class Base {};"4832 "class Derived : private Base {};",4833 cxxRecordDecl(hasAnyBase(isPrivate()))));4834}4835 4836TEST_P(ASTMatchersTest, HasAnyBase_IsPrivate_DefaultAccessSpecifierPrivate) {4837 if (!GetParam().isCXX()) {4838 return;4839 }4840 EXPECT_TRUE(matches("struct Base {};"4841 "class Derived : Base {};",4842 cxxRecordDecl(hasAnyBase(isPrivate()))));4843}4844 4845TEST_P(ASTMatchersTest, HasAnyBase_IsPrivate_Public) {4846 if (!GetParam().isCXX()) {4847 return;4848 }4849 EXPECT_TRUE(notMatches("class Base {};"4850 "class Derived : public Base {};",4851 cxxRecordDecl(hasAnyBase(isPrivate()))));4852}4853 4854TEST_P(ASTMatchersTest, HasAnyBase_IsPrivate_DefaultAccessSpecifierPublic) {4855 if (!GetParam().isCXX()) {4856 return;4857 }4858 EXPECT_TRUE(notMatches("class Base {};"4859 "struct Derived : Base {};",4860 cxxRecordDecl(hasAnyBase(isPrivate()))));4861}4862 4863TEST_P(ASTMatchersTest, HasAnyBase_IsPrivate_Protected) {4864 if (!GetParam().isCXX()) {4865 return;4866 }4867 EXPECT_TRUE(notMatches("class Base {};"4868 "class Derived : protected Base {};",4869 cxxRecordDecl(hasAnyBase(isPrivate()))));4870}4871 4872TEST_P(ASTMatchersTest, HasAnyBase_IsProtected_Protected) {4873 if (!GetParam().isCXX()) {4874 return;4875 }4876 EXPECT_TRUE(matches("class Base {};"4877 "class Derived : protected Base {};",4878 cxxRecordDecl(hasAnyBase(isProtected()))));4879}4880 4881TEST_P(ASTMatchersTest, HasAnyBase_IsProtected_Public) {4882 if (!GetParam().isCXX()) {4883 return;4884 }4885 EXPECT_TRUE(notMatches("class Base {};"4886 "class Derived : public Base {};",4887 cxxRecordDecl(hasAnyBase(isProtected()))));4888}4889 4890TEST_P(ASTMatchersTest, HasAnyBase_IsProtected_Private) {4891 if (!GetParam().isCXX()) {4892 return;4893 }4894 EXPECT_TRUE(notMatches("class Base {};"4895 "class Derived : private Base {};",4896 cxxRecordDecl(hasAnyBase(isProtected()))));4897}4898 4899TEST_P(ASTMatchersTest, HasAnyBase_IsVirtual_Directly) {4900 if (!GetParam().isCXX()) {4901 return;4902 }4903 EXPECT_TRUE(matches("class Base {};"4904 "class Derived : virtual Base {};",4905 cxxRecordDecl(hasAnyBase(isVirtual()))));4906}4907 4908TEST_P(ASTMatchersTest, HasAnyBase_IsVirtual_Indirectly) {4909 if (!GetParam().isCXX()) {4910 return;4911 }4912 EXPECT_TRUE(4913 matches("class Base {};"4914 "class Intermediate : virtual Base {};"4915 "class Derived : Intermediate {};",4916 cxxRecordDecl(hasName("Derived"), hasAnyBase(isVirtual()))));4917}4918 4919TEST_P(ASTMatchersTest, HasAnyBase_IsVirtual_NoVirtualBase) {4920 if (!GetParam().isCXX()) {4921 return;4922 }4923 EXPECT_TRUE(notMatches("class Base {};"4924 "class Derived : Base {};",4925 cxxRecordDecl(hasAnyBase(isVirtual()))));4926}4927 4928TEST_P(ASTMatchersTest, HasDirectBase) {4929 if (!GetParam().isCXX()) {4930 return;4931 }4932 4933 DeclarationMatcher ClassHasAnyDirectBase =4934 cxxRecordDecl(hasDirectBase(cxxBaseSpecifier()));4935 EXPECT_TRUE(notMatches("class X {};", ClassHasAnyDirectBase));4936 EXPECT_TRUE(matches("class X {}; class Y : X {};", ClassHasAnyDirectBase));4937 EXPECT_TRUE(matches("class X {}; class Y : public virtual X {};",4938 ClassHasAnyDirectBase));4939 4940 EXPECT_TRUE(matches(4941 R"cc(4942 class Base {};4943 class Derived : Base{};4944 )cc",4945 cxxRecordDecl(hasName("Derived"),4946 hasDirectBase(hasType(cxxRecordDecl(hasName("Base")))))));4947 4948 StringRef MultiDerived = R"cc(4949 class Base {};4950 class Base2 {};4951 class Derived : Base, Base2{};4952 )cc";4953 4954 EXPECT_TRUE(matches(4955 MultiDerived,4956 cxxRecordDecl(hasName("Derived"),4957 hasDirectBase(hasType(cxxRecordDecl(hasName("Base")))))));4958 EXPECT_TRUE(matches(4959 MultiDerived,4960 cxxRecordDecl(hasName("Derived"),4961 hasDirectBase(hasType(cxxRecordDecl(hasName("Base2")))))));4962 4963 StringRef Indirect = R"cc(4964 class Base {};4965 class Intermediate : Base {};4966 class Derived : Intermediate{};4967 )cc";4968 4969 EXPECT_TRUE(4970 matches(Indirect, cxxRecordDecl(hasName("Derived"),4971 hasDirectBase(hasType(cxxRecordDecl(4972 hasName("Intermediate")))))));4973 EXPECT_TRUE(notMatches(4974 Indirect,4975 cxxRecordDecl(hasName("Derived"),4976 hasDirectBase(hasType(cxxRecordDecl(hasName("Base")))))));4977}4978 4979TEST_P(ASTMatchersTest, CapturesThis) {4980 if (!GetParam().isCXX11OrLater()) {4981 return;4982 }4983 auto matcher = lambdaExpr(hasAnyCapture(lambdaCapture(capturesThis())));4984 EXPECT_TRUE(matches("class C { int cc; int f() { auto l = [this](){ return "4985 "cc; }; return l(); } };",4986 matcher));4987 EXPECT_TRUE(matches("class C { int cc; int f() { auto l = [=](){ return cc; "4988 "}; return l(); } };",4989 matcher));4990 EXPECT_TRUE(matches("class C { int cc; int f() { auto l = [&](){ return cc; "4991 "}; return l(); } };",4992 matcher));4993 EXPECT_FALSE(matches("class C { int cc; int f() { auto l = [cc](){ return "4994 "cc; }; return l(); } };",4995 matcher));4996 EXPECT_FALSE(matches("class C { int this; int f() { auto l = [this](){ "4997 "return this; }; return l(); } };",4998 matcher));4999}5000 5001TEST_P(ASTMatchersTest, IsImplicit_LambdaCapture) {5002 if (!GetParam().isCXX11OrLater()) {5003 return;5004 }5005 auto matcher = lambdaExpr(hasAnyCapture(5006 lambdaCapture(isImplicit(), capturesVar(varDecl(hasName("cc"))))));5007 EXPECT_TRUE(5008 matches("int main() { int cc; auto f = [&](){ return cc; }; }", matcher));5009 EXPECT_TRUE(5010 matches("int main() { int cc; auto f = [=](){ return cc; }; }", matcher));5011 EXPECT_FALSE(matches("int main() { int cc; auto f = [cc](){ return cc; }; }",5012 matcher));5013}5014 5015} // namespace ast_matchers5016} // namespace clang5017