brintos

brintos / llvm-project-archived public Read only

0
0
Text · 176.9 KiB · 5d45235 Raw
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