14da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//===- unittest/Tooling/ASTMatchersTest.cpp - AST matcher unit tests ------===//
24da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//
34da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//                     The LLVM Compiler Infrastructure
44da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//
54da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// This file is distributed under the University of Illinois Open Source
64da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// License. See LICENSE.TXT for details.
74da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//
84da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//===----------------------------------------------------------------------===//
94da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#include "ASTMatchersTest.h"
118b9ed7106a40e8dacf212fa06eb859804b75a875Benjamin Kramer#include "clang/AST/PrettyPrinter.h"
124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#include "clang/ASTMatchers/ASTMatchFinder.h"
131050e8b2252d89a0004a6fd25a58dab88b5ee625Chandler Carruth#include "clang/ASTMatchers/ASTMatchers.h"
144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#include "clang/Tooling/Tooling.h"
15651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/ADT/Triple.h"
16651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/Support/Host.h"
174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#include "gtest/gtest.h"
184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimeknamespace clang {
204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimeknamespace ast_matchers {
214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2278a0ce4ed3d6cf3ad98e1b07fb1cd43b47793598Benjamin Kramer#if GTEST_HAS_DEATH_TEST
234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasNameDeathTest, DiesOnEmptyName) {
244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  ASSERT_DEBUG_DEATH({
252dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper    DeclarationMatcher HasEmptyName = recordDecl(hasName(""));
264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    EXPECT_TRUE(notMatches("class X {};", HasEmptyName));
274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  }, "");
284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
30e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(HasNameDeathTest, DiesOnEmptyPattern) {
31e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  ASSERT_DEBUG_DEATH({
322dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      DeclarationMatcher HasEmptyName = recordDecl(matchesName(""));
33e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      EXPECT_TRUE(notMatches("class X {};", HasEmptyName));
34e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper    }, "");
35e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
36e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsDerivedFromDeathTest, DiesOnEmptyBaseName) {
384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  ASSERT_DEBUG_DEATH({
39a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    DeclarationMatcher IsDerivedFromEmpty = cxxRecordDecl(isDerivedFrom(""));
404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    EXPECT_TRUE(notMatches("class X {};", IsDerivedFromEmpty));
414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  }, "");
424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
4378a0ce4ed3d6cf3ad98e1b07fb1cd43b47793598Benjamin Kramer#endif
444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
45d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter CollingbourneTEST(Finder, DynamicOnlyAcceptsSomeMatchers) {
46d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne  MatchFinder Finder;
47c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_TRUE(Finder.addDynamicMatcher(decl(), nullptr));
48c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_TRUE(Finder.addDynamicMatcher(callExpr(), nullptr));
49c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_TRUE(Finder.addDynamicMatcher(constantArrayType(hasSize(42)),
50c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                                       nullptr));
51d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne
52d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne  // Do not accept non-toplevel matchers.
53c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_FALSE(Finder.addDynamicMatcher(isArrow(), nullptr));
54c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_FALSE(Finder.addDynamicMatcher(hasSize(2), nullptr));
55c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_FALSE(Finder.addDynamicMatcher(hasName("x"), nullptr));
56d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne}
57d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne
58715c9568ee5d75f25dab98229c87bcec880daf5dManuel KlimekTEST(Decl, MatchesDeclarations) {
59715c9568ee5d75f25dab98229c87bcec880daf5dManuel Klimek  EXPECT_TRUE(notMatches("", decl(usingDecl())));
60715c9568ee5d75f25dab98229c87bcec880daf5dManuel Klimek  EXPECT_TRUE(matches("namespace x { class X {}; } using x::X;",
61715c9568ee5d75f25dab98229c87bcec880daf5dManuel Klimek                      decl(usingDecl())));
62715c9568ee5d75f25dab98229c87bcec880daf5dManuel Klimek}
63715c9568ee5d75f25dab98229c87bcec880daf5dManuel Klimek
644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(NameableDeclaration, MatchesVariousDecls) {
652dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher NamedX = namedDecl(hasName("X"));
664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("typedef int X;", NamedX));
674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int X;", NamedX));
684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class foo { virtual void X(); };", NamedX));
694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", NamedX));
704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void foo() { int X; }", NamedX));
714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("namespace X { }", NamedX));
72e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("enum X { A, B, C };", NamedX));
734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("#define X 1", NamedX));
754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
77e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(NameableDeclaration, REMatchesVariousDecls) {
782dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher NamedX = namedDecl(matchesName("::X"));
79e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("typedef int Xa;", NamedX));
80e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("int Xb;", NamedX));
81e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("class foo { virtual void Xc(); };", NamedX));
82e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("void foo() try { } catch(int Xdef) { }", NamedX));
83e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("void foo() { int Xgh; }", NamedX));
84e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("namespace Xij { }", NamedX));
85e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("enum X { A, B, C };", NamedX));
86e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
87e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("#define Xkl 1", NamedX));
88e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
892dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher StartsWithNo = namedDecl(matchesName("::no"));
90e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("int no_foo;", StartsWithNo));
91e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("class foo { virtual void nobody(); };", StartsWithNo));
92e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher Abc = namedDecl(matchesName("a.*b.*c"));
94e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("int abc;", Abc));
95e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("int aFOObBARc;", Abc));
96e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("int cab;", Abc));
97e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("int cabc;", Abc));
98ec33b6f64480df41a6add1f112c7321ba96de378Manuel Klimek
99ec33b6f64480df41a6add1f112c7321ba96de378Manuel Klimek  DeclarationMatcher StartsWithK = namedDecl(matchesName(":k[^:]*$"));
100ec33b6f64480df41a6add1f112c7321ba96de378Manuel Klimek  EXPECT_TRUE(matches("int k;", StartsWithK));
101ec33b6f64480df41a6add1f112c7321ba96de378Manuel Klimek  EXPECT_TRUE(matches("int kAbc;", StartsWithK));
102ec33b6f64480df41a6add1f112c7321ba96de378Manuel Klimek  EXPECT_TRUE(matches("namespace x { int kTest; }", StartsWithK));
103ec33b6f64480df41a6add1f112c7321ba96de378Manuel Klimek  EXPECT_TRUE(matches("class C { int k; };", StartsWithK));
104ec33b6f64480df41a6add1f112c7321ba96de378Manuel Klimek  EXPECT_TRUE(notMatches("class C { int ckc; };", StartsWithK));
105e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
106e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
1074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, MatchClass) {
1082dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ClassMatcher(recordDecl());
109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  llvm::Triple Triple(llvm::sys::getDefaultTargetTriple());
110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (Triple.getOS() != llvm::Triple::Win32 ||
111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Triple.getEnvironment() != llvm::Triple::MSVC)
112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    EXPECT_FALSE(matches("", ClassMatcher));
113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  else
114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // Matches class type_info.
115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    EXPECT_TRUE(matches("", ClassMatcher));
1164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1172dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ClassX = recordDecl(recordDecl(hasName("X")));
1184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X;", ClassX));
1194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {};", ClassX));
1204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("template<class T> class X {};", ClassX));
1214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("", ClassX));
1224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
1234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, ClassIsDerived) {
125a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  DeclarationMatcher IsDerivedFromX = cxxRecordDecl(isDerivedFrom("X"));
1264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsDerivedFromX));
12876dafa7e6487c0b51fadebd16bdefe0e0e23d595Daniel Jasper  EXPECT_TRUE(notMatches("class X {};", IsDerivedFromX));
12976dafa7e6487c0b51fadebd16bdefe0e0e23d595Daniel Jasper  EXPECT_TRUE(notMatches("class X;", IsDerivedFromX));
1304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y;", IsDerivedFromX));
1314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("", IsDerivedFromX));
1324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
133a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  DeclarationMatcher IsAX = cxxRecordDecl(isSameOrDerivedFrom("X"));
13476dafa7e6487c0b51fadebd16bdefe0e0e23d595Daniel Jasper
13576dafa7e6487c0b51fadebd16bdefe0e0e23d595Daniel Jasper  EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsAX));
13676dafa7e6487c0b51fadebd16bdefe0e0e23d595Daniel Jasper  EXPECT_TRUE(matches("class X {};", IsAX));
13776dafa7e6487c0b51fadebd16bdefe0e0e23d595Daniel Jasper  EXPECT_TRUE(matches("class X;", IsAX));
13876dafa7e6487c0b51fadebd16bdefe0e0e23d595Daniel Jasper  EXPECT_TRUE(notMatches("class Y;", IsAX));
13976dafa7e6487c0b51fadebd16bdefe0e0e23d595Daniel Jasper  EXPECT_TRUE(notMatches("", IsAX));
14076dafa7e6487c0b51fadebd16bdefe0e0e23d595Daniel Jasper
1414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher ZIsDerivedFromX =
142a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxRecordDecl(hasName("Z"), isDerivedFrom("X"));
1434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; class Y : public X {}; class Z : public Y {};",
1454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZIsDerivedFromX));
1464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {};"
1484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "template<class T> class Y : public X {};"
1494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "class Z : public Y<int> {};", ZIsDerivedFromX));
1504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {}; template<class T> class Z : public X {};",
1514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      ZIsDerivedFromX));
1524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("template<class T> class X {}; "
1544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "template<class T> class Z : public X<T> {};",
1554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZIsDerivedFromX));
1564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("template<class T, class U=T> class X {}; "
1584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "template<class T> class Z : public X<T> {};",
1594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZIsDerivedFromX));
1604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("template<class X> class A { class Z : public X {}; };",
1624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 ZIsDerivedFromX));
1634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("template<class X> class A { public: class Z : public X {}; }; "
1654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "class X{}; void y() { A<X>::Z z; }", ZIsDerivedFromX));
1664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("template <class T> class X {}; "
1684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "template<class Y> class A { class Z : public X<Y> {}; };",
1694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZIsDerivedFromX));
1704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("template<template<class T> class X> class A { "
1724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "  class Z : public X<int> {}; };", ZIsDerivedFromX));
1734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("template<template<class T> class X> class A { "
1754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "  public: class Z : public X<int> {}; }; "
1764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "template<class T> class X {}; void y() { A<X>::Z z; }",
1774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZIsDerivedFromX));
1784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("template<class X> class A { class Z : public X::D {}; };",
1804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 ZIsDerivedFromX));
1814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("template<class X> class A { public: "
1834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "  class Z : public X::D {}; }; "
1844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "class Y { public: class X {}; typedef X D; }; "
1854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "void y() { A<Y>::Z z; }", ZIsDerivedFromX));
1864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; typedef X Y; class Z : public Y {};",
1884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZIsDerivedFromX));
1894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("template<class T> class Y { typedef typename T::U X; "
1914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "  class Z : public X {}; };", ZIsDerivedFromX));
1924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {}; class Z : public ::X {};",
1934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      ZIsDerivedFromX));
1944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("template<class T> class X {}; "
1964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                "template<class T> class A { class Z : public X<T>::D {}; };",
1974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                ZIsDerivedFromX));
1984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("template<class T> class X { public: typedef X<T> D; }; "
2004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "template<class T> class A { public: "
2014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "  class Z : public X<T>::D {}; }; void y() { A<int>::Z z; }",
2024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZIsDerivedFromX));
2034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("template<class X> class A { class Z : public X::D::E {}; };",
2054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 ZIsDerivedFromX));
2064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; typedef X V; typedef V W; class Z : public W {};",
2084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZIsDerivedFromX));
2094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; class Y : public X {}; "
2114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "typedef Y V; typedef V W; class Z : public W {};",
2124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZIsDerivedFromX));
2134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("template<class T, class U> class X {}; "
2154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "template<class T> class A { class Z : public X<T, int> {}; };",
2164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZIsDerivedFromX));
2174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("template<class X> class D { typedef X A; typedef A B; "
2194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "  typedef B C; class Z : public C {}; };",
2204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 ZIsDerivedFromX));
2214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; typedef X A; typedef A B; "
2234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "class Z : public B {};", ZIsDerivedFromX));
2244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; typedef X A; typedef A B; typedef B C; "
2264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "class Z : public C {};", ZIsDerivedFromX));
2274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class U {}; typedef U X; typedef X V; "
2294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "class Z : public V {};", ZIsDerivedFromX));
2304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Base {}; typedef Base X; "
2324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "class Z : public Base {};", ZIsDerivedFromX));
2334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Base {}; typedef Base Base2; typedef Base2 X; "
2354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "class Z : public Base {};", ZIsDerivedFromX));
2364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Base {}; class Base2 {}; typedef Base2 X; "
2384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "class Z : public Base {};", ZIsDerivedFromX));
2394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class A {}; typedef A X; typedef A Y; "
2414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "class Z : public Y {};", ZIsDerivedFromX));
2424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("template <typename T> class Z;"
2444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "template <> class Z<void> {};"
2454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "template <typename T> class Z : public Z<void> {};",
2464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 IsDerivedFromX));
2474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("template <typename T> class X;"
2494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "template <> class X<void> {};"
2504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "template <typename T> class X : public X<void> {};",
2514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              IsDerivedFromX));
2524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
2534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X {};"
2544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class Z;"
2554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <> class Z<void> {};"
2564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class Z : public Z<void>, public X {};",
2574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      ZIsDerivedFromX));
258987c2f590fade75245e32807ee83c31483e02d8aManuel Klimek  EXPECT_TRUE(
259987c2f590fade75245e32807ee83c31483e02d8aManuel Klimek      notMatches("template<int> struct X;"
260987c2f590fade75245e32807ee83c31483e02d8aManuel Klimek                 "template<int i> struct X : public X<i-1> {};",
261a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                 cxxRecordDecl(isDerivedFrom(recordDecl(hasName("Some"))))));
262987c2f590fade75245e32807ee83c31483e02d8aManuel Klimek  EXPECT_TRUE(matches(
263987c2f590fade75245e32807ee83c31483e02d8aManuel Klimek      "struct A {};"
264987c2f590fade75245e32807ee83c31483e02d8aManuel Klimek      "template<int> struct X;"
265987c2f590fade75245e32807ee83c31483e02d8aManuel Klimek      "template<int i> struct X : public X<i-1> {};"
266987c2f590fade75245e32807ee83c31483e02d8aManuel Klimek      "template<> struct X<0> : public A {};"
267987c2f590fade75245e32807ee83c31483e02d8aManuel Klimek      "struct B : public X<42> {};",
268a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxRecordDecl(hasName("B"), isDerivedFrom(recordDecl(hasName("A"))))));
2694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // FIXME: Once we have better matchers for template type matching,
2714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // get rid of the Variable(...) matching and match the right template
2724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // declarations directly.
2734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  const char *RecursiveTemplateOneParameter =
2744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Base1 {}; class Base2 {};"
2754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class Z;"
2764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <> class Z<void> : public Base1 {};"
2774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <> class Z<int> : public Base2 {};"
2784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <> class Z<float> : public Z<void> {};"
2794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <> class Z<double> : public Z<int> {};"
2804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class Z : public Z<float>, public Z<double> {};"
2814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void f() { Z<float> z_float; Z<double> z_double; Z<char> z_char; }";
2824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
2834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      RecursiveTemplateOneParameter,
2842dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("z_float"),
285a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1")))))));
2864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
2874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      RecursiveTemplateOneParameter,
2882dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("z_float"),
289a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2")))))));
2904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
2914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      RecursiveTemplateOneParameter,
2922dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("z_char"),
293a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1"),
2942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                                                isDerivedFrom("Base2")))))));
2954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  const char *RecursiveTemplateTwoParameters =
2974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Base1 {}; class Base2 {};"
2984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T1, typename T2> class Z;"
2994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class Z<void, T> : public Base1 {};"
3004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class Z<int, T> : public Base2 {};"
3014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class Z<float, T> : public Z<void, T> {};"
3024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class Z<double, T> : public Z<int, T> {};"
3034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T1, typename T2> class Z : "
3044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    public Z<float, T2>, public Z<double, T2> {};"
3054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void f() { Z<float, void> z_float; Z<double, void> z_double; "
3064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "           Z<char, void> z_char; }";
3074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
3084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      RecursiveTemplateTwoParameters,
3092dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("z_float"),
310a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1")))))));
3114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
3124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      RecursiveTemplateTwoParameters,
3132dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("z_float"),
314a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2")))))));
3154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
3164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      RecursiveTemplateTwoParameters,
3172dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("z_char"),
318a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1"),
3192dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                                                isDerivedFrom("Base2")))))));
32020b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper  EXPECT_TRUE(matches(
32120b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper      "namespace ns { class X {}; class Y : public X {}; }",
322a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxRecordDecl(isDerivedFrom("::ns::X"))));
32320b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper  EXPECT_TRUE(notMatches(
32420b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper      "class X {}; class Y : public X {};",
325a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxRecordDecl(isDerivedFrom("::ns::X"))));
32620b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper
32720b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper  EXPECT_TRUE(matches(
32820b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper      "class X {}; class Y : public X {};",
329a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    cxxRecordDecl(isDerivedFrom(recordDecl(hasName("X")).bind("test")))));
330b56da8c0e648d3bfd9bfe82266b9fea6a8df8a00Manuel Klimek
331b56da8c0e648d3bfd9bfe82266b9fea6a8df8a00Manuel Klimek  EXPECT_TRUE(matches(
332b56da8c0e648d3bfd9bfe82266b9fea6a8df8a00Manuel Klimek      "template<typename T> class X {};"
333b56da8c0e648d3bfd9bfe82266b9fea6a8df8a00Manuel Klimek      "template<typename T> using Z = X<T>;"
334b56da8c0e648d3bfd9bfe82266b9fea6a8df8a00Manuel Klimek      "template <typename T> class Y : Z<T> {};",
335a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    cxxRecordDecl(isDerivedFrom(namedDecl(hasName("X"))))));
3364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
3374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
3386a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin VaneTEST(DeclarationMatcher, hasMethod) {
3396a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane  EXPECT_TRUE(matches("class A { void func(); };",
340a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxRecordDecl(hasMethod(hasName("func")))));
3416a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane  EXPECT_TRUE(notMatches("class A { void func(); };",
342a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxRecordDecl(hasMethod(isPublic()))));
3436a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane}
3446a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane
34508f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel JasperTEST(DeclarationMatcher, ClassDerivedFromDependentTemplateSpecialization) {
34608f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper  EXPECT_TRUE(matches(
34708f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper     "template <typename T> struct A {"
34808f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper     "  template <typename T2> struct F {};"
34908f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper     "};"
35008f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper     "template <typename T> struct B : A<T>::template F<T> {};"
35108f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper     "B<int> b;",
352a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    cxxRecordDecl(hasName("B"), isDerivedFrom(recordDecl()))));
35308f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper}
35408f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper
355742d9e77e32f014194679575c97c6bb4fd0998c4Edwin VaneTEST(DeclarationMatcher, hasDeclContext) {
356742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(matches(
357742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane      "namespace N {"
358742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane      "  namespace M {"
359742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane      "    class D {};"
360742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane      "  }"
361742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane      "}",
362abe922342d67d4ffe05b366a5a2af972185272f8Daniel Jasper      recordDecl(hasDeclContext(namespaceDecl(hasName("M"))))));
363742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(notMatches(
364742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane      "namespace N {"
365742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane      "  namespace M {"
366742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane      "    class D {};"
367742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane      "  }"
368742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane      "}",
369abe922342d67d4ffe05b366a5a2af972185272f8Daniel Jasper      recordDecl(hasDeclContext(namespaceDecl(hasName("N"))))));
370abe922342d67d4ffe05b366a5a2af972185272f8Daniel Jasper
371abe922342d67d4ffe05b366a5a2af972185272f8Daniel Jasper  EXPECT_TRUE(matches("namespace {"
372abe922342d67d4ffe05b366a5a2af972185272f8Daniel Jasper                      "  namespace M {"
373abe922342d67d4ffe05b366a5a2af972185272f8Daniel Jasper                      "    class D {};"
374abe922342d67d4ffe05b366a5a2af972185272f8Daniel Jasper                      "  }"
375abe922342d67d4ffe05b366a5a2af972185272f8Daniel Jasper                      "}",
376abe922342d67d4ffe05b366a5a2af972185272f8Daniel Jasper                      recordDecl(hasDeclContext(namespaceDecl(
377abe922342d67d4ffe05b366a5a2af972185272f8Daniel Jasper                          hasName("M"), hasDeclContext(namespaceDecl()))))));
378176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
379176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("class D{};", decl(hasDeclContext(decl()))));
380176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
381176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
3820e2c34f92f00628d48968dfea096d36381f494cbStephen HinesTEST(DeclarationMatcher, translationUnitDecl) {
3830e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  const std::string Code = "int MyVar1;\n"
3840e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                           "namespace NameSpace {\n"
3850e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                           "int MyVar2;\n"
3860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                           "}  // namespace NameSpace\n";
3870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(matches(
3880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      Code, varDecl(hasName("MyVar1"), hasDeclContext(translationUnitDecl()))));
3890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_FALSE(matches(
3900e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      Code, varDecl(hasName("MyVar2"), hasDeclContext(translationUnitDecl()))));
3910e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(matches(
3920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      Code,
3930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      varDecl(hasName("MyVar2"),
3940e2c34f92f00628d48968dfea096d36381f494cbStephen Hines              hasDeclContext(decl(hasDeclContext(translationUnitDecl()))))));
3950e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
3960e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
397176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(DeclarationMatcher, LinkageSpecification) {
398176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("extern \"C\" { void foo() {}; }", linkageSpecDecl()));
399176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("void foo() {};", linkageSpecDecl()));
400742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane}
401742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane
4028456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(ClassTemplate, DoesNotMatchClass) {
4032dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ClassX = classTemplateDecl(hasName("X"));
4048456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches("class X;", ClassX));
4058456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches("class X {};", ClassX));
4068456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
4078456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
4088456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(ClassTemplate, MatchesClassTemplate) {
4092dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ClassX = classTemplateDecl(hasName("X"));
4108456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(matches("template<typename T> class X {};", ClassX));
4118456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(matches("class Z { template<class T> class X {}; };", ClassX));
4128456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
4138456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
4148456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(ClassTemplate, DoesNotMatchClassTemplateExplicitSpecialization) {
4158456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches("template<typename T> class X { };"
4168456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko                         "template<> class X<int> { int a; };",
4172dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              classTemplateDecl(hasName("X"),
4182dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                                hasDescendant(fieldDecl(hasName("a"))))));
4198456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
4208456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
4218456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(ClassTemplate, DoesNotMatchClassTemplatePartialSpecialization) {
4228456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches("template<typename T, typename U> class X { };"
4238456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko                         "template<typename T> class X<T, int> { int a; };",
4242dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              classTemplateDecl(hasName("X"),
4252dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                                hasDescendant(fieldDecl(hasName("a"))))));
4268456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
4278456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
4286a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(AllOf, AllOverloadsWork) {
4296a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  const char Program[] =
4307f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane      "struct T { };"
4317f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane      "int f(int, T*, int, int);"
4327f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane      "void g(int x) { T t; f(x, &t, 3, 4); }";
4336a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(matches(Program,
4342dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      callExpr(allOf(callee(functionDecl(hasName("f"))),
4352dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                     hasArgument(0, declRefExpr(to(varDecl())))))));
4366a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(matches(Program,
4372dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      callExpr(allOf(callee(functionDecl(hasName("f"))),
4382dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                     hasArgument(0, declRefExpr(to(varDecl()))),
4392dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                     hasArgument(1, hasType(pointsTo(
4402dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                                        recordDecl(hasName("T")))))))));
4417f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane  EXPECT_TRUE(matches(Program,
4427f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane      callExpr(allOf(callee(functionDecl(hasName("f"))),
4437f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane                     hasArgument(0, declRefExpr(to(varDecl()))),
4447f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane                     hasArgument(1, hasType(pointsTo(
4457f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane                                        recordDecl(hasName("T"))))),
4467f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane                     hasArgument(2, integerLiteral(equals(3)))))));
4477f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane  EXPECT_TRUE(matches(Program,
4487f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane      callExpr(allOf(callee(functionDecl(hasName("f"))),
4497f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane                     hasArgument(0, declRefExpr(to(varDecl()))),
4507f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane                     hasArgument(1, hasType(pointsTo(
4517f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane                                        recordDecl(hasName("T"))))),
4527f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane                     hasArgument(2, integerLiteral(equals(3))),
4537f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane                     hasArgument(3, integerLiteral(equals(4)))))));
4546a12449ec8862211856447d3df4c082a346339f2Daniel Jasper}
4556a12449ec8862211856447d3df4c082a346339f2Daniel Jasper
456a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST(ConstructVariadic, MismatchedTypes_Regression) {
4574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
458a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      matches("const int a = 0;",
459a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              internal::DynTypedMatcher::constructVariadic(
460a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                  internal::DynTypedMatcher::VO_AnyOf,
461a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                  ast_type_traits::ASTNodeKind::getFromNodeKind<QualType>(),
462a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                  {isConstQualified(), arrayType()})
463a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                  .convertTo<QualType>()));
464a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}
465a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
466a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST(DeclarationMatcher, MatchAnyOf) {
467a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  DeclarationMatcher YOrZDerivedFromX = cxxRecordDecl(
468a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      anyOf(hasName("Y"), allOf(isDerivedFrom("X"), hasName("Z"))));
469a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("class X {}; class Z : public X {};", YOrZDerivedFromX));
4704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y {};", YOrZDerivedFromX));
4714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
4724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X {}; class W : public X {};", YOrZDerivedFromX));
4734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Z {};", YOrZDerivedFromX));
4744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
475ff2fcb8db242a54f72bbb4e5595261e12672ed66Daniel Jasper  DeclarationMatcher XOrYOrZOrU =
4762dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U")));
477ff2fcb8db242a54f72bbb4e5595261e12672ed66Daniel Jasper  EXPECT_TRUE(matches("class X {};", XOrYOrZOrU));
478ff2fcb8db242a54f72bbb4e5595261e12672ed66Daniel Jasper  EXPECT_TRUE(notMatches("class V {};", XOrYOrZOrU));
479ff2fcb8db242a54f72bbb4e5595261e12672ed66Daniel Jasper
4804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher XOrYOrZOrUOrV =
4812dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U"),
4822dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                       hasName("V")));
4834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {};", XOrYOrZOrUOrV));
4844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y {};", XOrYOrZOrUOrV));
4854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Z {};", XOrYOrZOrUOrV));
4864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class U {};", XOrYOrZOrUOrV));
4874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class V {};", XOrYOrZOrUOrV));
4884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A {};", XOrYOrZOrUOrV));
489176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
490176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  StatementMatcher MixedTypes = stmt(anyOf(ifStmt(), binaryOperator()));
491176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("int F() { return 1 + 2; }", MixedTypes));
492176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("int F() { if (true) return 1; }", MixedTypes));
493176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("int F() { return 1; }", MixedTypes));
494a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
495a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(
496a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      matches("void f() try { } catch (int) { } catch (...) { }",
497a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              cxxCatchStmt(anyOf(hasDescendant(varDecl()), isCatchAll()))));
4984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
4994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, MatchHas) {
5012dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher HasClassX = recordDecl(has(recordDecl(hasName("X"))));
5024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { class X {}; };", HasClassX));
5034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {};", HasClassX));
5044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher YHasClassX =
5062dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("Y"), has(recordDecl(hasName("X"))));
5074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { class X {}; };", YHasClassX));
5084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class X {};", YHasClassX));
5094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
5104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { class Z { class X {}; }; };", YHasClassX));
5114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
5124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, MatchHasRecursiveAllOf) {
5144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher Recursive =
5152dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper    recordDecl(
5162dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      has(recordDecl(
5172dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper        has(recordDecl(hasName("X"))),
5182dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper        has(recordDecl(hasName("Y"))),
5194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek        hasName("Z"))),
5202dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      has(recordDecl(
5212dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper        has(recordDecl(hasName("A"))),
5222dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper        has(recordDecl(hasName("B"))),
5234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek        hasName("C"))),
5244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      hasName("F"));
5254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
5274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class F {"
5284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class Z {"
5294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class X {};"
5304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class Y {};"
5314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
5324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class C {"
5334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class A {};"
5344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class B {};"
5354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
5364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};", Recursive));
5374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
5394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class F {"
5404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class Z {"
5414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class A {};"
5424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class X {};"
5434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class Y {};"
5444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
5454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class C {"
5464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class X {};"
5474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class A {};"
5484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class B {};"
5494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
5504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};", Recursive));
5514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
5534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class O1 {"
5544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class O2 {"
5554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class F {"
5564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      class Z {"
5574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class A {};"
5584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class X {};"
5594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class Y {};"
5604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      };"
5614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      class C {"
5624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class X {};"
5634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class A {};"
5644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class B {};"
5654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      };"
5664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    };"
5674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
5684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};", Recursive));
5694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
5704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, MatchHasRecursiveAnyOf) {
5724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher Recursive =
5732dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
5744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          anyOf(
5752dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              has(recordDecl(
5764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                  anyOf(
5772dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      has(recordDecl(
5784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                          hasName("X"))),
5792dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      has(recordDecl(
5804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                          hasName("Y"))),
5814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      hasName("Z")))),
5822dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              has(recordDecl(
5834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                  anyOf(
5844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      hasName("C"),
5852dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      has(recordDecl(
5864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                          hasName("A"))),
5872dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      has(recordDecl(
5884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                          hasName("B")))))),
5894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              hasName("F")));
5904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class F {};", Recursive));
5924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Z {};", Recursive));
5934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class C {};", Recursive));
5944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class M { class N { class X {}; }; };", Recursive));
5954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class M { class N { class B {}; }; };", Recursive));
5964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
5974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class O1 { class O2 {"
5984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "  class M { class N { class B {}; }; }; "
5994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "}; };", Recursive));
6004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
6014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
6024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, MatchNot) {
6034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher NotClassX =
604a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    cxxRecordDecl(
6054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          isDerivedFrom("Y"),
6064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          unless(hasName("X")));
6074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("", NotClassX));
6084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y {};", NotClassX));
6094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y {}; class Z : public Y {};", NotClassX));
6104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y {}; class X : public Y {};", NotClassX));
6114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
6124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y {}; class Z {}; class X : public Y {};",
6134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 NotClassX));
6144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
6154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher ClassXHasNotClassY =
6162dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
6174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          hasName("X"),
6182dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          has(recordDecl(hasName("Z"))),
6194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          unless(
6202dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              has(recordDecl(hasName("Y")))));
6214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { class Z {}; };", ClassXHasNotClassY));
6224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class X { class Y {}; class Z {}; };",
6234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                         ClassXHasNotClassY));
624176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
625176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  DeclarationMatcher NamedNotRecord =
626176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      namedDecl(hasName("Foo"), unless(recordDecl()));
627176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("void Foo(){}", NamedNotRecord));
628176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("struct Foo {};", NamedNotRecord));
6294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
6304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
6314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, HasDescendant) {
6324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher ZDescendantClassX =
6332dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
6342dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasDescendant(recordDecl(hasName("X"))),
6354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          hasName("Z"));
6364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Z { class X {}; };", ZDescendantClassX));
6374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
6384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Z { class Y { class X {}; }; };", ZDescendantClassX));
6394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
6404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Z { class A { class Y { class X {}; }; }; };",
6414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZDescendantClassX));
6424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
6434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Z { class A { class B { class Y { class X {}; }; }; }; };",
6444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZDescendantClassX));
6454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Z {};", ZDescendantClassX));
6464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
6474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher ZDescendantClassXHasClassY =
6482dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
6492dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasDescendant(recordDecl(has(recordDecl(hasName("Y"))),
6504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                              hasName("X"))),
6514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          hasName("Z"));
6524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Z { class X { class Y {}; }; };",
6534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZDescendantClassXHasClassY));
6544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
6554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Z { class A { class B { class X { class Y {}; }; }; }; };",
6564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZDescendantClassXHasClassY));
6574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
6584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Z {"
6594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class A {"
6604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class B {"
6614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      class X {"
6624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class C {"
6634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "          class Y {};"
6644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        };"
6654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      };"
6664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    }; "
6674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
6684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};", ZDescendantClassXHasClassY));
6694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
6704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher ZDescendantClassXDescendantClassY =
6712dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
6722dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasDescendant(recordDecl(hasDescendant(recordDecl(hasName("Y"))),
6732dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                                   hasName("X"))),
6744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          hasName("Z"));
6754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
6764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Z { class A { class X { class B { class Y {}; }; }; }; };",
6774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZDescendantClassXDescendantClassY));
6784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
6794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Z {"
6804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class A {"
6814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class X {"
6824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      class B {"
6834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class Y {};"
6844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      };"
6854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      class Y {};"
6864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    };"
6874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
6884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};", ZDescendantClassXDescendantClassY));
6894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
6904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
691176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(DeclarationMatcher, HasDescendantMemoization) {
692176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  DeclarationMatcher CannotMemoize =
693176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      decl(hasDescendant(typeLoc().bind("x")), has(decl()));
694176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("void f() { int i; }", CannotMemoize));
695176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
696176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
697176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(DeclarationMatcher, HasDescendantMemoizationUsesRestrictKind) {
698176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  auto Name = hasName("i");
699176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  auto VD = internal::Matcher<VarDecl>(Name).dynCastTo<Decl>();
700176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  auto RD = internal::Matcher<RecordDecl>(Name).dynCastTo<Decl>();
701176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // Matching VD first should not make a cache hit for RD.
702176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("void f() { int i; }",
703176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                         decl(hasDescendant(VD), hasDescendant(RD))));
704176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("void f() { int i; }",
705176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                         decl(hasDescendant(RD), hasDescendant(VD))));
706176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // Not matching RD first should not make a cache hit for VD either.
707176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("void f() { int i; }",
708176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      decl(anyOf(hasDescendant(RD), hasDescendant(VD)))));
709176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
710176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
711176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(DeclarationMatcher, HasAttr) {
712176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("struct __attribute__((warn_unused)) X {};",
713176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      decl(hasAttr(clang::attr::WarnUnused))));
714176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_FALSE(matches("struct X {};",
715176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                       decl(hasAttr(clang::attr::WarnUnused))));
716176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
717176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
718176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(DeclarationMatcher, MatchCudaDecl) {
719176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matchesWithCuda("__global__ void f() { }"
720176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                              "void g() { f<<<1, 2>>>(); }",
721a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                              cudaKernelCallExpr()));
722176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matchesWithCuda("__attribute__((device)) void f() {}",
723176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                              hasAttr(clang::attr::CUDADevice)));
724176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatchesWithCuda("void f() {}",
725a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                                 cudaKernelCallExpr()));
726176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_FALSE(notMatchesWithCuda("__attribute__((global)) void f() {}",
727176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                  hasAttr(clang::attr::CUDAGlobal)));
728176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
729176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
730a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper// Implements a run method that returns whether BoundNodes contains a
731a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper// Decl bound to Id that can be dynamically cast to T.
732a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper// Optionally checks that the check succeeded a specific number of times.
733a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jaspertemplate <typename T>
734a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasperclass VerifyIdIsBoundTo : public BoundNodesCallback {
735a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasperpublic:
736a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Create an object that checks that a node of type \c T was bound to \c Id.
737a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Does not check for a certain number of matches.
738a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  explicit VerifyIdIsBoundTo(llvm::StringRef Id)
739a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    : Id(Id), ExpectedCount(-1), Count(0) {}
740a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
741a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Create an object that checks that a node of type \c T was bound to \c Id.
742a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Checks that there were exactly \c ExpectedCount matches.
743a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  VerifyIdIsBoundTo(llvm::StringRef Id, int ExpectedCount)
744a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    : Id(Id), ExpectedCount(ExpectedCount), Count(0) {}
745a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
746a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Create an object that checks that a node of type \c T was bound to \c Id.
747a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Checks that there was exactly one match with the name \c ExpectedName.
748a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Note that \c T must be a NamedDecl for this to work.
749374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek  VerifyIdIsBoundTo(llvm::StringRef Id, llvm::StringRef ExpectedName,
750374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek                    int ExpectedCount = 1)
751374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      : Id(Id), ExpectedCount(ExpectedCount), Count(0),
752374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek        ExpectedName(ExpectedName) {}
753a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
754651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void onEndOfTranslationUnit() override {
755a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    if (ExpectedCount != -1)
756a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      EXPECT_EQ(ExpectedCount, Count);
757a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    if (!ExpectedName.empty())
758a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      EXPECT_EQ(ExpectedName, Name);
759d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne    Count = 0;
760d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne    Name.clear();
761d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne  }
762d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne
76358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  ~VerifyIdIsBoundTo() override {
764d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne    EXPECT_EQ(0, Count);
765d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne    EXPECT_EQ("", Name);
766a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  }
767a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
76858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  bool run(const BoundNodes *Nodes) override {
7693f0e0402d8cd40b428f975f1a3607dbbd94d2ca6Peter Collingbourne    const BoundNodes::IDToNodeMap &M = Nodes->getMap();
770a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    if (Nodes->getNodeAs<T>(Id)) {
771a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      ++Count;
772a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      if (const NamedDecl *Named = Nodes->getNodeAs<NamedDecl>(Id)) {
773a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper        Name = Named->getNameAsString();
774a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      } else if (const NestedNameSpecifier *NNS =
775a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                 Nodes->getNodeAs<NestedNameSpecifier>(Id)) {
776a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper        llvm::raw_string_ostream OS(Name);
777a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper        NNS->print(OS, PrintingPolicy(LangOptions()));
778a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      }
7793f0e0402d8cd40b428f975f1a3607dbbd94d2ca6Peter Collingbourne      BoundNodes::IDToNodeMap::const_iterator I = M.find(Id);
7803f0e0402d8cd40b428f975f1a3607dbbd94d2ca6Peter Collingbourne      EXPECT_NE(M.end(), I);
7813f0e0402d8cd40b428f975f1a3607dbbd94d2ca6Peter Collingbourne      if (I != M.end())
7823f0e0402d8cd40b428f975f1a3607dbbd94d2ca6Peter Collingbourne        EXPECT_EQ(Nodes->getNodeAs<T>(Id), I->second.get<T>());
783a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      return true;
784a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    }
785c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    EXPECT_TRUE(M.count(Id) == 0 ||
786c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                M.find(Id)->second.template get<T>() == nullptr);
787a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    return false;
788a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  }
789a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
79058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  bool run(const BoundNodes *Nodes, ASTContext *Context) override {
791452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper    return run(Nodes);
792452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper  }
793452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper
794a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasperprivate:
795a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  const std::string Id;
796a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  const int ExpectedCount;
797a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  int Count;
798a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  const std::string ExpectedName;
799a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  std::string Name;
800a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper};
801a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
802a267cf6f87dc695143d65fc61ec1744564f55932Daniel JasperTEST(HasDescendant, MatchesDescendantTypes) {
803a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int i = 3; }",
804a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      decl(hasDescendant(loc(builtinType())))));
805a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int i = 3; }",
806a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      stmt(hasDescendant(builtinType()))));
807a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
808a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int i = 3; }",
809a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      stmt(hasDescendant(loc(builtinType())))));
810a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int i = 3; }",
811a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      stmt(hasDescendant(qualType(builtinType())))));
812a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
813a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(notMatches("void f() { float f = 2.0f; }",
814a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                         stmt(hasDescendant(isInteger()))));
815a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
816a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
817a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      "void f() { int a; float c; int d; int e; }",
818a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      functionDecl(forEachDescendant(
819a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper          varDecl(hasDescendant(isInteger())).bind("x"))),
820a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      new VerifyIdIsBoundTo<Decl>("x", 3)));
821a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper}
822a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
823a267cf6f87dc695143d65fc61ec1744564f55932Daniel JasperTEST(HasDescendant, MatchesDescendantsOfTypes) {
824a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int*** i; }",
825a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      qualType(hasDescendant(builtinType()))));
826a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int*** i; }",
827a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      qualType(hasDescendant(
828a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                          pointerType(pointee(builtinType()))))));
829a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int*** i; }",
8305be093c0ef46c7749c942d0d9056af6dc3d591a4David Blaikie                      typeLoc(hasDescendant(loc(builtinType())))));
831a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
832a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
833a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      "void f() { int*** i; }",
834a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      qualType(asString("int ***"), forEachDescendant(pointerType().bind("x"))),
835a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      new VerifyIdIsBoundTo<Type>("x", 2)));
836a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper}
837a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
838a267cf6f87dc695143d65fc61ec1744564f55932Daniel JasperTEST(Has, MatchesChildrenOfTypes) {
839a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("int i;",
840a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      varDecl(hasName("i"), has(isInteger()))));
841a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(notMatches("int** i;",
842a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                         varDecl(hasName("i"), has(isInteger()))));
843a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
844a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      "int (*f)(float, int);",
845a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      qualType(functionType(), forEach(qualType(isInteger()).bind("x"))),
846a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      new VerifyIdIsBoundTo<QualType>("x", 2)));
847a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper}
848a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
849a267cf6f87dc695143d65fc61ec1744564f55932Daniel JasperTEST(Has, MatchesChildTypes) {
850a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches(
851a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      "int* i;",
852a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      varDecl(hasName("i"), hasType(qualType(has(builtinType()))))));
853a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(notMatches(
854a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      "int* i;",
855a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      varDecl(hasName("i"), hasType(qualType(has(pointerType()))))));
856a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper}
857a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
858176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(ValueDecl, Matches) {
859176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("enum EnumType { EnumValue };",
860176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      valueDecl(hasType(asString("enum EnumType")))));
861176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("void FunctionDecl();",
862176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      valueDecl(hasType(asString("void (void)")))));
863176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
864176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
865e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Enum, DoesNotMatchClasses) {
866e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("class X {};", enumDecl(hasName("X"))));
867e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
868e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
869e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Enum, MatchesEnums) {
870e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("enum X {};", enumDecl(hasName("X"))));
871e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
872e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
873e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(EnumConstant, Matches) {
8742dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher Matcher = enumConstantDecl(hasName("A"));
875e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("enum X{ A };", Matcher));
876e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("enum X{ B };", Matcher));
877e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("enum X {};", Matcher));
878e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
879e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
8804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementMatcher, Has) {
8814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher HasVariableI =
8822dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      expr(hasType(pointsTo(recordDecl(hasName("X")))),
8832dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper           has(declRefExpr(to(varDecl(hasName("i"))))));
8844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
8864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X; X *x(int); void c() { int i; x(i); }", HasVariableI));
8874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
8884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X; X *x(int); void c() { int i; x(42); }", HasVariableI));
8894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
8904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementMatcher, HasDescendant) {
8924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher HasDescendantVariableI =
8932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      expr(hasType(pointsTo(recordDecl(hasName("X")))),
8942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper           hasDescendant(declRefExpr(to(varDecl(hasName("i"))))));
8954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
8974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X; X *x(bool); bool b(int); void c() { int i; x(b(i)); }",
8984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      HasDescendantVariableI));
8994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
9004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X; X *x(bool); bool b(int); void c() { int i; x(b(42)); }",
9014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      HasDescendantVariableI));
9024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
9034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(TypeMatcher, MatchesClassType) {
9052dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  TypeMatcher TypeA = hasDeclaration(recordDecl(hasName("A")));
9064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class A { public: A *a; };", TypeA));
9084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A {};", TypeA));
9094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
910a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  TypeMatcher TypeDerivedFromA =
911a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      hasDeclaration(cxxRecordDecl(isDerivedFrom("A")));
9124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class A {}; class B : public A { public: B *b; };",
9144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              TypeDerivedFromA));
9154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A {};", TypeA));
9164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  TypeMatcher TypeAHasClassB = hasDeclaration(
9182dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("A"), has(recordDecl(hasName("B")))));
9194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
9214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class A { public: A *a; class B {}; };", TypeAHasClassB));
922a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
923a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matchesC("struct S {}; void f(void) { struct S s; }",
924a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                       varDecl(hasType(namedDecl(hasName("S"))))));
925a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}
926a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
927a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST(TypeMatcher, MatchesDeclTypes) {
928a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  // TypedefType -> TypedefNameDecl
929a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("typedef int I; void f(I i);",
930a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      parmVarDecl(hasType(namedDecl(hasName("I"))))));
931a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  // ObjCObjectPointerType
932a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matchesObjC("@interface Foo @end void f(Foo *f);",
933a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                          parmVarDecl(hasType(objcObjectPointerType()))));
934a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  // ObjCObjectPointerType -> ObjCInterfaceType -> ObjCInterfaceDecl
935a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matchesObjC(
936a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      "@interface Foo @end void f(Foo *f);",
937a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      parmVarDecl(hasType(pointsTo(objcInterfaceDecl(hasName("Foo")))))));
938a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  // TemplateTypeParmType
939a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("template <typename T> void f(T t);",
940a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      parmVarDecl(hasType(templateTypeParmType()))));
941a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  // TemplateTypeParmType -> TemplateTypeParmDecl
942a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("template <typename T> void f(T t);",
943a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      parmVarDecl(hasType(namedDecl(hasName("T"))))));
944a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  // InjectedClassNameType
945a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("template <typename T> struct S {"
946a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      "  void f(S s);"
947a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      "};",
948a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      parmVarDecl(hasType(injectedClassNameType()))));
949a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("template <typename T> struct S {"
950a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         "  void g(S<T> s);"
951a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         "};",
952a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         parmVarDecl(hasType(injectedClassNameType()))));
953a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  // InjectedClassNameType -> CXXRecordDecl
954a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("template <typename T> struct S {"
955a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      "  void f(S s);"
956a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      "};",
957a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      parmVarDecl(hasType(namedDecl(hasName("S"))))));
958a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
959a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  static const char Using[] = "template <typename T>"
960a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                              "struct Base {"
961a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                              "  typedef T Foo;"
962a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                              "};"
963a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                              ""
964a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                              "template <typename T>"
965a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                              "struct S : private Base<T> {"
966a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                              "  using typename Base<T>::Foo;"
967a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                              "  void f(Foo);"
968a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                              "};";
969a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  // UnresolvedUsingTypenameDecl
970a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches(Using, unresolvedUsingTypenameDecl(hasName("Foo"))));
971a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  // UnresolvedUsingTypenameType -> UnresolvedUsingTypenameDecl
972a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches(Using, parmVarDecl(hasType(namedDecl(hasName("Foo"))))));
9734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
9744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, BindMatchedNodes) {
9762dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ClassX = has(recordDecl(hasName("::X")).bind("x"));
9774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class X {};",
979a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      ClassX, new VerifyIdIsBoundTo<CXXRecordDecl>("x")));
9804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse("class X {};",
982a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      ClassX, new VerifyIdIsBoundTo<CXXRecordDecl>("other-id")));
9834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  TypeMatcher TypeAHasClassB = hasDeclaration(
9852dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("A"), has(recordDecl(hasName("B")).bind("b"))));
9864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class A { public: A *a; class B {}; };",
9884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      TypeAHasClassB,
989a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<Decl>("b")));
9904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9912dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher MethodX =
992a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      callExpr(callee(cxxMethodDecl(hasName("x")))).bind("x");
9934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class A { void x() { x(); } };",
9954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      MethodX,
996a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<CXXMemberCallExpr>("x")));
997e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
998e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
999e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Matcher, BindTheSameNameInAlternatives) {
1000e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  StatementMatcher matcher = anyOf(
1001e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      binaryOperator(hasOperatorName("+"),
10022dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                     hasLHS(expr().bind("x")),
1003e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                     hasRHS(integerLiteral(equals(0)))),
1004e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      binaryOperator(hasOperatorName("+"),
1005e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                     hasLHS(integerLiteral(equals(0))),
10062dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                     hasRHS(expr().bind("x"))));
1007e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
1008e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
1009e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      // The first branch of the matcher binds x to 0 but then fails.
1010e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      // The second branch binds x to f() and succeeds.
1011e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "int f() { return 0 + f(); }",
1012e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      matcher,
1013a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<CallExpr>("x")));
10144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
10154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
101666341c596f93d0c6475d839db94072b8ebd1cf5bManuel KlimekTEST(Matcher, BindsIDForMemoizedResults) {
101766341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek  // Using the same matcher in two match expressions will make memoization
101866341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek  // kick in.
101966341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek  DeclarationMatcher ClassX = recordDecl(hasName("X")).bind("x");
102066341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
102166341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek      "class A { class B { class X {}; }; };",
102266341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek      DeclarationMatcher(anyOf(
102366341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek          recordDecl(hasName("A"), hasDescendant(ClassX)),
102466341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek          recordDecl(hasName("B"), hasDescendant(ClassX)))),
1025a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<Decl>("x", 2)));
102666341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek}
102766341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek
1028189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel JasperTEST(HasDeclaration, HasDeclarationOfEnumType) {
1029189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper  EXPECT_TRUE(matches("enum X {}; void y(X *x) { x; }",
1030189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper                      expr(hasType(pointsTo(
1031189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper                          qualType(hasDeclaration(enumDecl(hasName("X")))))))));
1032189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper}
1033189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper
1034b45083d08377a8b9528401fdafd7210e78895dbeEdwin VaneTEST(HasDeclaration, HasGetDeclTraitTest) {
1035b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane  EXPECT_TRUE(internal::has_getDecl<TypedefType>::value);
1036b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane  EXPECT_TRUE(internal::has_getDecl<RecordType>::value);
1037b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane  EXPECT_FALSE(internal::has_getDecl<TemplateSpecializationType>::value);
1038b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane}
1039b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane
1040523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin VaneTEST(HasDeclaration, HasDeclarationOfTypeWithDecl) {
1041523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane  EXPECT_TRUE(matches("typedef int X; X a;",
1042523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane                      varDecl(hasName("a"),
1043523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane                              hasType(typedefType(hasDeclaration(decl()))))));
1044523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane
1045523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane  // FIXME: Add tests for other types with getDecl() (e.g. RecordType)
1046523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane}
1047523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane
10483abf77872ca6c520903f9174cf6cd89a50df2714Edwin VaneTEST(HasDeclaration, HasDeclarationOfTemplateSpecializationType) {
10493abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane  EXPECT_TRUE(matches("template <typename T> class A {}; A<int> a;",
10503abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane                      varDecl(hasType(templateSpecializationType(
10513abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane                          hasDeclaration(namedDecl(hasName("A"))))))));
10523abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane}
10533abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane
10544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasType, TakesQualTypeMatcherAndMatchesExpr) {
10552dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
10564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10572dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX))));
10584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X {}; void y(X *x) { x; }",
10602dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 expr(hasType(ClassX))));
10614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; void y(X *x) { x; }",
10632dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              expr(hasType(pointsTo(ClassX)))));
10644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
10654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasType, TakesQualTypeMatcherAndMatchesValueDecl) {
10672dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
10684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10692dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX))));
10704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10712dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX))));
10724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; void y() { X *x; }",
10742dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              varDecl(hasType(pointsTo(ClassX)))));
10754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
10764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasType, TakesDeclMatcherAndMatchesExpr) {
10782dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ClassX = recordDecl(hasName("X"));
10794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10802dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX))));
10814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X {}; void y(X *x) { x; }",
10832dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 expr(hasType(ClassX))));
10844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
10854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasType, TakesDeclMatcherAndMatchesValueDecl) {
10872dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ClassX = recordDecl(hasName("X"));
10884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10892dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX))));
10904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10912dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX))));
10924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
10934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10941a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel KlimekTEST(HasTypeLoc, MatchesDeclaratorDecls) {
10951a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek  EXPECT_TRUE(matches("int x;",
10961a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek                      varDecl(hasName("x"), hasTypeLoc(loc(asString("int"))))));
10971a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek
10981a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek  // Make sure we don't crash on implicit constructors.
10991a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek  EXPECT_TRUE(notMatches("class X {}; X x;",
11001a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek                         declaratorDecl(hasTypeLoc(loc(asString("int"))))));
11011a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek}
11021a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek
11034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, Call) {
11044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // FIXME: Do we want to overload Call() to directly take
1105e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // Matcher<Decl>, too?
1106a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  StatementMatcher MethodX =
1107a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      callExpr(hasDeclaration(cxxMethodDecl(hasName("x"))));
11084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { x(); } };", MethodX));
11104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() {} };", MethodX));
11114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11122dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher MethodOnY =
1113a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxMemberCallExpr(on(hasType(recordDecl(hasName("Y")))));
11144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
11164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
11174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
11184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
11194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
11204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
11214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
11224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
11234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 MethodOnY));
11244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
11254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
11264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 MethodOnY));
11274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
11284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
11294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 MethodOnY));
11304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher MethodOnYPointer =
1132a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxMemberCallExpr(on(hasType(pointsTo(recordDecl(hasName("Y"))))));
11334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
11354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
11364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnYPointer));
11374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
11384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
11394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnYPointer));
11404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
11414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
11424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnYPointer));
11434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
11444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
11454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 MethodOnYPointer));
11464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
11474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
11484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 MethodOnYPointer));
11494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
11504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
115131f7c08a0d2b140bf31a08894d1948649de53c15Daniel JasperTEST(Matcher, Lambda) {
1152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_TRUE(matches("auto f = [] (int i) { return i; };",
115331f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      lambdaExpr()));
115431f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper}
115531f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper
115631f7c08a0d2b140bf31a08894d1948649de53c15Daniel JasperTEST(Matcher, ForRange) {
11571a00fee3933066024a2398f9456e5d6bc74344b9Daniel Jasper  EXPECT_TRUE(matches("int as[] = { 1, 2, 3 };"
11581a00fee3933066024a2398f9456e5d6bc74344b9Daniel Jasper                      "void f() { for (auto &a : as); }",
1159a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxForRangeStmt()));
116031f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  EXPECT_TRUE(notMatches("void f() { for (int i; i<5; ++i); }",
1161a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxForRangeStmt()));
116231f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper}
116331f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper
1164c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen HinesTEST(Matcher, SubstNonTypeTemplateParm) {
1165c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_FALSE(matches("template<int N>\n"
1166c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                       "struct A {  static const int n = 0; };\n"
1167c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                       "struct B : public A<42> {};",
1168c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                       substNonTypeTemplateParmExpr()));
1169c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_TRUE(matches("template<int N>\n"
1170c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                      "struct A {  static const int n = N; };\n"
1171c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                      "struct B : public A<42> {};",
1172c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                      substNonTypeTemplateParmExpr()));
1173c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines}
1174c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
1175a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST(Matcher, NonTypeTemplateParmDecl) {
1176a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("template <int N> void f();",
1177a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      nonTypeTemplateParmDecl(hasName("N"))));
1178a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(
1179a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      notMatches("template <typename T> void f();", nonTypeTemplateParmDecl()));
1180a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}
1181a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
1182a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST(Matcher, templateTypeParmDecl) {
1183a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("template <typename T> void f();",
1184a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      templateTypeParmDecl(hasName("T"))));
1185a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(
1186a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      notMatches("template <int N> void f();", templateTypeParmDecl()));
1187a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}
1188a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
118931f7c08a0d2b140bf31a08894d1948649de53c15Daniel JasperTEST(Matcher, UserDefinedLiteral) {
119031f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  EXPECT_TRUE(matches("constexpr char operator \"\" _inc (const char i) {"
119131f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      "  return i + 1;"
119231f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      "}"
119331f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      "char c = 'a'_inc;",
119431f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      userDefinedLiteral()));
119531f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper}
119631f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper
1197b54b7646b2d00a85d80e40adf7c49553f150c736Daniel JasperTEST(Matcher, FlowControl) {
1198b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() { while(true) { break; } }", breakStmt()));
1199b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() { while(true) { continue; } }",
1200b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper                      continueStmt()));
1201b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", gotoStmt()));
1202b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", labelStmt()));
1203b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() { return; }", returnStmt()));
1204b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper}
1205b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper
1206e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(HasType, MatchesAsString) {
1207e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(
1208e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }",
1209a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              cxxMemberCallExpr(on(hasType(asString("class Y *"))))));
1210a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(
1211a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      matches("class X { void x(int x) {} };",
1212a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              cxxMethodDecl(hasParameter(0, hasType(asString("int"))))));
1213e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("namespace ns { struct A {}; }  struct B { ns::A a; };",
12142dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      fieldDecl(hasType(asString("ns::A")))));
1215e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("namespace { struct A {}; }  struct B { A a; };",
1216651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      fieldDecl(hasType(asString("struct (anonymous namespace)::A")))));
1217e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1218e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
12194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, OverloadedOperatorCall) {
1220a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  StatementMatcher OpCall = cxxOperatorCallExpr();
12214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Unary operator
12224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { }; "
12234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "bool operator!(Y x) { return false; }; "
12244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "Y y; bool c = !y;", OpCall));
12254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // No match -- special operators like "new", "delete"
12264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // FIXME: operator new takes size_t, for which we need stddef.h, for which
12274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // we need to figure out include paths in the test.
12284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // EXPECT_TRUE(NotMatches("#include <stddef.h>\n"
12294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  //             "class Y { }; "
12304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  //             "void *operator new(size_t size) { return 0; } "
12314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  //             "Y *y = new Y;", OpCall));
12324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { }; "
12334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "void operator delete(void *p) { } "
12344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "void a() {Y *y = new Y; delete y;}", OpCall));
12354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Binary operator
12364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { }; "
12374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "bool operator&&(Y x, Y y) { return true; }; "
12384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "Y a; Y b; bool c = a && b;",
12394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              OpCall));
12404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // No match -- normal operator, not an overloaded one.
12414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("bool x = true, y = true; bool t = x && y;", OpCall));
12424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int t = 5 << 2;", OpCall));
12434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
12444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, HasOperatorNameForOverloadedOperatorCall) {
12464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OpCallAndAnd =
1247a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxOperatorCallExpr(hasOverloadedOperatorName("&&"));
12484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { }; "
12494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "bool operator&&(Y x, Y y) { return true; }; "
12504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "Y a; Y b; bool c = a && b;", OpCallAndAnd));
12514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OpCallLessLess =
1252a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxOperatorCallExpr(hasOverloadedOperatorName("<<"));
12534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { }; "
12544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "bool operator&&(Y x, Y y) { return true; }; "
12554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "Y a; Y b; bool c = a && b;",
12564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              OpCallLessLess));
1257176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  StatementMatcher OpStarCall =
1258a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxOperatorCallExpr(hasOverloadedOperatorName("*"));
1259176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("class Y; int operator*(Y &); void f(Y &y) { *y; }",
1260176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines              OpStarCall));
12616a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane  DeclarationMatcher ClassWithOpStar =
1262a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*")));
12636a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane  EXPECT_TRUE(matches("class Y { int operator*(); };",
12646a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane                      ClassWithOpStar));
12656a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane  EXPECT_TRUE(notMatches("class Y { void myOperator(); };",
12666a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane              ClassWithOpStar)) ;
1267176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  DeclarationMatcher AnyOpStar = functionDecl(hasOverloadedOperatorName("*"));
1268176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("class Y; int operator*(Y &);", AnyOpStar));
1269176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("class Y { int operator*(); };", AnyOpStar));
12704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
12714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1272278057fd9f44684af832695cb01676c02a257b14Daniel JasperTEST(Matcher, NestedOverloadedOperatorCalls) {
1273278057fd9f44684af832695cb01676c02a257b14Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
1274a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      "class Y { }; "
1275a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      "Y& operator&&(Y& x, Y& y) { return x; }; "
1276a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      "Y a; Y b; Y c; Y d = a && b && c;",
1277a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxOperatorCallExpr(hasOverloadedOperatorName("&&")).bind("x"),
1278a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      new VerifyIdIsBoundTo<CXXOperatorCallExpr>("x", 2)));
1279a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("class Y { }; "
1280a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      "Y& operator&&(Y& x, Y& y) { return x; }; "
1281a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      "Y a; Y b; Y c; Y d = a && b && c;",
1282a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxOperatorCallExpr(hasParent(cxxOperatorCallExpr()))));
1283a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(
1284a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      matches("class Y { }; "
1285a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              "Y& operator&&(Y& x, Y& y) { return x; }; "
1286a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              "Y a; Y b; Y c; Y d = a && b && c;",
1287a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              cxxOperatorCallExpr(hasDescendant(cxxOperatorCallExpr()))));
1288278057fd9f44684af832695cb01676c02a257b14Daniel Jasper}
1289278057fd9f44684af832695cb01676c02a257b14Daniel Jasper
12904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ThisPointerType) {
12919f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek  StatementMatcher MethodOnY =
1292a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    cxxMemberCallExpr(thisPointerType(recordDecl(hasName("Y"))));
12934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
12954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
12964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
12974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
12984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
12994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
13004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
13014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
13024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
13034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
13044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
13054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
13064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
13074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
13084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
13094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
13114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y {"
13124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  public: virtual void x();"
13134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};"
13144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X : public Y {"
13154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  public: virtual void x();"
13164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};"
13174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void z() { X *x; x->Y::x(); }", MethodOnY));
13184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, VariableUsage) {
13214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher Reference =
13222dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      declRefExpr(to(
13232dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          varDecl(hasInitializer(
1324a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              cxxMemberCallExpr(thisPointerType(recordDecl(hasName("Y"))))))));
13254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
13274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y {"
13284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      " public:"
13294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  bool x() const;"
13304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};"
13314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void z(const Y &y) {"
13324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  bool b = y.x();"
13334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  if (b) {}"
13344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "}", Reference));
13354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
13374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y {"
13384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      " public:"
13394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  bool x() const;"
13404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};"
13414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void z(const Y &y) {"
13424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  bool b = y.x();"
13434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "}", Reference));
13444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1346c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen HinesTEST(Matcher, VarDecl_Storage) {
1347c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  auto M = varDecl(hasName("X"), hasLocalStorage());
1348c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_TRUE(matches("void f() { int X; }", M));
1349c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_TRUE(notMatches("int X;", M));
1350c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_TRUE(notMatches("void f() { static int X; }", M));
1351c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
1352c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  M = varDecl(hasName("X"), hasGlobalStorage());
1353c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_TRUE(notMatches("void f() { int X; }", M));
1354c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_TRUE(matches("int X;", M));
1355c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_TRUE(matches("void f() { static int X; }", M));
1356c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines}
1357c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
1358a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST(Matcher, VarDecl_StorageDuration) {
1359a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  std::string T =
1360a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      "void f() { int x; static int y; } int a;";
1361a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
1362a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches(T, varDecl(hasName("x"), hasAutomaticStorageDuration())));
1363a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(
1364a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      notMatches(T, varDecl(hasName("y"), hasAutomaticStorageDuration())));
1365a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(
1366a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      notMatches(T, varDecl(hasName("a"), hasAutomaticStorageDuration())));
1367a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
1368a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches(T, varDecl(hasName("y"), hasStaticStorageDuration())));
1369a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches(T, varDecl(hasName("a"), hasStaticStorageDuration())));
1370a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches(T, varDecl(hasName("x"), hasStaticStorageDuration())));
1371a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
1372a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  // FIXME: It is really hard to test with thread_local itself because not all
1373a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  // targets support TLS, which causes this to be an error depending on what
1374a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  // platform the test is being run on. We do not have access to the TargetInfo
1375a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  // object to be able to test whether the platform supports TLS or not.
1376a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches(T, varDecl(hasName("x"), hasThreadStorageDuration())));
1377a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches(T, varDecl(hasName("y"), hasThreadStorageDuration())));
1378a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches(T, varDecl(hasName("a"), hasThreadStorageDuration())));
1379a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}
1380a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
13818cb9bf577e3cfe31f1f023ed3a978d726f136edcManuel KlimekTEST(Matcher, FindsVarDeclInFunctionParameter) {
13829bd2809085c2a84c980c40988896ee05065f14e4Daniel Jasper  EXPECT_TRUE(matches(
13839bd2809085c2a84c980c40988896ee05065f14e4Daniel Jasper      "void f(int i) {}",
13842dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("i"))));
13859bd2809085c2a84c980c40988896ee05065f14e4Daniel Jasper}
13869bd2809085c2a84c980c40988896ee05065f14e4Daniel Jasper
13874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, CalledVariable) {
13883680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher CallOnVariableY =
1389a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxMemberCallExpr(on(declRefExpr(to(varDecl(hasName("y"))))));
13904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
13924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y { public: void x() { Y y; y.x(); } };", CallOnVariableY));
13934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
13944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y { public: void x() const { Y y; y.x(); } };", CallOnVariableY));
13954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
13964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y { public: void x(); };"
13974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X : public Y { void z() { X y; y.x(); } };", CallOnVariableY));
13984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
13994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y { public: void x(); };"
14004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X : public Y { void z() { X *y; y->x(); } };", CallOnVariableY));
14014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
14024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y { public: void x(); };"
14034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X : public Y { void z() { unsigned long y; ((X*)y)->x(); } };",
14044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      CallOnVariableY));
14054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
14064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1407e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UnaryExprOrTypeTraitExpr, MatchesSizeOfAndAlignOf) {
1408e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("void x() { int a = sizeof(a); }",
1409e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      unaryExprOrTypeTraitExpr()));
1410e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }",
1411e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                         alignOfExpr(anything())));
1412e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // FIXME: Uncomment once alignof is enabled.
1413e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // EXPECT_TRUE(matches("void x() { int a = alignof(a); }",
1414e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  //                     unaryExprOrTypeTraitExpr()));
1415e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // EXPECT_TRUE(notMatches("void x() { int a = alignof(a); }",
1416e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  //                        sizeOfExpr()));
1417e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1418e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
1419e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UnaryExpressionOrTypeTraitExpression, MatchesCorrectType) {
1420e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("void x() { int a = sizeof(a); }", sizeOfExpr(
1421e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      hasArgumentOfType(asString("int")))));
1422e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
1423e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      hasArgumentOfType(asString("float")))));
1424e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
1425e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "struct A {}; void x() { A a; int b = sizeof(a); }",
14262dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      sizeOfExpr(hasArgumentOfType(hasDeclaration(recordDecl(hasName("A")))))));
1427e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
14282dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      hasArgumentOfType(hasDeclaration(recordDecl(hasName("string")))))));
1429e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1430e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
14314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MemberExpression, DoesNotMatchClasses) {
14322dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class Y { void x() {} };", memberExpr()));
14334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
14344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MemberExpression, MatchesMemberFunctionCall) {
14362dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpr()));
14374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
14384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MemberExpression, MatchesVariable) {
14404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14412dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class Y { void x() { this->y; } int y; };", memberExpr()));
14424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14432dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class Y { void x() { y; } int y; };", memberExpr()));
14444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14452dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class Y { void x() { Y y; y.y; } int y; };", memberExpr()));
14464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
14474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MemberExpression, MatchesStaticVariable) {
14494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
14502dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr()));
14514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
14522dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr()));
14534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { Y::y; } static int y; };",
14542dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr()));
14554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
14564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14576a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(IsInteger, MatchesIntegers) {
14582dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isInteger()))));
14592dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches(
14602dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      "long long i = 0; void f(long long) { }; void g() {f(i);}",
14612dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      callExpr(hasArgument(0, declRefExpr(
14622dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                                  to(varDecl(hasType(isInteger()))))))));
14636a12449ec8862211856447d3df4c082a346339f2Daniel Jasper}
14646a12449ec8862211856447d3df4c082a346339f2Daniel Jasper
14656a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(IsInteger, ReportsNoFalsePositives) {
14662dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("int *i;", varDecl(hasType(isInteger()))));
14676a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}",
14682dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      callExpr(hasArgument(0, declRefExpr(
14692dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          to(varDecl(hasType(isInteger()))))))));
14706a12449ec8862211856447d3df4c082a346339f2Daniel Jasper}
14716a12449ec8862211856447d3df4c082a346339f2Daniel Jasper
1472a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST(IsAnyCharacter, MatchesCharacters) {
1473a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("char i = 0;", varDecl(hasType(isAnyCharacter()))));
1474a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}
1475a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
1476a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST(IsAnyCharacter, ReportsNoFalsePositives) {
1477a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("int i;", varDecl(hasType(isAnyCharacter()))));
1478a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}
1479a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
14804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsArrow, MatchesMemberVariablesViaArrow) {
14814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };",
14822dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
14834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { y; } int y; };",
14842dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
14854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };",
14862dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
14874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
14884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsArrow, MatchesStaticMemberVariablesViaArrow) {
14904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
14912dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
14924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
14932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
14944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } static int y; };",
14952dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
14964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
14974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsArrow, MatchesMemberCallsViaArrow) {
14994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
15002dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
15014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { x(); } };",
15022dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
15034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",
15042dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
15054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
15064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Callee, MatchesDeclarations) {
1508a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  StatementMatcher CallMethodX = callExpr(callee(cxxMethodDecl(hasName("x"))));
15094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { x(); } };", CallMethodX));
15114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() {} };", CallMethodX));
1512b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
1513a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  CallMethodX = callExpr(callee(cxxConversionDecl()));
1514b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  EXPECT_TRUE(
1515b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      matches("struct Y { operator int() const; }; int i = Y();", CallMethodX));
1516b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  EXPECT_TRUE(notMatches("struct Y { operator int() const; }; Y y = Y();",
1517b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                         CallMethodX));
15184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
15194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1520a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST(ConversionDeclaration, IsExplicit) {
1521a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("struct S { explicit operator int(); };",
1522a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxConversionDecl(isExplicit())));
1523a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("struct S { operator int(); };",
1524a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxConversionDecl(isExplicit())));
1525a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}
1526a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
15274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Callee, MatchesMemberExpressions) {
15284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
15292dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              callExpr(callee(memberExpr()))));
15304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
15312dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      notMatches("class Y { void x() { this->x(); } };", callExpr(callee(callExpr()))));
15324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
15334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Function, MatchesFunctionDeclarations) {
15352dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher CallFunctionF = callExpr(callee(functionDecl(hasName("f"))));
15364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { f(); }", CallFunctionF));
15384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { }", CallFunctionF));
15394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1540651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getOS() !=
1541651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      llvm::Triple::Win32) {
1542651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // FIXME: Make this work for MSVC.
1543651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // Dependent contexts, but a non-dependent call.
1544651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    EXPECT_TRUE(matches("void f(); template <int N> void g() { f(); }",
1545651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                        CallFunctionF));
1546651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    EXPECT_TRUE(
1547651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        matches("void f(); template <int N> struct S { void g() { f(); } };",
1548651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                CallFunctionF));
1549651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
15504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Depedent calls don't match.
15524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
15534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("void f(int); template <typename T> void g(T t) { f(t); }",
15544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 CallFunctionF));
15554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
15564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("void f(int);"
15574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "template <typename T> struct S { void g(T t) { f(t); } };",
15584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 CallFunctionF));
1559a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
1560a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("void f(...);", functionDecl(isVariadic())));
1561a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("void f(int);", functionDecl(isVariadic())));
1562a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("template <typename... Ts> void f(Ts...);",
1563a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         functionDecl(isVariadic())));
1564a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("void f();", functionDecl(isVariadic())));
1565a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatchesC("void f();", functionDecl(isVariadic())));
15664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
15674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15688456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(FunctionTemplate, MatchesFunctionTemplateDeclarations) {
15698456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(
15708456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      matches("template <typename T> void f(T t) {}",
15712dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionTemplateDecl(hasName("f"))));
15728456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
15738456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
15748456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(FunctionTemplate, DoesNotMatchFunctionDeclarations) {
15758456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(
15768456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      notMatches("void f(double d); void f(int t) {}",
15772dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionTemplateDecl(hasName("f"))));
15788456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
15798456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
15808456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(FunctionTemplate, DoesNotMatchFunctionTemplateSpecializations) {
15818456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(
15828456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      notMatches("void g(); template <typename T> void f(T t) {}"
15838456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko                 "template <> void f(int t) { g(); }",
15842dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionTemplateDecl(hasName("f"),
15852dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                           hasDescendant(declRefExpr(to(
15862dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                               functionDecl(hasName("g"))))))));
15878456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
15888456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
15894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, Argument) {
15903680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher CallArgumentY = callExpr(
15913680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
15924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x(int) { int y; x(y); }", CallArgumentY));
15944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
15954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { void x(int) { int y; x(y); } };", CallArgumentY));
15964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x(int) { int z; x(z); }", CallArgumentY));
15974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15983680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher WrongIndex = callExpr(
15993680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
16004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x(int) { int y; x(y); }", WrongIndex));
16014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, AnyArgument) {
16043680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher CallArgumentY = callExpr(
16053680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasAnyArgument(declRefExpr(to(varDecl(hasName("y"))))));
16064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
16074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
16084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
16094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ArgumentCount) {
16123680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher Call1Arg = callExpr(argumentCountIs(1));
16134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg));
16154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg));
16164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg));
16174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
161936e29d6732814e958aea4b2f403cec63d7ed3116Daniel JasperTEST(Matcher, ParameterCount) {
162036e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper  DeclarationMatcher Function1Arg = functionDecl(parameterCountIs(1));
162136e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper  EXPECT_TRUE(matches("void f(int i) {}", Function1Arg));
162236e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper  EXPECT_TRUE(matches("class X { void f(int i) {} };", Function1Arg));
162336e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper  EXPECT_TRUE(notMatches("void f() {}", Function1Arg));
162436e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper  EXPECT_TRUE(notMatches("void f(int i, int j, int k) {}", Function1Arg));
162536e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper}
162636e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper
16274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, References) {
16282dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ReferenceClassX = varDecl(
16292dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      hasType(references(recordDecl(hasName("X")))));
16304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {}; void y(X y) { X &x = y; }",
16314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      ReferenceClassX));
16324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
16334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
16344b6730d40e7c603bd0e223d3fa8b56a0c88a324aMichael Han  // The match here is on the implicit copy constructor code for
16354b6730d40e7c603bd0e223d3fa8b56a0c88a324aMichael Han  // class X, not on code 'X x = y'.
16364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
16374b6730d40e7c603bd0e223d3fa8b56a0c88a324aMichael Han      matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
16384b6730d40e7c603bd0e223d3fa8b56a0c88a324aMichael Han  EXPECT_TRUE(
16394b6730d40e7c603bd0e223d3fa8b56a0c88a324aMichael Han      notMatches("class X {}; extern X x;", ReferenceClassX));
16404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
16414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
16424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16446a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin VaneTEST(QualType, hasCanonicalType) {
16456a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane  EXPECT_TRUE(notMatches("typedef int &int_ref;"
16466a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane                         "int a;"
16476a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane                         "int_ref b = a;",
16486a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane                         varDecl(hasType(qualType(referenceType())))));
16496a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane  EXPECT_TRUE(
16506a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane      matches("typedef int &int_ref;"
16516a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane              "int a;"
16526a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane              "int_ref b = a;",
16536a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane              varDecl(hasType(qualType(hasCanonicalType(referenceType()))))));
16546a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane}
16556a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane
16567b69cd09440976d6b93a0db661a770b2337be8d2Edwin VaneTEST(QualType, hasLocalQualifiers) {
16577b69cd09440976d6b93a0db661a770b2337be8d2Edwin Vane  EXPECT_TRUE(notMatches("typedef const int const_int; const_int i = 1;",
16587b69cd09440976d6b93a0db661a770b2337be8d2Edwin Vane                         varDecl(hasType(hasLocalQualifiers()))));
16597b69cd09440976d6b93a0db661a770b2337be8d2Edwin Vane  EXPECT_TRUE(matches("int *const j = nullptr;",
16607b69cd09440976d6b93a0db661a770b2337be8d2Edwin Vane                      varDecl(hasType(hasLocalQualifiers()))));
16617b69cd09440976d6b93a0db661a770b2337be8d2Edwin Vane  EXPECT_TRUE(matches("int *volatile k;",
16627b69cd09440976d6b93a0db661a770b2337be8d2Edwin Vane                      varDecl(hasType(hasLocalQualifiers()))));
16637b69cd09440976d6b93a0db661a770b2337be8d2Edwin Vane  EXPECT_TRUE(notMatches("int m;",
16647b69cd09440976d6b93a0db661a770b2337be8d2Edwin Vane                         varDecl(hasType(hasLocalQualifiers()))));
16657b69cd09440976d6b93a0db661a770b2337be8d2Edwin Vane}
16667b69cd09440976d6b93a0db661a770b2337be8d2Edwin Vane
16674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasParameter, CallsInnerMatcher) {
16684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { void x(int) {} };",
1669a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxMethodDecl(hasParameter(0, varDecl()))));
16704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class X { void x(int) {} };",
1671a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxMethodDecl(hasParameter(0, hasName("x")))));
16724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) {
16754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class X { void x(int) {} };",
1676a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxMethodDecl(hasParameter(42, varDecl()))));
16774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasType, MatchesParameterVariableTypesStrictly) {
1680a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches(
1681a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      "class X { void x(X x) {} };",
1682a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
1683a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches(
1684a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      "class X { void x(const X &x) {} };",
1685a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
16864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { void x(const X *x) {} };",
1687a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxMethodDecl(hasParameter(
1688a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                          0, hasType(pointsTo(recordDecl(hasName("X"))))))));
16894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { void x(const X &x) {} };",
1690a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxMethodDecl(hasParameter(
1691a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                          0, hasType(references(recordDecl(hasName("X"))))))));
16924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyParameter, MatchesIndependentlyOfPosition) {
1695a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches(
1696a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      "class Y {}; class X { void x(X x, Y y) {} };",
1697a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
1698a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches(
1699a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      "class Y {}; class X { void x(Y y, X x) {} };",
1700a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
17014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
17024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1703e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Returns, MatchesReturnTypes) {
1704e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("class Y { int f() { return 1; } };",
17052dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      functionDecl(returns(asString("int")))));
1706e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("class Y { int f() { return 1; } };",
17072dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         functionDecl(returns(asString("float")))));
1708e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("class Y { Y getMe() { return *this; } };",
17092dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      functionDecl(returns(hasDeclaration(
17102dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          recordDecl(hasName("Y")))))));
1711e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1712e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
17138cc7efa2da2c6be43cbd3d09a9ae01353bb921d2Daniel JasperTEST(IsExternC, MatchesExternCFunctionDeclarations) {
17142dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("extern \"C\" void f() {}", functionDecl(isExternC())));
17152dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("extern \"C\" { void f() {} }",
17162dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              functionDecl(isExternC())));
17172dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("void f() {}", functionDecl(isExternC())));
17188cc7efa2da2c6be43cbd3d09a9ae01353bb921d2Daniel Jasper}
17198cc7efa2da2c6be43cbd3d09a9ae01353bb921d2Daniel Jasper
1720176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(IsDeleted, MatchesDeletedFunctionDeclarations) {
1721176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(
1722176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      notMatches("void Func();", functionDecl(hasName("Func"), isDeleted())));
1723176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("void Func() = delete;",
1724176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      functionDecl(hasName("Func"), isDeleted())));
1725176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
1726176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1727a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST(IsNoThrow, MatchesNoThrowFunctionDeclarations) {
1728a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("void f();", functionDecl(isNoThrow())));
1729a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("void f() throw(int);", functionDecl(isNoThrow())));
1730a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(
1731a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      notMatches("void f() noexcept(false);", functionDecl(isNoThrow())));
1732a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("void f() throw();", functionDecl(isNoThrow())));
1733a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("void f() noexcept;", functionDecl(isNoThrow())));
1734a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}
1735a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
1736b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga NainarTEST(isConstexpr, MatchesConstexprDeclarations) {
1737b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  EXPECT_TRUE(matches("constexpr int foo = 42;",
1738b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                      varDecl(hasName("foo"), isConstexpr())));
1739b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  EXPECT_TRUE(matches("constexpr int bar();",
1740b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                      functionDecl(hasName("bar"), isConstexpr())));
1741b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar}
1742b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
17434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
1744a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches(
1745a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      "class Y {}; class X { void x(int) {} };",
1746a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
17474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
17484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
17494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyParameter, DoesNotMatchThisPointer) {
17504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y {}; class X { void x() {} };",
1751a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxMethodDecl(hasAnyParameter(
1752a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                             hasType(pointsTo(recordDecl(hasName("X"))))))));
17534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
17544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1755651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(HasName, MatchesParameterVariableDeclarations) {
17564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y {}; class X { void x(int x) {} };",
1757a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxMethodDecl(hasAnyParameter(hasName("x")))));
17584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
1759a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxMethodDecl(hasAnyParameter(hasName("x")))));
17604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
17614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1762371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel JasperTEST(Matcher, MatchesClassTemplateSpecialization) {
1763371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(matches("template<typename T> struct A {};"
1764371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper                      "template<> struct A<int> {};",
17652dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      classTemplateSpecializationDecl()));
1766371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(matches("template<typename T> struct A {}; A<int> a;",
17672dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      classTemplateSpecializationDecl()));
1768371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(notMatches("template<typename T> struct A {};",
17692dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         classTemplateSpecializationDecl()));
1770371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper}
1771371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper
17721a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel KlimekTEST(DeclaratorDecl, MatchesDeclaratorDecls) {
17731a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek  EXPECT_TRUE(matches("int x;", declaratorDecl()));
17741a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek  EXPECT_TRUE(notMatches("class A {};", declaratorDecl()));
17751a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek}
17761a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek
17771a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel KlimekTEST(ParmVarDecl, MatchesParmVars) {
17781a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek  EXPECT_TRUE(matches("void f(int x);", parmVarDecl()));
17791a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek  EXPECT_TRUE(notMatches("void f();", parmVarDecl()));
17801a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek}
17811a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek
1782371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel JasperTEST(Matcher, MatchesTypeTemplateArgument) {
1783371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(matches(
1784371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "template<typename T> struct B {};"
1785371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "B<int> b;",
17862dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToType(
1787371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper          asString("int"))))));
1788371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper}
1789371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper
1790371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel JasperTEST(Matcher, MatchesDeclarationReferenceTemplateArgument) {
1791371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(matches(
1792371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "struct B { int next; };"
1793371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "template<int(B::*next_ptr)> struct A {};"
1794371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "A<&B::next> a;",
17952dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      classTemplateSpecializationDecl(hasAnyTemplateArgument(
17962dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          refersToDeclaration(fieldDecl(hasName("next")))))));
1797aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper
1798aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper  EXPECT_TRUE(notMatches(
1799aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper      "template <typename T> struct A {};"
1800aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper      "A<int> a;",
1801aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper      classTemplateSpecializationDecl(hasAnyTemplateArgument(
1802aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper          refersToDeclaration(decl())))));
1803651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1804651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_TRUE(matches(
1805651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "struct B { int next; };"
1806651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "template<int(B::*next_ptr)> struct A {};"
1807651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "A<&B::next> a;",
1808651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      templateSpecializationType(hasAnyTemplateArgument(isExpr(
1809651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))));
1810651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1811651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_TRUE(notMatches(
1812651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "template <typename T> struct A {};"
1813651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "A<int> a;",
1814651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      templateSpecializationType(hasAnyTemplateArgument(
1815651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          refersToDeclaration(decl())))));
1816371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper}
1817371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper
1818371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel JasperTEST(Matcher, MatchesSpecificArgument) {
1819371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(matches(
1820371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "template<typename T, typename U> class A {};"
1821371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "A<bool, int> a;",
18222dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      classTemplateSpecializationDecl(hasTemplateArgument(
1823371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper          1, refersToType(asString("int"))))));
1824371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(notMatches(
1825371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "template<typename T, typename U> class A {};"
1826371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "A<int, bool> a;",
18272dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      classTemplateSpecializationDecl(hasTemplateArgument(
1828371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper          1, refersToType(asString("int"))))));
1829651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1830651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_TRUE(matches(
1831651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "template<typename T, typename U> class A {};"
1832651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "A<bool, int> a;",
1833651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      templateSpecializationType(hasTemplateArgument(
1834651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          1, refersToType(asString("int"))))));
1835651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_TRUE(notMatches(
1836651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "template<typename T, typename U> class A {};"
1837651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "A<int, bool> a;",
1838651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      templateSpecializationType(hasTemplateArgument(
1839651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          1, refersToType(asString("int"))))));
1840371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper}
1841371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper
1842176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(TemplateArgument, Matches) {
1843176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
1844176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      classTemplateSpecializationDecl(
1845176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                          hasAnyTemplateArgument(templateArgument()))));
1846176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches(
1847176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      "template<typename T> struct C {}; C<int> c;",
1848176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      templateSpecializationType(hasAnyTemplateArgument(templateArgument()))));
1849176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
1850176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1851176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(TemplateArgumentCountIs, Matches) {
1852176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(
1853176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      matches("template<typename T> struct C {}; C<int> c;",
1854176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines              classTemplateSpecializationDecl(templateArgumentCountIs(1))));
1855176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(
1856176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      notMatches("template<typename T> struct C {}; C<int> c;",
1857176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                 classTemplateSpecializationDecl(templateArgumentCountIs(2))));
1858176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1859176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
1860176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      templateSpecializationType(templateArgumentCountIs(1))));
1861176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(
1862176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      notMatches("template<typename T> struct C {}; C<int> c;",
1863176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                 templateSpecializationType(templateArgumentCountIs(2))));
1864176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
1865176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1866176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(IsIntegral, Matches) {
1867176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
1868176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      classTemplateSpecializationDecl(
1869176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                          hasAnyTemplateArgument(isIntegral()))));
1870176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("template<typename T> struct C {}; C<int> c;",
1871176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                         classTemplateSpecializationDecl(hasAnyTemplateArgument(
1872176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                             templateArgument(isIntegral())))));
1873176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
1874176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1875176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(RefersToIntegralType, Matches) {
1876176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
1877176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      classTemplateSpecializationDecl(
1878176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                          hasAnyTemplateArgument(refersToIntegralType(
1879176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                              asString("int"))))));
1880176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("template<unsigned T> struct C {}; C<42> c;",
1881176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                         classTemplateSpecializationDecl(hasAnyTemplateArgument(
1882176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                             refersToIntegralType(asString("int"))))));
1883176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
1884176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1885176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(EqualsIntegralValue, Matches) {
1886176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
1887176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      classTemplateSpecializationDecl(
1888176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                          hasAnyTemplateArgument(equalsIntegralValue("42")))));
1889176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("template<int T> struct C {}; C<-42> c;",
1890176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      classTemplateSpecializationDecl(
1891176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                          hasAnyTemplateArgument(equalsIntegralValue("-42")))));
1892176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("template<int T> struct C {}; C<-0042> c;",
1893176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      classTemplateSpecializationDecl(
1894176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                          hasAnyTemplateArgument(equalsIntegralValue("-34")))));
1895176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("template<int T> struct C {}; C<42> c;",
1896176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                         classTemplateSpecializationDecl(hasAnyTemplateArgument(
1897176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                             equalsIntegralValue("0042")))));
1898176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
1899176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1900f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel JasperTEST(Matcher, MatchesAccessSpecDecls) {
1901f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(matches("class C { public: int i; };", accessSpecDecl()));
1902f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(
1903f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      matches("class C { public: int i; };", accessSpecDecl(isPublic())));
1904f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(
1905f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      notMatches("class C { public: int i; };", accessSpecDecl(isProtected())));
1906f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(
1907f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      notMatches("class C { public: int i; };", accessSpecDecl(isPrivate())));
1908f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper
1909f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches("class C { int i; };", accessSpecDecl()));
1910f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper}
1911f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper
1912a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST(Matcher, MatchesFinal) {
1913a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("class X final {};", cxxRecordDecl(isFinal())));
1914a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("class X { virtual void f() final; };",
1915a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxMethodDecl(isFinal())));
1916a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("class X {};", cxxRecordDecl(isFinal())));
1917a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(
1918a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      notMatches("class X { virtual void f(); };", cxxMethodDecl(isFinal())));
1919a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}
1920a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
19215771a2f0830228ac50e3473740e24d9dca67b54fEdwin VaneTEST(Matcher, MatchesVirtualMethod) {
19225771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane  EXPECT_TRUE(matches("class X { virtual int f(); };",
1923a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxMethodDecl(isVirtual(), hasName("::X::f"))));
1924a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isVirtual())));
19255771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane}
19265771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane
1927651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(Matcher, MatchesPureMethod) {
1928651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_TRUE(matches("class X { virtual int f() = 0; };",
1929a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxMethodDecl(isPure(), hasName("::X::f"))));
1930a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isPure())));
1931a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}
1932a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
1933a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST(Matcher, MatchesCopyAssignmentOperator) {
1934a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("class X { X &operator=(X); };",
1935a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxMethodDecl(isCopyAssignmentOperator())));
1936a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("class X { X &operator=(X &); };",
1937a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxMethodDecl(isCopyAssignmentOperator())));
1938a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("class X { X &operator=(const X &); };",
1939a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxMethodDecl(isCopyAssignmentOperator())));
1940a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("class X { X &operator=(volatile X &); };",
1941a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxMethodDecl(isCopyAssignmentOperator())));
1942a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("class X { X &operator=(const volatile X &); };",
1943a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxMethodDecl(isCopyAssignmentOperator())));
1944a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("class X { X &operator=(X &&); };",
1945a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxMethodDecl(isCopyAssignmentOperator())));
1946651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
1947651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
194832a6ebc63900b85780328c337787bb7adad2bcabEdwin VaneTEST(Matcher, MatchesConstMethod) {
1949a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(
1950a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      matches("struct A { void foo() const; };", cxxMethodDecl(isConst())));
1951a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(
1952a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      notMatches("struct A { void foo(); };", cxxMethodDecl(isConst())));
195332a6ebc63900b85780328c337787bb7adad2bcabEdwin Vane}
195432a6ebc63900b85780328c337787bb7adad2bcabEdwin Vane
19555771a2f0830228ac50e3473740e24d9dca67b54fEdwin VaneTEST(Matcher, MatchesOverridingMethod) {
19565771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane  EXPECT_TRUE(matches("class X { virtual int f(); }; "
19575771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane                      "class Y : public X { int f(); };",
1958a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxMethodDecl(isOverride(), hasName("::Y::f"))));
19595771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane  EXPECT_TRUE(notMatches("class X { virtual int f(); }; "
1960a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         "class Y : public X { int f(); };",
1961a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxMethodDecl(isOverride(), hasName("::X::f"))));
19625771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane  EXPECT_TRUE(notMatches("class X { int f(); }; "
19635771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane                         "class Y : public X { int f(); };",
1964a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxMethodDecl(isOverride())));
19655771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane  EXPECT_TRUE(notMatches("class X { int f(); int f(int); }; ",
1966a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxMethodDecl(isOverride())));
19673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  EXPECT_TRUE(
19683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      matches("template <typename Base> struct Y : Base { void f() override;};",
1969a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              cxxMethodDecl(isOverride(), hasName("::Y::f"))));
19705771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane}
19715771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane
19724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ConstructorCall) {
1973a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  StatementMatcher Constructor = cxxConstructExpr();
19744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(); }; void x() { X x; }", Constructor));
19774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(); }; void x() { X x = X(); }",
19794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
19804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { X x = 0; }",
19824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
19834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {}; void x(int) { X x; }", Constructor));
19844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
19854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ConstructorArgument) {
1987a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  StatementMatcher Constructor = cxxConstructExpr(
19883680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
19894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { int y; X x(y); }",
19924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
19934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
19954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
19964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { int y; X x = y; }",
19984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
19994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int); }; void x() { int z; X x(z); }",
20014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 Constructor));
20024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2003a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  StatementMatcher WrongIndex = cxxConstructExpr(
20043680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
20054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int); }; void x() { int y; X x(y); }",
20074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 WrongIndex));
20084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
20094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ConstructorArgumentCount) {
2011a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  StatementMatcher Constructor1Arg = cxxConstructExpr(argumentCountIs(1));
20124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { X x(0); }",
20154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor1Arg));
20164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { X x = X(0); }",
20184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor1Arg));
20194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { X x = 0; }",
20214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor1Arg));
20224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
20244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 Constructor1Arg));
20254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
20264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2027651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(Matcher, ConstructorListInitialization) {
2028a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  StatementMatcher ConstructorListInit =
2029a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxConstructExpr(isListInitialization());
2030651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
2031651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_TRUE(
2032651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      matches("class X { public: X(int); }; void x() { X x{0}; }",
2033651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              ConstructorListInit));
2034651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_FALSE(
2035651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      matches("class X { public: X(int); }; void x() { X x(0); }",
2036651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              ConstructorListInit));
2037651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
2038651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
203970b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel KlimekTEST(Matcher,ThisExpr) {
204070b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel Klimek  EXPECT_TRUE(
2041a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      matches("struct X { int a; int f () { return a; } };", cxxThisExpr()));
204270b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel Klimek  EXPECT_TRUE(
2043a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      notMatches("struct X { int f () { int a; return a; } };", cxxThisExpr()));
204470b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel Klimek}
204570b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel Klimek
20464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, BindTemporaryExpression) {
2047a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  StatementMatcher TempExpression = cxxBindTemporaryExpr();
20484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  std::string ClassString = "class string { public: string(); ~string(); }; ";
20504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches(ClassString +
20534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "string GetStringByValue();"
20544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "void FunctionTakesString(string s);"
20554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "void run() { FunctionTakesString(GetStringByValue()); }",
20564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              TempExpression));
20574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches(ClassString +
20604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "string* GetStringPointer(); "
20614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "void FunctionTakesStringPtr(string* s);"
20624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "void run() {"
20634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "  string* s = GetStringPointer();"
20644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "  FunctionTakesStringPtr(GetStringPointer());"
20654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "  FunctionTakesStringPtr(s);"
20664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "}",
20674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 TempExpression));
20684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class no_dtor {};"
20714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "no_dtor GetObjByValue();"
20724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "void ConsumeObj(no_dtor param);"
20734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "void run() { ConsumeObj(GetObjByValue()); }",
20744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 TempExpression));
2075e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer}
2076e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer
2077e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam PanzerTEST(MaterializeTemporaryExpr, MatchesTemporary) {
2078e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer  std::string ClassString =
2079e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer      "class string { public: string(); int length(); }; ";
2080e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer
2081e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer  EXPECT_TRUE(
2082e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer      matches(ClassString +
2083e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer              "string GetStringByValue();"
2084e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer              "void FunctionTakesString(string s);"
2085e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer              "void run() { FunctionTakesString(GetStringByValue()); }",
2086e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer              materializeTemporaryExpr()));
2087e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer
2088e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer  EXPECT_TRUE(
2089e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer      notMatches(ClassString +
2090e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "string* GetStringPointer(); "
2091e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "void FunctionTakesStringPtr(string* s);"
2092e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "void run() {"
2093e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "  string* s = GetStringPointer();"
2094e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "  FunctionTakesStringPtr(GetStringPointer());"
2095e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "  FunctionTakesStringPtr(s);"
2096e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "}",
2097e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 materializeTemporaryExpr()));
2098e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer
2099e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer  EXPECT_TRUE(
2100e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer      notMatches(ClassString +
2101e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "string GetStringByValue();"
2102e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "void run() { int k = GetStringByValue().length(); }",
2103e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 materializeTemporaryExpr()));
2104e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer
2105e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer  EXPECT_TRUE(
2106e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer      notMatches(ClassString +
2107e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "string GetStringByValue();"
2108e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "void run() { GetStringByValue(); }",
2109e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 materializeTemporaryExpr()));
21104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ConstructorDeclaration, SimpleCase) {
21134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Foo { Foo(int i); };",
2114a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxConstructorDecl(ofClass(hasName("Foo")))));
21154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Foo { Foo(int i); };",
2116a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxConstructorDecl(ofClass(hasName("Bar")))));
21174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ConstructorDeclaration, IsImplicit) {
21204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // This one doesn't match because the constructor is not added by the
21214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // compiler (it is not needed).
21224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Foo { };",
2123a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxConstructorDecl(isImplicit())));
21244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // The compiler added the implicit default constructor.
21254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
2126a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxConstructorDecl(isImplicit())));
21274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Foo { Foo(){} };",
2128a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxConstructorDecl(unless(isImplicit()))));
21296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // The compiler added an implicit assignment operator.
21306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  EXPECT_TRUE(matches("struct A { int x; } a = {0}, b = a; void f() { a = b; }",
2131a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxMethodDecl(isImplicit(), hasName("operator="))));
2132a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}
2133a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
2134a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST(ConstructorDeclaration, IsExplicit) {
2135a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("struct S { explicit S(int); };",
2136a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxConstructorDecl(isExplicit())));
2137a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("struct S { S(int); };",
2138a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxConstructorDecl(isExplicit())));
2139a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}
2140a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
2141a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST(ConstructorDeclaration, Kinds) {
2142a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("struct S { S(); };",
2143a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxConstructorDecl(isDefaultConstructor())));
2144a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("struct S { S(); };",
2145a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxConstructorDecl(isCopyConstructor())));
2146a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("struct S { S(); };",
2147a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxConstructorDecl(isMoveConstructor())));
2148a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
2149a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("struct S { S(const S&); };",
2150a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxConstructorDecl(isDefaultConstructor())));
2151a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("struct S { S(const S&); };",
2152a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxConstructorDecl(isCopyConstructor())));
2153a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("struct S { S(const S&); };",
2154a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxConstructorDecl(isMoveConstructor())));
2155a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
2156a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("struct S { S(S&&); };",
2157a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxConstructorDecl(isDefaultConstructor())));
2158a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("struct S { S(S&&); };",
2159a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxConstructorDecl(isCopyConstructor())));
2160a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("struct S { S(S&&); };",
2161a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxConstructorDecl(isMoveConstructor())));
21624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2164e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(DestructorDeclaration, MatchesVirtualDestructor) {
2165e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };",
2166a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxDestructorDecl(ofClass(hasName("Foo")))));
2167e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2168e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
2169e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) {
21702dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class Foo {};",
2171a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxDestructorDecl(ofClass(hasName("Foo")))));
2172e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2173e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
21744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyConstructorInitializer, SimpleCase) {
2175a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(
2176a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      notMatches("class Foo { Foo() { } };",
2177a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                 cxxConstructorDecl(hasAnyConstructorInitializer(anything()))));
2178a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(
2179a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      matches("class Foo {"
2180a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              "  Foo() : foo_() { }"
2181a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              "  int foo_;"
2182a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              "};",
2183a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              cxxConstructorDecl(hasAnyConstructorInitializer(anything()))));
21844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyConstructorInitializer, ForField) {
21874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  static const char Code[] =
21884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Baz { };"
21894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Foo {"
21904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Foo() : foo_() { }"
21914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Baz foo_;"
21924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Baz bar_;"
21934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};";
2194a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
21952dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      forField(hasType(recordDecl(hasName("Baz"))))))));
2196a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
21974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      forField(hasName("foo_"))))));
2198a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
21992dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      forField(hasType(recordDecl(hasName("Bar"))))))));
22004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyConstructorInitializer, WithInitializer) {
22034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  static const char Code[] =
22044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Foo {"
22054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Foo() : foo_(0) { }"
22064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  int foo_;"
22074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};";
2208a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
22094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      withInitializer(integerLiteral(equals(0)))))));
2210a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
22114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      withInitializer(integerLiteral(equals(1)))))));
22124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyConstructorInitializer, IsWritten) {
22154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  static const char Code[] =
22164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "struct Bar { Bar(){} };"
22174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Foo {"
22184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Foo() : foo_() { }"
22194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Bar foo_;"
22204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Bar bar_;"
22214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};";
2222a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
22234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      allOf(forField(hasName("foo_")), isWritten())))));
2224a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
22254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      allOf(forField(hasName("bar_")), isWritten())))));
2226a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
22274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      allOf(forField(hasName("bar_")), unless(isWritten()))))));
22284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2230a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST(HasAnyConstructorInitializer, IsBaseInitializer) {
2231a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  static const char Code[] =
2232a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      "struct B {};"
2233a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      "struct D : B {"
2234a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      "  int I;"
2235a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      "  D(int i) : I(i) {}"
2236a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      "};"
2237a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      "struct E : B {"
2238a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      "  E() : B() {}"
2239a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      "};";
2240a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf(
2241a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())),
2242a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    hasName("E")))));
2243a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf(
2244a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())),
2245a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    hasName("D")))));
2246a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf(
2247a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())),
2248a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    hasName("D")))));
2249a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf(
2250a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())),
2251a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    hasName("E")))));
2252a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}
2253a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
22544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, NewExpression) {
2255a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  StatementMatcher New = cxxNewExpr();
22564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { public: X(); }; void x() { new X; }", New));
22584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(); }; void x() { new X(); }", New));
22604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { new X(0); }", New));
22624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {}; void x(int) { new X; }", New));
22634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, NewExpressionArgument) {
2266a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  StatementMatcher New = cxxConstructExpr(
22673680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
22684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { int y; new X(y); }",
22714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              New));
22724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { int y; new X(y); }",
22744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              New));
22754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int); }; void x() { int z; new X(z); }",
22774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 New));
22784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2279a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  StatementMatcher WrongIndex = cxxConstructExpr(
22803680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
22814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int); }; void x() { int y; new X(y); }",
22834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 WrongIndex));
22844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, NewExpressionArgumentCount) {
2287a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  StatementMatcher New = cxxConstructExpr(argumentCountIs(1));
22884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { new X(0); }", New));
22914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int, int); }; void x() { new X(0, 0); }",
22934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 New));
22944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2296e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Matcher, DeleteExpression) {
2297e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("struct A {}; void f(A* a) { delete a; }",
2298a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxDeleteExpr()));
2299e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2300e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
23014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, DefaultArgument) {
2302a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  StatementMatcher Arg = cxxDefaultArgExpr();
23034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x(int, int = 0) { int y; x(y); }", Arg));
23054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
23064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { void x(int, int = 0) { int y; x(y); } };", Arg));
23074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x(int, int = 0) { int y; x(y, 0); }", Arg));
23084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, StringLiterals) {
23113680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher Literal = stringLiteral();
23124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const char *s = \"string\";", Literal));
23134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // wide string
23144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const wchar_t *s = L\"string\";", Literal));
23154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // with escaped characters
23164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const char *s = \"\x05five\";", Literal));
23174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // no matching -- though the data type is the same, there is no string literal
23184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));
23194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, CharacterLiterals) {
23223680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher CharLiteral = characterLiteral();
23234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const char c = 'c';", CharLiteral));
23244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // wide character
23254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const char c = L'c';", CharLiteral));
23264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // wide character, Hex encoded, NOT MATCHED!
23274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("const wchar_t c = 0x2126;", CharLiteral));
23284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("const char c = 0x1;", CharLiteral));
23294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, IntegerLiterals) {
23323680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher HasIntLiteral = integerLiteral();
23334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = 10;", HasIntLiteral));
23344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = 0x1AB;", HasIntLiteral));
23354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = 10L;", HasIntLiteral));
23364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = 10U;", HasIntLiteral));
23374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Non-matching cases (character literals, float and double)
23394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int i = L'a';",
23404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                HasIntLiteral));  // this is actually a character
23414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                                  // literal cast to int
23424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int i = 'a';", HasIntLiteral));
23434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int i = 1e10;", HasIntLiteral));
23444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int i = 10.0;", HasIntLiteral));
23454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2347c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel JasperTEST(Matcher, FloatLiterals) {
2348c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel Jasper  StatementMatcher HasFloatLiteral = floatLiteral();
2349c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel Jasper  EXPECT_TRUE(matches("float i = 10.0;", HasFloatLiteral));
2350c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel Jasper  EXPECT_TRUE(matches("float i = 10.0f;", HasFloatLiteral));
2351c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel Jasper  EXPECT_TRUE(matches("double i = 10.0;", HasFloatLiteral));
2352c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel Jasper  EXPECT_TRUE(matches("double i = 10.0L;", HasFloatLiteral));
2353c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel Jasper  EXPECT_TRUE(matches("double i = 1e10;", HasFloatLiteral));
23540e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0))));
23550e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0f))));
23560e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(
23570e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      matches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(5.0)))));
2358c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel Jasper
2359c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel Jasper  EXPECT_TRUE(notMatches("float i = 10;", HasFloatLiteral));
23600e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0))));
23610e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0f))));
23620e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(
23630e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      notMatches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(6.0)))));
2364c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel Jasper}
2365c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel Jasper
236631f7c08a0d2b140bf31a08894d1948649de53c15Daniel JasperTEST(Matcher, NullPtrLiteral) {
2367a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("int* i = nullptr;", cxxNullPtrLiteralExpr()));
236831f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper}
236931f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper
2370b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga NainarTEST(Matcher, GNUNullExpr) {
2371b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  EXPECT_TRUE(matches("int* i = __null;", gnuNullExpr()));
2372b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar}
2373b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
2374b54b7646b2d00a85d80e40adf7c49553f150c736Daniel JasperTEST(Matcher, AsmStatement) {
2375b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void foo() { __asm(\"mov al, 2\"); }", asmStmt()));
2376b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper}
2377b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper
23784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, Conditions) {
2379a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  StatementMatcher Condition =
2380a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      ifStmt(hasCondition(cxxBoolLiteral(equals(true))));
23814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { if (true) {} }", Condition));
23834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { if (false) {} }", Condition));
23844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { bool a = true; if (a) {} }", Condition));
23854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { if (true || false) {} }", Condition));
23864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { if (1) {} }", Condition));
23874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesTEST(IfStmt, ChildTraversalMatchers) {
23906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  EXPECT_TRUE(matches("void f() { if (false) true; else false; }",
2391a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      ifStmt(hasThen(cxxBoolLiteral(equals(true))))));
23926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  EXPECT_TRUE(notMatches("void f() { if (false) false; else true; }",
2393a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         ifStmt(hasThen(cxxBoolLiteral(equals(true))))));
23946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  EXPECT_TRUE(matches("void f() { if (false) false; else true; }",
2395a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      ifStmt(hasElse(cxxBoolLiteral(equals(true))))));
23966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  EXPECT_TRUE(notMatches("void f() { if (false) true; else false; }",
2397a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         ifStmt(hasElse(cxxBoolLiteral(equals(true))))));
23986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
23996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
24004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MatchBinaryOperator, HasOperatorName) {
24014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
24024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true || false; }", OperatorOr));
24044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
24054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MatchBinaryOperator, HasLHSAndHasRHS) {
24084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OperatorTrueFalse =
2409a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      binaryOperator(hasLHS(cxxBoolLiteral(equals(true))),
2410a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                     hasRHS(cxxBoolLiteral(equals(false))));
24114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true || false; }", OperatorTrueFalse));
24134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse));
24144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { false || true; }", OperatorTrueFalse));
2415a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
2416a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  StatementMatcher OperatorIntPointer = arraySubscriptExpr(
2417a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      hasLHS(hasType(isInteger())), hasRHS(hasType(pointsTo(qualType()))));
2418a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("void x() { 1[\"abc\"]; }", OperatorIntPointer));
2419a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("void x() { \"abc\"[1]; }", OperatorIntPointer));
24204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MatchBinaryOperator, HasEitherOperand) {
24234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher HasOperand =
2424a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      binaryOperator(hasEitherOperand(cxxBoolLiteral(equals(false))));
24254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true || false; }", HasOperand));
24274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { false && true; }", HasOperand));
24284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand));
24294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, BinaryOperatorTypes) {
24324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Integration test that verifies the AST provides all binary operators in
24334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // a way we expect.
24344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // FIXME: Operator ','
24354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(","))));
24374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b; bool c = (b = true);",
24394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("="))));
24404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!="))));
24424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("=="))));
24444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("bool b = 1 < 2;", binaryOperator(hasOperatorName("<"))));
24454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<="))));
24474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<"))));
24494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 1; int j = (i <<= 2);",
24514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("<<="))));
24524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("bool b = 1 > 2;", binaryOperator(hasOperatorName(">"))));
24534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">="))));
24554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>"))));
24574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 1; int j = (i >>= 2);",
24594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName(">>="))));
24604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42 ^ 23;", binaryOperator(hasOperatorName("^"))));
24624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i ^= 42);",
24644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("^="))));
24654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42 % 23;", binaryOperator(hasOperatorName("%"))));
24674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i %= 42);",
24694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("%="))));
24704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 42  &23;", binaryOperator(hasOperatorName("&"))));
24724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = true && false;",
24744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("&&"))));
24754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = true; bool c = (b &= false);",
24774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("&="))));
24784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|"))));
24804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = true || false;",
24824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("||"))));
24834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = true; bool c = (b |= false);",
24854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("|="))));
24864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42  *23;", binaryOperator(hasOperatorName("*"))));
24884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i *= 23);",
24904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("*="))));
24914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42 / 23;", binaryOperator(hasOperatorName("/"))));
24934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i /= 23);",
24954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("/="))));
24964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42 + 23;", binaryOperator(hasOperatorName("+"))));
24984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i += 23);",
25004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("+="))));
25014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
25024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42 - 23;", binaryOperator(hasOperatorName("-"))));
25034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
25044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i -= 23);",
25054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("-="))));
25064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
25074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };",
25084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("->*"))));
25094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
25104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };",
25114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName(".*"))));
25124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Member expressions as operators are not supported in matches.
25144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
25154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("struct A { void x(A *a) { a->x(this); } };",
25164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 binaryOperator(hasOperatorName("->"))));
25174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Initializer assignments are not represented as operator equals.
25194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
25204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("bool b = true;", binaryOperator(hasOperatorName("="))));
25214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Array indexing is not represented as operator.
25234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int a[42]; void x() { a[23]; }", unaryOperator()));
25244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Overloaded operators do not match at all.
25264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
25274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "struct A { bool operator&&(const A &a) const { return false; } };"
25284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void x() { A a, b; a && b; }",
25294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      binaryOperator()));
25304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
25314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MatchUnaryOperator, HasOperatorName) {
25334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OperatorNot = unaryOperator(hasOperatorName("!"));
25344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { !true; } ", OperatorNot));
25364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
25374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
25384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MatchUnaryOperator, HasUnaryOperand) {
25404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OperatorOnFalse =
2541a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false))));
25424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse));
25444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse));
25454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
25464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, UnaryOperatorTypes) {
25484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Integration test that verifies the AST provides all unary operators in
25494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // a way we expect.
25504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("bool b = !true;", unaryOperator(hasOperatorName("!"))));
25514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
25524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&"))));
25534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = ~ 1;", unaryOperator(hasOperatorName("~"))));
25544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
25554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool *p; bool b = *p;", unaryOperator(hasOperatorName("*"))));
25564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
25574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = +i;", unaryOperator(hasOperatorName("+"))));
25584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
25594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = -i;", unaryOperator(hasOperatorName("-"))));
25604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
25614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = ++i;", unaryOperator(hasOperatorName("++"))));
25624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
25634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = i++;", unaryOperator(hasOperatorName("++"))));
25644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
25654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = --i;", unaryOperator(hasOperatorName("--"))));
25664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
25674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = i--;", unaryOperator(hasOperatorName("--"))));
25684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // We don't match conversion operators.
25704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int i; double d = (double)i;", unaryOperator()));
25714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Function calls are not represented as operator.
25734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f(); void x() { f(); }", unaryOperator()));
25744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Overloaded operators do not match at all.
25764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // FIXME: We probably want to add that.
25774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
25784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "struct A { bool operator!() const { return false; } };"
25794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void x() { A a; !a; }", unaryOperator(hasOperatorName("!"))));
25804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
25814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ConditionalOperator) {
25834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher Conditional = conditionalOperator(
2584a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      hasCondition(cxxBoolLiteral(equals(true))),
2585a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      hasTrueExpression(cxxBoolLiteral(equals(false))));
25864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true ? false : true; }", Conditional));
25884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { false ? false : true; }", Conditional));
25894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { true ? true : false; }", Conditional));
25904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher ConditionalFalse = conditionalOperator(
2592a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      hasFalseExpression(cxxBoolLiteral(equals(false))));
25934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
25954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
25964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("void x() { true ? false : true; }", ConditionalFalse));
25974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
25984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2599e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(ArraySubscriptMatchers, ArraySubscripts) {
2600e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("int i[2]; void f() { i[1] = 1; }",
2601e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      arraySubscriptExpr()));
2602e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("int i; void f() { i = 1; }",
2603e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                         arraySubscriptExpr()));
2604e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2605e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
2606e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(ArraySubscriptMatchers, ArrayIndex) {
2607e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
2608e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "int i[2]; void f() { i[1] = 1; }",
2609e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
2610e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
2611e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "int i[2]; void f() { 1[i] = 1; }",
2612e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
2613e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches(
2614e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "int i[2]; void f() { i[1] = 1; }",
2615e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      arraySubscriptExpr(hasIndex(integerLiteral(equals(0))))));
2616e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2617e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
2618e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(ArraySubscriptMatchers, MatchesArrayBase) {
2619e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
2620e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "int i[2]; void f() { i[1] = 2; }",
26212dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      arraySubscriptExpr(hasBase(implicitCastExpr(
26222dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasSourceExpression(declRefExpr()))))));
2623e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2624e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
26254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, HasNameSupportsNamespaces) {
26264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
26272dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("a::b::C"))));
26284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
26292dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("::a::b::C"))));
26304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
26312dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("b::C"))));
26324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
26332dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("C"))));
26344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
26352dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("c::b::C"))));
26364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
26372dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("a::c::C"))));
26384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
26392dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("a::b::A"))));
26404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
26412dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("::C"))));
26424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
26432dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("::b::C"))));
26444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
26452dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("z::a::b::C"))));
26464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
26472dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("a+b::C"))));
26484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
26492dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("C"))));
26504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
26514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
26524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, HasNameSupportsOuterClasses) {
26534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
26542dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class A { class B { class C; }; };",
26552dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("A::B::C"))));
26564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
26574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class A { class B { class C; }; };",
26582dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("::A::B::C"))));
26594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
26602dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class A { class B { class C; }; };",
26612dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("B::C"))));
26624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
26632dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class A { class B { class C; }; };",
26642dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("C"))));
26654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
26664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class A { class B { class C; }; };",
26672dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("c::B::C"))));
26684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
26694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class A { class B { class C; }; };",
26702dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("A::c::C"))));
26714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
26724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class A { class B { class C; }; };",
26732dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("A::B::A"))));
26744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
26752dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      notMatches("class A { class B { class C; }; };",
26762dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("::C"))));
26774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
26784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class A { class B { class C; }; };",
26792dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("::B::C"))));
26804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
26812dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("z::A::B::C"))));
26824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
26834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class A { class B { class C; }; };",
26842dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("A+B::C"))));
26854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
26864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
26874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, IsDefinition) {
26884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher DefinitionOfClassA =
26892dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("A"), isDefinition());
26904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class A {};", DefinitionOfClassA));
26914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A;", DefinitionOfClassA));
26924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
26934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher DefinitionOfVariableA =
26942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("a"), isDefinition());
26954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));
26964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));
26974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
26984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher DefinitionOfMethodA =
2699a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxMethodDecl(hasName("a"), isDefinition());
27004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));
27014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));
27024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, OfClass) {
2705a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  StatementMatcher Constructor = cxxConstructExpr(hasDeclaration(cxxMethodDecl(
27064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      ofClass(hasName("X")))));
27074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
27094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(); }; void x(int) { X x; }", Constructor));
27104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
27114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(); }; void x(int) { X x = X(); }",
27124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
27134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
27144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: Y(); }; void x(int) { Y y; }",
27154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 Constructor));
27164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, VisitsTemplateInstantiations) {
27194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
27204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class A { public: void x(); };"
27214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class B { public: void y() { T t; t.x(); } };"
27222dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      "void f() { B<A> b; b.y(); }",
2723a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      callExpr(callee(cxxMethodDecl(hasName("x"))))));
27244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
27264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class A { public: void x(); };"
27274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class C {"
27284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      " public:"
27294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  template <typename T> class B { public: void y() { T t; t.x(); } };"
27304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};"
27314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void f() {"
27324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  C::B<A> b; b.y();"
27332dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      "}",
2734a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      recordDecl(hasName("C"), hasDescendant(callExpr(
2735a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                                   callee(cxxMethodDecl(hasName("x"))))))));
27364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2738e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Matcher, HandlesNullQualTypes) {
2739e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // FIXME: Add a Type matcher so we can replace uses of this
2740e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // variable with Type(True())
2741e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  const TypeMatcher AnyType = anything();
2742e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
2743e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // We don't really care whether this matcher succeeds; we're testing that
2744e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // it completes without crashing.
2745e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
2746e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "struct A { };"
2747e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "template <typename T>"
2748e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "void f(T t) {"
2749e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "  T local_t(t /* this becomes a null QualType in the AST */);"
2750e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "}"
2751e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "void g() {"
2752e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "  f(0);"
2753e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "}",
27542dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      expr(hasType(TypeMatcher(
2755e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper          anyOf(
2756e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper              TypeMatcher(hasDeclaration(anything())),
2757e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper              pointsTo(AnyType),
2758e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper              references(AnyType)
2759e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper              // Other QualType matchers should go here.
2760e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                ))))));
2761e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2762e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
27634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// For testing AST_MATCHER_P().
2764e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperAST_MATCHER_P(Decl, just, internal::Matcher<Decl>, AMatcher) {
27654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Make sure all special variables are used: node, match_finder,
27664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // bound_nodes_builder, and the parameter named 'AMatcher'.
27674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  return AMatcher.matches(Node, Finder, Builder);
27684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(AstMatcherPMacro, Works) {
27712dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher HasClassB = just(has(recordDecl(hasName("B")).bind("b")));
27724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
2774a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
27754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
2777a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("a")));
27784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
2780a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
27814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27833ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga NainarAST_POLYMORPHIC_MATCHER_P(polymorphicHas,
27843ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                          AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt),
27853ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                          internal::Matcher<Decl>, AMatcher) {
27864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  return Finder->matchesChildOf(
2787a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek      Node, AMatcher, Builder,
27884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
27894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      ASTMatchFinder::BK_First);
27904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(AstPolymorphicMatcherPMacro, Works) {
27932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher HasClassB =
27942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      polymorphicHas(recordDecl(hasName("B")).bind("b"));
27954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
2797a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
27984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
2800a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("a")));
28014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
2803a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
28044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher StatementHasClassB =
28062dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      polymorphicHas(recordDecl(hasName("B")));
28074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { class B {}; }", StatementHasClassB));
28094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(For, FindsForLoops) {
28124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { for(;;); }", forStmt()));
28134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { if(true) for(;;); }", forStmt()));
28141a00fee3933066024a2398f9456e5d6bc74344b9Daniel Jasper  EXPECT_TRUE(notMatches("int as[] = { 1, 2, 3 };"
28151a00fee3933066024a2398f9456e5d6bc74344b9Daniel Jasper                         "void f() { for (auto &a : as); }",
281631f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                         forStmt()));
28174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28196a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(For, ForLoopInternals) {
28206a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(matches("void f(){ int i; for (; i < 3 ; ); }",
28216a12449ec8862211856447d3df4c082a346339f2Daniel Jasper                      forStmt(hasCondition(anything()))));
28226a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(matches("void f() { for (int i = 0; ;); }",
28236a12449ec8862211856447d3df4c082a346339f2Daniel Jasper                      forStmt(hasLoopInit(anything()))));
28246a12449ec8862211856447d3df4c082a346339f2Daniel Jasper}
28256a12449ec8862211856447d3df4c082a346339f2Daniel Jasper
2826651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(For, ForRangeLoopInternals) {
2827651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_TRUE(matches("void f(){ int a[] {1, 2}; for (int i : a); }",
2828a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxForRangeStmt(hasLoopVariable(anything()))));
28296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  EXPECT_TRUE(matches(
28306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      "void f(){ int a[] {1, 2}; for (int i : a); }",
2831a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxForRangeStmt(hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))))));
2832651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
2833651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
28346a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(For, NegativeForLoopInternals) {
28356a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }",
28362dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         forStmt(hasCondition(expr()))));
28376a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(notMatches("void f() {int i; for (; i < 4; ++i) {} }",
28386a12449ec8862211856447d3df4c082a346339f2Daniel Jasper                         forStmt(hasLoopInit(anything()))));
28396a12449ec8862211856447d3df4c082a346339f2Daniel Jasper}
28406a12449ec8862211856447d3df4c082a346339f2Daniel Jasper
28414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(For, ReportsNoFalsePositives) {
28424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { ; }", forStmt()));
28434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { if(true); }", forStmt()));
28444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(CompoundStatement, HandlesSimpleCases) {
28472dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("void f();", compoundStmt()));
28482dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("void f() {}", compoundStmt()));
28492dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("void f() {{}}", compoundStmt()));
28504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(CompoundStatement, DoesNotMatchEmptyStruct) {
28534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // It's not a compound statement just because there's "{}" in the source
28544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // text. This is an AST search, not grep.
28554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace n { struct S {}; }",
28562dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt()));
28574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("namespace n { struct S { void f() {{}} }; }",
28582dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt()));
28594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28616a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(HasBody, FindsBodyOfForWhileDoLoops) {
28624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { for(;;) {} }",
28632dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              forStmt(hasBody(compoundStmt()))));
28644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { for(;;); }",
28652dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              forStmt(hasBody(compoundStmt()))));
28666a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(matches("void f() { while(true) {} }",
28672dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              whileStmt(hasBody(compoundStmt()))));
28686a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(matches("void f() { do {} while(true); }",
28692dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              doStmt(hasBody(compoundStmt()))));
28706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  EXPECT_TRUE(matches("void f() { int p[2]; for (auto x : p) {} }",
2871a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              cxxForRangeStmt(hasBody(compoundStmt()))));
28724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
28754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // The simplest case: every compound statement is in a function
28764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // definition, and the function body itself must be a compound
28774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // statement.
28784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { for (;;); }",
28792dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(hasAnySubstatement(forStmt()))));
28804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnySubstatement, IsNotRecursive) {
28834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // It's really "has any immediate substatement".
28844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { if (true) for (;;); }",
28852dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(hasAnySubstatement(forStmt()))));
28864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnySubstatement, MatchesInNestedCompoundStatements) {
28894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { if (true) { for (;;); } }",
28902dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(hasAnySubstatement(forStmt()))));
28914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnySubstatement, FindsSubstatementBetweenOthers) {
28944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { 1; 2; 3; for (;;); 4; 5; 6; }",
28952dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(hasAnySubstatement(forStmt()))));
28964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) {
28994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { }",
29002dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(0))));
29014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() {}",
29022dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(1))));
29034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
29054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementCountIs, AppearsToMatchOnlyOneCount) {
29064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { 1; }",
29072dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(1))));
29084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { 1; }",
29092dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(0))));
29104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { 1; }",
29112dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(2))));
29124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
29144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementCountIs, WorksWithMultipleStatements) {
29154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { 1; 2; 3; }",
29162dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(3))));
29174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
29194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementCountIs, WorksWithNestedCompoundStatements) {
29204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
29212dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(1))));
29224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
29232dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(2))));
29244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
29252dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(3))));
29264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
29272dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(4))));
29284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
29304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Member, WorksInSimplestCase) {
29314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
29322dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      memberExpr(member(hasName("first")))));
29334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
29354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Member, DoesNotMatchTheBaseExpression) {
29364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Don't pick out the wrong part of the member expression, this should
29374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // be checking the member (name) only.
29384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
29392dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         memberExpr(member(hasName("first")))));
29404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
29424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Member, MatchesInMemberFunctionCall) {
29434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() {"
29444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "  struct { void first() {}; } s;"
29454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "  s.first();"
29464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "};",
29472dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      memberExpr(member(hasName("first")))));
29484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2950c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel JasperTEST(Member, MatchesMember) {
2951c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper  EXPECT_TRUE(matches(
2952c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper      "struct A { int i; }; void f() { A a; a.i = 2; }",
2953c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper      memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
2954c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper  EXPECT_TRUE(notMatches(
2955c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper      "struct A { float f; }; void f() { A a; a.f = 2.0f; }",
2956c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper      memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
2957c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper}
2958c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper
2959f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel JasperTEST(Member, UnderstandsAccess) {
2960f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(matches(
2961f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "struct A { int i; };", fieldDecl(isPublic(), hasName("i"))));
2962f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches(
2963f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "struct A { int i; };", fieldDecl(isProtected(), hasName("i"))));
2964f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches(
2965f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "struct A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
2966f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper
2967f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches(
2968f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "class A { int i; };", fieldDecl(isPublic(), hasName("i"))));
2969f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches(
2970f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "class A { int i; };", fieldDecl(isProtected(), hasName("i"))));
2971f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(matches(
2972f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "class A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
2973f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper
2974f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches(
2975f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "class A { protected: int i; };", fieldDecl(isPublic(), hasName("i"))));
2976f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(matches("class A { protected: int i; };",
2977f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper                      fieldDecl(isProtected(), hasName("i"))));
2978f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches(
2979f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "class A { protected: int i; };", fieldDecl(isPrivate(), hasName("i"))));
2980f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper
2981f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  // Non-member decls have the AccessSpecifier AS_none and thus aren't matched.
2982f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches("int i;", varDecl(isPublic(), hasName("i"))));
2983f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches("int i;", varDecl(isProtected(), hasName("i"))));
2984f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches("int i;", varDecl(isPrivate(), hasName("i"))));
2985f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper}
2986f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper
2987671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri GribenkoTEST(Member, MatchesMemberAllocationFunction) {
298831f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  // Fails in C++11 mode
298931f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  EXPECT_TRUE(matchesConditionally(
299031f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper      "namespace std { typedef typeof(sizeof(int)) size_t; }"
299131f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper      "class X { void *operator new(std::size_t); };",
2992a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxMethodDecl(ofClass(hasName("X"))), true, "-std=gnu++98"));
2993671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri Gribenko
2994671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri Gribenko  EXPECT_TRUE(matches("class X { void operator delete(void*); };",
2995a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxMethodDecl(ofClass(hasName("X")))));
2996671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri Gribenko
299731f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  // Fails in C++11 mode
299831f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  EXPECT_TRUE(matchesConditionally(
29992dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      "namespace std { typedef typeof(sizeof(int)) size_t; }"
30002dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      "class X { void operator delete[](void*, std::size_t); };",
3001a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxMethodDecl(ofClass(hasName("X"))), true, "-std=gnu++98"));
3002671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri Gribenko}
3003671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri Gribenko
30044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasObjectExpression, DoesNotMatchMember) {
30054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
30064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
30072dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
30084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
30094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
30104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasObjectExpression, MatchesBaseOfVariable) {
30114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
30124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "struct X { int m; }; void f(X x) { x.m; }",
30132dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
30144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
30154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "struct X { int m; }; void f(X* x) { x->m; }",
30162dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberExpr(hasObjectExpression(
30172dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasType(pointsTo(recordDecl(hasName("X"))))))));
30184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
30194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
30204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasObjectExpression,
30214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek     MatchesObjectExpressionOfImplicitlyFormedMemberExpression) {
30224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
30234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X {}; struct S { X m; void f() { this->m; } };",
30242dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberExpr(hasObjectExpression(
30252dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasType(pointsTo(recordDecl(hasName("S"))))))));
30264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
30274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X {}; struct S { X m; void f() { m; } };",
30282dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberExpr(hasObjectExpression(
30292dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasType(pointsTo(recordDecl(hasName("S"))))))));
30304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
30314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
30324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Field, DoesNotMatchNonFieldMembers) {
30332dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class X { void m(); };", fieldDecl(hasName("m"))));
30342dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class X { class m {}; };", fieldDecl(hasName("m"))));
30352dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class X { enum { m }; };", fieldDecl(hasName("m"))));
30362dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class X { enum m {}; };", fieldDecl(hasName("m"))));
30374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
30384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
30394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Field, MatchesField) {
30402dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("class X { int m; };", fieldDecl(hasName("m"))));
30414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
30424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
3043a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST(IsVolatileQualified, QualifiersMatch) {
3044a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("volatile int i = 42;",
3045a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      varDecl(hasType(isVolatileQualified()))));
3046a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("volatile int *i;",
3047a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         varDecl(hasType(isVolatileQualified()))));
3048a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("typedef volatile int v_int; v_int i = 42;",
3049a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      varDecl(hasType(isVolatileQualified()))));
3050a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}
3051a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
30524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsConstQualified, MatchesConstInt) {
30534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const int i = 42;",
30542dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasType(isConstQualified()))));
30554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
30564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
30574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsConstQualified, MatchesConstPointer) {
30584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = 42; int* const p(&i);",
30592dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasType(isConstQualified()))));
30604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
30614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
30624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsConstQualified, MatchesThroughTypedef) {
30634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
30642dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasType(isConstQualified()))));
30654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p(0);",
30662dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasType(isConstQualified()))));
30674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
30684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
30694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsConstQualified, DoesNotMatchInappropriately) {
30704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
30712dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasType(isConstQualified()))));
30724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int const* p;",
30732dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasType(isConstQualified()))));
30744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
30754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
3076089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(CastExpression, MatchesExplicitCasts) {
30773680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("char *p = reinterpret_cast<char *>(&p);",castExpr()));
30783680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("void *p = (void *)(&p);", castExpr()));
30793680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("char q, *p = const_cast<char *>(&q);", castExpr()));
30803680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("char c = char(0);", castExpr()));
3081089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3082089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(CastExpression, MatchesImplicitCasts) {
3083089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from int to char.
30843680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("char c = 0;", castExpr()));
3085089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from lvalue to rvalue.
30863680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("char c = 0, d = c;", castExpr()));
3087089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3088089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3089089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(CastExpression, DoesNotMatchNonCasts) {
30903680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(notMatches("char c = '0';", castExpr()));
30913680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(notMatches("char c, &q = c;", castExpr()));
30923680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(notMatches("int i = (0);", castExpr()));
30933680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
3094089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3095089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
30964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ReinterpretCast, MatchesSimpleCase) {
30974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("char* p = reinterpret_cast<char*>(&p);",
3098a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxReinterpretCastExpr()));
30994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
31004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
31014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ReinterpretCast, DoesNotMatchOtherCasts) {
3102a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("char* p = (char*)(&p);", cxxReinterpretCastExpr()));
31034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
3104a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxReinterpretCastExpr()));
31054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void* p = static_cast<void*>(&p);",
3106a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxReinterpretCastExpr()));
31074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
31084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                         "B b;"
31094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                         "D* p = dynamic_cast<D*>(&b);",
3110a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxReinterpretCastExpr()));
31114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
31124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
31134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(FunctionalCast, MatchesSimpleCase) {
3114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::string foo_class = "class Foo { public: Foo(const char*); };";
31154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",
3116a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxFunctionalCastExpr()));
31174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
31184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
31194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(FunctionalCast, DoesNotMatchOtherCasts) {
3120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::string FooClass = "class Foo { public: Foo(const char*); };";
31214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
31224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",
3123a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                 cxxFunctionalCastExpr()));
31244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
31254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches(FooClass + "void r() { Foo f = \"hello world\"; }",
3126a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                 cxxFunctionalCastExpr()));
31274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
31284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
31294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DynamicCast, MatchesSimpleCase) {
31304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("struct B { virtual ~B() {} }; struct D : B {};"
31314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "B b;"
31324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "D* p = dynamic_cast<D*>(&b);",
3133a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxDynamicCastExpr()));
31344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
31354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
31364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StaticCast, MatchesSimpleCase) {
31374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void* p(static_cast<void*>(&p));",
3138a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxStaticCastExpr()));
31394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
31404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
31414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StaticCast, DoesNotMatchOtherCasts) {
3142a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("char* p = (char*)(&p);", cxxStaticCastExpr()));
31434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
3144a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxStaticCastExpr()));
31454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void* p = reinterpret_cast<char*>(&p);",
3146a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxStaticCastExpr()));
31474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
31484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                         "B b;"
31494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                         "D* p = dynamic_cast<D*>(&b);",
3150a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxStaticCastExpr()));
31514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
31524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
3153e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel JasperTEST(CStyleCast, MatchesSimpleCase) {
3154e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper  EXPECT_TRUE(matches("int i = (int) 2.2f;", cStyleCastExpr()));
3155e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper}
3156e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper
3157e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel JasperTEST(CStyleCast, DoesNotMatchOtherCasts) {
3158e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper  EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);"
3159e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         "char q, *r = const_cast<char*>(&q);"
3160e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         "void* s = reinterpret_cast<char*>(&s);"
3161e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         "struct B { virtual ~B() {} }; struct D : B {};"
3162e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         "B b;"
3163e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         "D* t = dynamic_cast<D*>(&b);",
3164e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         cStyleCastExpr()));
3165e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper}
3166e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper
31674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasDestinationType, MatchesSimpleCase) {
31684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
3169a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxStaticCastExpr(hasDestinationType(
31703680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          pointsTo(TypeMatcher(anything()))))));
31714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
31724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
3173089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(HasImplicitDestinationType, MatchesSimpleCase) {
3174089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit const cast.
3175089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x; const int i = x;",
31763680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      implicitCastExpr(
31773680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          hasImplicitDestinationType(isInteger()))));
3178089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit array-to-pointer cast.
3179089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int arr[3]; int *p = arr;",
31803680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      implicitCastExpr(hasImplicitDestinationType(
31813680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          pointsTo(TypeMatcher(anything()))))));
3182089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3183089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3184089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(HasImplicitDestinationType, DoesNotMatchIncorrectly) {
3185089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from int to char.
3186089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char c = 0;",
31873680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      implicitCastExpr(hasImplicitDestinationType(
31883680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          unless(anything())))));
3189089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit array-to-pointer cast.
3190089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int arr[3]; int *p = arr;",
31913680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      implicitCastExpr(hasImplicitDestinationType(
31923680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          unless(anything())))));
3193089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3194089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3195089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(ImplicitCast, MatchesSimpleCase) {
3196089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit const cast.
3197089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0; const int y = x;",
31982dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(implicitCastExpr()))));
3199089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from int to char.
3200089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("char c = 0;",
32012dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(implicitCastExpr()))));
3202089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit array-to-pointer cast.
3203089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int arr[6]; int *p = arr;",
32042dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(implicitCastExpr()))));
3205089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3206089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3207089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(ImplicitCast, DoesNotMatchIncorrectly) {
32082dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  // This test verifies that implicitCastExpr() matches exactly when implicit casts
3209089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // are present, and that it ignores explicit and paren casts.
3210089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3211089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These two test cases have no casts.
3212089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x = 0;",
32132dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(implicitCastExpr()))));
3214089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x = 0, &y = x;",
32152dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(implicitCastExpr()))));
3216089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3217089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x = 0; double d = (double) x;",
32182dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(implicitCastExpr()))));
3219089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("const int *p; int *q = const_cast<int *>(p);",
32202dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(implicitCastExpr()))));
3221089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3222089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x = (0);",
32232dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(implicitCastExpr()))));
3224089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3225089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3226089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringImpCasts, MatchesImpCasts) {
3227089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test checks that ignoringImpCasts matches when implicit casts are
3228089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // present and its inner matcher alone does not match.
3229089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // Note that this test creates an implicit const cast.
3230089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0; const int y = x;",
32312dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringImpCasts(
32322dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          declRefExpr(to(varDecl(hasName("x")))))))));
3233089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implict cast from int to char.
3234089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("char x = 0;",
32352dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringImpCasts(
3236089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                          integerLiteral(equals(0)))))));
3237089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3238089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3239089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringImpCasts, DoesNotMatchIncorrectly) {
3240089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These tests verify that ignoringImpCasts does not match if the inner
3241089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // matcher does not match.
3242089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // Note that the first test creates an implicit const cast.
3243089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x; const int y = x;",
32442dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
3245089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
3246089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x; int y = x;",
32472dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
3248089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
3249089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3250089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These tests verify that ignoringImplictCasts does not look through explicit
3251089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // casts or parentheses.
3252089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
32532dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
32542dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
3255089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int i = (0);",
32562dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
32572dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
3258089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("float i = (float)0;",
32592dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
32602dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
3261089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("float i = float(0);",
32622dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
32632dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
3264089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3265089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3266089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringImpCasts, MatchesWithoutImpCasts) {
3267089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test verifies that expressions that do not have implicit casts
3268089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // still match the inner matcher.
3269089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0; int &y = x;",
32702dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringImpCasts(
32712dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          declRefExpr(to(varDecl(hasName("x")))))))));
3272089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3273089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3274089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenCasts, MatchesParenCasts) {
3275089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test checks that ignoringParenCasts matches when parentheses and/or
3276089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // casts are present and its inner matcher alone does not match.
3277089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = (0);",
32782dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
32792dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
3280089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = (((((0)))));",
32812dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
32822dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
3283089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3284089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implict cast from int to char in addition to the
3285089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // parentheses.
3286089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("char x = (0);",
32872dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
32882dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
3289089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3290089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("char x = (char)0;",
32912dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
32922dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
3293089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
32942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
3295089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                          integerLiteral(equals(0)))))));
3296089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3297089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3298089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenCasts, MatchesWithoutParenCasts) {
3299089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test verifies that expressions that do not have any casts still match.
3300089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0;",
33012dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
33022dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
3303089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3304089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3305089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenCasts, DoesNotMatchIncorrectly) {
3306089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These tests verify that ignoringImpCasts does not match if the inner
3307089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // matcher does not match.
3308089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x = ((0));",
33092dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenCasts(
3310089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
3311089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3312089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from int to char in addition to the
3313089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // parentheses.
3314089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char x = ((0));",
33152dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenCasts(
3316089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
3317089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3318089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char *x = static_cast<char *>((0));",
33192dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenCasts(
3320089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
3321089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3322089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3323089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenAndImpCasts, MatchesParenImpCasts) {
3324089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test checks that ignoringParenAndImpCasts matches when
3325089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // parentheses and/or implicit casts are present and its inner matcher alone
3326089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // does not match.
3327089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // Note that this test creates an implicit const cast.
3328089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0; const int y = x;",
33292dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenImpCasts(
33302dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          declRefExpr(to(varDecl(hasName("x")))))))));
3331089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from int to char.
3332089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("const char x = (0);",
33332dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenImpCasts(
33342dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
3335089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3336089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3337089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenAndImpCasts, MatchesWithoutParenImpCasts) {
3338089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test verifies that expressions that do not have parentheses or
3339089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // implicit casts still match.
3340089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0; int &y = x;",
33412dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenImpCasts(
33422dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          declRefExpr(to(varDecl(hasName("x")))))))));
3343089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0;",
33442dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenImpCasts(
33452dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
3346089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3347089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3348089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenAndImpCasts, DoesNotMatchIncorrectly) {
3349089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These tests verify that ignoringParenImpCasts does not match if
3350089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // the inner matcher does not match.
3351089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast.
3352089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char c = ((3));",
33532dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenImpCasts(
3354089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
3355089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These tests verify that ignoringParenAndImplictCasts does not look
3356089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // through explicit casts.
3357089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("float y = (float(0));",
33582dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenImpCasts(
33592dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
3360089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("float y = (float)0;",
33612dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenImpCasts(
33622dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
3363089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
33642dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenImpCasts(
33652dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
3366089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3367089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3368715c9568ee5d75f25dab98229c87bcec880daf5dManuel KlimekTEST(HasSourceExpression, MatchesImplicitCasts) {
33694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
33704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "void r() {string a_string; URL url = a_string; }",
33713680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      implicitCastExpr(
3372a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                          hasSourceExpression(cxxConstructExpr()))));
33734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
33744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
3375715c9568ee5d75f25dab98229c87bcec880daf5dManuel KlimekTEST(HasSourceExpression, MatchesExplicitCasts) {
3376715c9568ee5d75f25dab98229c87bcec880daf5dManuel Klimek  EXPECT_TRUE(matches("float x = static_cast<float>(42);",
33773680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      explicitCastExpr(
33782dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          hasSourceExpression(hasDescendant(
33793680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                              expr(integerLiteral()))))));
3380715c9568ee5d75f25dab98229c87bcec880daf5dManuel Klimek}
3381715c9568ee5d75f25dab98229c87bcec880daf5dManuel Klimek
33824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Statement, DoesNotMatchDeclarations) {
33832dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class X {};", stmt()));
33844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
33854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
33864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Statement, MatchesCompoundStatments) {
33872dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("void x() {}", stmt()));
33884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
33894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
33904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationStatement, DoesNotMatchCompoundStatements) {
33912dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("void x() {}", declStmt()));
33924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
33934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
33944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationStatement, MatchesVariableDeclarationStatements) {
33952dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("void x() { int a; }", declStmt()));
33964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
33974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
3398651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(ExprWithCleanups, MatchesExprWithCleanups) {
3399651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_TRUE(matches("struct Foo { ~Foo(); };"
3400651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                      "const Foo f = Foo();",
3401651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                      varDecl(hasInitializer(exprWithCleanups()))));
3402651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_FALSE(matches("struct Foo { };"
3403651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                      "const Foo f = Foo();",
3404651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                      varDecl(hasInitializer(exprWithCleanups()))));
3405651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
3406651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3407e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(InitListExpression, MatchesInitListExpression) {
3408e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("int a[] = { 1, 2 };",
3409e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      initListExpr(hasType(asString("int [2]")))));
3410e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };",
34112dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      initListExpr(hasType(recordDecl(hasName("B"))))));
34120e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(matches("struct S { S(void (*a)()); };"
34130e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                      "void f();"
34140e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                      "S s[1] = { &f };",
34150e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                      declRefExpr(to(functionDecl(hasName("f"))))));
34160e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(
34170e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      matches("int i[1] = {42, [0] = 43};", integerLiteral(equals(42))));
3418e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
3419e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
3420e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UsingDeclaration, MatchesUsingDeclarations) {
3421e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("namespace X { int x; } using X::x;",
3422e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      usingDecl()));
3423e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
3424e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
3425e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UsingDeclaration, MatchesShadowUsingDelcarations) {
3426e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("namespace f { int a; } using f::a;",
3427e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      usingDecl(hasAnyUsingShadowDecl(hasName("a")))));
3428e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
3429e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
3430e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UsingDeclaration, MatchesSpecificTarget) {
3431e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
3432e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      usingDecl(hasAnyUsingShadowDecl(
34332dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          hasTargetDecl(functionDecl())))));
3434e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
3435e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                         usingDecl(hasAnyUsingShadowDecl(
34362dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             hasTargetDecl(functionDecl())))));
3437e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
3438e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
3439e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UsingDeclaration, ThroughUsingDeclaration) {
3440e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
3441e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "namespace a { void f(); } using a::f; void g() { f(); }",
34422dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      declRefExpr(throughUsingDecl(anything()))));
3443e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches(
3444e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "namespace a { void f(); } using a::f; void g() { a::f(); }",
34452dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      declRefExpr(throughUsingDecl(anything()))));
3446e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
3447e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
3448176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(UsingDirectiveDeclaration, MatchesUsingNamespace) {
3449176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("namespace X { int x; } using namespace X;",
3450176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      usingDirectiveDecl()));
3451176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_FALSE(
3452176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      matches("namespace X { int x; } using X::x;", usingDirectiveDecl()));
3453176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
3454176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
3455425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam PanzerTEST(SingleDecl, IsSingleDecl) {
3456425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  StatementMatcher SingleDeclStmt =
34572dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      declStmt(hasSingleDecl(varDecl(hasInitializer(anything()))));
3458425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(matches("void f() {int a = 4;}", SingleDeclStmt));
3459425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(notMatches("void f() {int a;}", SingleDeclStmt));
3460425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
3461425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer                          SingleDeclStmt));
3462425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer}
3463425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer
3464425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam PanzerTEST(DeclStmt, ContainsDeclaration) {
34652dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher MatchesInit = varDecl(hasInitializer(anything()));
3466425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer
3467425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(matches("void f() {int a = 4;}",
34682dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      declStmt(containsDeclaration(0, MatchesInit))));
3469425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(matches("void f() {int a = 4, b = 3;}",
34702dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      declStmt(containsDeclaration(0, MatchesInit),
34712dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                               containsDeclaration(1, MatchesInit))));
3472425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  unsigned WrongIndex = 42;
3473425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
34742dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         declStmt(containsDeclaration(WrongIndex,
3475425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer                                                      MatchesInit))));
3476425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer}
3477425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer
3478425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam PanzerTEST(DeclCount, DeclCountIsCorrect) {
3479425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(matches("void f() {int i,j;}",
34802dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      declStmt(declCountIs(2))));
3481425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(notMatches("void f() {int i,j; int k;}",
34822dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         declStmt(declCountIs(3))));
3483425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(notMatches("void f() {int i,j, k, l;}",
34842dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         declStmt(declCountIs(3))));
3485425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer}
3486425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer
34874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(While, MatchesWhileLoops) {
34884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() {}", whileStmt()));
34894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { while(true); }", whileStmt()));
34904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { do {} while(true); }", whileStmt()));
34914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
34924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
34934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Do, MatchesDoLoops) {
34944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { do {} while(true); }", doStmt()));
34954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { do ; while(false); }", doStmt()));
34964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
34974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
34984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Do, DoesNotMatchWhileLoops) {
34994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { while(true) {} }", doStmt()));
35004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
35014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
35024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(SwitchCase, MatchesCase) {
35034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchCase()));
35044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchCase()));
35054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchCase()));
35064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { switch(42) {} }", switchCase()));
35074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
35084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
3509b54b7646b2d00a85d80e40adf7c49553f150c736Daniel JasperTEST(SwitchCase, MatchesSwitch) {
3510b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchStmt()));
3511b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchStmt()));
3512b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchStmt()));
3513b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(notMatches("void x() {}", switchStmt()));
3514b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper}
3515b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper
3516acf02715ab1aa1e5a791f20e0d1ca217af256823Peter CollingbourneTEST(SwitchCase, MatchesEachCase) {
3517acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne  EXPECT_TRUE(notMatches("void x() { switch(42); }",
3518acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne                         switchStmt(forEachSwitchCase(caseStmt()))));
3519acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne  EXPECT_TRUE(matches("void x() { switch(42) case 42:; }",
3520acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne                      switchStmt(forEachSwitchCase(caseStmt()))));
3521acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne  EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }",
3522acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne                      switchStmt(forEachSwitchCase(caseStmt()))));
3523acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne  EXPECT_TRUE(notMatches(
3524acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne      "void x() { if (1) switch(42) { case 42: switch (42) { default:; } } }",
3525acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne      ifStmt(has(switchStmt(forEachSwitchCase(defaultStmt()))))));
3526acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne  EXPECT_TRUE(matches("void x() { switch(42) { case 1+1: case 4:; } }",
3527acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne                      switchStmt(forEachSwitchCase(
3528acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne                          caseStmt(hasCaseConstant(integerLiteral()))))));
3529acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne  EXPECT_TRUE(notMatches("void x() { switch(42) { case 1+1: case 2+2:; } }",
3530acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne                         switchStmt(forEachSwitchCase(
3531acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne                             caseStmt(hasCaseConstant(integerLiteral()))))));
3532acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne  EXPECT_TRUE(notMatches("void x() { switch(42) { case 1 ... 2:; } }",
3533acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne                         switchStmt(forEachSwitchCase(
3534acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne                             caseStmt(hasCaseConstant(integerLiteral()))))));
3535acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne  EXPECT_TRUE(matchAndVerifyResultTrue(
3536acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne      "void x() { switch (42) { case 1: case 2: case 3: default:; } }",
3537acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne      switchStmt(forEachSwitchCase(caseStmt().bind("x"))),
3538acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne      new VerifyIdIsBoundTo<CaseStmt>("x", 3)));
3539acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne}
3540acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne
354106963013d1972f1f7a58875bb40976b60522700bManuel KlimekTEST(ForEachConstructorInitializer, MatchesInitializers) {
354206963013d1972f1f7a58875bb40976b60522700bManuel Klimek  EXPECT_TRUE(matches(
354306963013d1972f1f7a58875bb40976b60522700bManuel Klimek      "struct X { X() : i(42), j(42) {} int i, j; };",
3544a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxConstructorDecl(forEachConstructorInitializer(cxxCtorInitializer()))));
354506963013d1972f1f7a58875bb40976b60522700bManuel Klimek}
354606963013d1972f1f7a58875bb40976b60522700bManuel Klimek
3547b54b7646b2d00a85d80e40adf7c49553f150c736Daniel JasperTEST(ExceptionHandling, SimpleCases) {
3548a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", cxxCatchStmt()));
3549a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", cxxTryStmt()));
3550a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(
3551a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      notMatches("void foo() try { } catch(int X) { }", cxxThrowExpr()));
3552b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void foo() try { throw; } catch(int X) { }",
3553a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxThrowExpr()));
3554b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void foo() try { throw 5;} catch(int X) { }",
3555a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxThrowExpr()));
3556a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("void foo() try { throw; } catch(...) { }",
3557a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxCatchStmt(isCatchAll())));
3558a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("void foo() try { throw; } catch(int) { }",
3559a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxCatchStmt(isCatchAll())));
3560a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("void foo() try {} catch(int X) { }",
3561a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      varDecl(isExceptionVariable())));
3562a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("void foo() try { int X; } catch (...) { }",
3563a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         varDecl(isExceptionVariable())));
3564b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper}
3565b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper
35664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasConditionVariableStatement, DoesNotMatchCondition) {
35674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
35684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void x() { if(true) {} }",
35692dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      ifStmt(hasConditionVariableStatement(declStmt()))));
35704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
35714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void x() { int x; if((x = 42)) {} }",
35722dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      ifStmt(hasConditionVariableStatement(declStmt()))));
35734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
35744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
35754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasConditionVariableStatement, MatchesConditionVariables) {
35764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
35774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void x() { if(int* a = 0) {} }",
35782dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      ifStmt(hasConditionVariableStatement(declStmt()))));
35794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
35804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
35814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEach, BindsOneNode) {
35824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
35832dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"), forEach(fieldDecl(hasName("x")).bind("x"))),
3584a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("x", 1)));
35854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
35864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
35874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEach, BindsMultipleNodes) {
35884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
35892dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"), forEach(fieldDecl().bind("f"))),
3590a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("f", 3)));
35914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
35924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
35934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEach, BindsRecursiveCombinations) {
35944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
35954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class C { class D { int x; int y; }; class E { int y; int z; }; };",
35962dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"),
35972dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 forEach(recordDecl(forEach(fieldDecl().bind("f"))))),
3598a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("f", 4)));
35994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
36004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
36014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEachDescendant, BindsOneNode) {
36024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
36032dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"),
36042dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 forEachDescendant(fieldDecl(hasName("x")).bind("x"))),
3605a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("x", 1)));
36064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
36074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
36085f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel JasperTEST(ForEachDescendant, NestedForEachDescendant) {
36095f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper  DeclarationMatcher m = recordDecl(
36105f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper      isDefinition(), decl().bind("x"), hasName("C"));
36115f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
36125f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper    "class A { class B { class C {}; }; };",
36135f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper    recordDecl(hasName("A"), anyOf(m, forEachDescendant(m))),
36145f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper    new VerifyIdIsBoundTo<Decl>("x", "C")));
36155f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper
3616054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // Check that a partial match of 'm' that binds 'x' in the
3617054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // first part of anyOf(m, anything()) will not overwrite the
3618054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // binding created by the earlier binding in the hasDescendant.
3619054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3620054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "class A { class B { class C {}; }; };",
3621054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      recordDecl(hasName("A"), allOf(hasDescendant(m), anyOf(m, anything()))),
3622054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", "C")));
36235f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper}
36245f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper
36254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEachDescendant, BindsMultipleNodes) {
36264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
36274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class C { class D { int x; int y; }; "
36284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "          class E { class F { int y; int z; }; }; };",
36292dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"), forEachDescendant(fieldDecl().bind("f"))),
3630a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("f", 4)));
36314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
36324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
36334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEachDescendant, BindsRecursiveCombinations) {
36344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
36354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class C { class D { "
36364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "          class E { class F { class G { int y; int z; }; }; }; }; };",
36372dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"), forEachDescendant(recordDecl(
36382dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          forEachDescendant(fieldDecl().bind("f"))))),
3639a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("f", 8)));
36404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
36414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
3642054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel KlimekTEST(ForEachDescendant, BindsCombinations) {
3643054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3644054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "void f() { if(true) {} if (true) {} while (true) {} if (true) {} while "
3645054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "(true) {} }",
3646054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      compoundStmt(forEachDescendant(ifStmt().bind("if")),
3647054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek                   forEachDescendant(whileStmt().bind("while"))),
3648054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<IfStmt>("if", 6)));
3649054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek}
3650054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek
3651054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel KlimekTEST(Has, DoesNotDeleteBindings) {
3652054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3653054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "class X { int a; };", recordDecl(decl().bind("x"), has(fieldDecl())),
3654054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
3655054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek}
3656054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek
3657054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel KlimekTEST(LoopingMatchers, DoNotOverwritePreviousMatchResultOnFailure) {
3658054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // Those matchers cover all the cases where an inner matcher is called
3659054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // and there is not a 1:1 relationship between the match of the outer
3660054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // matcher and the match of the inner matcher.
3661054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // The pattern to look for is:
3662054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  //   ... return InnerMatcher.matches(...); ...
3663054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // In which case no special handling is needed.
3664054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  //
3665054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // On the other hand, if there are multiple alternative matches
3666054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // (for example forEach*) or matches might be discarded (for example has*)
3667054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // the implementation must make sure that the discarded matches do not
3668054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // affect the bindings.
3669054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // When new such matchers are added, add a test here that:
3670054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // - matches a simple node, and binds it as the first thing in the matcher:
3671054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  //     recordDecl(decl().bind("x"), hasName("X")))
3672054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // - uses the matcher under test afterwards in a way that not the first
3673054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  //   alternative is matched; for anyOf, that means the first branch
3674054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  //   would need to return false; for hasAncestor, it means that not
3675054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  //   the direct parent matches the inner matcher.
3676054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek
3677054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3678054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "class X { int y; };",
3679054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      recordDecl(
3680054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek          recordDecl().bind("x"), hasName("::X"),
3681054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek          anyOf(forEachDescendant(recordDecl(hasName("Y"))), anything())),
3682054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<CXXRecordDecl>("x", 1)));
3683054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3684054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "class X {};", recordDecl(recordDecl().bind("x"), hasName("::X"),
3685054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek                                anyOf(unless(anything()), anything())),
3686054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<CXXRecordDecl>("x", 1)));
3687054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3688054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "template<typename T1, typename T2> class X {}; X<float, int> x;",
3689054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      classTemplateSpecializationDecl(
3690054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek          decl().bind("x"),
3691054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek          hasAnyTemplateArgument(refersToType(asString("int")))),
3692054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
3693054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3694054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "class X { void f(); void g(); };",
3695a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxRecordDecl(decl().bind("x"), hasMethod(hasName("g"))),
3696054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
3697054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3698054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "class X { X() : a(1), b(2) {} double a; int b; };",
3699054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      recordDecl(decl().bind("x"),
3700a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                 has(cxxConstructorDecl(
3701054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek                     hasAnyConstructorInitializer(forField(hasName("b")))))),
3702054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
3703054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3704054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "void x(int, int) { x(0, 42); }",
3705054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      callExpr(expr().bind("x"), hasAnyArgument(integerLiteral(equals(42)))),
3706054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Expr>("x", 1)));
3707054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3708054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "void x(int, int y) {}",
3709054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      functionDecl(decl().bind("x"), hasAnyParameter(hasName("y"))),
3710054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
3711054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3712054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "void x() { return; if (true) {} }",
3713054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      functionDecl(decl().bind("x"),
3714054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek                   has(compoundStmt(hasAnySubstatement(ifStmt())))),
3715054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
3716054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3717054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "namespace X { void b(int); void b(); }"
3718054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "using X::b;",
3719054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      usingDecl(decl().bind("x"), hasAnyUsingShadowDecl(hasTargetDecl(
3720054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek                                      functionDecl(parameterCountIs(1))))),
3721054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
3722054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3723054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "class A{}; class B{}; class C : B, A {};",
3724a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxRecordDecl(decl().bind("x"), isDerivedFrom("::A")),
3725054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
3726054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3727054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "class A{}; typedef A B; typedef A C; typedef A D;"
3728054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "class E : A {};",
3729a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxRecordDecl(decl().bind("x"), isDerivedFrom("C")),
3730054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
3731054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3732054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "class A { class B { void f() {} }; };",
3733054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      functionDecl(decl().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
3734054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
3735054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3736054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "template <typename T> struct A { struct B {"
3737054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "  void f() { if(true) {} }"
3738054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "}; };"
3739054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "void t() { A<int>::B b; b.f(); }",
3740054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      ifStmt(stmt().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
3741054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Stmt>("x", 2)));
3742054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3743054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "class A {};",
3744054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      recordDecl(hasName("::A"), decl().bind("x"), unless(hasName("fooble"))),
3745054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
374606963013d1972f1f7a58875bb40976b60522700bManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
374706963013d1972f1f7a58875bb40976b60522700bManuel Klimek      "class A { A() : s(), i(42) {} const char *s; int i; };",
3748a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxConstructorDecl(hasName("::A::A"), decl().bind("x"),
3749a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         forEachConstructorInitializer(forField(hasName("i")))),
375006963013d1972f1f7a58875bb40976b60522700bManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
3751054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek}
3752054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek
375311c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel JasperTEST(ForEachDescendant, BindsCorrectNodes) {
375411c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
375511c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      "class C { void f(); int i; };",
375611c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
375711c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("decl", 1)));
375811c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
375911c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      "class C { void f() {} int i; };",
376011c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
376111c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      new VerifyIdIsBoundTo<FunctionDecl>("decl", 1)));
376211c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper}
376311c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper
3764152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel KlimekTEST(FindAll, BindsNodeOnMatch) {
3765152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3766152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      "class A {};",
3767152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      recordDecl(hasName("::A"), findAll(recordDecl(hasName("::A")).bind("v"))),
3768152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      new VerifyIdIsBoundTo<CXXRecordDecl>("v", 1)));
3769152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek}
3770152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek
3771152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel KlimekTEST(FindAll, BindsDescendantNodeOnMatch) {
3772152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3773152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      "class A { int a; int b; };",
3774152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      recordDecl(hasName("::A"), findAll(fieldDecl().bind("v"))),
3775152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      new VerifyIdIsBoundTo<FieldDecl>("v", 2)));
3776152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek}
3777152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek
3778152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel KlimekTEST(FindAll, BindsNodeAndDescendantNodesOnOneMatch) {
3779152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3780152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      "class A { int a; int b; };",
3781152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      recordDecl(hasName("::A"),
3782152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek                 findAll(decl(anyOf(recordDecl(hasName("::A")).bind("v"),
3783152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek                                    fieldDecl().bind("v"))))),
3784152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      new VerifyIdIsBoundTo<Decl>("v", 3)));
3785152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek
3786152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3787152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      "class A { class B {}; class C {}; };",
3788152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("v"))),
3789152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      new VerifyIdIsBoundTo<CXXRecordDecl>("v", 3)));
3790152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek}
3791152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek
37927387673f83b8b37f660422947c9990778ba88193Manuel KlimekTEST(EachOf, TriggersForEachMatch) {
37937387673f83b8b37f660422947c9990778ba88193Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
37947387673f83b8b37f660422947c9990778ba88193Manuel Klimek      "class A { int a; int b; };",
37957387673f83b8b37f660422947c9990778ba88193Manuel Klimek      recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
37967387673f83b8b37f660422947c9990778ba88193Manuel Klimek                        has(fieldDecl(hasName("b")).bind("v")))),
37977387673f83b8b37f660422947c9990778ba88193Manuel Klimek      new VerifyIdIsBoundTo<FieldDecl>("v", 2)));
37987387673f83b8b37f660422947c9990778ba88193Manuel Klimek}
37997387673f83b8b37f660422947c9990778ba88193Manuel Klimek
38007387673f83b8b37f660422947c9990778ba88193Manuel KlimekTEST(EachOf, BehavesLikeAnyOfUnlessBothMatch) {
38017387673f83b8b37f660422947c9990778ba88193Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
38027387673f83b8b37f660422947c9990778ba88193Manuel Klimek      "class A { int a; int c; };",
38037387673f83b8b37f660422947c9990778ba88193Manuel Klimek      recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
38047387673f83b8b37f660422947c9990778ba88193Manuel Klimek                        has(fieldDecl(hasName("b")).bind("v")))),
38057387673f83b8b37f660422947c9990778ba88193Manuel Klimek      new VerifyIdIsBoundTo<FieldDecl>("v", 1)));
38067387673f83b8b37f660422947c9990778ba88193Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
38077387673f83b8b37f660422947c9990778ba88193Manuel Klimek      "class A { int c; int b; };",
38087387673f83b8b37f660422947c9990778ba88193Manuel Klimek      recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
38097387673f83b8b37f660422947c9990778ba88193Manuel Klimek                        has(fieldDecl(hasName("b")).bind("v")))),
38107387673f83b8b37f660422947c9990778ba88193Manuel Klimek      new VerifyIdIsBoundTo<FieldDecl>("v", 1)));
38117387673f83b8b37f660422947c9990778ba88193Manuel Klimek  EXPECT_TRUE(notMatches(
38127387673f83b8b37f660422947c9990778ba88193Manuel Klimek      "class A { int c; int d; };",
38137387673f83b8b37f660422947c9990778ba88193Manuel Klimek      recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
38147387673f83b8b37f660422947c9990778ba88193Manuel Klimek                        has(fieldDecl(hasName("b")).bind("v"))))));
38157387673f83b8b37f660422947c9990778ba88193Manuel Klimek}
38164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
38174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) {
38184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Make sure that we can both match the class by name (::X) and by the type
38194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // the template was instantiated with (via a field).
38204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
38214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
38224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X {}; class A {}; X<A> x;",
3823a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
38244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
38254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
38264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X { T t; }; class A {}; X<A> x;",
3827a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxRecordDecl(isTemplateInstantiation(), hasDescendant(
38282dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          fieldDecl(hasType(recordDecl(hasName("A"))))))));
38294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
38304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
38314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) {
38324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
38334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
38342dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionDecl(hasParameter(0, hasType(recordDecl(hasName("A")))),
38354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek               isTemplateInstantiation())));
38364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
38374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
38384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) {
38394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
38404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X { T t; }; class A {};"
38414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template class X<A>;",
3842a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxRecordDecl(isTemplateInstantiation(), hasDescendant(
38432dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          fieldDecl(hasType(recordDecl(hasName("A"))))))));
38444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
38454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
38464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation,
38474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek     MatchesInstantiationOfPartiallySpecializedClassTemplate) {
38484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
38494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X {};"
38504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
3851a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
38524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
38534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
38544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation,
38554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek     MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
38564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
38574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class A {};"
38584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X {"
38594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  template <typename U> class Y { U u; };"
38604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Y<A> y;"
38614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};",
3862a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxRecordDecl(hasName("::X::Y"), isTemplateInstantiation())));
38634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
38644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
38654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) {
38664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // FIXME: Figure out whether this makes sense. It doesn't affect the
38674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // normal use case as long as the uppermost instantiation always is marked
38684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // as template instantiation, but it might be confusing as a predicate.
38694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
38704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class A {};"
38714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X {"
38724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  template <typename U> class Y { U u; };"
38734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Y<T> y;"
38744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "}; X<A> x;",
3875a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxRecordDecl(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
38764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
38774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
38784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) {
38794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
38804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X {}; class A {};"
38814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <> class X<A> {}; X<A> x;",
3882a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
38834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
38844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
38854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) {
38864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
38874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class A {}; class Y { A a; };",
3888a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxRecordDecl(isTemplateInstantiation())));
38894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
38904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
3891176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(IsInstantiated, MatchesInstantiation) {
3892176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(
3893176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      matches("template<typename T> class A { T i; }; class Y { A<int> a; };",
3894a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              cxxRecordDecl(isInstantiated())));
3895176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
3896176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
3897176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(IsInstantiated, NotMatchesDefinition) {
3898176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("template<typename T> class A { T i; };",
3899a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         cxxRecordDecl(isInstantiated())));
3900176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
3901176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
3902176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(IsInTemplateInstantiation, MatchesInstantiationStmt) {
3903176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("template<typename T> struct A { A() { T i; } };"
3904176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      "class Y { A<int> a; }; Y y;",
3905176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      declStmt(isInTemplateInstantiation())));
3906176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
3907176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
3908176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(IsInTemplateInstantiation, NotMatchesDefinitionStmt) {
3909176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("template<typename T> struct A { void x() { T i; } };",
3910176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                         declStmt(isInTemplateInstantiation())));
3911176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
3912176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
3913176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(IsInstantiated, MatchesFunctionInstantiation) {
3914176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(
3915176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
3916176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines              functionDecl(isInstantiated())));
3917176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
3918176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
3919176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(IsInstantiated, NotMatchesFunctionDefinition) {
3920176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
3921176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                         varDecl(isInstantiated())));
3922176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
3923176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
3924176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(IsInTemplateInstantiation, MatchesFunctionInstantiationStmt) {
3925176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(
3926176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
3927176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines              declStmt(isInTemplateInstantiation())));
3928176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
3929176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
3930176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(IsInTemplateInstantiation, NotMatchesFunctionDefinitionStmt) {
3931176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
3932176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                         declStmt(isInTemplateInstantiation())));
3933176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
3934176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
3935176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(IsInTemplateInstantiation, Sharing) {
3936176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  auto Matcher = binaryOperator(unless(isInTemplateInstantiation()));
3937176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // FIXME: Node sharing is an implementation detail, exposing it is ugly
3938176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // and makes the matcher behave in non-obvious ways.
3939176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches(
3940176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      "int j; template<typename T> void A(T t) { j += 42; } void x() { A(0); }",
3941176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      Matcher));
3942176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches(
3943176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      "int j; template<typename T> void A(T t) { j += t; } void x() { A(0); }",
3944176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      Matcher));
3945176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
3946176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
39478456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(IsExplicitTemplateSpecialization,
39488456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko     DoesNotMatchPrimaryTemplate) {
39498456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
39508456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> class X {};",
3951a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxRecordDecl(isExplicitTemplateSpecialization())));
39528456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
39538456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> void f(T t);",
39542dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionDecl(isExplicitTemplateSpecialization())));
39558456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
39568456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
39578456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(IsExplicitTemplateSpecialization,
39588456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko     DoesNotMatchExplicitTemplateInstantiations) {
39598456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
39608456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> class X {};"
39618456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template class X<int>; extern template class X<long>;",
3962a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxRecordDecl(isExplicitTemplateSpecialization())));
39638456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
39648456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> void f(T t) {}"
39658456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template void f(int t); extern template void f(long t);",
39662dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionDecl(isExplicitTemplateSpecialization())));
39678456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
39688456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
39698456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(IsExplicitTemplateSpecialization,
39708456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko     DoesNotMatchImplicitTemplateInstantiations) {
39718456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
39728456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> class X {}; X<int> x;",
3973a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxRecordDecl(isExplicitTemplateSpecialization())));
39748456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
39758456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> void f(T t); void g() { f(10); }",
39762dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionDecl(isExplicitTemplateSpecialization())));
39778456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
39788456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
39798456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(IsExplicitTemplateSpecialization,
39808456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko     MatchesExplicitTemplateSpecializations) {
39818456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(matches(
39828456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> class X {};"
39838456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template<> class X<int> {};",
3984a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxRecordDecl(isExplicitTemplateSpecialization())));
39858456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(matches(
39868456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> void f(T t) {}"
39878456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template<> void f(int t) {}",
39882dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionDecl(isExplicitTemplateSpecialization())));
39898456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
39908456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
3991579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncenstor, MatchesDeclarationAncestors) {
3992579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
3993579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "class A { class B { class C {}; }; };",
3994579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("A"))))));
3995579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3996579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3997579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncenstor, FailsIfNoAncestorMatches) {
3998579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(notMatches(
3999579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "class A { class B { class C {}; }; };",
4000579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("X"))))));
4001579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
4002579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
4003579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, MatchesDeclarationsThatGetVisitedLater) {
4004579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
4005579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "class A { class B { void f() { C c; } class C {}; }; };",
4006579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      varDecl(hasName("c"), hasType(recordDecl(hasName("C"),
4007579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek          hasAncestor(recordDecl(hasName("A"))))))));
4008579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
4009579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
4010579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncenstor, MatchesStatementAncestors) {
4011579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
4012579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "void f() { if (true) { while (false) { 42; } } }",
40133680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      integerLiteral(equals(42), hasAncestor(ifStmt()))));
4014579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
4015579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
4016579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, DrillsThroughDifferentHierarchies) {
4017579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
4018579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "void f() { if (true) { int x = 42; } }",
40193680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      integerLiteral(equals(42), hasAncestor(functionDecl(hasName("f"))))));
4020579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
4021579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
4022579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, BindsRecursiveCombinations) {
4023579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
4024579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "class C { class D { class E { class F { int y; }; }; }; };",
4025579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      fieldDecl(hasAncestor(recordDecl(hasAncestor(recordDecl().bind("r"))))),
4026a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<CXXRecordDecl>("r", 1)));
4027579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
4028579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
4029579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, BindsCombinationsWithHasDescendant) {
4030579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
4031579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "class C { class D { class E { class F { int y; }; }; }; };",
4032579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      fieldDecl(hasAncestor(
4033579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek          decl(
4034579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek            hasDescendant(recordDecl(isDefinition(),
4035579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek                                     hasAncestor(recordDecl())))
4036579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek          ).bind("d")
4037579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      )),
4038a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<CXXRecordDecl>("d", "E")));
4039579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
4040579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
4041374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel KlimekTEST(HasAncestor, MatchesClosestAncestor) {
4042374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
4043374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      "template <typename T> struct C {"
4044374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      "  void f(int) {"
4045374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      "    struct I { void g(T) { int x; } } i; i.g(42);"
4046374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      "  }"
4047374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      "};"
4048374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      "template struct C<int>;",
4049374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      varDecl(hasName("x"),
4050374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek              hasAncestor(functionDecl(hasParameter(
4051374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek                  0, varDecl(hasType(asString("int"))))).bind("f"))).bind("v"),
4052374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      new VerifyIdIsBoundTo<FunctionDecl>("f", "g", 2)));
4053374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek}
4054374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek
4055579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, MatchesInTemplateInstantiations) {
4056579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
4057579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "template <typename T> struct A { struct B { struct C { T t; }; }; }; "
4058579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "A<int>::B::C a;",
4059579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      fieldDecl(hasType(asString("int")),
4060579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek                hasAncestor(recordDecl(hasName("A"))))));
4061579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
4062579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
4063579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, MatchesInImplicitCode) {
4064579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
4065579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "struct X {}; struct A { A() {} X x; };",
4066a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxConstructorDecl(
4067579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek          hasAnyConstructorInitializer(withInitializer(expr(
4068579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek              hasAncestor(recordDecl(hasName("A")))))))));
4069579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
4070579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
4071c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel JasperTEST(HasParent, MatchesOnlyParent) {
4072c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper  EXPECT_TRUE(matches(
4073c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      "void f() { if (true) { int x = 42; } }",
4074c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      compoundStmt(hasParent(ifStmt()))));
4075c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper  EXPECT_TRUE(notMatches(
4076c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      "void f() { for (;;) { int x = 42; } }",
4077c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      compoundStmt(hasParent(ifStmt()))));
4078c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper  EXPECT_TRUE(notMatches(
4079c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      "void f() { if (true) for (;;) { int x = 42; } }",
4080c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      compoundStmt(hasParent(ifStmt()))));
4081c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper}
4082c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper
408330ace3715015b4a9bc5fa538a6515481abed40f9Manuel KlimekTEST(HasAncestor, MatchesAllAncestors) {
408430ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek  EXPECT_TRUE(matches(
408530ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "template <typename T> struct C { static void f() { 42; } };"
408630ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "void t() { C<int>::f(); }",
408730ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      integerLiteral(
408830ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek          equals(42),
4089a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar          allOf(
4090a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              hasAncestor(cxxRecordDecl(isTemplateInstantiation())),
4091a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              hasAncestor(cxxRecordDecl(unless(isTemplateInstantiation())))))));
409230ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek}
409330ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek
409430ace3715015b4a9bc5fa538a6515481abed40f9Manuel KlimekTEST(HasParent, MatchesAllParents) {
409530ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek  EXPECT_TRUE(matches(
409630ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "template <typename T> struct C { static void f() { 42; } };"
409730ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "void t() { C<int>::f(); }",
409830ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      integerLiteral(
409930ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek          equals(42),
410030ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek          hasParent(compoundStmt(hasParent(functionDecl(
4101a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              hasParent(cxxRecordDecl(isTemplateInstantiation())))))))));
4102a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(
4103a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      matches("template <typename T> struct C { static void f() { 42; } };"
4104a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              "void t() { C<int>::f(); }",
4105a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              integerLiteral(
4106a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                  equals(42),
4107a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                  hasParent(compoundStmt(hasParent(functionDecl(hasParent(
4108a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxRecordDecl(unless(isTemplateInstantiation()))))))))));
410930ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek  EXPECT_TRUE(matches(
411030ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "template <typename T> struct C { static void f() { 42; } };"
411130ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "void t() { C<int>::f(); }",
411230ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      integerLiteral(equals(42),
4113a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                     hasParent(compoundStmt(
4114a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         allOf(hasParent(functionDecl(hasParent(
4115a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                                   cxxRecordDecl(isTemplateInstantiation())))),
4116a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                               hasParent(functionDecl(hasParent(cxxRecordDecl(
4117a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                                   unless(isTemplateInstantiation())))))))))));
4118374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek  EXPECT_TRUE(
4119374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      notMatches("template <typename T> struct C { static void f() {} };"
4120374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek                 "void t() { C<int>::f(); }",
4121374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek                 compoundStmt(hasParent(recordDecl()))));
412230ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek}
412330ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek
4124c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen HinesTEST(HasParent, NoDuplicateParents) {
4125c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  class HasDuplicateParents : public BoundNodesCallback {
4126c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  public:
4127c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    bool run(const BoundNodes *Nodes) override { return false; }
4128c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    bool run(const BoundNodes *Nodes, ASTContext *Context) override {
4129c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      const Stmt *Node = Nodes->getNodeAs<Stmt>("node");
4130c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      std::set<const void *> Parents;
4131c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      for (const auto &Parent : Context->getParents(*Node)) {
4132c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines        if (!Parents.insert(Parent.getMemoizationData()).second) {
4133c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines          return true;
4134c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines        }
4135c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      }
4136c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      return false;
4137c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    }
4138c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  };
4139c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_FALSE(matchAndVerifyResultTrue(
4140c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      "template <typename T> int Foo() { return 1 + 2; }\n"
4141c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      "int x = Foo<int>() + Foo<unsigned>();",
4142c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      stmt().bind("node"), new HasDuplicateParents()));
4143c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines}
4144c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
4145ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesTypes) {
4146ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("struct S {};", qualType().bind("loc")));
4147ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
4148ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
41490e2c34f92f00628d48968dfea096d36381f494cbStephen HinesTEST(TypeMatching, MatchesVoid) {
4150a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("struct S { void func(); };",
4151a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      cxxMethodDecl(returns(voidType()))));
41520e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
41530e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
4154ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesArrayTypes) {
4155ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[] = {2,3};", arrayType()));
4156ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[42];", arrayType()));
4157ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("void f(int b) { int a[b]; }", arrayType()));
4158ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4159ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches("struct A {}; A a[7];",
4160ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                         arrayType(hasElementType(builtinType()))));
4161ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4162ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
4163ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int const a[] = { 2, 3 };",
4164ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(arrayType(hasElementType(builtinType())))));
4165ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
4166ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int const a[] = { 2, 3 };",
4167ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
4168ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
4169ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "typedef const int T; T x[] = { 1, 2 };",
4170ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(isConstQualified(), arrayType())));
4171ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4172ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
4173ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int a[] = { 2, 3 };",
4174ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
4175ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
4176ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int a[] = { 2, 3 };",
4177ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(arrayType(hasElementType(isConstQualified(), builtinType())))));
4178ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
4179ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int const a[] = { 2, 3 };",
4180ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(arrayType(hasElementType(builtinType())),
4181ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper               unless(isConstQualified()))));
4182ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4183ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[2];",
4184ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                      constantArrayType(hasElementType(builtinType()))));
4185ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("const int a = 0;", qualType(isInteger())));
4186ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
4187ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4188a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST(TypeMatching, DecayedType) {
4189a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("void f(int i[]);", valueDecl(hasType(decayedType(hasDecayedType(pointerType()))))));
4190a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("int i[7];", decayedType()));
4191a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}
4192a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
4193ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesComplexTypes) {
4194ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("_Complex float f;", complexType()));
4195ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
4196ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "_Complex float f;",
4197ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    complexType(hasElementType(builtinType()))));
4198ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
4199ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "_Complex float f;",
4200ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    complexType(hasElementType(isInteger()))));
4201ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
4202ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4203ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesConstantArrayTypes) {
4204ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[2];", constantArrayType()));
4205ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
4206ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "void f() { int a[] = { 2, 3 }; int b[a[0]]; }",
4207ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    constantArrayType(hasElementType(builtinType()))));
4208ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4209ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[42];", constantArrayType(hasSize(42))));
4210ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int b[2*21];", constantArrayType(hasSize(42))));
4211ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches("int c[41], d[43];", constantArrayType(hasSize(42))));
4212ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
4213ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4214ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesDependentSizedArrayTypes) {
4215ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
4216ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "template <typename T, int Size> class array { T data[Size]; };",
4217ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    dependentSizedArrayType()));
4218ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
4219ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "int a[42]; int b[] = { 2, 3 }; void f() { int c[b[0]]; }",
4220ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    dependentSizedArrayType()));
4221ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
4222ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4223ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesIncompleteArrayType) {
4224ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[] = { 2, 3 };", incompleteArrayType()));
4225ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("void f(int a[]) {}", incompleteArrayType()));
4226ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4227ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches("int a[42]; void f() { int b[a[0]]; }",
4228ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                         incompleteArrayType()));
4229ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
4230ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4231ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesVariableArrayType) {
4232ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("void f(int b) { int a[b]; }", variableArrayType()));
4233ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches("int a[] = {2, 3}; int b[42];", variableArrayType()));
4234ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4235ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
4236ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "void f(int b) { int a[b]; }",
4237ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    variableArrayType(hasSizeExpr(ignoringImpCasts(declRefExpr(to(
4238ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      varDecl(hasName("b")))))))));
4239ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
4240ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4241ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesAtomicTypes) {
4242651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getOS() !=
4243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      llvm::Triple::Win32) {
4244651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // FIXME: Make this work for MSVC.
4245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    EXPECT_TRUE(matches("_Atomic(int) i;", atomicType()));
4246651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4247651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    EXPECT_TRUE(matches("_Atomic(int) i;",
4248651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                        atomicType(hasValueType(isInteger()))));
4249651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    EXPECT_TRUE(notMatches("_Atomic(float) f;",
4250651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                           atomicType(hasValueType(isInteger()))));
4251651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
4252ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
4253ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4254ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesAutoTypes) {
4255ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("auto i = 2;", autoType()));
4256ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int v[] = { 2, 3 }; void f() { for (int i : v) {} }",
4257ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                      autoType()));
4258ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
42599b1317531d376738fd6631291b0a04109c76a63bRichard Smith  // FIXME: Matching against the type-as-written can't work here, because the
42609b1317531d376738fd6631291b0a04109c76a63bRichard Smith  //        type as written was not deduced.
42619b1317531d376738fd6631291b0a04109c76a63bRichard Smith  //EXPECT_TRUE(matches("auto a = 1;",
42629b1317531d376738fd6631291b0a04109c76a63bRichard Smith  //                    autoType(hasDeducedType(isInteger()))));
42639b1317531d376738fd6631291b0a04109c76a63bRichard Smith  //EXPECT_TRUE(notMatches("auto b = 2.0;",
42649b1317531d376738fd6631291b0a04109c76a63bRichard Smith  //                       autoType(hasDeducedType(isInteger()))));
4265ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
4266ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4267a267cf6f87dc695143d65fc61ec1744564f55932Daniel JasperTEST(TypeMatching, MatchesFunctionTypes) {
4268a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("int (*f)(int);", functionType()));
4269a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f(int i) {}", functionType()));
4270a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper}
4271a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
427288be2fdec7a1375bc729a6499629532e7872f11aEdwin VaneTEST(TypeMatching, MatchesParenType) {
427388be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane  EXPECT_TRUE(
427488be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane      matches("int (*array)[4];", varDecl(hasType(pointsTo(parenType())))));
427588be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane  EXPECT_TRUE(notMatches("int *array[4];", varDecl(hasType(parenType()))));
427688be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane
427788be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane  EXPECT_TRUE(matches(
427888be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane      "int (*ptr_to_func)(int);",
427988be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane      varDecl(hasType(pointsTo(parenType(innerType(functionType())))))));
428088be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane  EXPECT_TRUE(notMatches(
428188be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane      "int (*ptr_to_array)[4];",
428288be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane      varDecl(hasType(pointsTo(parenType(innerType(functionType())))))));
428388be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane}
428488be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane
4285ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, PointerTypes) {
42861802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  // FIXME: Reactive when these tests can be more specific (not matching
42871802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  // implicit code on certain platforms), likely when we have hasDescendant for
42881802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  // Types/TypeLocs.
42891802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //EXPECT_TRUE(matchAndVerifyResultTrue(
42901802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    "int* a;",
42911802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    pointerTypeLoc(pointeeLoc(typeLoc().bind("loc"))),
42921802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    new VerifyIdIsBoundTo<TypeLoc>("loc", 1)));
42931802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //EXPECT_TRUE(matchAndVerifyResultTrue(
42941802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    "int* a;",
42951802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    pointerTypeLoc().bind("loc"),
42961802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    new VerifyIdIsBoundTo<TypeLoc>("loc", 1)));
4297ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
4298ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int** a;",
42995be093c0ef46c7749c942d0d9056af6dc3d591a4David Blaikie      loc(pointerType(pointee(qualType())))));
4300ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
4301ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int** a;",
4302ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      loc(pointerType(pointee(pointerType())))));
4303ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
4304ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int* b; int* * const a = &b;",
4305ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      loc(qualType(isConstQualified(), pointerType()))));
4306ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4307ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  std::string Fragment = "struct A { int i; }; int A::* ptr = &A::i;";
43081802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
43091802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(blockPointerType()))));
43101802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(matches(Fragment, varDecl(hasName("ptr"),
43111802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                        hasType(memberPointerType()))));
43121802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
43131802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(pointerType()))));
43141802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
43151802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(referenceType()))));
4316f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4317f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(lValueReferenceType()))));
4318f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4319f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(rValueReferenceType()))));
43201802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper
43211802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  Fragment = "int *ptr;";
43221802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
43231802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(blockPointerType()))));
43241802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
43251802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(memberPointerType()))));
43261802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(matches(Fragment, varDecl(hasName("ptr"),
43271802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                        hasType(pointerType()))));
43281802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
43291802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(referenceType()))));
43301802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper
43311802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  Fragment = "int a; int &ref = a;";
43321802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
43331802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(blockPointerType()))));
43341802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
43351802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(memberPointerType()))));
43361802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
43371802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(pointerType()))));
43381802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
43391802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                        hasType(referenceType()))));
4340f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
4341f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(lValueReferenceType()))));
4342f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4343f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(rValueReferenceType()))));
4344f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane
4345f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  Fragment = "int &&ref = 2;";
4346f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4347f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(blockPointerType()))));
4348f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4349f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(memberPointerType()))));
4350f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4351f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(pointerType()))));
4352f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
4353f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(referenceType()))));
4354f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4355f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(lValueReferenceType()))));
4356f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
4357f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(rValueReferenceType()))));
4358f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane}
4359f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane
4360f4b48042724d2253d0426cadcb93e24eeb47e264Edwin VaneTEST(TypeMatching, AutoRefTypes) {
4361f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  std::string Fragment = "auto a = 1;"
4362f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                         "auto b = a;"
4363f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                         "auto &c = a;"
4364f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                         "auto &&d = c;"
4365f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                         "auto &&e = 2;";
4366f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("a"),
4367f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(referenceType()))));
4368f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("b"),
4369f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(referenceType()))));
4370f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("c"),
4371f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(referenceType()))));
4372f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("c"),
4373f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(lValueReferenceType()))));
4374f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("c"),
4375f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(rValueReferenceType()))));
4376f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("d"),
4377f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(referenceType()))));
4378f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("d"),
4379f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(lValueReferenceType()))));
4380f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("d"),
4381f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(rValueReferenceType()))));
4382f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("e"),
4383f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(referenceType()))));
4384f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("e"),
4385f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(lValueReferenceType()))));
4386f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("e"),
4387f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(rValueReferenceType()))));
4388ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
4389ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4390ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, PointeeTypes) {
4391ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int b; int &a = b;",
4392ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                      referenceType(pointee(builtinType()))));
4393ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int *a;", pointerType(pointee(builtinType()))));
4394ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4395ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int *a;",
43965be093c0ef46c7749c942d0d9056af6dc3d591a4David Blaikie                      loc(pointerType(pointee(builtinType())))));
4397ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4398ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
4399ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int const *A;",
4400ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      pointerType(pointee(isConstQualified(), builtinType()))));
4401ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
4402ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int *A;",
4403ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      pointerType(pointee(isConstQualified(), builtinType()))));
4404ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
4405ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4406ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesPointersToConstTypes) {
4407ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int b; int * const a = &b;",
4408ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                      loc(pointerType())));
4409ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int b; int * const a = &b;",
44105be093c0ef46c7749c942d0d9056af6dc3d591a4David Blaikie                      loc(pointerType())));
4411ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
4412ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int b; const int * a = &b;",
44135be093c0ef46c7749c942d0d9056af6dc3d591a4David Blaikie      loc(pointerType(pointee(builtinType())))));
4414ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
4415ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int b; const int * a = &b;",
4416ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      pointerType(pointee(builtinType()))));
4417ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
4418ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4419ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesTypedefTypes) {
44201802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(matches("typedef int X; X a;", varDecl(hasName("a"),
44211802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                                     hasType(typedefType()))));
4422ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
4423ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
44243abf77872ca6c520903f9174cf6cd89a50df2714Edwin VaneTEST(TypeMatching, MatchesTemplateSpecializationType) {
4425742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(matches("template <typename T> class A{}; A<int> a;",
44263abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane                      templateSpecializationType()));
44273abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane}
44283abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane
4429742d9e77e32f014194679575c97c6bb4fd0998c4Edwin VaneTEST(TypeMatching, MatchesRecordType) {
4430742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(matches("class C{}; C c;", recordType()));
44310cc798f29d489140dd81b558e9c052e9a83cce39Manuel Klimek  EXPECT_TRUE(matches("struct S{}; S s;",
44320cc798f29d489140dd81b558e9c052e9a83cce39Manuel Klimek                      recordType(hasDeclaration(recordDecl(hasName("S"))))));
44330cc798f29d489140dd81b558e9c052e9a83cce39Manuel Klimek  EXPECT_TRUE(notMatches("int i;",
44340cc798f29d489140dd81b558e9c052e9a83cce39Manuel Klimek                         recordType(hasDeclaration(recordDecl(hasName("S"))))));
4435742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane}
4436742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane
4437742d9e77e32f014194679575c97c6bb4fd0998c4Edwin VaneTEST(TypeMatching, MatchesElaboratedType) {
4438742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(matches(
4439742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "namespace N {"
4440742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  namespace M {"
4441742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "    class D {};"
4442742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  }"
4443742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "}"
4444742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "N::M::D d;", elaboratedType()));
4445742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(matches("class C {} c;", elaboratedType()));
4446742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(notMatches("class C {}; C c;", elaboratedType()));
4447742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane}
4448742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane
4449742d9e77e32f014194679575c97c6bb4fd0998c4Edwin VaneTEST(ElaboratedTypeNarrowing, hasQualifier) {
4450742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(matches(
4451742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "namespace N {"
4452742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  namespace M {"
4453742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "    class D {};"
4454742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  }"
4455742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "}"
4456742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "N::M::D d;",
4457742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
4458742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(notMatches(
4459742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "namespace M {"
4460742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  class D {};"
4461742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "}"
4462742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "M::D d;",
4463742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
4464aec89ac22e1876bb1cfff9062c882a622bc84510Edwin Vane  EXPECT_TRUE(notMatches(
4465aec89ac22e1876bb1cfff9062c882a622bc84510Edwin Vane    "struct D {"
4466aec89ac22e1876bb1cfff9062c882a622bc84510Edwin Vane    "} d;",
4467aec89ac22e1876bb1cfff9062c882a622bc84510Edwin Vane    elaboratedType(hasQualifier(nestedNameSpecifier()))));
4468742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane}
4469742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane
4470742d9e77e32f014194679575c97c6bb4fd0998c4Edwin VaneTEST(ElaboratedTypeNarrowing, namesType) {
4471742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(matches(
4472742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "namespace N {"
4473742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  namespace M {"
4474742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "    class D {};"
4475742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  }"
4476742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "}"
4477742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "N::M::D d;",
4478742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    elaboratedType(elaboratedType(namesType(recordType(
4479742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane        hasDeclaration(namedDecl(hasName("D")))))))));
4480742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(notMatches(
4481742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "namespace M {"
4482742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  class D {};"
4483742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "}"
4484742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "M::D d;",
4485742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    elaboratedType(elaboratedType(namesType(typedefType())))));
4486742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane}
4487742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane
4488a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST(TypeMatching, MatchesSubstTemplateTypeParmType) {
4489a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  const std::string code = "template <typename T>"
4490a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                           "int F() {"
4491a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                           "  return 1 + T();"
4492a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                           "}"
4493a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                           "int i = F<int>();";
4494a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_FALSE(matches(code, binaryOperator(hasLHS(
4495a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                                 expr(hasType(substTemplateTypeParmType()))))));
4496a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches(code, binaryOperator(hasRHS(
4497a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                                expr(hasType(substTemplateTypeParmType()))))));
4498a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}
4499a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
4500a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, MatchesNestedNameSpecifiers) {
4501a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;",
4502a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper                      nestedNameSpecifier()));
4503a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("template <typename T> class A { typename T::B b; };",
4504a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper                      nestedNameSpecifier()));
4505a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("struct A { void f(); }; void A::f() {}",
4506a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper                      nestedNameSpecifier()));
4507a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("namespace a { namespace b {} } namespace ab = a::b;",
4508a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      nestedNameSpecifier()));
4509a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
4510a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches(
4511a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    "struct A { static void f() {} }; void g() { A::f(); }",
4512a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    nestedNameSpecifier()));
4513a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(notMatches(
4514a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    "struct A { static void f() {} }; void g(A* a) { a->f(); }",
4515a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    nestedNameSpecifier()));
4516a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
4517a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
4518b54b7646b2d00a85d80e40adf7c49553f150c736Daniel JasperTEST(NullStatement, SimpleCases) {
4519b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() {int i;;}", nullStmt()));
4520b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(notMatches("void f() {int i;}", nullStmt()));
4521b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper}
4522b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper
4523a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST(NS, Anonymous) {
4524a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(notMatches("namespace N {}", namespaceDecl(isAnonymous())));
4525a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("namespace {}", namespaceDecl(isAnonymous())));
4526a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}
4527a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
4528a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST(NS, Alias) {
4529a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("namespace test {} namespace alias = ::test;",
4530a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      namespaceAliasDecl(hasName("alias"))));
4531a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}
4532a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
4533a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, MatchesTypes) {
4534a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  NestedNameSpecifierMatcher Matcher = nestedNameSpecifier(
4535a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    specifiesType(hasDeclaration(recordDecl(hasName("A")))));
4536a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("struct A { struct B {}; }; A::B b;", Matcher));
4537a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("struct A { struct B { struct C {}; }; }; A::B::C c;",
4538a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper                      Matcher));
4539a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(notMatches("namespace A { struct B {}; } A::B b;", Matcher));
4540a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
4541a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
4542a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, MatchesNamespaceDecls) {
4543a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  NestedNameSpecifierMatcher Matcher = nestedNameSpecifier(
4544a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    specifiesNamespace(hasName("ns")));
4545a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;", Matcher));
4546a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(notMatches("namespace xx { struct A {}; } xx::A a;", Matcher));
4547a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(notMatches("struct ns { struct A {}; }; ns::A a;", Matcher));
4548a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
4549a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
4550a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, BindsNestedNameSpecifiers) {
4551a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
4552a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      "namespace ns { struct E { struct B {}; }; } ns::E::B b;",
4553a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      nestedNameSpecifier(specifiesType(asString("struct ns::E"))).bind("nns"),
4554a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifier>("nns", "ns::struct E::")));
4555a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
4556a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
4557a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, BindsNestedNameSpecifierLocs) {
4558a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
4559a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      "namespace ns { struct B {}; } ns::B b;",
4560a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      loc(nestedNameSpecifier()).bind("loc"),
4561a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("loc", 1)));
4562a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
4563a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
4564a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, MatchesNestedNameSpecifierPrefixes) {
4565a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches(
4566a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      "struct A { struct B { struct C {}; }; }; A::B::C c;",
4567a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      nestedNameSpecifier(hasPrefix(specifiesType(asString("struct A"))))));
4568a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches(
4569a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      "struct A { struct B { struct C {}; }; }; A::B::C c;",
4570ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      nestedNameSpecifierLoc(hasPrefix(
4571ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper          specifiesTypeLoc(loc(qualType(asString("struct A"))))))));
4572a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
4573a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
4574d1ce3c178b9c648687591b190e0d252124fc2459Daniel JasperTEST(NNS, DescendantsOfNestedNameSpecifiers) {
4575d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  std::string Fragment =
4576d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "namespace a { struct A { struct B { struct C {}; }; }; };"
4577d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "void f() { a::A::B::C c; }";
4578d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
4579d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4580d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
4581d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                          hasDescendant(nestedNameSpecifier(
4582d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                              specifiesNamespace(hasName("a")))))));
4583d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(notMatches(
4584d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4585d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
4586d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                          has(nestedNameSpecifier(
4587d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                              specifiesNamespace(hasName("a")))))));
4588d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
4589d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4590d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifier(specifiesType(asString("struct a::A")),
4591d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                          has(nestedNameSpecifier(
4592d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                              specifiesNamespace(hasName("a")))))));
4593d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
4594d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  // Not really useful because a NestedNameSpecifier can af at most one child,
4595d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  // but to complete the interface.
4596d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
4597d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4598d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
4599d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                          forEach(nestedNameSpecifier().bind("x"))),
4600d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifier>("x", 1)));
4601d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper}
4602d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
4603d1ce3c178b9c648687591b190e0d252124fc2459Daniel JasperTEST(NNS, NestedNameSpecifiersAsDescendants) {
4604d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  std::string Fragment =
4605d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "namespace a { struct A { struct B { struct C {}; }; }; };"
4606d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "void f() { a::A::B::C c; }";
4607d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
4608d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4609d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      decl(hasDescendant(nestedNameSpecifier(specifiesType(
4610d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper          asString("struct a::A")))))));
4611d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
4612d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4613d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      functionDecl(hasName("f"),
4614d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                   forEachDescendant(nestedNameSpecifier().bind("x"))),
4615d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      // Nested names: a, a::A and a::A::B.
4616d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifier>("x", 3)));
4617d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper}
4618d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
4619d1ce3c178b9c648687591b190e0d252124fc2459Daniel JasperTEST(NNSLoc, DescendantsOfNestedNameSpecifierLocs) {
4620d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  std::string Fragment =
4621d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "namespace a { struct A { struct B { struct C {}; }; }; };"
4622d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "void f() { a::A::B::C c; }";
4623d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
4624d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4625d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
4626d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                             hasDescendant(loc(nestedNameSpecifier(
4627d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                                 specifiesNamespace(hasName("a"))))))));
4628d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(notMatches(
4629d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4630d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
4631d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                             has(loc(nestedNameSpecifier(
4632d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                                 specifiesNamespace(hasName("a"))))))));
4633d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
4634d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4635d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A"))),
4636d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                             has(loc(nestedNameSpecifier(
4637d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                                 specifiesNamespace(hasName("a"))))))));
4638d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
4639d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
4640d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4641d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
4642d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                             forEach(nestedNameSpecifierLoc().bind("x"))),
4643d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("x", 1)));
4644d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper}
4645d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
4646d1ce3c178b9c648687591b190e0d252124fc2459Daniel JasperTEST(NNSLoc, NestedNameSpecifierLocsAsDescendants) {
4647d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  std::string Fragment =
4648d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "namespace a { struct A { struct B { struct C {}; }; }; };"
4649d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "void f() { a::A::B::C c; }";
4650d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
4651d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4652d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      decl(hasDescendant(loc(nestedNameSpecifier(specifiesType(
4653d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper          asString("struct a::A"))))))));
4654d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
4655d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4656d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      functionDecl(hasName("f"),
4657d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                   forEachDescendant(nestedNameSpecifierLoc().bind("x"))),
4658d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      // Nested names: a, a::A and a::A::B.
4659d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("x", 3)));
4660d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper}
4661d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
466260969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimektemplate <typename T> class VerifyMatchOnNode : public BoundNodesCallback {
46633e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimekpublic:
4664cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek  VerifyMatchOnNode(StringRef Id, const internal::Matcher<T> &InnerMatcher,
4665cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek                    StringRef InnerId)
4666cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek      : Id(Id), InnerMatcher(InnerMatcher), InnerId(InnerId) {
4667452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper  }
4668452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper
466958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  bool run(const BoundNodes *Nodes) override { return false; }
467060969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek
467158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  bool run(const BoundNodes *Nodes, ASTContext *Context) override {
46723e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek    const T *Node = Nodes->getNodeAs<T>(Id);
4673176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return selectFirst<T>(InnerId, match(InnerMatcher, *Node, *Context)) !=
4674176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines           nullptr;
46753e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek  }
46763e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimekprivate:
46773e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek  std::string Id;
46783e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek  internal::Matcher<T> InnerMatcher;
4679cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek  std::string InnerId;
46803e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek};
46813e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek
46823e2aa99e992b89bd421ac2a6bf79307114d257fcManuel KlimekTEST(MatchFinder, CanMatchDeclarationsRecursively) {
468360969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
468460969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
468560969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      new VerifyMatchOnNode<clang::Decl>(
4686cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "X", decl(hasDescendant(recordDecl(hasName("X::Y")).bind("Y"))),
4687cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "Y")));
468860969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse(
468960969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
469060969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      new VerifyMatchOnNode<clang::Decl>(
4691cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "X", decl(hasDescendant(recordDecl(hasName("X::Z")).bind("Z"))),
4692cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "Z")));
46933e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek}
46943e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek
46953e2aa99e992b89bd421ac2a6bf79307114d257fcManuel KlimekTEST(MatchFinder, CanMatchStatementsRecursively) {
469660969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
469760969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
4698cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek      new VerifyMatchOnNode<clang::Stmt>(
4699cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "if", stmt(hasDescendant(forStmt().bind("for"))), "for")));
470060969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse(
470160969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
4702cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek      new VerifyMatchOnNode<clang::Stmt>(
4703cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "if", stmt(hasDescendant(declStmt().bind("decl"))), "decl")));
470460969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek}
470560969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek
470660969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel KlimekTEST(MatchFinder, CanMatchSingleNodesRecursively) {
470760969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
470860969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
470960969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      new VerifyMatchOnNode<clang::Decl>(
4710cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "X", recordDecl(has(recordDecl(hasName("X::Y")).bind("Y"))), "Y")));
471160969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse(
471260969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
471360969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      new VerifyMatchOnNode<clang::Decl>(
4714cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "X", recordDecl(has(recordDecl(hasName("X::Z")).bind("Z"))), "Z")));
47153e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek}
47163e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek
4717fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimektemplate <typename T>
4718fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimekclass VerifyAncestorHasChildIsEqual : public BoundNodesCallback {
4719fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimekpublic:
472058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  bool run(const BoundNodes *Nodes) override { return false; }
4721fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek
472258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  bool run(const BoundNodes *Nodes, ASTContext *Context) override {
4723fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek    const T *Node = Nodes->getNodeAs<T>("");
4724fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek    return verify(*Nodes, *Context, Node);
4725fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek  }
4726fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek
4727fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek  bool verify(const BoundNodes &Nodes, ASTContext &Context, const Stmt *Node) {
47286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // Use the original typed pointer to verify we can pass pointers to subtypes
47296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // to equalsNode.
47306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    const T *TypedNode = cast<T>(Node);
4731176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return selectFirst<T>(
47326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines               "", match(stmt(hasParent(
47336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                             stmt(has(stmt(equalsNode(TypedNode)))).bind(""))),
4734c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                         *Node, Context)) != nullptr;
4735fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek  }
4736fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek  bool verify(const BoundNodes &Nodes, ASTContext &Context, const Decl *Node) {
47376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // Use the original typed pointer to verify we can pass pointers to subtypes
47386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // to equalsNode.
47396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    const T *TypedNode = cast<T>(Node);
4740176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return selectFirst<T>(
47416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines               "", match(decl(hasParent(
47426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                             decl(has(decl(equalsNode(TypedNode)))).bind(""))),
4743c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                         *Node, Context)) != nullptr;
4744fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek  }
4745a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  bool verify(const BoundNodes &Nodes, ASTContext &Context, const Type *Node) {
4746a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    // Use the original typed pointer to verify we can pass pointers to subtypes
4747a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    // to equalsNode.
4748a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    const T *TypedNode = cast<T>(Node);
4749a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    const auto *Dec = Nodes.getNodeAs<FieldDecl>("decl");
4750a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    return selectFirst<T>(
4751a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar               "", match(fieldDecl(hasParent(decl(has(fieldDecl(
4752a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                             hasType(type(equalsNode(TypedNode)).bind(""))))))),
4753a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                         *Dec, Context)) != nullptr;
4754a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  }
4755fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek};
4756fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek
4757fa37c5ca61af275a329386407e58cf70f4d9f596Manuel KlimekTEST(IsEqualTo, MatchesNodesByIdentity) {
4758fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
4759fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek      "class X { class Y {}; };", recordDecl(hasName("::X::Y")).bind(""),
47606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      new VerifyAncestorHasChildIsEqual<CXXRecordDecl>()));
47616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  EXPECT_TRUE(matchAndVerifyResultTrue(
47626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      "void f() { if (true) if(true) {} }", ifStmt().bind(""),
47636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      new VerifyAncestorHasChildIsEqual<IfStmt>()));
4764a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matchAndVerifyResultTrue(
4765a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      "class X { class Y {} y; };",
4766a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      fieldDecl(hasName("y"), hasType(type().bind(""))).bind("decl"),
4767a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      new VerifyAncestorHasChildIsEqual<Type>()));
4768fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek}
4769fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek
4770176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(MatchFinder, CheckProfiling) {
4771176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  MatchFinder::MatchFinderOptions Options;
4772176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  llvm::StringMap<llvm::TimeRecord> Records;
4773176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Options.CheckProfiling.emplace(Records);
4774176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  MatchFinder Finder(std::move(Options));
4775176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4776176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  struct NamedCallback : public MatchFinder::MatchCallback {
4777176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    void run(const MatchFinder::MatchResult &Result) override {}
4778176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    StringRef getID() const override { return "MyID"; }
4779176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  } Callback;
4780176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Finder.addMatcher(decl(), &Callback);
4781176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  std::unique_ptr<FrontendActionFactory> Factory(
4782176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      newFrontendActionFactory(&Finder));
4783176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
4784176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4785176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_EQ(1u, Records.size());
4786176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_EQ("MyID", Records.begin()->getKey());
4787176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
4788176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4789e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimekclass VerifyStartOfTranslationUnit : public MatchFinder::MatchCallback {
4790e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimekpublic:
4791e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  VerifyStartOfTranslationUnit() : Called(false) {}
479258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  void run(const MatchFinder::MatchResult &Result) override {
4793e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek    EXPECT_TRUE(Called);
4794e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  }
479558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  void onStartOfTranslationUnit() override { Called = true; }
4796e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  bool Called;
4797e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek};
4798e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek
4799e579328ec9a95acc7f181e04c58a747ba001d80fManuel KlimekTEST(MatchFinder, InterceptsStartOfTranslationUnit) {
4800e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  MatchFinder Finder;
4801e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  VerifyStartOfTranslationUnit VerifyCallback;
4802e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  Finder.addMatcher(decl(), &VerifyCallback);
4803651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<FrontendActionFactory> Factory(
4804651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      newFrontendActionFactory(&Finder));
4805e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
4806e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  EXPECT_TRUE(VerifyCallback.Called);
480751fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne
480851fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne  VerifyCallback.Called = false;
4809651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<ASTUnit> AST(tooling::buildASTFromCode("int x;"));
481051fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne  ASSERT_TRUE(AST.get());
481151fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne  Finder.matchAST(AST->getASTContext());
481251fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne  EXPECT_TRUE(VerifyCallback.Called);
4813e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek}
4814e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek
48158f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourneclass VerifyEndOfTranslationUnit : public MatchFinder::MatchCallback {
48168f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbournepublic:
48178f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne  VerifyEndOfTranslationUnit() : Called(false) {}
481858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  void run(const MatchFinder::MatchResult &Result) override {
48198f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne    EXPECT_FALSE(Called);
48208f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne  }
482158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  void onEndOfTranslationUnit() override { Called = true; }
48228f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne  bool Called;
48238f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne};
48248f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne
48258f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter CollingbourneTEST(MatchFinder, InterceptsEndOfTranslationUnit) {
48268f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne  MatchFinder Finder;
48278f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne  VerifyEndOfTranslationUnit VerifyCallback;
48288f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne  Finder.addMatcher(decl(), &VerifyCallback);
4829651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<FrontendActionFactory> Factory(
4830651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      newFrontendActionFactory(&Finder));
48318f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne  ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
48328f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne  EXPECT_TRUE(VerifyCallback.Called);
483351fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne
483451fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne  VerifyCallback.Called = false;
4835651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<ASTUnit> AST(tooling::buildASTFromCode("int x;"));
483651fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne  ASSERT_TRUE(AST.get());
483751fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne  Finder.matchAST(AST->getASTContext());
483851fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne  EXPECT_TRUE(VerifyCallback.Called);
48398f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne}
48408f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne
4841cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel KlimekTEST(EqualsBoundNodeMatcher, QualType) {
4842cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek  EXPECT_TRUE(matches(
4843cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "int i = 1;", varDecl(hasType(qualType().bind("type")),
4844cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                            hasInitializer(ignoringParenImpCasts(
4845cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                                hasType(qualType(equalsBoundNode("type"))))))));
4846cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek  EXPECT_TRUE(notMatches("int i = 1.f;",
4847cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                         varDecl(hasType(qualType().bind("type")),
4848cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                                 hasInitializer(ignoringParenImpCasts(hasType(
4849cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                                     qualType(equalsBoundNode("type"))))))));
4850cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek}
4851cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek
4852cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel KlimekTEST(EqualsBoundNodeMatcher, NonMatchingTypes) {
4853cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek  EXPECT_TRUE(notMatches(
4854cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "int i = 1;", varDecl(namedDecl(hasName("i")).bind("name"),
4855cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                            hasInitializer(ignoringParenImpCasts(
4856cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                                hasType(qualType(equalsBoundNode("type"))))))));
4857cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek}
4858cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek
4859cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel KlimekTEST(EqualsBoundNodeMatcher, Stmt) {
4860cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek  EXPECT_TRUE(
4861cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      matches("void f() { if(true) {} }",
4862cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek              stmt(allOf(ifStmt().bind("if"),
4863cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                         hasParent(stmt(has(stmt(equalsBoundNode("if")))))))));
4864cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek
4865cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek  EXPECT_TRUE(notMatches(
4866cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "void f() { if(true) { if (true) {} } }",
4867cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      stmt(allOf(ifStmt().bind("if"), has(stmt(equalsBoundNode("if")))))));
4868cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek}
4869cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek
4870cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel KlimekTEST(EqualsBoundNodeMatcher, Decl) {
4871cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek  EXPECT_TRUE(matches(
4872cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "class X { class Y {}; };",
4873cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      decl(allOf(recordDecl(hasName("::X::Y")).bind("record"),
4874cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                 hasParent(decl(has(decl(equalsBoundNode("record")))))))));
4875cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek
4876cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek  EXPECT_TRUE(notMatches("class X { class Y {}; };",
4877cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                         decl(allOf(recordDecl(hasName("::X")).bind("record"),
4878cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                                    has(decl(equalsBoundNode("record")))))));
4879cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek}
4880cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek
4881cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel KlimekTEST(EqualsBoundNodeMatcher, Type) {
4882cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek  EXPECT_TRUE(matches(
4883cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "class X { int a; int b; };",
4884cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      recordDecl(
4885cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek          has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
4886cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek          has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
4887cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek
4888cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek  EXPECT_TRUE(notMatches(
4889cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "class X { int a; double b; };",
4890cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      recordDecl(
4891cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek          has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
4892cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek          has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
4893cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek}
4894cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek
4895cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel KlimekTEST(EqualsBoundNodeMatcher, UsingForEachDescendant) {
4896cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
4897cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "int f() {"
4898cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "  if (1) {"
4899cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "    int i = 9;"
4900cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "  }"
4901cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "  int j = 10;"
4902cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "  {"
4903cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "    float k = 9.0;"
4904cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "  }"
4905cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "  return 0;"
4906cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "}",
4907cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      // Look for variable declarations within functions whose type is the same
4908cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      // as the function return type.
4909cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      functionDecl(returns(qualType().bind("type")),
4910cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                   forEachDescendant(varDecl(hasType(
4911cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                       qualType(equalsBoundNode("type")))).bind("decl"))),
4912cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      // Only i and j should match, not k.
4913cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      new VerifyIdIsBoundTo<VarDecl>("decl", 2)));
4914cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek}
4915cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek
4916cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel KlimekTEST(EqualsBoundNodeMatcher, FiltersMatchedCombinations) {
4917cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
4918cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "void f() {"
4919cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "  int x;"
4920cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "  double d;"
4921cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "  x = d + x - d + x;"
4922cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "}",
4923cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      functionDecl(
4924cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek          hasName("f"), forEachDescendant(varDecl().bind("d")),
4925cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek          forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d")))))),
4926cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      new VerifyIdIsBoundTo<VarDecl>("d", 5)));
4927cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek}
4928cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek
4929651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(EqualsBoundNodeMatcher, UnlessDescendantsOfAncestorsMatch) {
4930651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_TRUE(matchAndVerifyResultTrue(
4931651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "struct StringRef { int size() const; const char* data() const; };"
4932651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "void f(StringRef v) {"
4933651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "  v.data();"
4934651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "}",
4935a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxMemberCallExpr(
4936a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar          callee(cxxMethodDecl(hasName("data"))),
4937a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar          on(declRefExpr(to(
4938a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
4939a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar          unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
4940a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
4941651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
4942651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          .bind("data"),
4943651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      new VerifyIdIsBoundTo<Expr>("data", 1)));
4944651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4945651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_FALSE(matches(
4946651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "struct StringRef { int size() const; const char* data() const; };"
4947651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "void f(StringRef v) {"
4948651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "  v.data();"
4949651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "  v.size();"
4950651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "}",
4951a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      cxxMemberCallExpr(
4952a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar          callee(cxxMethodDecl(hasName("data"))),
4953a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar          on(declRefExpr(to(
4954a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
4955a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar          unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
4956a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar              callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
4957651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
4958651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          .bind("data")));
4959651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
4960651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
49610e2c34f92f00628d48968dfea096d36381f494cbStephen HinesTEST(TypeDefDeclMatcher, Match) {
49620e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(matches("typedef int typedefDeclTest;",
49630e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                      typedefDecl(hasName("typedefDeclTest"))));
49640e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
49650e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
4966a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarTEST(IsInlineMatcher, IsInline) {
4967a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("void g(); inline void f();",
4968a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      functionDecl(isInline(), hasName("f"))));
4969a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matches("namespace n { inline namespace m {} }",
4970a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                      namespaceDecl(isInline(), hasName("m"))));
4971a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}
4972a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
49730e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// FIXME: Figure out how to specify paths so the following tests pass on Windows.
49740e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#ifndef LLVM_ON_WIN32
49750e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49760e2c34f92f00628d48968dfea096d36381f494cbStephen HinesTEST(Matcher, IsExpansionInMainFileMatcher) {
49770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(matches("class X {};",
49780e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                      recordDecl(hasName("X"), isExpansionInMainFile())));
49790e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(notMatches("", recordDecl(isExpansionInMainFile())));
49800e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  FileContentMappings M;
49810e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  M.push_back(std::make_pair("/other", "class X {};"));
49820e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(matchesConditionally("#include <other>\n",
49830e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                   recordDecl(isExpansionInMainFile()), false,
49840e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                   "-isystem/", M));
49850e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
49860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49870e2c34f92f00628d48968dfea096d36381f494cbStephen HinesTEST(Matcher, IsExpansionInSystemHeader) {
49880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  FileContentMappings M;
49890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  M.push_back(std::make_pair("/other", "class X {};"));
49900e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(matchesConditionally(
49910e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      "#include \"other\"\n", recordDecl(isExpansionInSystemHeader()), true,
49920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      "-isystem/", M));
49930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(matchesConditionally("#include \"other\"\n",
49940e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                   recordDecl(isExpansionInSystemHeader()),
49950e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                   false, "-I/", M));
49960e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(notMatches("class X {};",
49970e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                         recordDecl(isExpansionInSystemHeader())));
49980e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(notMatches("", recordDecl(isExpansionInSystemHeader())));
49990e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
50000e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50010e2c34f92f00628d48968dfea096d36381f494cbStephen HinesTEST(Matcher, IsExpansionInFileMatching) {
50020e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  FileContentMappings M;
50030e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  M.push_back(std::make_pair("/foo", "class A {};"));
50040e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  M.push_back(std::make_pair("/bar", "class B {};"));
50050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(matchesConditionally(
50060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      "#include <foo>\n"
50070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      "#include <bar>\n"
50080e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      "class X {};",
50090e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      recordDecl(isExpansionInFileMatching("b.*"), hasName("B")), true,
50100e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      "-isystem/", M));
50110e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(matchesConditionally(
50120e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      "#include <foo>\n"
50130e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      "#include <bar>\n"
50140e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      "class X {};",
50150e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      recordDecl(isExpansionInFileMatching("f.*"), hasName("X")), false,
50160e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      "-isystem/", M));
50170e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
50180e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50190e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#endif // LLVM_ON_WIN32
50200e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
50223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga NainarTEST(ObjCMessageExprMatcher, SimpleExprs) {
50233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // don't find ObjCMessageExpr where none are present
50243ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  EXPECT_TRUE(notMatchesObjC("", objcMessageExpr(anything())));
50253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
50263ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  std::string Objc1String =
50273ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  "@interface Str "
50283ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  " - (Str *)uppercaseString:(Str *)str;"
50293ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  "@end "
50303ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  "@interface foo "
50313ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  "- (void)meth:(Str *)text;"
50323ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  "@end "
50333ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  " "
50343ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  "@implementation foo "
50353ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  "- (void) meth:(Str *)text { "
50363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  "  [self contents];"
50373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  "  Str *up = [text uppercaseString];"
50383ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  "} "
50393ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  "@end ";
50403ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  EXPECT_TRUE(matchesObjC(
50413ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      Objc1String,
50423ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      objcMessageExpr(anything())));
50433ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  EXPECT_TRUE(matchesObjC(
50443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      Objc1String,
50453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      objcMessageExpr(hasSelector("contents"))));
50463ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  EXPECT_TRUE(matchesObjC(
50473ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      Objc1String,
50483ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      objcMessageExpr(matchesSelector("cont*"))));
50493ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  EXPECT_FALSE(matchesObjC(
50503ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      Objc1String,
50513ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      objcMessageExpr(matchesSelector("?cont*"))));
50523ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  EXPECT_TRUE(notMatchesObjC(
50533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      Objc1String,
50543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      objcMessageExpr(hasSelector("contents"), hasNullSelector())));
50553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  EXPECT_TRUE(matchesObjC(
50563ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      Objc1String,
50573ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      objcMessageExpr(hasSelector("contents"), hasUnarySelector())));
50583ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  EXPECT_TRUE(matchesObjC(
50593ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      Objc1String,
5060a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      objcMessageExpr(hasSelector("contents"), numSelectorArgs(0))));
5061a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  EXPECT_TRUE(matchesObjC(
5062a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      Objc1String,
50633ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      objcMessageExpr(matchesSelector("uppercase*"),
50643ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                      argumentCountIs(0)
50653ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                      )));
50663ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
50673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar}
50683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
50694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek} // end namespace ast_matchers
50704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek} // end namespace clang
5071