brintos

brintos / llvm-project-archived public Read only

0
0
Text · 104.3 KiB · 108b32e Raw
2891 lines · cpp
1//== unittests/ASTMatchers/ASTMatchersNodeTest.cpp - AST matcher unit tests ==//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-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, Decl_CXX) {22  if (!GetParam().isCXX()) {23    // FIXME: Add a test for `decl()` that does not depend on C++.24    return;25  }26  EXPECT_TRUE(notMatches("", decl(usingDecl())));27  EXPECT_TRUE(28      matches("namespace x { class X {}; } using x::X;", decl(usingDecl())));29}30 31TEST_P(ASTMatchersTest, NameableDeclaration_MatchesVariousDecls) {32  DeclarationMatcher NamedX = namedDecl(hasName("X"));33  EXPECT_TRUE(matches("typedef int X;", NamedX));34  EXPECT_TRUE(matches("int X;", NamedX));35  EXPECT_TRUE(matches("void foo() { int X; }", NamedX));36  EXPECT_TRUE(matches("enum X { A, B, C };", NamedX));37 38  EXPECT_TRUE(notMatches("#define X 1", NamedX));39}40 41TEST_P(ASTMatchersTest, NamedDecl_CXX) {42  if (!GetParam().isCXX()) {43    return;44  }45  DeclarationMatcher NamedX = namedDecl(hasName("X"));46  EXPECT_TRUE(matches("class foo { virtual void X(); };", NamedX));47  EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", NamedX));48  EXPECT_TRUE(matches("namespace X { }", NamedX));49}50 51TEST_P(ASTMatchersTest, MatchesNameRE) {52  DeclarationMatcher NamedX = namedDecl(matchesName("::X"));53  EXPECT_TRUE(matches("typedef int Xa;", NamedX));54  EXPECT_TRUE(matches("int Xb;", NamedX));55  EXPECT_TRUE(matches("void foo() { int Xgh; }", NamedX));56  EXPECT_TRUE(matches("enum X { A, B, C };", NamedX));57 58  EXPECT_TRUE(notMatches("#define Xkl 1", NamedX));59 60  DeclarationMatcher StartsWithNo = namedDecl(matchesName("::no"));61  EXPECT_TRUE(matches("int no_foo;", StartsWithNo));62 63  DeclarationMatcher Abc = namedDecl(matchesName("a.*b.*c"));64  EXPECT_TRUE(matches("int abc;", Abc));65  EXPECT_TRUE(matches("int aFOObBARc;", Abc));66  EXPECT_TRUE(notMatches("int cab;", Abc));67  EXPECT_TRUE(matches("int cabc;", Abc));68 69  DeclarationMatcher StartsWithK = namedDecl(matchesName(":k[^:]*$"));70  EXPECT_TRUE(matches("int k;", StartsWithK));71  EXPECT_TRUE(matches("int kAbc;", StartsWithK));72}73 74TEST_P(ASTMatchersTest, MatchesNameRE_CXX) {75  if (!GetParam().isCXX()) {76    return;77  }78  DeclarationMatcher NamedX = namedDecl(matchesName("::X"));79  EXPECT_TRUE(matches("class foo { virtual void Xc(); };", NamedX));80  EXPECT_TRUE(matches("void foo() try { } catch(int Xdef) { }", NamedX));81  EXPECT_TRUE(matches("namespace Xij { }", NamedX));82 83  DeclarationMatcher StartsWithNo = namedDecl(matchesName("::no"));84  EXPECT_TRUE(matches("class foo { virtual void nobody(); };", StartsWithNo));85 86  DeclarationMatcher StartsWithK = namedDecl(matchesName(":k[^:]*$"));87  EXPECT_TRUE(matches("namespace x { int kTest; }", StartsWithK));88  EXPECT_TRUE(matches("class C { int k; };", StartsWithK));89  EXPECT_TRUE(notMatches("class C { int ckc; };", StartsWithK));90  EXPECT_TRUE(notMatches("int K;", StartsWithK));91 92  DeclarationMatcher StartsWithKIgnoreCase =93      namedDecl(matchesName(":k[^:]*$", llvm::Regex::IgnoreCase));94  EXPECT_TRUE(matches("int k;", StartsWithKIgnoreCase));95  EXPECT_TRUE(matches("int K;", StartsWithKIgnoreCase));96}97 98TEST_P(ASTMatchersTest, DeclarationMatcher_MatchClass) {99  if (!GetParam().isCXX()) {100    return;101  }102 103  DeclarationMatcher ClassX = recordDecl(recordDecl(hasName("X")));104  EXPECT_TRUE(matches("class X;", ClassX));105  EXPECT_TRUE(matches("class X {};", ClassX));106  EXPECT_TRUE(matches("template<class T> class X {};", ClassX));107  EXPECT_TRUE(notMatches("", ClassX));108}109 110TEST_P(ASTMatchersTest, TranslationUnitDecl) {111  if (!GetParam().isCXX()) {112    // FIXME: Add a test for `translationUnitDecl()` that does not depend on113    // C++.114    return;115  }116  StringRef Code = "int MyVar1;\n"117                   "namespace NameSpace {\n"118                   "int MyVar2;\n"119                   "}  // namespace NameSpace\n";120  EXPECT_TRUE(matches(121      Code, varDecl(hasName("MyVar1"), hasDeclContext(translationUnitDecl()))));122  EXPECT_FALSE(matches(123      Code, varDecl(hasName("MyVar2"), hasDeclContext(translationUnitDecl()))));124  EXPECT_TRUE(matches(125      Code,126      varDecl(hasName("MyVar2"),127              hasDeclContext(decl(hasDeclContext(translationUnitDecl()))))));128}129 130TEST_P(ASTMatchersTest, LinkageSpecDecl) {131  if (!GetParam().isCXX()) {132    return;133  }134  EXPECT_TRUE(matches("extern \"C\" { void foo() {}; }", linkageSpecDecl()));135  EXPECT_TRUE(notMatches("void foo() {};", linkageSpecDecl()));136}137 138TEST_P(ASTMatchersTest, ClassTemplateDecl_DoesNotMatchClass) {139  if (!GetParam().isCXX()) {140    return;141  }142  DeclarationMatcher ClassX = classTemplateDecl(hasName("X"));143  EXPECT_TRUE(notMatches("class X;", ClassX));144  EXPECT_TRUE(notMatches("class X {};", ClassX));145}146 147TEST_P(ASTMatchersTest, ClassTemplateDecl_MatchesClassTemplate) {148  if (!GetParam().isCXX()) {149    return;150  }151  DeclarationMatcher ClassX = classTemplateDecl(hasName("X"));152  EXPECT_TRUE(matches("template<typename T> class X {};", ClassX));153  EXPECT_TRUE(matches("class Z { template<class T> class X {}; };", ClassX));154}155 156TEST_P(ASTMatchersTest,157       ClassTemplateDecl_DoesNotMatchClassTemplateExplicitSpecialization) {158  if (!GetParam().isCXX()) {159    return;160  }161  EXPECT_TRUE(notMatches(162      "template<typename T> class X { };"163      "template<> class X<int> { int a; };",164      classTemplateDecl(hasName("X"), hasDescendant(fieldDecl(hasName("a"))))));165}166 167TEST_P(ASTMatchersTest,168       ClassTemplateDecl_DoesNotMatchClassTemplatePartialSpecialization) {169  if (!GetParam().isCXX()) {170    return;171  }172  EXPECT_TRUE(notMatches(173      "template<typename T, typename U> class X { };"174      "template<typename T> class X<T, int> { int a; };",175      classTemplateDecl(hasName("X"), hasDescendant(fieldDecl(hasName("a"))))));176}177 178TEST(ASTMatchersTestCUDA, CUDAKernelCallExpr) {179  EXPECT_TRUE(matchesWithCuda("__global__ void f() { }"180                              "void g() { f<<<1, 2>>>(); }",181                              cudaKernelCallExpr()));182  EXPECT_TRUE(notMatchesWithCuda("void f() {}", cudaKernelCallExpr()));183}184 185TEST(ASTMatchersTestCUDA, HasAttrCUDA) {186  EXPECT_TRUE(matchesWithCuda("__attribute__((device)) void f() {}",187                              hasAttr(clang::attr::CUDADevice)));188  EXPECT_FALSE(notMatchesWithCuda("__attribute__((global)) void f() {}",189                                  hasAttr(clang::attr::CUDAGlobal)));190}191 192TEST_P(ASTMatchersTest, ExportDecl) {193  if (!GetParam().isCXX20OrLater()) {194    return;195  }196  const std::string moduleHeader = "module;export module ast_matcher_test;";197  EXPECT_TRUE(matches(moduleHeader + "export void foo();",198                      exportDecl(has(functionDecl()))));199  EXPECT_TRUE(matches(moduleHeader + "export { void foo(); int v; }",200                      exportDecl(has(functionDecl()))));201  EXPECT_TRUE(matches(moduleHeader + "export { void foo(); int v; }",202                      exportDecl(has(varDecl()))));203  EXPECT_TRUE(matches(moduleHeader + "export namespace aa { void foo(); }",204                      exportDecl(has(namespaceDecl()))));205}206 207TEST_P(ASTMatchersTest, ValueDecl) {208  if (!GetParam().isCXX()) {209    // FIXME: Fix this test in non-C++ language modes.210    return;211  }212  EXPECT_TRUE(matches("enum EnumType { EnumValue };",213                      valueDecl(hasType(asString("enum EnumType")))));214  EXPECT_TRUE(matches("void FunctionDecl();",215                      valueDecl(hasType(asString("void (void)")))));216}217 218TEST_P(ASTMatchersTest, FriendDecl) {219  if (!GetParam().isCXX()) {220    return;221  }222  EXPECT_TRUE(matches("class Y { friend class X; };",223                      friendDecl(hasType(asString("class X")))));224  EXPECT_TRUE(matches("class Y { friend class X; };",225                      friendDecl(hasType(recordDecl(hasName("X"))))));226 227  EXPECT_TRUE(matches("class Y { friend void f(); };",228                      functionDecl(hasName("f"), hasParent(friendDecl()))));229}230 231TEST_P(ASTMatchersTest, EnumDecl_DoesNotMatchClasses) {232  if (!GetParam().isCXX()) {233    return;234  }235  EXPECT_TRUE(notMatches("class X {};", enumDecl(hasName("X"))));236}237 238TEST_P(ASTMatchersTest, EnumDecl_MatchesEnums) {239  if (!GetParam().isCXX()) {240    // FIXME: Fix this test in non-C++ language modes.241    return;242  }243  EXPECT_TRUE(matches("enum X {};", enumDecl(hasName("X"))));244}245 246TEST_P(ASTMatchersTest, EnumConstantDecl) {247  if (!GetParam().isCXX()) {248    // FIXME: Fix this test in non-C++ language modes.249    return;250  }251  DeclarationMatcher Matcher = enumConstantDecl(hasName("A"));252  EXPECT_TRUE(matches("enum X{ A };", Matcher));253  EXPECT_TRUE(notMatches("enum X{ B };", Matcher));254  EXPECT_TRUE(notMatches("enum X {};", Matcher));255}256 257TEST_P(ASTMatchersTest, TagDecl) {258  if (!GetParam().isCXX()) {259    // FIXME: Fix this test in non-C++ language modes.260    return;261  }262  EXPECT_TRUE(matches("struct X {};", tagDecl(hasName("X"))));263  EXPECT_TRUE(matches("union U {};", tagDecl(hasName("U"))));264  EXPECT_TRUE(matches("enum E {};", tagDecl(hasName("E"))));265}266 267TEST_P(ASTMatchersTest, TagDecl_CXX) {268  if (!GetParam().isCXX()) {269    return;270  }271  EXPECT_TRUE(matches("class C {};", tagDecl(hasName("C"))));272}273 274TEST_P(ASTMatchersTest, UnresolvedLookupExpr) {275  if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {276    // FIXME: Fix this test to work with delayed template parsing.277    return;278  }279 280  EXPECT_TRUE(matches("template<typename T>"281                      "T foo() { T a; return a; }"282                      "template<typename T>"283                      "void bar() {"284                      "  foo<T>();"285                      "}",286                      unresolvedLookupExpr()));287}288 289TEST_P(ASTMatchersTest, UsesADL) {290  if (!GetParam().isCXX()) {291    return;292  }293 294  StatementMatcher ADLMatch = callExpr(usesADL());295  StatementMatcher ADLMatchOper = cxxOperatorCallExpr(usesADL());296  StringRef NS_Str = R"cpp(297  namespace NS {298    struct X {};299    void f(X);300    void operator+(X, X);301  }302  struct MyX {};303  void f(...);304  void operator+(MyX, MyX);305)cpp";306 307  auto MkStr = [&](StringRef Body) {308    return (NS_Str + "void test_fn() { " + Body + " }").str();309  };310 311  EXPECT_TRUE(matches(MkStr("NS::X x; f(x);"), ADLMatch));312  EXPECT_TRUE(notMatches(MkStr("NS::X x; NS::f(x);"), ADLMatch));313  EXPECT_TRUE(notMatches(MkStr("MyX x; f(x);"), ADLMatch));314  EXPECT_TRUE(notMatches(MkStr("NS::X x; using NS::f; f(x);"), ADLMatch));315 316  // Operator call expressions317  EXPECT_TRUE(matches(MkStr("NS::X x; x + x;"), ADLMatch));318  EXPECT_TRUE(matches(MkStr("NS::X x; x + x;"), ADLMatchOper));319  EXPECT_TRUE(notMatches(MkStr("MyX x; x + x;"), ADLMatch));320  EXPECT_TRUE(notMatches(MkStr("MyX x; x + x;"), ADLMatchOper));321  EXPECT_TRUE(matches(MkStr("NS::X x; operator+(x, x);"), ADLMatch));322  EXPECT_TRUE(notMatches(MkStr("NS::X x; NS::operator+(x, x);"), ADLMatch));323}324 325TEST_P(ASTMatchersTest, CallExpr_CXX) {326  if (!GetParam().isCXX()) {327    // FIXME: Add a test for `callExpr()` that does not depend on C++.328    return;329  }330  // FIXME: Do we want to overload Call() to directly take331  // Matcher<Decl>, too?332  StatementMatcher MethodX =333      callExpr(hasDeclaration(cxxMethodDecl(hasName("x"))));334 335  EXPECT_TRUE(matches("class Y { void x() { x(); } };", MethodX));336  EXPECT_TRUE(notMatches("class Y { void x() {} };", MethodX));337 338  StatementMatcher MethodOnY =339      cxxMemberCallExpr(on(hasType(recordDecl(hasName("Y")))));340 341  EXPECT_TRUE(matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",342                      MethodOnY));343  EXPECT_TRUE(matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",344                      MethodOnY));345  EXPECT_TRUE(notMatches(346      "class Y { public: void x(); }; void z(Y *&y) { y->x(); }", MethodOnY));347  EXPECT_TRUE(notMatches(348      "class Y { public: void x(); }; void z(Y y[]) { y->x(); }", MethodOnY));349  EXPECT_TRUE(notMatches(350      "class Y { public: void x(); }; void z() { Y *y; y->x(); }", MethodOnY));351 352  StatementMatcher MethodOnYPointer =353      cxxMemberCallExpr(on(hasType(pointsTo(recordDecl(hasName("Y"))))));354 355  EXPECT_TRUE(356      matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",357              MethodOnYPointer));358  EXPECT_TRUE(359      matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",360              MethodOnYPointer));361  EXPECT_TRUE(362      matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",363              MethodOnYPointer));364  EXPECT_TRUE(365      notMatches("class Y { public: void x(); }; void z() { Y y; y.x(); }",366                 MethodOnYPointer));367  EXPECT_TRUE(368      notMatches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",369                 MethodOnYPointer));370}371 372TEST_P(ASTMatchersTest, LambdaExpr) {373  if (!GetParam().isCXX11OrLater()) {374    return;375  }376  EXPECT_TRUE(matches("auto f = [] (int i) { return i; };", lambdaExpr()));377}378 379TEST_P(ASTMatchersTest, CXXForRangeStmt) {380  EXPECT_TRUE(381      notMatches("void f() { for (int i; i<5; ++i); }", cxxForRangeStmt()));382}383 384TEST_P(ASTMatchersTest, CXXForRangeStmt_CXX11) {385  if (!GetParam().isCXX11OrLater()) {386    return;387  }388  EXPECT_TRUE(matches("int as[] = { 1, 2, 3 };"389                      "void f() { for (auto &a : as); }",390                      cxxForRangeStmt()));391}392 393TEST_P(ASTMatchersTest, SubstNonTypeTemplateParmExpr) {394  if (!GetParam().isCXX()) {395    return;396  }397  EXPECT_FALSE(matches("template<int N>\n"398                       "struct A {  static const int n = 0; };\n"399                       "struct B : public A<42> {};",400                       traverse(TK_AsIs, substNonTypeTemplateParmExpr())));401  EXPECT_TRUE(matches("template<int N>\n"402                      "struct A {  static const int n = N; };\n"403                      "struct B : public A<42> {};",404                      traverse(TK_AsIs, substNonTypeTemplateParmExpr())));405}406 407TEST_P(ASTMatchersTest, NonTypeTemplateParmDecl) {408  if (!GetParam().isCXX()) {409    return;410  }411  EXPECT_TRUE(matches("template <int N> void f();",412                      nonTypeTemplateParmDecl(hasName("N"))));413  EXPECT_TRUE(414      notMatches("template <typename T> void f();", nonTypeTemplateParmDecl()));415}416 417TEST_P(ASTMatchersTest, TemplateTypeParmDecl) {418  if (!GetParam().isCXX()) {419    return;420  }421  EXPECT_TRUE(matches("template <typename T> void f();",422                      templateTypeParmDecl(hasName("T"))));423  EXPECT_TRUE(notMatches("template <int N> void f();", templateTypeParmDecl()));424}425 426TEST_P(ASTMatchersTest, TemplateTemplateParmDecl) {427  if (!GetParam().isCXX())428    return;429  EXPECT_TRUE(matches("template <template <typename> class Z> void f();",430                      templateTemplateParmDecl(hasName("Z"))));431  EXPECT_TRUE(notMatches("template <typename, int> void f();",432                         templateTemplateParmDecl()));433}434 435TEST_P(ASTMatchersTest, UserDefinedLiteral) {436  if (!GetParam().isCXX11OrLater()) {437    return;438  }439  EXPECT_TRUE(matches("constexpr char operator \"\" _inc (const char i) {"440                      "  return i + 1;"441                      "}"442                      "char c = 'a'_inc;",443                      userDefinedLiteral()));444}445 446TEST_P(ASTMatchersTest, FlowControl) {447  EXPECT_TRUE(matches("void f() { while(1) { break; } }", breakStmt()));448  EXPECT_TRUE(matches("void f() { while(1) { continue; } }", continueStmt()));449  EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", gotoStmt()));450  EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}",451                      labelStmt(hasDeclaration(labelDecl(hasName("FOO"))))));452  EXPECT_TRUE(matches("void f() { FOO: ; void *ptr = &&FOO; goto *ptr; }",453                      addrLabelExpr()));454  EXPECT_TRUE(matches("void f() { return; }", returnStmt()));455}456 457TEST_P(ASTMatchersTest, CXXOperatorCallExpr) {458  if (!GetParam().isCXX()) {459    return;460  }461 462  StatementMatcher OpCall = cxxOperatorCallExpr();463  // Unary operator464  EXPECT_TRUE(matches("class Y { }; "465                      "bool operator!(Y x) { return false; }; "466                      "Y y; bool c = !y;",467                      OpCall));468  // No match -- special operators like "new", "delete"469  // FIXME: operator new takes size_t, for which we need stddef.h, for which470  // we need to figure out include paths in the test.471  // EXPECT_TRUE(NotMatches("#include <stddef.h>\n"472  //             "class Y { }; "473  //             "void *operator new(size_t size) { return 0; } "474  //             "Y *y = new Y;", OpCall));475  EXPECT_TRUE(notMatches("class Y { }; "476                         "void operator delete(void *p) { } "477                         "void a() {Y *y = new Y; delete y;}",478                         OpCall));479  // Binary operator480  EXPECT_TRUE(matches("class Y { }; "481                      "bool operator&&(Y x, Y y) { return true; }; "482                      "Y a; Y b; bool c = a && b;",483                      OpCall));484  // No match -- normal operator, not an overloaded one.485  EXPECT_TRUE(notMatches("bool x = true, y = true; bool t = x && y;", OpCall));486  EXPECT_TRUE(notMatches("int t = 5 << 2;", OpCall));487}488 489TEST_P(ASTMatchersTest, FoldExpr) {490  if (!GetParam().isCXX() || !GetParam().isCXX17OrLater()) {491    return;492  }493 494  EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "495                      "return (0 + ... + args); }",496                      cxxFoldExpr()));497  EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "498                      "return (args + ...); }",499                      cxxFoldExpr()));500}501 502TEST_P(ASTMatchersTest, ThisPointerType) {503  if (!GetParam().isCXX()) {504    return;505  }506 507  StatementMatcher MethodOnY = traverse(508      TK_AsIs, cxxMemberCallExpr(thisPointerType(recordDecl(hasName("Y")))));509 510  EXPECT_TRUE(matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",511                      MethodOnY));512  EXPECT_TRUE(matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",513                      MethodOnY));514  EXPECT_TRUE(matches(515      "class Y { public: void x(); }; void z(Y *&y) { y->x(); }", MethodOnY));516  EXPECT_TRUE(matches(517      "class Y { public: void x(); }; void z(Y y[]) { y->x(); }", MethodOnY));518  EXPECT_TRUE(matches(519      "class Y { public: void x(); }; void z() { Y *y; y->x(); }", MethodOnY));520 521  EXPECT_TRUE(matches("class Y {"522                      "  public: virtual void x();"523                      "};"524                      "class X : public Y {"525                      "  public: virtual void x();"526                      "};"527                      "void z() { X *x; x->Y::x(); }",528                      MethodOnY));529}530 531TEST_P(ASTMatchersTest, DeclRefExpr) {532  if (!GetParam().isCXX()) {533    // FIXME: Add a test for `declRefExpr()` that does not depend on C++.534    return;535  }536  StatementMatcher Reference = declRefExpr(to(varDecl(hasInitializer(537      cxxMemberCallExpr(thisPointerType(recordDecl(hasName("Y"))))))));538 539  EXPECT_TRUE(matches("class Y {"540                      " public:"541                      "  bool x() const;"542                      "};"543                      "void z(const Y &y) {"544                      "  bool b = y.x();"545                      "  if (b) {}"546                      "}",547                      Reference));548 549  EXPECT_TRUE(notMatches("class Y {"550                         " public:"551                         "  bool x() const;"552                         "};"553                         "void z(const Y &y) {"554                         "  bool b = y.x();"555                         "}",556                         Reference));557}558 559TEST_P(ASTMatchersTest, DependentScopeDeclRefExpr) {560  if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {561    // FIXME: Fix this test to work with delayed template parsing.562    return;563  }564 565  EXPECT_TRUE(matches("template <class T> class X : T { void f() { T::v; } };",566                      dependentScopeDeclRefExpr()));567 568  EXPECT_TRUE(569      matches("template <typename T> struct S { static T Foo; };"570              "template <typename T> void declToImport() { (void)S<T>::Foo; }",571              dependentScopeDeclRefExpr()));572}573 574TEST_P(ASTMatchersTest, CXXMemberCallExpr) {575  if (!GetParam().isCXX()) {576    return;577  }578  StatementMatcher CallOnVariableY =579      cxxMemberCallExpr(on(declRefExpr(to(varDecl(hasName("y"))))));580 581  EXPECT_TRUE(matches("class Y { public: void x() { Y y; y.x(); } };",582                      CallOnVariableY));583  EXPECT_TRUE(matches("class Y { public: void x() const { Y y; y.x(); } };",584                      CallOnVariableY));585  EXPECT_TRUE(matches("class Y { public: void x(); };"586                      "class X : public Y { void z() { X y; y.x(); } };",587                      CallOnVariableY));588  EXPECT_TRUE(matches("class Y { public: void x(); };"589                      "class X : public Y { void z() { X *y; y->x(); } };",590                      CallOnVariableY));591  EXPECT_TRUE(notMatches(592      "class Y { public: void x(); };"593      "class X : public Y { void z() { unsigned long y; ((X*)y)->x(); } };",594      CallOnVariableY));595}596 597TEST_P(ASTMatchersTest, UnaryExprOrTypeTraitExpr) {598  EXPECT_TRUE(599      matches("void x() { int a = sizeof(a); }", unaryExprOrTypeTraitExpr()));600}601 602TEST_P(ASTMatchersTest, AlignOfExpr) {603  EXPECT_TRUE(604      notMatches("void x() { int a = sizeof(a); }", alignOfExpr(anything())));605  // FIXME: Uncomment once alignof is enabled.606  // EXPECT_TRUE(matches("void x() { int a = alignof(a); }",607  //                     unaryExprOrTypeTraitExpr()));608  // EXPECT_TRUE(notMatches("void x() { int a = alignof(a); }",609  //                        sizeOfExpr()));610}611 612TEST_P(ASTMatchersTest, MemberExpr_DoesNotMatchClasses) {613  if (!GetParam().isCXX()) {614    return;615  }616  EXPECT_TRUE(notMatches("class Y { void x() {} };", memberExpr()));617  EXPECT_TRUE(notMatches("class Y { void x() {} };", unresolvedMemberExpr()));618  EXPECT_TRUE(619      notMatches("class Y { void x() {} };", cxxDependentScopeMemberExpr()));620}621 622TEST_P(ASTMatchersTest, MemberExpr_MatchesMemberFunctionCall) {623  if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {624    // FIXME: Fix this test to work with delayed template parsing.625    return;626  }627  EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpr()));628  EXPECT_TRUE(matches("class Y { template <class T> void x() { x<T>(); } };",629                      unresolvedMemberExpr()));630  EXPECT_TRUE(matches("template <class T> void x() { T t; t.f(); }",631                      cxxDependentScopeMemberExpr()));632}633 634TEST_P(ASTMatchersTest, MemberExpr_MatchesVariable) {635  if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) {636    // FIXME: Fix this test to work with delayed template parsing.637    return;638  }639  EXPECT_TRUE(640      matches("class Y { void x() { this->y; } int y; };", memberExpr()));641  EXPECT_TRUE(matches("class Y { void x() { y; } int y; };", memberExpr()));642  EXPECT_TRUE(643      matches("class Y { void x() { Y y; y.y; } int y; };", memberExpr()));644  EXPECT_TRUE(matches("template <class T>"645                      "class X : T { void f() { this->T::v; } };",646                      cxxDependentScopeMemberExpr()));647  EXPECT_TRUE(matches("template <class T> class X : T { void f() { T::v; } };",648                      dependentScopeDeclRefExpr()));649  EXPECT_TRUE(matches("template <class T> void x() { T t; t.v; }",650                      cxxDependentScopeMemberExpr()));651}652 653TEST_P(ASTMatchersTest, MemberExpr_MatchesStaticVariable) {654  if (!GetParam().isCXX()) {655    return;656  }657  EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",658                      memberExpr()));659  EXPECT_TRUE(660      notMatches("class Y { void x() { y; } static int y; };", memberExpr()));661  EXPECT_TRUE(notMatches("class Y { void x() { Y::y; } static int y; };",662                         memberExpr()));663}664 665TEST_P(ASTMatchersTest, FunctionDecl) {666  StatementMatcher CallFunctionF = callExpr(callee(functionDecl(hasName("f"))));667 668  EXPECT_TRUE(matches("void f() { f(); }", CallFunctionF));669  EXPECT_TRUE(notMatches("void f() { }", CallFunctionF));670 671  EXPECT_TRUE(notMatches("void f(int);", functionDecl(isVariadic())));672  EXPECT_TRUE(notMatches("void f();", functionDecl(isVariadic())));673  EXPECT_TRUE(matches("void f(int, ...);", functionDecl(parameterCountIs(1))));674}675 676TEST_P(ASTMatchersTest, FunctionDecl_C) {677  if (!GetParam().isC()) {678    return;679  }680  EXPECT_TRUE(notMatches("void f();", functionDecl(isVariadic())));681  EXPECT_TRUE(matches("void f();", functionDecl(parameterCountIs(0))));682}683 684TEST_P(ASTMatchersTest, FunctionDecl_CXX) {685  if (!GetParam().isCXX()) {686    return;687  }688 689  StatementMatcher CallFunctionF = callExpr(callee(functionDecl(hasName("f"))));690 691  if (!GetParam().hasDelayedTemplateParsing()) {692    // FIXME: Fix this test to work with delayed template parsing.693    // Dependent contexts, but a non-dependent call.694    EXPECT_TRUE(695        matches("void f(); template <int N> void g() { f(); }", CallFunctionF));696    EXPECT_TRUE(697        matches("void f(); template <int N> struct S { void g() { f(); } };",698                CallFunctionF));699  }700 701  // Dependent calls don't match.702  EXPECT_TRUE(703      notMatches("void f(int); template <typename T> void g(T t) { f(t); }",704                 CallFunctionF));705  EXPECT_TRUE(706      notMatches("void f(int);"707                 "template <typename T> struct S { void g(T t) { f(t); } };",708                 CallFunctionF));709 710  EXPECT_TRUE(matches("void f(...);", functionDecl(isVariadic())));711  EXPECT_TRUE(matches("void f(...);", functionDecl(parameterCountIs(0))));712}713 714TEST_P(ASTMatchersTest, FunctionDecl_CXX11) {715  if (!GetParam().isCXX11OrLater()) {716    return;717  }718 719  EXPECT_TRUE(notMatches("template <typename... Ts> void f(Ts...);",720                         functionDecl(isVariadic())));721}722 723TEST_P(ASTMatchersTest,724       FunctionTemplateDecl_MatchesFunctionTemplateDeclarations) {725  if (!GetParam().isCXX()) {726    return;727  }728  EXPECT_TRUE(matches("template <typename T> void f(T t) {}",729                      functionTemplateDecl(hasName("f"))));730}731 732TEST_P(ASTMatchersTest, FunctionTemplate_DoesNotMatchFunctionDeclarations) {733  EXPECT_TRUE(734      notMatches("void f(double d);", functionTemplateDecl(hasName("f"))));735  EXPECT_TRUE(736      notMatches("void f(int t) {}", functionTemplateDecl(hasName("f"))));737}738 739TEST_P(ASTMatchersTest,740       FunctionTemplateDecl_DoesNotMatchFunctionTemplateSpecializations) {741  if (!GetParam().isCXX()) {742    return;743  }744  EXPECT_TRUE(notMatches(745      "void g(); template <typename T> void f(T t) {}"746      "template <> void f(int t) { g(); }",747      functionTemplateDecl(hasName("f"), hasDescendant(declRefExpr(to(748                                             functionDecl(hasName("g"))))))));749}750 751TEST_P(ASTMatchersTest, ClassTemplateSpecializationDecl) {752  if (!GetParam().isCXX()) {753    return;754  }755  EXPECT_TRUE(matches("template<typename T> struct A {};"756                      "template<> struct A<int> {};",757                      classTemplateSpecializationDecl()));758  EXPECT_TRUE(matches("template<typename T> struct A {}; A<int> a;",759                      classTemplateSpecializationDecl()));760  EXPECT_TRUE(notMatches("template<typename T> struct A {};",761                         classTemplateSpecializationDecl()));762}763 764TEST_P(ASTMatchersTest, DeclaratorDecl) {765  EXPECT_TRUE(matches("int x;", declaratorDecl()));766  EXPECT_TRUE(notMatches("struct A {};", declaratorDecl()));767}768 769TEST_P(ASTMatchersTest, DeclaratorDecl_CXX) {770  if (!GetParam().isCXX()) {771    return;772  }773  EXPECT_TRUE(notMatches("class A {};", declaratorDecl()));774}775 776TEST_P(ASTMatchersTest, ParmVarDecl) {777  EXPECT_TRUE(matches("void f(int x);", parmVarDecl()));778  EXPECT_TRUE(notMatches("void f();", parmVarDecl()));779}780 781TEST_P(ASTMatchersTest, StaticAssertDecl) {782  if (!GetParam().isCXX11OrLater())783    return;784 785  EXPECT_TRUE(matches("static_assert(true, \"\");", staticAssertDecl()));786  EXPECT_TRUE(787      notMatches("constexpr bool staticassert(bool B, const char *M) "788                 "{ return true; };\n void f() { staticassert(true, \"\"); }",789                 staticAssertDecl()));790}791 792TEST_P(ASTMatchersTest, Matcher_ConstructorCall) {793  if (!GetParam().isCXX()) {794    return;795  }796 797  StatementMatcher Constructor = traverse(TK_AsIs, cxxConstructExpr());798 799  EXPECT_TRUE(800      matches("class X { public: X(); }; void x() { X x; }", Constructor));801  EXPECT_TRUE(matches("class X { public: X(); }; void x() { X x = X(); }",802                      Constructor));803  EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x = 0; }",804                      Constructor));805  EXPECT_TRUE(matches("class X {}; void x(int) { X x; }", Constructor));806}807 808TEST_P(ASTMatchersTest, Match_ConstructorInitializers) {809  if (!GetParam().isCXX()) {810    return;811  }812  EXPECT_TRUE(matches("class C { int i; public: C(int ii) : i(ii) {} };",813                      cxxCtorInitializer(forField(hasName("i")))));814}815 816TEST_P(ASTMatchersTest, Matcher_ThisExpr) {817  if (!GetParam().isCXX()) {818    return;819  }820  EXPECT_TRUE(821      matches("struct X { int a; int f () { return a; } };", cxxThisExpr()));822  EXPECT_TRUE(823      notMatches("struct X { int f () { int a; return a; } };", cxxThisExpr()));824}825 826TEST_P(ASTMatchersTest, Matcher_BindTemporaryExpression) {827  if (!GetParam().isCXX()) {828    return;829  }830 831  StatementMatcher TempExpression = traverse(TK_AsIs, cxxBindTemporaryExpr());832 833  StringRef ClassString = "class string { public: string(); ~string(); }; ";834 835  EXPECT_TRUE(matches(836      ClassString + "string GetStringByValue();"837                    "void FunctionTakesString(string s);"838                    "void run() { FunctionTakesString(GetStringByValue()); }",839      TempExpression));840 841  EXPECT_TRUE(notMatches(ClassString +842                             "string* GetStringPointer(); "843                             "void FunctionTakesStringPtr(string* s);"844                             "void run() {"845                             "  string* s = GetStringPointer();"846                             "  FunctionTakesStringPtr(GetStringPointer());"847                             "  FunctionTakesStringPtr(s);"848                             "}",849                         TempExpression));850 851  EXPECT_TRUE(notMatches("class no_dtor {};"852                         "no_dtor GetObjByValue();"853                         "void ConsumeObj(no_dtor param);"854                         "void run() { ConsumeObj(GetObjByValue()); }",855                         TempExpression));856}857 858TEST_P(ASTMatchersTest, MaterializeTemporaryExpr_MatchesTemporaryCXX11CXX14) {859  if (GetParam().Language != Lang_CXX11 && GetParam().Language != Lang_CXX14) {860    return;861  }862 863  StatementMatcher TempExpression =864      traverse(TK_AsIs, materializeTemporaryExpr());865 866  EXPECT_TRUE(matches("class string { public: string(); }; "867                      "string GetStringByValue();"868                      "void FunctionTakesString(string s);"869                      "void run() { FunctionTakesString(GetStringByValue()); }",870                      TempExpression));871}872 873TEST_P(ASTMatchersTest, MaterializeTemporaryExpr_MatchesTemporary) {874  if (!GetParam().isCXX()) {875    return;876  }877 878  StringRef ClassString = "class string { public: string(); int length(); }; ";879  StatementMatcher TempExpression =880      traverse(TK_AsIs, materializeTemporaryExpr());881 882  EXPECT_TRUE(notMatches(ClassString +883                             "string* GetStringPointer(); "884                             "void FunctionTakesStringPtr(string* s);"885                             "void run() {"886                             "  string* s = GetStringPointer();"887                             "  FunctionTakesStringPtr(GetStringPointer());"888                             "  FunctionTakesStringPtr(s);"889                             "}",890                         TempExpression));891 892  EXPECT_TRUE(matches(ClassString +893                          "string GetStringByValue();"894                          "void run() { int k = GetStringByValue().length(); }",895                      TempExpression));896 897  EXPECT_TRUE(notMatches(ClassString + "string GetStringByValue();"898                                       "void run() { GetStringByValue(); }",899                         TempExpression));900}901 902TEST_P(ASTMatchersTest, Matcher_NewExpression) {903  if (!GetParam().isCXX()) {904    return;905  }906 907  StatementMatcher New = cxxNewExpr();908 909  EXPECT_TRUE(matches("class X { public: X(); }; void x() { new X; }", New));910  EXPECT_TRUE(matches("class X { public: X(); }; void x() { new X(); }", New));911  EXPECT_TRUE(912      matches("class X { public: X(int); }; void x() { new X(0); }", New));913  EXPECT_TRUE(matches("class X {}; void x(int) { new X; }", New));914}915 916TEST_P(ASTMatchersTest, Matcher_DeleteExpression) {917  if (!GetParam().isCXX()) {918    return;919  }920  EXPECT_TRUE(921      matches("struct A {}; void f(A* a) { delete a; }", cxxDeleteExpr()));922}923 924TEST_P(ASTMatchersTest, Matcher_NoexceptExpression) {925  if (!GetParam().isCXX11OrLater()) {926    return;927  }928  StatementMatcher NoExcept = cxxNoexceptExpr();929  EXPECT_TRUE(matches("void foo(); bool bar = noexcept(foo());", NoExcept));930  EXPECT_TRUE(931      matches("void foo() noexcept; bool bar = noexcept(foo());", NoExcept));932  EXPECT_TRUE(notMatches("void foo() noexcept;", NoExcept));933  EXPECT_TRUE(notMatches("void foo() noexcept(0+1);", NoExcept));934  EXPECT_TRUE(matches("void foo() noexcept(noexcept(1+1));", NoExcept));935}936 937TEST_P(ASTMatchersTest, Matcher_DefaultArgument) {938  if (!GetParam().isCXX()) {939    return;940  }941  StatementMatcher Arg = cxxDefaultArgExpr();942  EXPECT_TRUE(matches("void x(int, int = 0) { int y; x(y); }", Arg));943  EXPECT_TRUE(944      matches("class X { void x(int, int = 0) { int y; x(y); } };", Arg));945  EXPECT_TRUE(notMatches("void x(int, int = 0) { int y; x(y, 0); }", Arg));946}947 948TEST_P(ASTMatchersTest, StringLiteral) {949  StatementMatcher Literal = stringLiteral();950  EXPECT_TRUE(matches("const char *s = \"string\";", Literal));951  // with escaped characters952  EXPECT_TRUE(matches("const char *s = \"\x05five\";", Literal));953  // no matching -- though the data type is the same, there is no string literal954  EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));955}956 957TEST_P(ASTMatchersTest, StringLiteral_CXX) {958  if (!GetParam().isCXX()) {959    return;960  }961  EXPECT_TRUE(matches("const wchar_t *s = L\"string\";", stringLiteral()));962}963 964TEST_P(ASTMatchersTest, CharacterLiteral) {965  EXPECT_TRUE(matches("const char c = 'c';", characterLiteral()));966  EXPECT_TRUE(notMatches("const char c = 0x1;", characterLiteral()));967}968 969TEST_P(ASTMatchersTest, CharacterLiteral_CXX) {970  if (!GetParam().isCXX()) {971    return;972  }973  // wide character974  EXPECT_TRUE(matches("const char c = L'c';", characterLiteral()));975  // wide character, Hex encoded, NOT MATCHED!976  EXPECT_TRUE(notMatches("const wchar_t c = 0x2126;", characterLiteral()));977}978 979TEST_P(ASTMatchersTest, IntegerLiteral) {980  StatementMatcher HasIntLiteral = integerLiteral();981  EXPECT_TRUE(matches("int i = 10;", HasIntLiteral));982  EXPECT_TRUE(matches("int i = 0x1AB;", HasIntLiteral));983  EXPECT_TRUE(matches("int i = 10L;", HasIntLiteral));984  EXPECT_TRUE(matches("int i = 10U;", HasIntLiteral));985 986  // Non-matching cases (character literals, float and double)987  EXPECT_TRUE(notMatches("int i = L'a';",988                         HasIntLiteral)); // this is actually a character989  // literal cast to int990  EXPECT_TRUE(notMatches("int i = 'a';", HasIntLiteral));991  EXPECT_TRUE(notMatches("int i = 1e10;", HasIntLiteral));992  EXPECT_TRUE(notMatches("int i = 10.0;", HasIntLiteral));993 994  // Negative integers.995  EXPECT_TRUE(996      matches("int i = -10;",997              unaryOperator(hasOperatorName("-"),998                            hasUnaryOperand(integerLiteral(equals(10))))));999}1000 1001TEST_P(ASTMatchersTest, FloatLiteral) {1002  StatementMatcher HasFloatLiteral = floatLiteral();1003  EXPECT_TRUE(matches("float i = 10.0;", HasFloatLiteral));1004  EXPECT_TRUE(matches("float i = 10.0f;", HasFloatLiteral));1005  EXPECT_TRUE(matches("double i = 10.0;", HasFloatLiteral));1006  EXPECT_TRUE(matches("double i = 10.0L;", HasFloatLiteral));1007  EXPECT_TRUE(matches("double i = 1e10;", HasFloatLiteral));1008  EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0))));1009  EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0f))));1010  EXPECT_TRUE(1011      matches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(5.0)))));1012 1013  EXPECT_TRUE(notMatches("float i = 10;", HasFloatLiteral));1014  EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0))));1015  EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0f))));1016  EXPECT_TRUE(1017      notMatches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(6.0)))));1018}1019 1020TEST_P(ASTMatchersTest, FixedPointLiterals) {1021  StatementMatcher HasFixedPointLiteral = fixedPointLiteral();1022  EXPECT_TRUE(matchesWithFixedpoint("_Fract i = 0.25r;", HasFixedPointLiteral));1023  EXPECT_TRUE(1024      matchesWithFixedpoint("_Fract i = 0.25hr;", HasFixedPointLiteral));1025  EXPECT_TRUE(1026      matchesWithFixedpoint("_Fract i = 0.25uhr;", HasFixedPointLiteral));1027  EXPECT_TRUE(1028      matchesWithFixedpoint("_Fract i = 0.25ur;", HasFixedPointLiteral));1029  EXPECT_TRUE(1030      matchesWithFixedpoint("_Fract i = 0.25lr;", HasFixedPointLiteral));1031  EXPECT_TRUE(1032      matchesWithFixedpoint("_Fract i = 0.25ulr;", HasFixedPointLiteral));1033  EXPECT_TRUE(matchesWithFixedpoint("_Accum i = 1.25k;", HasFixedPointLiteral));1034  EXPECT_TRUE(1035      matchesWithFixedpoint("_Accum i = 1.25hk;", HasFixedPointLiteral));1036  EXPECT_TRUE(1037      matchesWithFixedpoint("_Accum i = 1.25uhk;", HasFixedPointLiteral));1038  EXPECT_TRUE(1039      matchesWithFixedpoint("_Accum i = 1.25uk;", HasFixedPointLiteral));1040  EXPECT_TRUE(1041      matchesWithFixedpoint("_Accum i = 1.25lk;", HasFixedPointLiteral));1042  EXPECT_TRUE(1043      matchesWithFixedpoint("_Accum i = 1.25ulk;", HasFixedPointLiteral));1044  EXPECT_TRUE(matchesWithFixedpoint("_Accum decexp1 = 1.575e1k;",1045                                    HasFixedPointLiteral));1046  EXPECT_TRUE(1047      matchesWithFixedpoint("_Accum hex = 0x1.25fp2k;", HasFixedPointLiteral));1048  EXPECT_TRUE(matchesWithFixedpoint("_Sat long _Fract i = 0.25r;",1049                                    HasFixedPointLiteral));1050  EXPECT_TRUE(matchesWithFixedpoint("_Sat short _Accum i = 256.0k;",1051                                    HasFixedPointLiteral));1052  EXPECT_TRUE(matchesWithFixedpoint(1053      "_Accum i = 256.0k;",1054      fixedPointLiteral(equals(llvm::APInt(32, 0x800000, true)))));1055  EXPECT_TRUE(matchesWithFixedpoint(1056      "_Fract i = 0.25ulr;",1057      fixedPointLiteral(equals(llvm::APInt(32, 0x40000000, false)))));1058  EXPECT_TRUE(matchesWithFixedpoint(1059      "_Fract i = 0.5hr;",1060      fixedPointLiteral(equals(llvm::APInt(8, 0x40, true)))));1061 1062  EXPECT_TRUE(1063      notMatchesWithFixedpoint("short _Accum i = 2u;", HasFixedPointLiteral));1064  EXPECT_TRUE(1065      notMatchesWithFixedpoint("short _Accum i = 2;", HasFixedPointLiteral));1066  EXPECT_TRUE(1067      notMatchesWithFixedpoint("_Accum i = 1.25;", HasFixedPointLiteral));1068  EXPECT_TRUE(notMatchesWithFixedpoint("_Accum i = (double)(1.25 *  4.5i);",1069                                       HasFixedPointLiteral));1070  EXPECT_TRUE(notMatchesWithFixedpoint(1071      "_Accum i = 256.0k;",1072      fixedPointLiteral(equals(llvm::APInt(32, 0x800001, true)))));1073  EXPECT_TRUE(notMatchesWithFixedpoint(1074      "_Fract i = 0.25ulr;",1075      fixedPointLiteral(equals(llvm::APInt(32, 0x40000001, false)))));1076  EXPECT_TRUE(notMatchesWithFixedpoint(1077      "_Fract i = 0.5hr;",1078      fixedPointLiteral(equals(llvm::APInt(8, 0x41, true)))));1079}1080 1081TEST_P(ASTMatchersTest, CXXNullPtrLiteralExpr) {1082  if (!GetParam().isCXX11OrLater()) {1083    return;1084  }1085  EXPECT_TRUE(matches("int* i = nullptr;", cxxNullPtrLiteralExpr()));1086}1087 1088TEST_P(ASTMatchersTest, ChooseExpr) {1089  EXPECT_TRUE(matches("void f() { (void)__builtin_choose_expr(1, 2, 3); }",1090                      chooseExpr()));1091}1092 1093TEST_P(ASTMatchersTest, ConvertVectorExpr) {1094  EXPECT_TRUE(matches(1095      "typedef double vector4double __attribute__((__vector_size__(32)));"1096      "typedef float  vector4float  __attribute__((__vector_size__(16)));"1097      "vector4float vf;"1098      "void f() { (void)__builtin_convertvector(vf, vector4double); }",1099      convertVectorExpr()));1100  EXPECT_TRUE(notMatches("void f() { (void)__builtin_choose_expr(1, 2, 3); }",1101                         convertVectorExpr()));1102}1103 1104TEST_P(ASTMatchersTest, GNUNullExpr) {1105  if (!GetParam().isCXX()) {1106    return;1107  }1108  EXPECT_TRUE(matches("int* i = __null;", gnuNullExpr()));1109}1110 1111TEST_P(ASTMatchersTest, GenericSelectionExpr) {1112  EXPECT_TRUE(matches("void f() { (void)_Generic(1, int: 1, float: 2.0); }",1113                      genericSelectionExpr()));1114}1115 1116TEST_P(ASTMatchersTest, AtomicExpr) {1117  EXPECT_TRUE(matches("void foo() { int *ptr; __atomic_load_n(ptr, 1); }",1118                      atomicExpr()));1119}1120 1121TEST_P(ASTMatchersTest, Initializers_C99) {1122  if (!GetParam().isC99OrLater()) {1123    return;1124  }1125  EXPECT_TRUE(matches(1126      "void foo() { struct point { double x; double y; };"1127      "  struct point ptarray[10] = "1128      "      { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }",1129      initListExpr(hasSyntacticForm(initListExpr(1130          has(designatedInitExpr(designatorCountIs(2),1131                                 hasDescendant(floatLiteral(equals(1.0))),1132                                 hasDescendant(integerLiteral(equals(2))))),1133          has(designatedInitExpr(designatorCountIs(2),1134                                 hasDescendant(floatLiteral(equals(2.0))),1135                                 hasDescendant(integerLiteral(equals(2))))),1136          has(designatedInitExpr(1137              designatorCountIs(2), hasDescendant(floatLiteral(equals(1.0))),1138              hasDescendant(integerLiteral(equals(0))))))))));1139}1140 1141TEST_P(ASTMatchersTest, Initializers_CXX) {1142  if (GetParam().Language != Lang_CXX03) {1143    // FIXME: Make this test pass with other C++ standard versions.1144    return;1145  }1146  EXPECT_TRUE(matches(1147      "void foo() { struct point { double x; double y; };"1148      "  struct point ptarray[10] = "1149      "      { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }",1150      initListExpr(1151          has(cxxConstructExpr(requiresZeroInitialization())),1152          has(initListExpr(1153              hasType(asString("struct point")), has(floatLiteral(equals(1.0))),1154              has(implicitValueInitExpr(hasType(asString("double")))))),1155          has(initListExpr(hasType(asString("struct point")),1156                           has(floatLiteral(equals(2.0))),1157                           has(floatLiteral(equals(1.0))))))));1158}1159 1160TEST_P(ASTMatchersTest, ParenListExpr) {1161  if (!GetParam().isCXX()) {1162    return;1163  }1164  EXPECT_TRUE(1165      matches("template<typename T> class foo { void bar() { foo X(*this); } };"1166              "template class foo<int>;",1167              varDecl(hasInitializer(parenListExpr(has(unaryOperator()))))));1168}1169 1170TEST_P(ASTMatchersTest, StmtExpr) {1171  EXPECT_TRUE(matches("void declToImport() { int C = ({int X=4; X;}); }",1172                      varDecl(hasInitializer(stmtExpr()))));1173}1174 1175TEST_P(ASTMatchersTest, PredefinedExpr) {1176  // __func__ expands as StringLiteral("foo")1177  EXPECT_TRUE(matches("void foo() { __func__; }",1178                      predefinedExpr(hasType(asString("const char[4]")),1179                                     has(stringLiteral()))));1180}1181 1182TEST_P(ASTMatchersTest, FileScopeAsmDecl) {1183  EXPECT_TRUE(matches("__asm(\"nop\");", fileScopeAsmDecl()));1184  EXPECT_TRUE(1185      notMatches("void f() { __asm(\"mov al, 2\"); }", fileScopeAsmDecl()));1186}1187 1188TEST_P(ASTMatchersTest, AsmStatement) {1189  EXPECT_TRUE(matches("void foo() { __asm(\"mov al, 2\"); }", asmStmt()));1190}1191 1192TEST_P(ASTMatchersTest, HasConditionVariableStatement) {1193  if (!GetParam().isCXX()) {1194    // FIXME: Add a test for `hasConditionVariableStatement()` that does not1195    // depend on C++.1196    return;1197  }1198 1199  StatementMatcher IfCondition =1200      ifStmt(hasConditionVariableStatement(declStmt()));1201 1202  EXPECT_TRUE(matches("void x() { if (int* a = 0) {} }", IfCondition));1203  EXPECT_TRUE(notMatches("void x() { if (true) {} }", IfCondition));1204  EXPECT_TRUE(notMatches("void x() { int x; if ((x = 42)) {} }", IfCondition));1205 1206  StatementMatcher SwitchCondition =1207      switchStmt(hasConditionVariableStatement(declStmt()));1208 1209  EXPECT_TRUE(matches("void x() { switch (int a = 0) {} }", SwitchCondition));1210  if (GetParam().isCXX17OrLater()) {1211    EXPECT_TRUE(1212        notMatches("void x() { switch (int a = 0; a) {} }", SwitchCondition));1213  }1214 1215  StatementMatcher ForCondition =1216      forStmt(hasConditionVariableStatement(declStmt()));1217 1218  EXPECT_TRUE(matches("void x() { for (; int a = 0; ) {} }", ForCondition));1219  EXPECT_TRUE(notMatches("void x() { for (int a = 0; ; ) {} }", ForCondition));1220 1221  EXPECT_TRUE(matches("void x() { while (int a = 0) {} }",1222                      whileStmt(hasConditionVariableStatement(declStmt()))));1223}1224 1225TEST_P(ASTMatchersTest, HasCondition) {1226  if (!GetParam().isCXX()) {1227    // FIXME: Add a test for `hasCondition()` that does not depend on C++.1228    return;1229  }1230 1231  StatementMatcher Condition =1232      ifStmt(hasCondition(cxxBoolLiteral(equals(true))));1233 1234  EXPECT_TRUE(matches("void x() { if (true) {} }", Condition));1235  EXPECT_TRUE(notMatches("void x() { if (false) {} }", Condition));1236  EXPECT_TRUE(notMatches("void x() { bool a = true; if (a) {} }", Condition));1237  EXPECT_TRUE(notMatches("void x() { if (true || false) {} }", Condition));1238  EXPECT_TRUE(notMatches("void x() { if (1) {} }", Condition));1239}1240 1241TEST_P(ASTMatchersTest, ConditionalOperator) {1242  if (!GetParam().isCXX()) {1243    // FIXME: Add a test for `conditionalOperator()` that does not depend on1244    // C++.1245    return;1246  }1247 1248  StatementMatcher Conditional =1249      conditionalOperator(hasCondition(cxxBoolLiteral(equals(true))),1250                          hasTrueExpression(cxxBoolLiteral(equals(false))));1251 1252  EXPECT_TRUE(matches("void x() { true ? false : true; }", Conditional));1253  EXPECT_TRUE(notMatches("void x() { false ? false : true; }", Conditional));1254  EXPECT_TRUE(notMatches("void x() { true ? true : false; }", Conditional));1255 1256  StatementMatcher ConditionalFalse =1257      conditionalOperator(hasFalseExpression(cxxBoolLiteral(equals(false))));1258 1259  EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));1260  EXPECT_TRUE(1261      notMatches("void x() { true ? false : true; }", ConditionalFalse));1262 1263  EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));1264  EXPECT_TRUE(1265      notMatches("void x() { true ? false : true; }", ConditionalFalse));1266}1267 1268TEST_P(ASTMatchersTest, BinaryConditionalOperator) {1269  if (!GetParam().isCXX()) {1270    // FIXME: This test should work in non-C++ language modes.1271    return;1272  }1273 1274  StatementMatcher AlwaysOne = traverse(1275      TK_AsIs, binaryConditionalOperator(1276                   hasCondition(implicitCastExpr(has(opaqueValueExpr(1277                       hasSourceExpression((integerLiteral(equals(1)))))))),1278                   hasFalseExpression(integerLiteral(equals(0)))));1279 1280  EXPECT_TRUE(matches("void x() { 1 ?: 0; }", AlwaysOne));1281 1282  StatementMatcher FourNotFive = binaryConditionalOperator(1283      hasTrueExpression(1284          opaqueValueExpr(hasSourceExpression((integerLiteral(equals(4)))))),1285      hasFalseExpression(integerLiteral(equals(5))));1286 1287  EXPECT_TRUE(matches("void x() { 4 ?: 5; }", FourNotFive));1288}1289 1290TEST_P(ASTMatchersTest, ArraySubscriptExpr) {1291  EXPECT_TRUE(1292      matches("int i[2]; void f() { i[1] = 1; }", arraySubscriptExpr()));1293  EXPECT_TRUE(notMatches("int i; void f() { i = 1; }", arraySubscriptExpr()));1294}1295 1296TEST_P(ASTMatchersTest, ForStmt) {1297  EXPECT_TRUE(matches("void f() { for(;;); }", forStmt()));1298  EXPECT_TRUE(matches("void f() { if(1) for(;;); }", forStmt()));1299}1300 1301TEST_P(ASTMatchersTest, ForStmt_CXX11) {1302  if (!GetParam().isCXX11OrLater()) {1303    return;1304  }1305  EXPECT_TRUE(notMatches("int as[] = { 1, 2, 3 };"1306                         "void f() { for (auto &a : as); }",1307                         forStmt()));1308}1309 1310TEST_P(ASTMatchersTest, ForStmt_NoFalsePositives) {1311  EXPECT_TRUE(notMatches("void f() { ; }", forStmt()));1312  EXPECT_TRUE(notMatches("void f() { if(1); }", forStmt()));1313}1314 1315TEST_P(ASTMatchersTest, CompoundStatement) {1316  EXPECT_TRUE(notMatches("void f();", compoundStmt()));1317  EXPECT_TRUE(matches("void f() {}", compoundStmt()));1318  EXPECT_TRUE(matches("void f() {{}}", compoundStmt()));1319}1320 1321TEST_P(ASTMatchersTest, CompoundStatement_DoesNotMatchEmptyStruct) {1322  if (!GetParam().isCXX()) {1323    // FIXME: Add a similar test that does not depend on C++.1324    return;1325  }1326  // It's not a compound statement just because there's "{}" in the source1327  // text. This is an AST search, not grep.1328  EXPECT_TRUE(notMatches("namespace n { struct S {}; }", compoundStmt()));1329  EXPECT_TRUE(1330      matches("namespace n { struct S { void f() {{}} }; }", compoundStmt()));1331}1332 1333TEST_P(ASTMatchersTest, CastExpr_MatchesExplicitCasts) {1334  EXPECT_TRUE(matches("void *p = (void *)(&p);", castExpr()));1335}1336 1337TEST_P(ASTMatchersTest, CastExpr_MatchesExplicitCasts_CXX) {1338  if (!GetParam().isCXX()) {1339    return;1340  }1341  EXPECT_TRUE(matches("char *p = reinterpret_cast<char *>(&p);", castExpr()));1342  EXPECT_TRUE(matches("char q, *p = const_cast<char *>(&q);", castExpr()));1343  EXPECT_TRUE(matches("char c = char(0);", castExpr()));1344}1345 1346TEST_P(ASTMatchersTest, CastExpression_MatchesImplicitCasts) {1347  // This test creates an implicit cast from int to char.1348  EXPECT_TRUE(matches("char c = 0;", traverse(TK_AsIs, castExpr())));1349  // This test creates an implicit cast from lvalue to rvalue.1350  EXPECT_TRUE(matches("void f() { char c = 0, d = c; }",1351                      traverse(TK_AsIs, castExpr())));1352}1353 1354TEST_P(ASTMatchersTest, CastExpr_DoesNotMatchNonCasts) {1355  if (GetParam().isC()) {1356    // This does have a cast in C1357    EXPECT_TRUE(matches("char c = '0';", implicitCastExpr()));1358  } else {1359    EXPECT_TRUE(notMatches("char c = '0';", castExpr()));1360  }1361  EXPECT_TRUE(notMatches("int i = (0);", castExpr()));1362  EXPECT_TRUE(notMatches("int i = 0;", castExpr()));1363}1364 1365TEST_P(ASTMatchersTest, CastExpr_DoesNotMatchNonCasts_CXX) {1366  if (!GetParam().isCXX()) {1367    return;1368  }1369  EXPECT_TRUE(notMatches("char c, &q = c;", castExpr()));1370}1371 1372TEST_P(ASTMatchersTest, CXXReinterpretCastExpr) {1373  if (!GetParam().isCXX()) {1374    return;1375  }1376  EXPECT_TRUE(matches("char* p = reinterpret_cast<char*>(&p);",1377                      cxxReinterpretCastExpr()));1378}1379 1380TEST_P(ASTMatchersTest, CXXReinterpretCastExpr_DoesNotMatchOtherCasts) {1381  if (!GetParam().isCXX()) {1382    return;1383  }1384  EXPECT_TRUE(notMatches("char* p = (char*)(&p);", cxxReinterpretCastExpr()));1385  EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",1386                         cxxReinterpretCastExpr()));1387  EXPECT_TRUE(notMatches("void* p = static_cast<void*>(&p);",1388                         cxxReinterpretCastExpr()));1389  EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"1390                         "B b;"1391                         "D* p = dynamic_cast<D*>(&b);",1392                         cxxReinterpretCastExpr()));1393}1394 1395TEST_P(ASTMatchersTest, CXXFunctionalCastExpr_MatchesSimpleCase) {1396  if (!GetParam().isCXX()) {1397    return;1398  }1399  StringRef foo_class = "class Foo { public: Foo(const char*); };";1400  EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",1401                      cxxFunctionalCastExpr()));1402}1403 1404TEST_P(ASTMatchersTest, CXXFunctionalCastExpr_DoesNotMatchOtherCasts) {1405  if (!GetParam().isCXX()) {1406    return;1407  }1408  StringRef FooClass = "class Foo { public: Foo(const char*); };";1409  EXPECT_TRUE(1410      notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",1411                 cxxFunctionalCastExpr()));1412  EXPECT_TRUE(notMatches(FooClass + "void r() { Foo f = \"hello world\"; }",1413                         cxxFunctionalCastExpr()));1414}1415 1416TEST_P(ASTMatchersTest, CXXDynamicCastExpr) {1417  if (!GetParam().isCXX()) {1418    return;1419  }1420  EXPECT_TRUE(matches("struct B { virtual ~B() {} }; struct D : B {};"1421                      "B b;"1422                      "D* p = dynamic_cast<D*>(&b);",1423                      cxxDynamicCastExpr()));1424}1425 1426TEST_P(ASTMatchersTest, CXXStaticCastExpr_MatchesSimpleCase) {1427  if (!GetParam().isCXX()) {1428    return;1429  }1430  EXPECT_TRUE(matches("void* p(static_cast<void*>(&p));", cxxStaticCastExpr()));1431}1432 1433TEST_P(ASTMatchersTest, CXXStaticCastExpr_DoesNotMatchOtherCasts) {1434  if (!GetParam().isCXX()) {1435    return;1436  }1437  EXPECT_TRUE(notMatches("char* p = (char*)(&p);", cxxStaticCastExpr()));1438  EXPECT_TRUE(1439      notMatches("char q, *p = const_cast<char*>(&q);", cxxStaticCastExpr()));1440  EXPECT_TRUE(notMatches("void* p = reinterpret_cast<char*>(&p);",1441                         cxxStaticCastExpr()));1442  EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"1443                         "B b;"1444                         "D* p = dynamic_cast<D*>(&b);",1445                         cxxStaticCastExpr()));1446}1447 1448TEST_P(ASTMatchersTest, CStyleCastExpr_MatchesSimpleCase) {1449  EXPECT_TRUE(matches("int i = (int) 2.2f;", cStyleCastExpr()));1450}1451 1452TEST_P(ASTMatchersTest, CStyleCastExpr_DoesNotMatchOtherCasts) {1453  if (!GetParam().isCXX()) {1454    return;1455  }1456  EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);"1457                         "char q, *r = const_cast<char*>(&q);"1458                         "void* s = reinterpret_cast<char*>(&s);"1459                         "struct B { virtual ~B() {} }; struct D : B {};"1460                         "B b;"1461                         "D* t = dynamic_cast<D*>(&b);",1462                         cStyleCastExpr()));1463}1464 1465TEST_P(ASTMatchersTest, ImplicitCastExpr_MatchesSimpleCase) {1466  // This test creates an implicit const cast.1467  EXPECT_TRUE(1468      matches("void f() { int x = 0; const int y = x; }",1469              traverse(TK_AsIs, varDecl(hasInitializer(implicitCastExpr())))));1470  // This test creates an implicit cast from int to char.1471  EXPECT_TRUE(1472      matches("char c = 0;",1473              traverse(TK_AsIs, varDecl(hasInitializer(implicitCastExpr())))));1474  // This test creates an implicit array-to-pointer cast.1475  EXPECT_TRUE(1476      matches("int arr[6]; int *p = arr;",1477              traverse(TK_AsIs, varDecl(hasInitializer(implicitCastExpr())))));1478}1479 1480TEST_P(ASTMatchersTest, ImplicitCastExpr_DoesNotMatchIncorrectly) {1481  // This test verifies that implicitCastExpr() matches exactly when implicit1482  // casts are present, and that it ignores explicit and paren casts.1483 1484  // These two test cases have no casts.1485  EXPECT_TRUE(1486      notMatches("int x = 0;", varDecl(hasInitializer(implicitCastExpr()))));1487  EXPECT_TRUE(1488      notMatches("int x = (0);", varDecl(hasInitializer(implicitCastExpr()))));1489  EXPECT_TRUE(notMatches("void f() { int x = 0; double d = (double) x; }",1490                         varDecl(hasInitializer(implicitCastExpr()))));1491}1492 1493TEST_P(ASTMatchersTest, ImplicitCastExpr_DoesNotMatchIncorrectly_CXX) {1494  if (!GetParam().isCXX()) {1495    return;1496  }1497  EXPECT_TRUE(notMatches("int x = 0, &y = x;",1498                         varDecl(hasInitializer(implicitCastExpr()))));1499  EXPECT_TRUE(notMatches("const int *p; int *q = const_cast<int *>(p);",1500                         varDecl(hasInitializer(implicitCastExpr()))));1501}1502 1503TEST_P(ASTMatchersTest, Stmt_DoesNotMatchDeclarations) {1504  EXPECT_TRUE(notMatches("struct X {};", stmt()));1505}1506 1507TEST_P(ASTMatchersTest, Stmt_MatchesCompoundStatments) {1508  EXPECT_TRUE(matches("void x() {}", stmt()));1509}1510 1511TEST_P(ASTMatchersTest, DeclStmt_DoesNotMatchCompoundStatements) {1512  EXPECT_TRUE(notMatches("void x() {}", declStmt()));1513}1514 1515TEST_P(ASTMatchersTest, DeclStmt_MatchesVariableDeclarationStatements) {1516  EXPECT_TRUE(matches("void x() { int a; }", declStmt()));1517}1518 1519TEST_P(ASTMatchersTest, ExprWithCleanups_MatchesExprWithCleanups) {1520  if (!GetParam().isCXX()) {1521    return;1522  }1523  EXPECT_TRUE(1524      matches("struct Foo { ~Foo(); };"1525              "const Foo f = Foo();",1526              traverse(TK_AsIs, varDecl(hasInitializer(exprWithCleanups())))));1527  EXPECT_FALSE(1528      matches("struct Foo { }; Foo a;"1529              "const Foo f = a;",1530              traverse(TK_AsIs, varDecl(hasInitializer(exprWithCleanups())))));1531}1532 1533TEST_P(ASTMatchersTest, InitListExpr) {1534  EXPECT_TRUE(matches("int a[] = { 1, 2 };",1535                      initListExpr(hasType(asString("int[2]")))));1536  EXPECT_TRUE(matches("struct B { int x, y; }; struct B b = { 5, 6 };",1537                      initListExpr(hasType(recordDecl(hasName("B"))))));1538  EXPECT_TRUE(1539      matches("int i[1] = {42, [0] = 43};", integerLiteral(equals(42))));1540}1541 1542TEST_P(ASTMatchersTest, InitListExpr_CXX) {1543  if (!GetParam().isCXX()) {1544    return;1545  }1546  EXPECT_TRUE(matches("struct S { S(void (*a)()); };"1547                      "void f();"1548                      "S s[1] = { &f };",1549                      declRefExpr(to(functionDecl(hasName("f"))))));1550}1551 1552TEST_P(ASTMatchersTest,1553       CXXStdInitializerListExpression_MatchesCXXStdInitializerListExpression) {1554  if (!GetParam().isCXX11OrLater()) {1555    return;1556  }1557  StringRef code = "namespace std {"1558                   "template <typename E> class initializer_list {"1559                   "  public: const E *a, *b;"1560                   "};"1561                   "}"1562                   "struct A {"1563                   "  A(std::initializer_list<int>) {}"1564                   "};";1565  EXPECT_TRUE(matches(1566      code + "A a{0};",1567      traverse(TK_AsIs, cxxConstructExpr(has(cxxStdInitializerListExpr()),1568                                         hasDeclaration(cxxConstructorDecl(1569                                             ofClass(hasName("A"))))))));1570  EXPECT_TRUE(matches(1571      code + "A a = {0};",1572      traverse(TK_AsIs, cxxConstructExpr(has(cxxStdInitializerListExpr()),1573                                         hasDeclaration(cxxConstructorDecl(1574                                             ofClass(hasName("A"))))))));1575 1576  EXPECT_TRUE(notMatches("int a[] = { 1, 2 };", cxxStdInitializerListExpr()));1577  EXPECT_TRUE(notMatches("struct B { int x, y; }; B b = { 5, 6 };",1578                         cxxStdInitializerListExpr()));1579}1580 1581TEST_P(ASTMatchersTest, UsingDecl_MatchesUsingDeclarations) {1582  if (!GetParam().isCXX()) {1583    return;1584  }1585  EXPECT_TRUE(matches("namespace X { int x; } using X::x;", usingDecl()));1586}1587 1588TEST_P(ASTMatchersTest, UsingDecl_MatchesShadowUsingDelcarations) {1589  if (!GetParam().isCXX()) {1590    return;1591  }1592  EXPECT_TRUE(matches("namespace f { int a; } using f::a;",1593                      usingDecl(hasAnyUsingShadowDecl(hasName("a")))));1594}1595 1596TEST_P(ASTMatchersTest, UsingEnumDecl_MatchesUsingEnumDeclarations) {1597  if (!GetParam().isCXX20OrLater()) {1598    return;1599  }1600  EXPECT_TRUE(1601      matches("namespace X { enum x {}; } using enum X::x;", usingEnumDecl()));1602}1603 1604TEST_P(ASTMatchersTest, UsingEnumDecl_MatchesShadowUsingDeclarations) {1605  if (!GetParam().isCXX20OrLater()) {1606    return;1607  }1608  EXPECT_TRUE(matches("namespace f { enum a {b}; } using enum f::a;",1609                      usingEnumDecl(hasAnyUsingShadowDecl(hasName("b")))));1610}1611 1612TEST_P(ASTMatchersTest, UsingDirectiveDecl_MatchesUsingNamespace) {1613  if (!GetParam().isCXX()) {1614    return;1615  }1616  EXPECT_TRUE(matches("namespace X { int x; } using namespace X;",1617                      usingDirectiveDecl()));1618  EXPECT_FALSE(1619      matches("namespace X { int x; } using X::x;", usingDirectiveDecl()));1620}1621 1622TEST_P(ASTMatchersTest, WhileStmt) {1623  EXPECT_TRUE(notMatches("void x() {}", whileStmt()));1624  EXPECT_TRUE(matches("void x() { while(1); }", whileStmt()));1625  EXPECT_TRUE(notMatches("void x() { do {} while(1); }", whileStmt()));1626}1627 1628TEST_P(ASTMatchersTest, DoStmt_MatchesDoLoops) {1629  EXPECT_TRUE(matches("void x() { do {} while(1); }", doStmt()));1630  EXPECT_TRUE(matches("void x() { do ; while(0); }", doStmt()));1631}1632 1633TEST_P(ASTMatchersTest, DoStmt_DoesNotMatchWhileLoops) {1634  EXPECT_TRUE(notMatches("void x() { while(1) {} }", doStmt()));1635}1636 1637TEST_P(ASTMatchersTest, SwitchCase_MatchesCase) {1638  EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchCase()));1639  EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchCase()));1640  EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchCase()));1641  EXPECT_TRUE(notMatches("void x() { switch(42) {} }", switchCase()));1642}1643 1644TEST_P(ASTMatchersTest, SwitchCase_MatchesSwitch) {1645  EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchStmt()));1646  EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchStmt()));1647  EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchStmt()));1648  EXPECT_TRUE(notMatches("void x() {}", switchStmt()));1649}1650 1651TEST_P(ASTMatchersTest, CxxExceptionHandling_SimpleCases) {1652  if (!GetParam().isCXX()) {1653    return;1654  }1655  EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", cxxCatchStmt()));1656  EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", cxxTryStmt()));1657  EXPECT_TRUE(1658      notMatches("void foo() try { } catch(int X) { }", cxxThrowExpr()));1659  EXPECT_TRUE(1660      matches("void foo() try { throw; } catch(int X) { }", cxxThrowExpr()));1661  EXPECT_TRUE(1662      matches("void foo() try { throw 5;} catch(int X) { }", cxxThrowExpr()));1663  EXPECT_TRUE(matches("void foo() try { throw; } catch(...) { }",1664                      cxxCatchStmt(isCatchAll())));1665  EXPECT_TRUE(notMatches("void foo() try { throw; } catch(int) { }",1666                         cxxCatchStmt(isCatchAll())));1667  EXPECT_TRUE(matches("void foo() try {} catch(int X) { }",1668                      varDecl(isExceptionVariable())));1669  EXPECT_TRUE(notMatches("void foo() try { int X; } catch (...) { }",1670                         varDecl(isExceptionVariable())));1671}1672 1673TEST_P(ASTMatchersTest, ParenExpr_SimpleCases) {1674  EXPECT_TRUE(matches("int i = (3);", traverse(TK_AsIs, parenExpr())));1675  EXPECT_TRUE(matches("int i = (3 + 7);", traverse(TK_AsIs, parenExpr())));1676  EXPECT_TRUE(notMatches("int i = 3;", traverse(TK_AsIs, parenExpr())));1677  EXPECT_TRUE(notMatches("int f() { return 1; }; void g() { int a = f(); }",1678                         traverse(TK_AsIs, parenExpr())));1679}1680 1681TEST_P(ASTMatchersTest, IgnoringParens) {1682  EXPECT_FALSE(matches("const char* str = (\"my-string\");",1683                       traverse(TK_AsIs, implicitCastExpr(hasSourceExpression(1684                                             stringLiteral())))));1685  EXPECT_TRUE(1686      matches("const char* str = (\"my-string\");",1687              traverse(TK_AsIs, implicitCastExpr(hasSourceExpression(1688                                    ignoringParens(stringLiteral()))))));1689}1690 1691TEST_P(ASTMatchersTest, QualType) {1692  EXPECT_TRUE(matches("struct S {};", qualType().bind("loc")));1693}1694 1695TEST_P(ASTMatchersTest, ConstantArrayType) {1696  EXPECT_TRUE(matches("int a[2];", constantArrayType()));1697  EXPECT_TRUE(notMatches("void f() { int a[] = { 2, 3 }; int b[a[0]]; }",1698                         constantArrayType(hasElementType(builtinType()))));1699 1700  EXPECT_TRUE(matches("int a[42];", constantArrayType(hasSize(42))));1701  EXPECT_TRUE(matches("int b[2*21];", constantArrayType(hasSize(42))));1702  EXPECT_TRUE(notMatches("int c[41], d[43];", constantArrayType(hasSize(42))));1703}1704 1705TEST_P(ASTMatchersTest, DependentSizedArrayType) {1706  if (!GetParam().isCXX()) {1707    return;1708  }1709  EXPECT_TRUE(1710      matches("template <typename T, int Size> class array { T data[Size]; };",1711              dependentSizedArrayType()));1712  EXPECT_TRUE(1713      notMatches("int a[42]; int b[] = { 2, 3 }; void f() { int c[b[0]]; }",1714                 dependentSizedArrayType()));1715}1716 1717TEST_P(ASTMatchersTest, DependentSizedExtVectorType) {1718  if (!GetParam().isCXX()) {1719    return;1720  }1721  EXPECT_TRUE(matches("template<typename T, int Size>"1722                      "class vector {"1723                      "  typedef T __attribute__((ext_vector_type(Size))) type;"1724                      "};",1725                      dependentSizedExtVectorType()));1726  EXPECT_TRUE(1727      notMatches("int a[42]; int b[] = { 2, 3 }; void f() { int c[b[0]]; }",1728                 dependentSizedExtVectorType()));1729}1730 1731TEST_P(ASTMatchersTest, IncompleteArrayType) {1732  EXPECT_TRUE(matches("int a[] = { 2, 3 };", incompleteArrayType()));1733  EXPECT_TRUE(matches("void f(int a[]) {}", incompleteArrayType()));1734 1735  EXPECT_TRUE(notMatches("int a[42]; void f() { int b[a[0]]; }",1736                         incompleteArrayType()));1737}1738 1739TEST_P(ASTMatchersTest, VariableArrayType) {1740  EXPECT_TRUE(matches("void f(int b) { int a[b]; }", variableArrayType()));1741  EXPECT_TRUE(notMatches("int a[] = {2, 3}; int b[42];", variableArrayType()));1742 1743  EXPECT_TRUE(matches("void f(int b) { int a[b]; }",1744                      variableArrayType(hasSizeExpr(ignoringImpCasts(1745                          declRefExpr(to(varDecl(hasName("b")))))))));1746}1747 1748TEST_P(ASTMatchersTest, AtomicType) {1749  if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getOS() !=1750      llvm::Triple::Win32) {1751    // FIXME: Make this work for MSVC.1752    EXPECT_TRUE(matches("_Atomic(int) i;", atomicType()));1753 1754    EXPECT_TRUE(1755        matches("_Atomic(int) i;", atomicType(hasValueType(isInteger()))));1756    EXPECT_TRUE(1757        notMatches("_Atomic(float) f;", atomicType(hasValueType(isInteger()))));1758  }1759}1760 1761TEST_P(ASTMatchersTest, AutoType) {1762  if (!GetParam().isCXX11OrLater()) {1763    return;1764  }1765  EXPECT_TRUE(matches("auto i = 2;", autoType()));1766  EXPECT_TRUE(matches("int v[] = { 2, 3 }; void f() { for (int i : v) {} }",1767                      autoType()));1768 1769  EXPECT_TRUE(matches("auto i = 2;", varDecl(hasType(isInteger()))));1770  EXPECT_TRUE(matches("struct X{}; auto x = X{};",1771                      varDecl(hasType(recordDecl(hasName("X"))))));1772 1773  // FIXME: Matching against the type-as-written can't work here, because the1774  //        type as written was not deduced.1775  // EXPECT_TRUE(matches("auto a = 1;",1776  //                    autoType(hasDeducedType(isInteger()))));1777  // EXPECT_TRUE(notMatches("auto b = 2.0;",1778  //                       autoType(hasDeducedType(isInteger()))));1779}1780 1781TEST_P(ASTMatchersTest, DecltypeType) {1782  if (!GetParam().isCXX11OrLater()) {1783    return;1784  }1785  EXPECT_TRUE(matches("decltype(1 + 1) sum = 1 + 1;", decltypeType()));1786  EXPECT_TRUE(matches("decltype(1 + 1) sum = 1 + 1;",1787                      decltypeType(hasUnderlyingType(isInteger()))));1788}1789 1790TEST_P(ASTMatchersTest, FunctionType) {1791  EXPECT_TRUE(matches("int (*f)(int);", functionType()));1792  EXPECT_TRUE(matches("void f(int i) {}", functionType()));1793}1794 1795TEST_P(ASTMatchersTest, IgnoringParens_Type) {1796  EXPECT_TRUE(1797      notMatches("void (*fp)(void);", pointerType(pointee(functionType()))));1798  EXPECT_TRUE(matches("void (*fp)(void);",1799                      pointerType(pointee(ignoringParens(functionType())))));1800}1801 1802TEST_P(ASTMatchersTest, FunctionProtoType) {1803  EXPECT_TRUE(matches("int (*f)(int);", functionProtoType()));1804  EXPECT_TRUE(matches("void f(int i);", functionProtoType()));1805  EXPECT_TRUE(matches("void f(void);", functionProtoType(parameterCountIs(0))));1806}1807 1808TEST_P(ASTMatchersTest, FunctionProtoType_C) {1809  if (!GetParam().isCOrEarlier(17)) {1810    return;1811  }1812  EXPECT_TRUE(notMatches("void f();", functionProtoType()));1813}1814 1815TEST_P(ASTMatchersTest, FunctionProtoType_CXX) {1816  if (!GetParam().isCXX()) {1817    return;1818  }1819  EXPECT_TRUE(matches("void f();", functionProtoType(parameterCountIs(0))));1820}1821 1822TEST_P(ASTMatchersTest, ParenType) {1823  EXPECT_TRUE(1824      matches("int (*array)[4];", varDecl(hasType(pointsTo(parenType())))));1825  EXPECT_TRUE(notMatches("int *array[4];", varDecl(hasType(parenType()))));1826 1827  EXPECT_TRUE(matches(1828      "int (*ptr_to_func)(int);",1829      varDecl(hasType(pointsTo(parenType(innerType(functionType())))))));1830  EXPECT_TRUE(notMatches(1831      "int (*ptr_to_array)[4];",1832      varDecl(hasType(pointsTo(parenType(innerType(functionType())))))));1833}1834 1835TEST_P(ASTMatchersTest, PointerType) {1836  // FIXME: Reactive when these tests can be more specific (not matching1837  // implicit code on certain platforms), likely when we have hasDescendant for1838  // Types/TypeLocs.1839  // EXPECT_TRUE(matchAndVerifyResultTrue(1840  //    "int* a;",1841  //    pointerTypeLoc(pointeeLoc(typeLoc().bind("loc"))),1842  //    std::make_unique<VerifyIdIsBoundTo<TypeLoc>>("loc", 1)));1843  // EXPECT_TRUE(matchAndVerifyResultTrue(1844  //    "int* a;",1845  //    pointerTypeLoc().bind("loc"),1846  //    std::make_unique<VerifyIdIsBoundTo<TypeLoc>>("loc", 1)));1847  EXPECT_TRUE(matches("int** a;", loc(pointerType(pointee(qualType())))));1848  EXPECT_TRUE(matches("int** a;", loc(pointerType(pointee(pointerType())))));1849  EXPECT_TRUE(matches("int* b; int* * const a = &b;",1850                      loc(qualType(isConstQualified(), pointerType()))));1851 1852  StringRef Fragment = "int *ptr;";1853  EXPECT_TRUE(notMatches(Fragment,1854                         varDecl(hasName("ptr"), hasType(blockPointerType()))));1855  EXPECT_TRUE(notMatches(1856      Fragment, varDecl(hasName("ptr"), hasType(memberPointerType()))));1857  EXPECT_TRUE(1858      matches(Fragment, varDecl(hasName("ptr"), hasType(pointerType()))));1859  EXPECT_TRUE(1860      notMatches(Fragment, varDecl(hasName("ptr"), hasType(referenceType()))));1861}1862 1863TEST_P(ASTMatchersTest, PointerType_CXX) {1864  if (!GetParam().isCXX()) {1865    return;1866  }1867  StringRef Fragment = "struct A { int i; }; int A::* ptr = &A::i;";1868  EXPECT_TRUE(notMatches(Fragment,1869                         varDecl(hasName("ptr"), hasType(blockPointerType()))));1870  EXPECT_TRUE(1871      matches(Fragment, varDecl(hasName("ptr"), hasType(memberPointerType()))));1872  EXPECT_TRUE(1873      notMatches(Fragment, varDecl(hasName("ptr"), hasType(pointerType()))));1874  EXPECT_TRUE(1875      notMatches(Fragment, varDecl(hasName("ptr"), hasType(referenceType()))));1876  EXPECT_TRUE(notMatches(1877      Fragment, varDecl(hasName("ptr"), hasType(lValueReferenceType()))));1878  EXPECT_TRUE(notMatches(1879      Fragment, varDecl(hasName("ptr"), hasType(rValueReferenceType()))));1880 1881  Fragment = "int a; int &ref = a;";1882  EXPECT_TRUE(notMatches(Fragment,1883                         varDecl(hasName("ref"), hasType(blockPointerType()))));1884  EXPECT_TRUE(notMatches(1885      Fragment, varDecl(hasName("ref"), hasType(memberPointerType()))));1886  EXPECT_TRUE(1887      notMatches(Fragment, varDecl(hasName("ref"), hasType(pointerType()))));1888  EXPECT_TRUE(1889      matches(Fragment, varDecl(hasName("ref"), hasType(referenceType()))));1890  EXPECT_TRUE(matches(Fragment,1891                      varDecl(hasName("ref"), hasType(lValueReferenceType()))));1892  EXPECT_TRUE(notMatches(1893      Fragment, varDecl(hasName("ref"), hasType(rValueReferenceType()))));1894}1895 1896TEST_P(ASTMatchersTest, PointerType_CXX11) {1897  if (!GetParam().isCXX11OrLater()) {1898    return;1899  }1900  StringRef Fragment = "int &&ref = 2;";1901  EXPECT_TRUE(notMatches(Fragment,1902                         varDecl(hasName("ref"), hasType(blockPointerType()))));1903  EXPECT_TRUE(notMatches(1904      Fragment, varDecl(hasName("ref"), hasType(memberPointerType()))));1905  EXPECT_TRUE(1906      notMatches(Fragment, varDecl(hasName("ref"), hasType(pointerType()))));1907  EXPECT_TRUE(1908      matches(Fragment, varDecl(hasName("ref"), hasType(referenceType()))));1909  EXPECT_TRUE(notMatches(1910      Fragment, varDecl(hasName("ref"), hasType(lValueReferenceType()))));1911  EXPECT_TRUE(matches(Fragment,1912                      varDecl(hasName("ref"), hasType(rValueReferenceType()))));1913}1914 1915TEST_P(ASTMatchersTest, AutoRefTypes) {1916  if (!GetParam().isCXX11OrLater()) {1917    return;1918  }1919 1920  StringRef Fragment = "auto a = 1;"1921                       "auto b = a;"1922                       "auto &c = a;"1923                       "auto &&d = c;"1924                       "auto &&e = 2;";1925  EXPECT_TRUE(1926      notMatches(Fragment, varDecl(hasName("a"), hasType(referenceType()))));1927  EXPECT_TRUE(1928      notMatches(Fragment, varDecl(hasName("b"), hasType(referenceType()))));1929  EXPECT_TRUE(1930      matches(Fragment, varDecl(hasName("c"), hasType(referenceType()))));1931  EXPECT_TRUE(1932      matches(Fragment, varDecl(hasName("c"), hasType(lValueReferenceType()))));1933  EXPECT_TRUE(notMatches(1934      Fragment, varDecl(hasName("c"), hasType(rValueReferenceType()))));1935  EXPECT_TRUE(1936      matches(Fragment, varDecl(hasName("d"), hasType(referenceType()))));1937  EXPECT_TRUE(1938      matches(Fragment, varDecl(hasName("d"), hasType(lValueReferenceType()))));1939  EXPECT_TRUE(notMatches(1940      Fragment, varDecl(hasName("d"), hasType(rValueReferenceType()))));1941  EXPECT_TRUE(1942      matches(Fragment, varDecl(hasName("e"), hasType(referenceType()))));1943  EXPECT_TRUE(notMatches(1944      Fragment, varDecl(hasName("e"), hasType(lValueReferenceType()))));1945  EXPECT_TRUE(1946      matches(Fragment, varDecl(hasName("e"), hasType(rValueReferenceType()))));1947}1948 1949TEST_P(ASTMatchersTest, EnumType) {1950  EXPECT_TRUE(1951      matches("enum Color { Green }; enum Color color;", loc(enumType())));1952}1953 1954TEST_P(ASTMatchersTest, EnumType_CXX) {1955  if (!GetParam().isCXX()) {1956    return;1957  }1958  EXPECT_TRUE(matches("enum Color { Green }; Color color;", loc(enumType())));1959}1960 1961TEST_P(ASTMatchersTest, EnumType_CXX11) {1962  if (!GetParam().isCXX11OrLater()) {1963    return;1964  }1965  EXPECT_TRUE(1966      matches("enum class Color { Green }; Color color;", loc(enumType())));1967}1968 1969TEST_P(ASTMatchersTest, PointerType_MatchesPointersToConstTypes) {1970  EXPECT_TRUE(matches("int b; int * const a = &b;", loc(pointerType())));1971  EXPECT_TRUE(matches("int b; int * const a = &b;", loc(pointerType())));1972  EXPECT_TRUE(matches("int b; const int * a = &b;",1973                      loc(pointerType(pointee(builtinType())))));1974  EXPECT_TRUE(matches("int b; const int * a = &b;",1975                      pointerType(pointee(builtinType()))));1976}1977 1978TEST_P(ASTMatchersTest, TypedefType) {1979  EXPECT_TRUE(matches("typedef int X; X a;",1980                      varDecl(hasName("a"), hasType(typedefType()))));1981}1982 1983TEST_P(ASTMatchersTest, MacroQualifiedType) {1984  EXPECT_TRUE(matches(1985      R"(1986        #define CDECL __attribute__((cdecl))1987        typedef void (CDECL *X)();1988      )",1989      typedefDecl(hasType(pointerType(pointee(macroQualifiedType()))))));1990  EXPECT_TRUE(notMatches(1991      R"(1992        typedef void (__attribute__((cdecl)) *Y)();1993      )",1994      typedefDecl(hasType(pointerType(pointee(macroQualifiedType()))))));1995}1996 1997TEST_P(ASTMatchersTest, TemplateSpecializationType) {1998  if (!GetParam().isCXX()) {1999    return;2000  }2001  EXPECT_TRUE(matches("template <typename T> class A{}; A<int> a;",2002                      templateSpecializationType()));2003}2004 2005TEST_P(ASTMatchersTest, DeducedTemplateSpecializationType) {2006  if (!GetParam().isCXX17OrLater()) {2007    return;2008  }2009  EXPECT_TRUE(2010      matches("template <typename T> class A{ public: A(T) {} }; A a(1);",2011              deducedTemplateSpecializationType()));2012}2013 2014TEST_P(ASTMatchersTest, DependentNameType) {2015  if (!GetParam().isCXX()) {2016    return;2017  }2018 2019  EXPECT_TRUE(matches(2020      R"(2021        template <typename T> struct declToImport {2022          typedef typename T::type dependent_name;2023        };2024      )",2025      dependentNameType()));2026}2027 2028TEST_P(ASTMatchersTest, DependentTemplateSpecializationType) {2029  if (!GetParam().isCXX()) {2030    return;2031  }2032 2033  EXPECT_TRUE(matches(2034      R"(2035        template<typename T> struct A;2036        template<typename T> struct declToImport {2037          typename A<T>::template B<T> a;2038        };2039      )",2040      templateSpecializationType()));2041}2042 2043TEST_P(ASTMatchersTest, RecordType) {2044  EXPECT_TRUE(matches("struct S {}; struct S s;",2045                      recordType(hasDeclaration(recordDecl(hasName("S"))))));2046  EXPECT_TRUE(notMatches("int i;",2047                         recordType(hasDeclaration(recordDecl(hasName("S"))))));2048}2049 2050TEST_P(ASTMatchersTest, RecordType_CXX) {2051  if (!GetParam().isCXX()) {2052    return;2053  }2054  EXPECT_TRUE(matches("class C {}; C c;", recordType()));2055  EXPECT_TRUE(matches("struct S {}; S s;",2056                      recordType(hasDeclaration(recordDecl(hasName("S"))))));2057}2058 2059TEST_P(ASTMatchersTest, SubstTemplateTypeParmType) {2060  if (!GetParam().isCXX()) {2061    return;2062  }2063  StringRef code = "template <typename T>"2064                   "int F() {"2065                   "  return 1 + T();"2066                   "}"2067                   "int i = F<int>();";2068  EXPECT_FALSE(matches(code, binaryOperator(hasLHS(2069                                 expr(hasType(substTemplateTypeParmType()))))));2070  EXPECT_TRUE(matches(code, binaryOperator(hasRHS(2071                                expr(hasType(substTemplateTypeParmType()))))));2072}2073 2074TEST_P(ASTMatchersTest, NestedNameSpecifier) {2075  if (!GetParam().isCXX()) {2076    return;2077  }2078  EXPECT_TRUE(2079      matches("namespace ns { struct A {}; } ns::A a;", nestedNameSpecifier()));2080  EXPECT_TRUE(matches("template <typename T> class A { typename T::B b; };",2081                      nestedNameSpecifier()));2082  EXPECT_TRUE(2083      matches("struct A { void f(); }; void A::f() {}", nestedNameSpecifier()));2084  EXPECT_TRUE(matches("namespace a { namespace b {} } namespace ab = a::b;",2085                      nestedNameSpecifier()));2086 2087  EXPECT_TRUE(matches("struct A { static void f() {} }; void g() { A::f(); }",2088                      nestedNameSpecifier()));2089  EXPECT_TRUE(2090      notMatches("struct A { static void f() {} }; void g(A* a) { a->f(); }",2091                 nestedNameSpecifier()));2092}2093 2094TEST_P(ASTMatchersTest, Attr) {2095  // Windows adds some implicit attributes.2096  bool AutomaticAttributes = StringRef(GetParam().Target).contains("win32");2097  if (GetParam().isCXX11OrLater()) {2098    EXPECT_TRUE(matches("struct [[clang::warn_unused_result]] F{};", attr()));2099 2100    // Unknown attributes are not parsed into an AST node.2101    if (!AutomaticAttributes) {2102      EXPECT_TRUE(notMatches("int x [[unknownattr]];", attr()));2103    }2104  }2105  if (GetParam().isCXX17OrLater()) {2106    EXPECT_TRUE(matches("struct [[nodiscard]] F{};", attr()));2107  }2108  EXPECT_TRUE(matches("int x(int * __attribute__((nonnull)) );", attr()));2109  if (!AutomaticAttributes) {2110    EXPECT_TRUE(notMatches("struct F{}; int x(int *);", attr()));2111    // Some known attributes are not parsed into an AST node.2112    EXPECT_TRUE(notMatches("typedef int x __attribute__((ext_vector_type(1)));",2113                           attr()));2114  }2115}2116 2117TEST_P(ASTMatchersTest, NullStmt) {2118  EXPECT_TRUE(matches("void f() {int i;;}", nullStmt()));2119  EXPECT_TRUE(notMatches("void f() {int i;}", nullStmt()));2120}2121 2122TEST_P(ASTMatchersTest, NamespaceAliasDecl) {2123  if (!GetParam().isCXX()) {2124    return;2125  }2126  EXPECT_TRUE(matches("namespace test {} namespace alias = ::test;",2127                      namespaceAliasDecl(hasName("alias"))));2128}2129 2130TEST_P(ASTMatchersTest, NestedNameSpecifier_MatchesTypes) {2131  if (!GetParam().isCXX()) {2132    return;2133  }2134  NestedNameSpecifierMatcher Matcher = nestedNameSpecifier(2135      specifiesType(hasDeclaration(recordDecl(hasName("A")))));2136  EXPECT_TRUE(matches("struct A { struct B {}; }; A::B b;", Matcher));2137  EXPECT_TRUE(2138      matches("struct A { struct B { struct C {}; }; }; A::B::C c;", Matcher));2139  EXPECT_TRUE(notMatches("namespace A { struct B {}; } A::B b;", Matcher));2140}2141 2142TEST_P(ASTMatchersTest, NestedNameSpecifier_MatchesNamespaceDecls) {2143  if (!GetParam().isCXX()) {2144    return;2145  }2146  NestedNameSpecifierMatcher Matcher =2147      nestedNameSpecifier(specifiesNamespace(hasName("ns")));2148  EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;", Matcher));2149  EXPECT_TRUE(notMatches("namespace xx { struct A {}; } xx::A a;", Matcher));2150  EXPECT_TRUE(notMatches("struct ns { struct A {}; }; ns::A a;", Matcher));2151}2152 2153TEST_P(ASTMatchersTest,2154       NestedNameSpecifier_MatchesNestedNameSpecifierPrefixes) {2155  if (!GetParam().isCXX()) {2156    return;2157  }2158  EXPECT_TRUE(2159      matches("struct A { struct B { struct C {}; }; }; A::B::C c;",2160              nestedNameSpecifier(hasPrefix(specifiesType(asString("A"))))));2161  EXPECT_TRUE(matches("struct A { struct B { struct C {}; }; }; A::B::C c;",2162                      nestedNameSpecifierLoc(hasPrefix(2163                          specifiesTypeLoc(loc(qualType(asString("A"))))))));2164  EXPECT_TRUE(matches(2165      "namespace N { struct A { struct B { struct C {}; }; }; } N::A::B::C c;",2166      nestedNameSpecifierLoc(2167          hasPrefix(specifiesTypeLoc(loc(qualType(asString("N::A"))))))));2168}2169 2170template <typename T>2171class VerifyAncestorHasChildIsEqual : public BoundNodesCallback {2172public:2173  bool run(const BoundNodes *Nodes, ASTContext *Context) override {2174    const T *Node = Nodes->getNodeAs<T>("");2175    return verify(*Nodes, *Context, Node);2176  }2177 2178  bool verify(const BoundNodes &Nodes, ASTContext &Context, const Stmt *Node) {2179    // Use the original typed pointer to verify we can pass pointers to subtypes2180    // to equalsNode.2181    const T *TypedNode = cast<T>(Node);2182    return selectFirst<T>(2183               "", match(stmt(hasParent(2184                             stmt(has(stmt(equalsNode(TypedNode)))).bind(""))),2185                         *Node, Context)) != nullptr;2186  }2187  bool verify(const BoundNodes &Nodes, ASTContext &Context, const Decl *Node) {2188    // Use the original typed pointer to verify we can pass pointers to subtypes2189    // to equalsNode.2190    const T *TypedNode = cast<T>(Node);2191    return selectFirst<T>(2192               "", match(decl(hasParent(2193                             decl(has(decl(equalsNode(TypedNode)))).bind(""))),2194                         *Node, Context)) != nullptr;2195  }2196  bool verify(const BoundNodes &Nodes, ASTContext &Context, const Type *Node) {2197    // Use the original typed pointer to verify we can pass pointers to subtypes2198    // to equalsNode.2199    const T *TypedNode = cast<T>(Node);2200    const auto *Dec = Nodes.getNodeAs<FieldDecl>("decl");2201    return selectFirst<T>(2202               "", match(fieldDecl(hasParent(decl(has(fieldDecl(2203                             hasType(type(equalsNode(TypedNode)).bind(""))))))),2204                         *Dec, Context)) != nullptr;2205  }2206};2207 2208TEST_P(ASTMatchersTest, IsEqualTo_MatchesNodesByIdentity) {2209  EXPECT_TRUE(matchAndVerifyResultTrue(2210      "void f() { if (1) if(1) {} }", ifStmt().bind(""),2211      std::make_unique<VerifyAncestorHasChildIsEqual<IfStmt>>()));2212}2213 2214TEST_P(ASTMatchersTest, IsEqualTo_MatchesNodesByIdentity_Cxx) {2215  if (!GetParam().isCXX()) {2216    return;2217  }2218  EXPECT_TRUE(matchAndVerifyResultTrue(2219      "class X { class Y {}; };", recordDecl(hasName("::X::Y")).bind(""),2220      std::make_unique<VerifyAncestorHasChildIsEqual<CXXRecordDecl>>()));2221  EXPECT_TRUE(matchAndVerifyResultTrue(2222      "class X { class Y {} y; };",2223      fieldDecl(hasName("y"), hasType(type().bind(""))).bind("decl"),2224      std::make_unique<VerifyAncestorHasChildIsEqual<Type>>()));2225}2226 2227TEST_P(ASTMatchersTest, TypedefDecl) {2228  EXPECT_TRUE(matches("typedef int typedefDeclTest;",2229                      typedefDecl(hasName("typedefDeclTest"))));2230}2231 2232TEST_P(ASTMatchersTest, TypedefDecl_Cxx) {2233  if (!GetParam().isCXX11OrLater()) {2234    return;2235  }2236  EXPECT_TRUE(notMatches("using typedefDeclTest = int;",2237                         typedefDecl(hasName("typedefDeclTest"))));2238}2239 2240TEST_P(ASTMatchersTest, TypeAliasDecl) {2241  EXPECT_TRUE(notMatches("typedef int typeAliasTest;",2242                         typeAliasDecl(hasName("typeAliasTest"))));2243}2244 2245TEST_P(ASTMatchersTest, TypeAliasDecl_CXX) {2246  if (!GetParam().isCXX11OrLater()) {2247    return;2248  }2249  EXPECT_TRUE(matches("using typeAliasTest = int;",2250                      typeAliasDecl(hasName("typeAliasTest"))));2251}2252 2253TEST_P(ASTMatchersTest, TypedefNameDecl) {2254  EXPECT_TRUE(matches("typedef int typedefNameDeclTest1;",2255                      typedefNameDecl(hasName("typedefNameDeclTest1"))));2256}2257 2258TEST_P(ASTMatchersTest, TypedefNameDecl_CXX) {2259  if (!GetParam().isCXX11OrLater()) {2260    return;2261  }2262  EXPECT_TRUE(matches("using typedefNameDeclTest = int;",2263                      typedefNameDecl(hasName("typedefNameDeclTest"))));2264}2265 2266TEST_P(ASTMatchersTest, TypeAliasTemplateDecl) {2267  if (!GetParam().isCXX11OrLater()) {2268    return;2269  }2270  StringRef Code = R"(2271    template <typename T>2272    class X { T t; };2273 2274    template <typename T>2275    using typeAliasTemplateDecl = X<T>;2276 2277    using typeAliasDecl = X<int>;2278  )";2279  EXPECT_TRUE(2280      matches(Code, typeAliasTemplateDecl(hasName("typeAliasTemplateDecl"))));2281  EXPECT_TRUE(2282      notMatches(Code, typeAliasTemplateDecl(hasName("typeAliasDecl"))));2283}2284 2285TEST_P(ASTMatchersTest, QualifiedTypeLocTest_BindsToConstIntVarDecl) {2286  EXPECT_TRUE(matches("const int x = 0;",2287                      qualifiedTypeLoc(loc(asString("const int")))));2288}2289 2290TEST_P(ASTMatchersTest, QualifiedTypeLocTest_BindsToConstIntFunctionDecl) {2291  EXPECT_TRUE(matches("const int f() { return 5; }",2292                      qualifiedTypeLoc(loc(asString("const int")))));2293}2294 2295TEST_P(ASTMatchersTest, QualifiedTypeLocTest_DoesNotBindToUnqualifiedVarDecl) {2296  EXPECT_TRUE(notMatches("int x = 0;", qualifiedTypeLoc(loc(asString("int")))));2297}2298 2299TEST_P(ASTMatchersTest, QualifiedTypeLocTest_IntDoesNotBindToConstIntDecl) {2300  EXPECT_TRUE(2301      notMatches("const int x = 0;", qualifiedTypeLoc(loc(asString("int")))));2302}2303 2304TEST_P(ASTMatchersTest, QualifiedTypeLocTest_IntDoesNotBindToConstFloatDecl) {2305  EXPECT_TRUE(2306      notMatches("const float x = 0;", qualifiedTypeLoc(loc(asString("int")))));2307}2308 2309TEST_P(ASTMatchersTest, PointerTypeLocTest_BindsToAnyPointerTypeLoc) {2310  auto matcher = varDecl(hasName("x"), hasTypeLoc(pointerTypeLoc()));2311  EXPECT_TRUE(matches("int* x;", matcher));2312  EXPECT_TRUE(matches("float* x;", matcher));2313  EXPECT_TRUE(matches("char* x;", matcher));2314  EXPECT_TRUE(matches("void* x;", matcher));2315}2316 2317TEST_P(ASTMatchersTest, PointerTypeLocTest_DoesNotBindToNonPointerTypeLoc) {2318  auto matcher = varDecl(hasName("x"), hasTypeLoc(pointerTypeLoc()));2319  EXPECT_TRUE(notMatches("int x;", matcher));2320  EXPECT_TRUE(notMatches("float x;", matcher));2321  EXPECT_TRUE(notMatches("char x;", matcher));2322}2323 2324TEST_P(ASTMatchersTest, ReferenceTypeLocTest_BindsToAnyReferenceTypeLoc) {2325  if (!GetParam().isCXX()) {2326    return;2327  }2328  auto matcher = varDecl(hasName("r"), hasTypeLoc(referenceTypeLoc()));2329  EXPECT_TRUE(matches("int rr = 3; int& r = rr;", matcher));2330  EXPECT_TRUE(matches("int rr = 3; auto& r = rr;", matcher));2331  EXPECT_TRUE(matches("int rr = 3; const int& r = rr;", matcher));2332  EXPECT_TRUE(matches("float rr = 3.0; float& r = rr;", matcher));2333  EXPECT_TRUE(matches("char rr = 'a'; char& r = rr;", matcher));2334}2335 2336TEST_P(ASTMatchersTest, ReferenceTypeLocTest_DoesNotBindToNonReferenceTypeLoc) {2337  auto matcher = varDecl(hasName("r"), hasTypeLoc(referenceTypeLoc()));2338  EXPECT_TRUE(notMatches("int r;", matcher));2339  EXPECT_TRUE(notMatches("int r = 3;", matcher));2340  EXPECT_TRUE(notMatches("const int r = 3;", matcher));2341  EXPECT_TRUE(notMatches("int* r;", matcher));2342  EXPECT_TRUE(notMatches("float r;", matcher));2343  EXPECT_TRUE(notMatches("char r;", matcher));2344}2345 2346TEST_P(ASTMatchersTest, ReferenceTypeLocTest_BindsToAnyRvalueReferenceTypeLoc) {2347  if (!GetParam().isCXX()) {2348    return;2349  }2350  auto matcher = varDecl(hasName("r"), hasTypeLoc(referenceTypeLoc()));2351  EXPECT_TRUE(matches("int&& r = 3;", matcher));2352  EXPECT_TRUE(matches("auto&& r = 3;", matcher));2353  EXPECT_TRUE(matches("float&& r = 3.0;", matcher));2354}2355 2356TEST_P(ASTMatchersTest, ArrayTypeLocTest_BindsToAnyArrayTypeLoc) {2357  auto matcher = varDecl(hasName("x"), hasTypeLoc(arrayTypeLoc()));2358  EXPECT_TRUE(matches("int x[3];", matcher));2359  EXPECT_TRUE(matches("float x[3];", matcher));2360  EXPECT_TRUE(matches("char x[3];", matcher));2361  EXPECT_TRUE(matches("void* x[3];", matcher));2362  EXPECT_TRUE(matches("const int x[3] = {1, 2, 3};", matcher));2363  EXPECT_TRUE(matches("int x[3][4];", matcher));2364  EXPECT_TRUE(matches("void foo(int x[]);", matcher));2365  EXPECT_TRUE(matches("int a[] = {1, 2}; void foo() {int x[a[0]];}", matcher));2366}2367 2368TEST_P(ASTMatchersTest, ArrayTypeLocTest_DoesNotBindToNonArrayTypeLoc) {2369  auto matcher = varDecl(hasName("x"), hasTypeLoc(arrayTypeLoc()));2370  EXPECT_TRUE(notMatches("int x;", matcher));2371  EXPECT_TRUE(notMatches("float x;", matcher));2372  EXPECT_TRUE(notMatches("char x;", matcher));2373  EXPECT_TRUE(notMatches("void* x;", matcher));2374}2375 2376TEST_P(ASTMatchersTest,2377       TemplateSpecializationTypeLocTest_BindsToVarDeclTemplateSpecialization) {2378  if (!GetParam().isCXX()) {2379    return;2380  }2381  EXPECT_TRUE(matches(2382      "template <typename T> class C {}; C<char> var;",2383      varDecl(hasName("var"), hasTypeLoc(templateSpecializationTypeLoc()))));2384}2385 2386TEST_P(2387    ASTMatchersTest,2388    TemplateSpecializationTypeLocTest_DoesNotBindToNonTemplateSpecialization) {2389  if (!GetParam().isCXX()) {2390    return;2391  }2392  EXPECT_TRUE(notMatches(2393      "class C {}; C var;",2394      varDecl(hasName("var"), hasTypeLoc(templateSpecializationTypeLoc()))));2395}2396 2397TEST_P(ASTMatchersTest, LambdaCaptureTest) {2398  if (!GetParam().isCXX11OrLater()) {2399    return;2400  }2401  EXPECT_TRUE(matches("int main() { int cc; auto f = [cc](){ return cc; }; }",2402                      lambdaExpr(hasAnyCapture(lambdaCapture()))));2403}2404 2405TEST_P(ASTMatchersTest, LambdaCaptureTest_BindsToCaptureOfVarDecl) {2406  if (!GetParam().isCXX11OrLater()) {2407    return;2408  }2409  auto matcher = lambdaExpr(2410      hasAnyCapture(lambdaCapture(capturesVar(varDecl(hasName("cc"))))));2411  EXPECT_TRUE(matches("int main() { int cc; auto f = [cc](){ return cc; }; }",2412                      matcher));2413  EXPECT_TRUE(matches("int main() { int cc; auto f = [&cc](){ return cc; }; }",2414                      matcher));2415  EXPECT_TRUE(2416      matches("int main() { int cc; auto f = [=](){ return cc; }; }", matcher));2417  EXPECT_TRUE(2418      matches("int main() { int cc; auto f = [&](){ return cc; }; }", matcher));2419  EXPECT_TRUE(matches(2420      "void f(int a) { int cc[a]; auto f = [&](){ return cc;}; }", matcher));2421}2422 2423TEST_P(ASTMatchersTest, LambdaCaptureTest_BindsToCaptureWithInitializer) {2424  if (!GetParam().isCXX14OrLater()) {2425    return;2426  }2427  auto matcher = lambdaExpr(hasAnyCapture(lambdaCapture(capturesVar(2428      varDecl(hasName("cc"), hasInitializer(integerLiteral(equals(1))))))));2429  EXPECT_TRUE(2430      matches("int main() { auto lambda = [cc = 1] {return cc;}; }", matcher));2431  EXPECT_TRUE(2432      matches("int main() { int cc = 2; auto lambda = [cc = 1] {return cc;}; }",2433              matcher));2434}2435 2436TEST_P(ASTMatchersTest, LambdaCaptureTest_DoesNotBindToCaptureOfVarDecl) {2437  if (!GetParam().isCXX11OrLater()) {2438    return;2439  }2440  auto matcher = lambdaExpr(2441      hasAnyCapture(lambdaCapture(capturesVar(varDecl(hasName("cc"))))));2442  EXPECT_FALSE(matches("int main() { auto f = [](){ return 5; }; }", matcher));2443  EXPECT_FALSE(matches("int main() { int xx; auto f = [xx](){ return xx; }; }",2444                       matcher));2445}2446 2447TEST_P(ASTMatchersTest,2448       LambdaCaptureTest_DoesNotBindToCaptureWithInitializerAndDifferentName) {2449  if (!GetParam().isCXX14OrLater()) {2450    return;2451  }2452  EXPECT_FALSE(matches(2453      "int main() { auto lambda = [xx = 1] {return xx;}; }",2454      lambdaExpr(hasAnyCapture(lambdaCapture(capturesVar(varDecl(2455          hasName("cc"), hasInitializer(integerLiteral(equals(1))))))))));2456}2457 2458TEST_P(ASTMatchersTest, LambdaCaptureTest_BindsToCaptureOfReferenceType) {2459  if (!GetParam().isCXX20OrLater()) {2460    return;2461  }2462  auto matcher = lambdaExpr(hasAnyCapture(2463      lambdaCapture(capturesVar(varDecl(hasType(referenceType()))))));2464  EXPECT_TRUE(matches("template <class ...T> void f(T &...args) {"2465                      "  [&...args = args] () mutable {"2466                      "  }();"2467                      "}"2468                      "int main() {"2469                      "  int a;"2470                      "  f(a);"2471                      "}",2472                      matcher));2473  EXPECT_FALSE(matches("template <class ...T> void f(T &...args) {"2474                       "  [...args = args] () mutable {"2475                       "  }();"2476                       "}"2477                       "int main() {"2478                       "  int a;"2479                       "  f(a);"2480                       "}",2481                       matcher));2482}2483 2484TEST_P(ASTMatchersTest, IsDerivedFromRecursion) {2485  if (!GetParam().isCXX11OrLater())2486    return;2487 2488  // Check we don't crash on cycles in the traversal and inheritance hierarchy.2489  // Clang will normally enforce there are no cycles, but matchers opted to2490  // traverse primary template for dependent specializations, spuriously2491  // creating the cycles.2492  DeclarationMatcher matcher = cxxRecordDecl(isDerivedFrom("X"));2493  EXPECT_TRUE(notMatches(R"cpp(2494      template <typename T1, typename T2>2495      struct M;2496 2497      template <typename T1>2498      struct M<T1, void> {};2499 2500      template <typename T1, typename T2>2501      struct L : M<T1, T2> {};2502 2503      template <typename T1, typename T2>2504      struct M : L<M<T1, T2>, M<T1, T2>> {};2505  )cpp",2506                         matcher));2507 2508  // Check the running time is not exponential. The number of subojects to2509  // traverse grows as fibonacci numbers even though the number of bases to2510  // traverse is quadratic.2511  // The test will hang if implementation of matchers traverses all subojects.2512  EXPECT_TRUE(notMatches(R"cpp(2513    template <class T> struct A0 {};2514    template <class T> struct A1 : A0<T> {};2515    template <class T> struct A2 : A1<T>, A0<T> {};2516    template <class T> struct A3 : A2<T>, A1<T> {};2517    template <class T> struct A4 : A3<T>, A2<T> {};2518    template <class T> struct A5 : A4<T>, A3<T> {};2519    template <class T> struct A6 : A5<T>, A4<T> {};2520    template <class T> struct A7 : A6<T>, A5<T> {};2521    template <class T> struct A8 : A7<T>, A6<T> {};2522    template <class T> struct A9 : A8<T>, A7<T> {};2523    template <class T> struct A10 : A9<T>, A8<T> {};2524    template <class T> struct A11 : A10<T>, A9<T> {};2525    template <class T> struct A12 : A11<T>, A10<T> {};2526    template <class T> struct A13 : A12<T>, A11<T> {};2527    template <class T> struct A14 : A13<T>, A12<T> {};2528    template <class T> struct A15 : A14<T>, A13<T> {};2529    template <class T> struct A16 : A15<T>, A14<T> {};2530    template <class T> struct A17 : A16<T>, A15<T> {};2531    template <class T> struct A18 : A17<T>, A16<T> {};2532    template <class T> struct A19 : A18<T>, A17<T> {};2533    template <class T> struct A20 : A19<T>, A18<T> {};2534    template <class T> struct A21 : A20<T>, A19<T> {};2535    template <class T> struct A22 : A21<T>, A20<T> {};2536    template <class T> struct A23 : A22<T>, A21<T> {};2537    template <class T> struct A24 : A23<T>, A22<T> {};2538    template <class T> struct A25 : A24<T>, A23<T> {};2539    template <class T> struct A26 : A25<T>, A24<T> {};2540    template <class T> struct A27 : A26<T>, A25<T> {};2541    template <class T> struct A28 : A27<T>, A26<T> {};2542    template <class T> struct A29 : A28<T>, A27<T> {};2543    template <class T> struct A30 : A29<T>, A28<T> {};2544    template <class T> struct A31 : A30<T>, A29<T> {};2545    template <class T> struct A32 : A31<T>, A30<T> {};2546    template <class T> struct A33 : A32<T>, A31<T> {};2547    template <class T> struct A34 : A33<T>, A32<T> {};2548    template <class T> struct A35 : A34<T>, A33<T> {};2549    template <class T> struct A36 : A35<T>, A34<T> {};2550    template <class T> struct A37 : A36<T>, A35<T> {};2551    template <class T> struct A38 : A37<T>, A36<T> {};2552    template <class T> struct A39 : A38<T>, A37<T> {};2553    template <class T> struct A40 : A39<T>, A38<T> {};2554)cpp",2555                         matcher));2556}2557 2558TEST(ASTMatchersTestObjC, ObjCMessageCalees) {2559  StatementMatcher MessagingFoo =2560      objcMessageExpr(callee(objcMethodDecl(hasName("foo"))));2561 2562  EXPECT_TRUE(matchesObjC("@interface I"2563                          "+ (void)foo;"2564                          "@end\n"2565                          "int main() {"2566                          "  [I foo];"2567                          "}",2568                          MessagingFoo));2569  EXPECT_TRUE(notMatchesObjC("@interface I"2570                             "+ (void)foo;"2571                             "+ (void)bar;"2572                             "@end\n"2573                             "int main() {"2574                             "  [I bar];"2575                             "}",2576                             MessagingFoo));2577  EXPECT_TRUE(matchesObjC("@interface I"2578                          "- (void)foo;"2579                          "- (void)bar;"2580                          "@end\n"2581                          "int main() {"2582                          "  I *i;"2583                          "  [i foo];"2584                          "}",2585                          MessagingFoo));2586  EXPECT_TRUE(notMatchesObjC("@interface I"2587                             "- (void)foo;"2588                             "- (void)bar;"2589                             "@end\n"2590                             "int main() {"2591                             "  I *i;"2592                             "  [i bar];"2593                             "}",2594                             MessagingFoo));2595}2596 2597TEST(ASTMatchersTestObjC, ObjCMessageExpr) {2598  // Don't find ObjCMessageExpr where none are present.2599  EXPECT_TRUE(notMatchesObjC("", objcMessageExpr(anything())));2600 2601  StringRef Objc1String = "@interface Str "2602                          " - (Str *)uppercaseString;"2603                          "@end "2604                          "@interface foo "2605                          "- (void)contents;"2606                          "- (void)meth:(Str *)text;"2607                          "@end "2608                          " "2609                          "@implementation foo "2610                          "- (void) meth:(Str *)text { "2611                          "  [self contents];"2612                          "  Str *up = [text uppercaseString];"2613                          "} "2614                          "@end ";2615  EXPECT_TRUE(matchesObjC(Objc1String, objcMessageExpr(anything())));2616  EXPECT_TRUE(matchesObjC(Objc1String,2617                          objcMessageExpr(hasAnySelector({"contents", "meth:"}))2618 2619                              ));2620  EXPECT_TRUE(2621      matchesObjC(Objc1String, objcMessageExpr(hasSelector("contents"))));2622  EXPECT_TRUE(matchesObjC(2623      Objc1String, objcMessageExpr(hasAnySelector("contents", "contentsA"))));2624  EXPECT_FALSE(matchesObjC(2625      Objc1String, objcMessageExpr(hasAnySelector("contentsB", "contentsC"))));2626  EXPECT_TRUE(2627      matchesObjC(Objc1String, objcMessageExpr(matchesSelector("cont*"))));2628  EXPECT_FALSE(2629      matchesObjC(Objc1String, objcMessageExpr(matchesSelector("?cont*"))));2630  EXPECT_TRUE(2631      notMatchesObjC(Objc1String, objcMessageExpr(hasSelector("contents"),2632                                                  hasNullSelector())));2633  EXPECT_TRUE(matchesObjC(Objc1String, objcMessageExpr(hasSelector("contents"),2634                                                       hasUnarySelector())));2635  EXPECT_TRUE(matchesObjC(Objc1String, objcMessageExpr(hasSelector("contents"),2636                                                       numSelectorArgs(0))));2637  EXPECT_TRUE(2638      matchesObjC(Objc1String, objcMessageExpr(matchesSelector("uppercase*"),2639                                               argumentCountIs(0))));2640}2641 2642TEST(ASTMatchersTestObjC, ObjCStringLiteral) {2643 2644  StringRef Objc1String = "@interface NSObject "2645                          "@end "2646                          "@interface NSString "2647                          "@end "2648                          "@interface Test : NSObject "2649                          "+ (void)someFunction:(NSString *)Desc; "2650                          "@end "2651                          "@implementation Test "2652                          "+ (void)someFunction:(NSString *)Desc { "2653                          "    return; "2654                          "} "2655                          "- (void) foo { "2656                          "    [Test someFunction:@\"Ola!\"]; "2657                          "}\n"2658                          "@end ";2659  EXPECT_TRUE(matchesObjC(Objc1String, objcStringLiteral()));2660}2661 2662TEST(ASTMatchersTestObjC, ObjCDecls) {2663  StringRef ObjCString = "@protocol Proto "2664                         "- (void)protoDidThing; "2665                         "@end "2666                         "@interface Thing "2667                         "@property int enabled; "2668                         "@end "2669                         "@interface Thing (ABC) "2670                         "- (void)abc_doThing; "2671                         "@end "2672                         "@implementation Thing "2673                         "{ id _ivar; } "2674                         "- (void)anything {} "2675                         "@end "2676                         "@implementation Thing (ABC) "2677                         "- (void)abc_doThing {} "2678                         "@end ";2679 2680  EXPECT_TRUE(matchesObjC(ObjCString, objcProtocolDecl(hasName("Proto"))));2681  EXPECT_TRUE(2682      matchesObjC(ObjCString, objcImplementationDecl(hasName("Thing"))));2683  EXPECT_TRUE(matchesObjC(ObjCString, objcCategoryDecl(hasName("ABC"))));2684  EXPECT_TRUE(matchesObjC(ObjCString, objcCategoryImplDecl(hasName("ABC"))));2685  EXPECT_TRUE(2686      matchesObjC(ObjCString, objcMethodDecl(hasName("protoDidThing"))));2687  EXPECT_TRUE(matchesObjC(ObjCString, objcMethodDecl(hasName("abc_doThing"))));2688  EXPECT_TRUE(matchesObjC(ObjCString, objcMethodDecl(hasName("anything"))));2689  EXPECT_TRUE(matchesObjC(ObjCString, objcIvarDecl(hasName("_ivar"))));2690  EXPECT_TRUE(matchesObjC(ObjCString, objcPropertyDecl(hasName("enabled"))));2691}2692 2693TEST(ASTMatchersTestObjC, ObjCExceptionStmts) {2694  StringRef ObjCString = "void f(id obj) {"2695                         "  @try {"2696                         "    @throw obj;"2697                         "  } @catch (...) {"2698                         "  } @finally {}"2699                         "}";2700 2701  EXPECT_TRUE(matchesObjC(ObjCString, objcTryStmt()));2702  EXPECT_TRUE(matchesObjC(ObjCString, objcThrowStmt()));2703  EXPECT_TRUE(matchesObjC(ObjCString, objcCatchStmt()));2704  EXPECT_TRUE(matchesObjC(ObjCString, objcFinallyStmt()));2705}2706 2707TEST(ASTMatchersTest, DecompositionDecl) {2708  StringRef Code = R"cpp(2709void foo()2710{2711    int arr[3];2712    auto &[f, s, t] = arr;2713 2714    f = 42;2715}2716  )cpp";2717  EXPECT_TRUE(matchesConditionally(2718      Code, decompositionDecl(hasBinding(0, bindingDecl(hasName("f")))), true,2719      {"-std=c++17"}));2720  EXPECT_FALSE(matchesConditionally(2721      Code, decompositionDecl(hasBinding(42, bindingDecl(hasName("f")))), true,2722      {"-std=c++17"}));2723  EXPECT_FALSE(matchesConditionally(2724      Code, decompositionDecl(hasBinding(0, bindingDecl(hasName("s")))), true,2725      {"-std=c++17"}));2726  EXPECT_TRUE(matchesConditionally(2727      Code, decompositionDecl(hasBinding(1, bindingDecl(hasName("s")))), true,2728      {"-std=c++17"}));2729 2730  EXPECT_TRUE(matchesConditionally(2731      Code,2732      bindingDecl(decl().bind("self"), hasName("f"),2733                  forDecomposition(decompositionDecl(2734                      hasAnyBinding(bindingDecl(equalsBoundNode("self")))))),2735      true, {"-std=c++17"}));2736}2737 2738TEST(ASTMatchersTestObjC, ObjCAutoreleasePoolStmt) {2739  StringRef ObjCString = "void f() {"2740                         "@autoreleasepool {"2741                         "  int x = 1;"2742                         "}"2743                         "}";2744  EXPECT_TRUE(matchesObjC(ObjCString, autoreleasePoolStmt()));2745  StringRef ObjCStringNoPool = "void f() { int x = 1; }";2746  EXPECT_FALSE(matchesObjC(ObjCStringNoPool, autoreleasePoolStmt()));2747}2748 2749TEST(ASTMatchersTestOpenMP, OMPExecutableDirective) {2750  auto Matcher = stmt(ompExecutableDirective());2751 2752  StringRef Source0 = R"(2753void x() {2754#pragma omp parallel2755;2756})";2757  EXPECT_TRUE(matchesWithOpenMP(Source0, Matcher));2758 2759  StringRef Source1 = R"(2760void x() {2761#pragma omp taskyield2762;2763})";2764  EXPECT_TRUE(matchesWithOpenMP(Source1, Matcher));2765 2766  StringRef Source2 = R"(2767void x() {2768;2769})";2770  EXPECT_TRUE(notMatchesWithOpenMP(Source2, Matcher));2771}2772 2773TEST(ASTMatchersTestOpenMP, OMPDefaultClause) {2774  auto Matcher = ompExecutableDirective(hasAnyClause(ompDefaultClause()));2775 2776  StringRef Source0 = R"(2777void x() {2778;2779})";2780  EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));2781 2782  StringRef Source1 = R"(2783void x() {2784#pragma omp parallel2785;2786})";2787  EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));2788 2789  StringRef Source2 = R"(2790void x() {2791#pragma omp parallel default(none)2792;2793})";2794  EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher));2795 2796  StringRef Source3 = R"(2797void x() {2798#pragma omp parallel default(shared)2799;2800})";2801  EXPECT_TRUE(matchesWithOpenMP(Source3, Matcher));2802 2803  StringRef Source4 = R"(2804void x() {2805#pragma omp parallel default(firstprivate)2806;2807})";2808  EXPECT_TRUE(matchesWithOpenMP51(Source4, Matcher));2809 2810  StringRef Source5 = R"(2811void x(int x) {2812#pragma omp parallel num_threads(x)2813;2814})";2815  EXPECT_TRUE(notMatchesWithOpenMP(Source5, Matcher));2816}2817 2818TEST(ASTMatchersTest, Finder_DynamicOnlyAcceptsSomeMatchers) {2819  MatchFinder Finder;2820  EXPECT_TRUE(Finder.addDynamicMatcher(decl(), nullptr));2821  EXPECT_TRUE(Finder.addDynamicMatcher(callExpr(), nullptr));2822  EXPECT_TRUE(2823      Finder.addDynamicMatcher(constantArrayType(hasSize(42)), nullptr));2824 2825  // Do not accept non-toplevel matchers.2826  EXPECT_FALSE(Finder.addDynamicMatcher(isMain(), nullptr));2827  EXPECT_FALSE(Finder.addDynamicMatcher(hasName("x"), nullptr));2828}2829 2830TEST(MatchFinderAPI, MatchesDynamic) {2831  StringRef SourceCode = "struct A { void f() {} };";2832  auto Matcher = functionDecl(isDefinition()).bind("method");2833 2834  auto astUnit = tooling::buildASTFromCode(SourceCode);2835 2836  auto GlobalBoundNodes = matchDynamic(Matcher, astUnit->getASTContext());2837 2838  EXPECT_EQ(GlobalBoundNodes.size(), 1u);2839  EXPECT_EQ(GlobalBoundNodes[0].getMap().size(), 1u);2840 2841  auto GlobalMethodNode = GlobalBoundNodes[0].getNodeAs<FunctionDecl>("method");2842  EXPECT_TRUE(GlobalMethodNode != nullptr);2843 2844  auto MethodBoundNodes =2845      matchDynamic(Matcher, *GlobalMethodNode, astUnit->getASTContext());2846  EXPECT_EQ(MethodBoundNodes.size(), 1u);2847  EXPECT_EQ(MethodBoundNodes[0].getMap().size(), 1u);2848 2849  auto MethodNode = MethodBoundNodes[0].getNodeAs<FunctionDecl>("method");2850  EXPECT_EQ(MethodNode, GlobalMethodNode);2851}2852 2853static std::vector<TestClangConfig> allTestClangConfigs() {2854  std::vector<TestClangConfig> all_configs;2855  for (TestLanguage lang : {2856#define TESTLANGUAGE(lang, version, std_flag, version_index)                   \2857  Lang_##lang##version,2858#include "clang/Testing/TestLanguage.def"2859       }) {2860    TestClangConfig config;2861    config.Language = lang;2862 2863    // Use an unknown-unknown triple so we don't instantiate the full system2864    // toolchain.  On Linux, instantiating the toolchain involves stat'ing2865    // large portions of /usr/lib, and this slows down not only this test, but2866    // all other tests, via contention in the kernel.2867    //2868    // FIXME: This is a hack to work around the fact that there's no way to do2869    // the equivalent of runToolOnCodeWithArgs without instantiating a full2870    // Driver.  We should consider having a function, at least for tests, that2871    // invokes cc1.2872    config.Target = "i386-unknown-unknown";2873    all_configs.push_back(config);2874 2875    // Windows target is interesting to test because it enables2876    // `-fdelayed-template-parsing`.2877    config.Target = "x86_64-pc-win32-msvc";2878    all_configs.push_back(config);2879  }2880  return all_configs;2881}2882 2883INSTANTIATE_TEST_SUITE_P(2884    ASTMatchersTests, ASTMatchersTest, testing::ValuesIn(allTestClangConfigs()),2885    [](const testing::TestParamInfo<TestClangConfig> &Info) {2886      return Info.param.toShortString();2887    });2888 2889} // namespace ast_matchers2890} // namespace clang2891