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({
392dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper    DeclarationMatcher IsDerivedFromEmpty = recordDecl(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) {
1252dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher IsDerivedFromX = recordDecl(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
13363d88728d862f8a69b3291e533d193d1d8513f5aDaniel Jasper  DeclarationMatcher IsAX = recordDecl(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 =
1422dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(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> {};",
261987c2f590fade75245e32807ee83c31483e02d8aManuel Klimek                 recordDecl(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> {};",
268987c2f590fade75245e32807ee83c31483e02d8aManuel Klimek      recordDecl(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"),
2852dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              hasInitializer(hasType(recordDecl(isDerivedFrom("Base1")))))));
2864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
2874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      RecursiveTemplateOneParameter,
2882dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("z_float"),
2892dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              hasInitializer(hasType(recordDecl(isDerivedFrom("Base2")))))));
2904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
2914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      RecursiveTemplateOneParameter,
2922dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("z_char"),
2932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              hasInitializer(hasType(recordDecl(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"),
3102dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              hasInitializer(hasType(recordDecl(isDerivedFrom("Base1")))))));
3114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
3124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      RecursiveTemplateTwoParameters,
3132dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("z_float"),
3142dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              hasInitializer(hasType(recordDecl(isDerivedFrom("Base2")))))));
3154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
3164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      RecursiveTemplateTwoParameters,
3172dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("z_char"),
3182dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              hasInitializer(hasType(recordDecl(isDerivedFrom("Base1"),
3192dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                                                isDerivedFrom("Base2")))))));
32020b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper  EXPECT_TRUE(matches(
32120b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper      "namespace ns { class X {}; class Y : public X {}; }",
3222dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isDerivedFrom("::ns::X"))));
32320b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper  EXPECT_TRUE(notMatches(
32420b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper      "class X {}; class Y : public X {};",
3252dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isDerivedFrom("::ns::X"))));
32620b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper
32720b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper  EXPECT_TRUE(matches(
32820b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper      "class X {}; class Y : public X {};",
3292dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(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> {};",
335b56da8c0e648d3bfd9bfe82266b9fea6a8df8a00Manuel Klimek      recordDecl(isDerivedFrom(namedDecl(hasName("X"))))));
3364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
3374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
3386a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin VaneTEST(DeclarationMatcher, hasMethod) {
3396a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane  EXPECT_TRUE(matches("class A { void func(); };",
3406a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane                      recordDecl(hasMethod(hasName("func")))));
3416a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane  EXPECT_TRUE(notMatches("class A { void func(); };",
3426a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane                         recordDecl(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;",
35208f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper     recordDecl(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
4564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, MatchAnyOf) {
4574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher YOrZDerivedFromX =
4582dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(anyOf(hasName("Y"), allOf(isDerivedFrom("X"), hasName("Z"))));
4594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
4604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; class Z : public X {};", YOrZDerivedFromX));
4614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y {};", YOrZDerivedFromX));
4624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
4634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X {}; class W : public X {};", YOrZDerivedFromX));
4644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Z {};", YOrZDerivedFromX));
4654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
466ff2fcb8db242a54f72bbb4e5595261e12672ed66Daniel Jasper  DeclarationMatcher XOrYOrZOrU =
4672dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U")));
468ff2fcb8db242a54f72bbb4e5595261e12672ed66Daniel Jasper  EXPECT_TRUE(matches("class X {};", XOrYOrZOrU));
469ff2fcb8db242a54f72bbb4e5595261e12672ed66Daniel Jasper  EXPECT_TRUE(notMatches("class V {};", XOrYOrZOrU));
470ff2fcb8db242a54f72bbb4e5595261e12672ed66Daniel Jasper
4714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher XOrYOrZOrUOrV =
4722dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U"),
4732dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                       hasName("V")));
4744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {};", XOrYOrZOrUOrV));
4754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y {};", XOrYOrZOrUOrV));
4764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Z {};", XOrYOrZOrUOrV));
4774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class U {};", XOrYOrZOrUOrV));
4784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class V {};", XOrYOrZOrUOrV));
4794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A {};", XOrYOrZOrUOrV));
480176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
481176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  StatementMatcher MixedTypes = stmt(anyOf(ifStmt(), binaryOperator()));
482176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("int F() { return 1 + 2; }", MixedTypes));
483176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("int F() { if (true) return 1; }", MixedTypes));
484176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("int F() { return 1; }", MixedTypes));
4854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
4864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
4874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, MatchHas) {
4882dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher HasClassX = recordDecl(has(recordDecl(hasName("X"))));
4894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { class X {}; };", HasClassX));
4904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {};", HasClassX));
4914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
4924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher YHasClassX =
4932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("Y"), has(recordDecl(hasName("X"))));
4944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { class X {}; };", YHasClassX));
4954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class X {};", YHasClassX));
4964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
4974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { class Z { class X {}; }; };", YHasClassX));
4984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
4994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, MatchHasRecursiveAllOf) {
5014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher Recursive =
5022dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper    recordDecl(
5032dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      has(recordDecl(
5042dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper        has(recordDecl(hasName("X"))),
5052dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper        has(recordDecl(hasName("Y"))),
5064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek        hasName("Z"))),
5072dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      has(recordDecl(
5082dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper        has(recordDecl(hasName("A"))),
5092dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper        has(recordDecl(hasName("B"))),
5104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek        hasName("C"))),
5114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      hasName("F"));
5124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
5144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class F {"
5154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class Z {"
5164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class X {};"
5174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class Y {};"
5184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
5194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class C {"
5204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class A {};"
5214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class B {};"
5224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
5234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};", Recursive));
5244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
5264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class F {"
5274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class Z {"
5284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class A {};"
5294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class X {};"
5304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class Y {};"
5314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
5324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class C {"
5334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class X {};"
5344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class A {};"
5354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class B {};"
5364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
5374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};", Recursive));
5384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
5404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class O1 {"
5414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class O2 {"
5424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class F {"
5434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      class Z {"
5444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class A {};"
5454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class X {};"
5464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class Y {};"
5474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      };"
5484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      class C {"
5494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class X {};"
5504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class A {};"
5514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class B {};"
5524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      };"
5534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    };"
5544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
5554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};", Recursive));
5564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
5574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, MatchHasRecursiveAnyOf) {
5594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher Recursive =
5602dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
5614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          anyOf(
5622dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              has(recordDecl(
5634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                  anyOf(
5642dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      has(recordDecl(
5654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                          hasName("X"))),
5662dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      has(recordDecl(
5674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                          hasName("Y"))),
5684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      hasName("Z")))),
5692dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              has(recordDecl(
5704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                  anyOf(
5714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      hasName("C"),
5722dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      has(recordDecl(
5734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                          hasName("A"))),
5742dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      has(recordDecl(
5754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                          hasName("B")))))),
5764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              hasName("F")));
5774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class F {};", Recursive));
5794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Z {};", Recursive));
5804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class C {};", Recursive));
5814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class M { class N { class X {}; }; };", Recursive));
5824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class M { class N { class B {}; }; };", Recursive));
5834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
5844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class O1 { class O2 {"
5854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "  class M { class N { class B {}; }; }; "
5864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "}; };", Recursive));
5874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
5884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, MatchNot) {
5904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher NotClassX =
5912dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
5924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          isDerivedFrom("Y"),
5934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          unless(hasName("X")));
5944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("", NotClassX));
5954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y {};", NotClassX));
5964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y {}; class Z : public Y {};", NotClassX));
5974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y {}; class X : public Y {};", NotClassX));
5984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
5994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y {}; class Z {}; class X : public Y {};",
6004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 NotClassX));
6014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
6024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher ClassXHasNotClassY =
6032dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
6044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          hasName("X"),
6052dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          has(recordDecl(hasName("Z"))),
6064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          unless(
6072dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              has(recordDecl(hasName("Y")))));
6084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { class Z {}; };", ClassXHasNotClassY));
6094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class X { class Y {}; class Z {}; };",
6104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                         ClassXHasNotClassY));
611176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
612176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  DeclarationMatcher NamedNotRecord =
613176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      namedDecl(hasName("Foo"), unless(recordDecl()));
614176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("void Foo(){}", NamedNotRecord));
615176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("struct Foo {};", NamedNotRecord));
6164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
6174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
6184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, HasDescendant) {
6194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher ZDescendantClassX =
6202dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
6212dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasDescendant(recordDecl(hasName("X"))),
6224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          hasName("Z"));
6234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Z { class X {}; };", ZDescendantClassX));
6244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
6254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Z { class Y { class X {}; }; };", ZDescendantClassX));
6264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
6274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Z { class A { class Y { class X {}; }; }; };",
6284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZDescendantClassX));
6294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
6304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Z { class A { class B { class Y { class X {}; }; }; }; };",
6314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZDescendantClassX));
6324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Z {};", ZDescendantClassX));
6334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
6344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher ZDescendantClassXHasClassY =
6352dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
6362dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasDescendant(recordDecl(has(recordDecl(hasName("Y"))),
6374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                              hasName("X"))),
6384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          hasName("Z"));
6394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Z { class X { class Y {}; }; };",
6404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZDescendantClassXHasClassY));
6414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
6424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Z { class A { class B { class X { class Y {}; }; }; }; };",
6434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZDescendantClassXHasClassY));
6444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
6454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Z {"
6464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class A {"
6474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class B {"
6484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      class X {"
6494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class C {"
6504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "          class Y {};"
6514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        };"
6524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      };"
6534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    }; "
6544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
6554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};", ZDescendantClassXHasClassY));
6564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
6574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher ZDescendantClassXDescendantClassY =
6582dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
6592dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasDescendant(recordDecl(hasDescendant(recordDecl(hasName("Y"))),
6602dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                                   hasName("X"))),
6614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          hasName("Z"));
6624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
6634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Z { class A { class X { class B { class Y {}; }; }; }; };",
6644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZDescendantClassXDescendantClassY));
6654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
6664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Z {"
6674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class A {"
6684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class X {"
6694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      class B {"
6704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class Y {};"
6714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      };"
6724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      class Y {};"
6734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    };"
6744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
6754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};", ZDescendantClassXDescendantClassY));
6764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
6774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
678176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(DeclarationMatcher, HasDescendantMemoization) {
679176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  DeclarationMatcher CannotMemoize =
680176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      decl(hasDescendant(typeLoc().bind("x")), has(decl()));
681176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("void f() { int i; }", CannotMemoize));
682176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
683176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
684176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(DeclarationMatcher, HasDescendantMemoizationUsesRestrictKind) {
685176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  auto Name = hasName("i");
686176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  auto VD = internal::Matcher<VarDecl>(Name).dynCastTo<Decl>();
687176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  auto RD = internal::Matcher<RecordDecl>(Name).dynCastTo<Decl>();
688176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // Matching VD first should not make a cache hit for RD.
689176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("void f() { int i; }",
690176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                         decl(hasDescendant(VD), hasDescendant(RD))));
691176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("void f() { int i; }",
692176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                         decl(hasDescendant(RD), hasDescendant(VD))));
693176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // Not matching RD first should not make a cache hit for VD either.
694176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("void f() { int i; }",
695176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      decl(anyOf(hasDescendant(RD), hasDescendant(VD)))));
696176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
697176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
698176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(DeclarationMatcher, HasAttr) {
699176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("struct __attribute__((warn_unused)) X {};",
700176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      decl(hasAttr(clang::attr::WarnUnused))));
701176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_FALSE(matches("struct X {};",
702176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                       decl(hasAttr(clang::attr::WarnUnused))));
703176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
704176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
705176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(DeclarationMatcher, MatchCudaDecl) {
706176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matchesWithCuda("__global__ void f() { }"
707176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                              "void g() { f<<<1, 2>>>(); }",
708176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                              CUDAKernelCallExpr()));
709176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matchesWithCuda("__attribute__((device)) void f() {}",
710176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                              hasAttr(clang::attr::CUDADevice)));
711176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatchesWithCuda("void f() {}",
712176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                 CUDAKernelCallExpr()));
713176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_FALSE(notMatchesWithCuda("__attribute__((global)) void f() {}",
714176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                  hasAttr(clang::attr::CUDAGlobal)));
715176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
716176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
717a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper// Implements a run method that returns whether BoundNodes contains a
718a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper// Decl bound to Id that can be dynamically cast to T.
719a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper// Optionally checks that the check succeeded a specific number of times.
720a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jaspertemplate <typename T>
721a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasperclass VerifyIdIsBoundTo : public BoundNodesCallback {
722a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasperpublic:
723a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Create an object that checks that a node of type \c T was bound to \c Id.
724a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Does not check for a certain number of matches.
725a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  explicit VerifyIdIsBoundTo(llvm::StringRef Id)
726a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    : Id(Id), ExpectedCount(-1), Count(0) {}
727a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
728a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Create an object that checks that a node of type \c T was bound to \c Id.
729a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Checks that there were exactly \c ExpectedCount matches.
730a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  VerifyIdIsBoundTo(llvm::StringRef Id, int ExpectedCount)
731a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    : Id(Id), ExpectedCount(ExpectedCount), Count(0) {}
732a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
733a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Create an object that checks that a node of type \c T was bound to \c Id.
734a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Checks that there was exactly one match with the name \c ExpectedName.
735a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Note that \c T must be a NamedDecl for this to work.
736374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek  VerifyIdIsBoundTo(llvm::StringRef Id, llvm::StringRef ExpectedName,
737374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek                    int ExpectedCount = 1)
738374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      : Id(Id), ExpectedCount(ExpectedCount), Count(0),
739374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek        ExpectedName(ExpectedName) {}
740a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
741651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void onEndOfTranslationUnit() override {
742a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    if (ExpectedCount != -1)
743a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      EXPECT_EQ(ExpectedCount, Count);
744a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    if (!ExpectedName.empty())
745a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      EXPECT_EQ(ExpectedName, Name);
746d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne    Count = 0;
747d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne    Name.clear();
748d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne  }
749d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne
75033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  ~VerifyIdIsBoundTo() override {
751d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne    EXPECT_EQ(0, Count);
752d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne    EXPECT_EQ("", Name);
753a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  }
754a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
75533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  bool run(const BoundNodes *Nodes) override {
7563f0e0402d8cd40b428f975f1a3607dbbd94d2ca6Peter Collingbourne    const BoundNodes::IDToNodeMap &M = Nodes->getMap();
757a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    if (Nodes->getNodeAs<T>(Id)) {
758a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      ++Count;
759a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      if (const NamedDecl *Named = Nodes->getNodeAs<NamedDecl>(Id)) {
760a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper        Name = Named->getNameAsString();
761a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      } else if (const NestedNameSpecifier *NNS =
762a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                 Nodes->getNodeAs<NestedNameSpecifier>(Id)) {
763a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper        llvm::raw_string_ostream OS(Name);
764a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper        NNS->print(OS, PrintingPolicy(LangOptions()));
765a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      }
7663f0e0402d8cd40b428f975f1a3607dbbd94d2ca6Peter Collingbourne      BoundNodes::IDToNodeMap::const_iterator I = M.find(Id);
7673f0e0402d8cd40b428f975f1a3607dbbd94d2ca6Peter Collingbourne      EXPECT_NE(M.end(), I);
7683f0e0402d8cd40b428f975f1a3607dbbd94d2ca6Peter Collingbourne      if (I != M.end())
7693f0e0402d8cd40b428f975f1a3607dbbd94d2ca6Peter Collingbourne        EXPECT_EQ(Nodes->getNodeAs<T>(Id), I->second.get<T>());
770a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      return true;
771a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    }
772c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    EXPECT_TRUE(M.count(Id) == 0 ||
773c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                M.find(Id)->second.template get<T>() == nullptr);
774a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    return false;
775a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  }
776a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
77733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  bool run(const BoundNodes *Nodes, ASTContext *Context) override {
778452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper    return run(Nodes);
779452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper  }
780452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper
781a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasperprivate:
782a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  const std::string Id;
783a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  const int ExpectedCount;
784a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  int Count;
785a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  const std::string ExpectedName;
786a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  std::string Name;
787a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper};
788a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
789a267cf6f87dc695143d65fc61ec1744564f55932Daniel JasperTEST(HasDescendant, MatchesDescendantTypes) {
790a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int i = 3; }",
791a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      decl(hasDescendant(loc(builtinType())))));
792a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int i = 3; }",
793a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      stmt(hasDescendant(builtinType()))));
794a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
795a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int i = 3; }",
796a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      stmt(hasDescendant(loc(builtinType())))));
797a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int i = 3; }",
798a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      stmt(hasDescendant(qualType(builtinType())))));
799a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
800a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(notMatches("void f() { float f = 2.0f; }",
801a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                         stmt(hasDescendant(isInteger()))));
802a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
803a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
804a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      "void f() { int a; float c; int d; int e; }",
805a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      functionDecl(forEachDescendant(
806a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper          varDecl(hasDescendant(isInteger())).bind("x"))),
807a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      new VerifyIdIsBoundTo<Decl>("x", 3)));
808a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper}
809a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
810a267cf6f87dc695143d65fc61ec1744564f55932Daniel JasperTEST(HasDescendant, MatchesDescendantsOfTypes) {
811a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int*** i; }",
812a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      qualType(hasDescendant(builtinType()))));
813a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int*** i; }",
814a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      qualType(hasDescendant(
815a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                          pointerType(pointee(builtinType()))))));
816a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int*** i; }",
8175be093c0ef46c7749c942d0d9056af6dc3d591a4David Blaikie                      typeLoc(hasDescendant(loc(builtinType())))));
818a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
819a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
820a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      "void f() { int*** i; }",
821a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      qualType(asString("int ***"), forEachDescendant(pointerType().bind("x"))),
822a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      new VerifyIdIsBoundTo<Type>("x", 2)));
823a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper}
824a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
825a267cf6f87dc695143d65fc61ec1744564f55932Daniel JasperTEST(Has, MatchesChildrenOfTypes) {
826a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("int i;",
827a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      varDecl(hasName("i"), has(isInteger()))));
828a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(notMatches("int** i;",
829a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                         varDecl(hasName("i"), has(isInteger()))));
830a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
831a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      "int (*f)(float, int);",
832a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      qualType(functionType(), forEach(qualType(isInteger()).bind("x"))),
833a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      new VerifyIdIsBoundTo<QualType>("x", 2)));
834a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper}
835a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
836a267cf6f87dc695143d65fc61ec1744564f55932Daniel JasperTEST(Has, MatchesChildTypes) {
837a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches(
838a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      "int* i;",
839a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      varDecl(hasName("i"), hasType(qualType(has(builtinType()))))));
840a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(notMatches(
841a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      "int* i;",
842a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      varDecl(hasName("i"), hasType(qualType(has(pointerType()))))));
843a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper}
844a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
845176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(ValueDecl, Matches) {
846176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("enum EnumType { EnumValue };",
847176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      valueDecl(hasType(asString("enum EnumType")))));
848176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("void FunctionDecl();",
849176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      valueDecl(hasType(asString("void (void)")))));
850176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
851176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
852e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Enum, DoesNotMatchClasses) {
853e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("class X {};", enumDecl(hasName("X"))));
854e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
855e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
856e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Enum, MatchesEnums) {
857e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("enum X {};", enumDecl(hasName("X"))));
858e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
859e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
860e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(EnumConstant, Matches) {
8612dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher Matcher = enumConstantDecl(hasName("A"));
862e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("enum X{ A };", Matcher));
863e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("enum X{ B };", Matcher));
864e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("enum X {};", Matcher));
865e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
866e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
8674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementMatcher, Has) {
8684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher HasVariableI =
8692dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      expr(hasType(pointsTo(recordDecl(hasName("X")))),
8702dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper           has(declRefExpr(to(varDecl(hasName("i"))))));
8714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
8734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X; X *x(int); void c() { int i; x(i); }", HasVariableI));
8744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
8754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X; X *x(int); void c() { int i; x(42); }", HasVariableI));
8764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
8774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementMatcher, HasDescendant) {
8794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher HasDescendantVariableI =
8802dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      expr(hasType(pointsTo(recordDecl(hasName("X")))),
8812dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper           hasDescendant(declRefExpr(to(varDecl(hasName("i"))))));
8824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
8844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X; X *x(bool); bool b(int); void c() { int i; x(b(i)); }",
8854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      HasDescendantVariableI));
8864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
8874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X; X *x(bool); bool b(int); void c() { int i; x(b(42)); }",
8884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      HasDescendantVariableI));
8894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
8904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(TypeMatcher, MatchesClassType) {
8922dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  TypeMatcher TypeA = hasDeclaration(recordDecl(hasName("A")));
8934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class A { public: A *a; };", TypeA));
8954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A {};", TypeA));
8964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8972dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  TypeMatcher TypeDerivedFromA = hasDeclaration(recordDecl(isDerivedFrom("A")));
8984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class A {}; class B : public A { public: B *b; };",
9004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              TypeDerivedFromA));
9014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A {};", TypeA));
9024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  TypeMatcher TypeAHasClassB = hasDeclaration(
9042dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("A"), has(recordDecl(hasName("B")))));
9054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
9074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class A { public: A *a; class B {}; };", TypeAHasClassB));
9084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
9094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, BindMatchedNodes) {
9112dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ClassX = has(recordDecl(hasName("::X")).bind("x"));
9124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class X {};",
914a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      ClassX, new VerifyIdIsBoundTo<CXXRecordDecl>("x")));
9154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse("class X {};",
917a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      ClassX, new VerifyIdIsBoundTo<CXXRecordDecl>("other-id")));
9184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  TypeMatcher TypeAHasClassB = hasDeclaration(
9202dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("A"), has(recordDecl(hasName("B")).bind("b"))));
9214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class A { public: A *a; class B {}; };",
9234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      TypeAHasClassB,
924a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<Decl>("b")));
9254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9262dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher MethodX =
9272dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      callExpr(callee(methodDecl(hasName("x")))).bind("x");
9284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class A { void x() { x(); } };",
9304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      MethodX,
931a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<CXXMemberCallExpr>("x")));
932e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
933e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
934e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Matcher, BindTheSameNameInAlternatives) {
935e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  StatementMatcher matcher = anyOf(
936e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      binaryOperator(hasOperatorName("+"),
9372dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                     hasLHS(expr().bind("x")),
938e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                     hasRHS(integerLiteral(equals(0)))),
939e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      binaryOperator(hasOperatorName("+"),
940e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                     hasLHS(integerLiteral(equals(0))),
9412dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                     hasRHS(expr().bind("x"))));
942e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
943e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
944e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      // The first branch of the matcher binds x to 0 but then fails.
945e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      // The second branch binds x to f() and succeeds.
946e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "int f() { return 0 + f(); }",
947e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      matcher,
948a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<CallExpr>("x")));
9494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
9504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
95166341c596f93d0c6475d839db94072b8ebd1cf5bManuel KlimekTEST(Matcher, BindsIDForMemoizedResults) {
95266341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek  // Using the same matcher in two match expressions will make memoization
95366341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek  // kick in.
95466341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek  DeclarationMatcher ClassX = recordDecl(hasName("X")).bind("x");
95566341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
95666341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek      "class A { class B { class X {}; }; };",
95766341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek      DeclarationMatcher(anyOf(
95866341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek          recordDecl(hasName("A"), hasDescendant(ClassX)),
95966341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek          recordDecl(hasName("B"), hasDescendant(ClassX)))),
960a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<Decl>("x", 2)));
96166341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek}
96266341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek
963189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel JasperTEST(HasDeclaration, HasDeclarationOfEnumType) {
964189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper  EXPECT_TRUE(matches("enum X {}; void y(X *x) { x; }",
965189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper                      expr(hasType(pointsTo(
966189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper                          qualType(hasDeclaration(enumDecl(hasName("X")))))))));
967189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper}
968189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper
969b45083d08377a8b9528401fdafd7210e78895dbeEdwin VaneTEST(HasDeclaration, HasGetDeclTraitTest) {
970b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane  EXPECT_TRUE(internal::has_getDecl<TypedefType>::value);
971b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane  EXPECT_TRUE(internal::has_getDecl<RecordType>::value);
972b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane  EXPECT_FALSE(internal::has_getDecl<TemplateSpecializationType>::value);
973b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane}
974b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane
975523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin VaneTEST(HasDeclaration, HasDeclarationOfTypeWithDecl) {
976523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane  EXPECT_TRUE(matches("typedef int X; X a;",
977523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane                      varDecl(hasName("a"),
978523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane                              hasType(typedefType(hasDeclaration(decl()))))));
979523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane
980523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane  // FIXME: Add tests for other types with getDecl() (e.g. RecordType)
981523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane}
982523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane
9833abf77872ca6c520903f9174cf6cd89a50df2714Edwin VaneTEST(HasDeclaration, HasDeclarationOfTemplateSpecializationType) {
9843abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane  EXPECT_TRUE(matches("template <typename T> class A {}; A<int> a;",
9853abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane                      varDecl(hasType(templateSpecializationType(
9863abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane                          hasDeclaration(namedDecl(hasName("A"))))))));
9873abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane}
9883abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane
9894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasType, TakesQualTypeMatcherAndMatchesExpr) {
9902dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
9914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
9922dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX))));
9934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
9944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X {}; void y(X *x) { x; }",
9952dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 expr(hasType(ClassX))));
9964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
9974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; void y(X *x) { x; }",
9982dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              expr(hasType(pointsTo(ClassX)))));
9994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
10004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasType, TakesQualTypeMatcherAndMatchesValueDecl) {
10022dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
10034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10042dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX))));
10054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10062dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX))));
10074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; void y() { X *x; }",
10092dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              varDecl(hasType(pointsTo(ClassX)))));
10104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
10114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasType, TakesDeclMatcherAndMatchesExpr) {
10132dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ClassX = recordDecl(hasName("X"));
10144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10152dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX))));
10164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X {}; void y(X *x) { x; }",
10182dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 expr(hasType(ClassX))));
10194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
10204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasType, TakesDeclMatcherAndMatchesValueDecl) {
10222dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ClassX = recordDecl(hasName("X"));
10234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10242dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX))));
10254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10262dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX))));
10274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
10284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10291a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel KlimekTEST(HasTypeLoc, MatchesDeclaratorDecls) {
10301a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek  EXPECT_TRUE(matches("int x;",
10311a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek                      varDecl(hasName("x"), hasTypeLoc(loc(asString("int"))))));
10321a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek
10331a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek  // Make sure we don't crash on implicit constructors.
10341a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek  EXPECT_TRUE(notMatches("class X {}; X x;",
10351a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek                         declaratorDecl(hasTypeLoc(loc(asString("int"))))));
10361a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek}
10371a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek
10384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, Call) {
10394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // FIXME: Do we want to overload Call() to directly take
1040e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // Matcher<Decl>, too?
10412dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher MethodX = callExpr(hasDeclaration(methodDecl(hasName("x"))));
10424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { x(); } };", MethodX));
10444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() {} };", MethodX));
10454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10462dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher MethodOnY =
10472dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberCallExpr(on(hasType(recordDecl(hasName("Y")))));
10484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
10514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
10524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
10544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
10554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
10574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 MethodOnY));
10584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
10604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 MethodOnY));
10614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
10634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 MethodOnY));
10644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher MethodOnYPointer =
10662dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberCallExpr(on(hasType(pointsTo(recordDecl(hasName("Y"))))));
10674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
10704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnYPointer));
10714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
10734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnYPointer));
10744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
10764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnYPointer));
10774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
10794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 MethodOnYPointer));
10804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
10824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 MethodOnYPointer));
10834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
10844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
108531f7c08a0d2b140bf31a08894d1948649de53c15Daniel JasperTEST(Matcher, Lambda) {
1086651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_TRUE(matches("auto f = [] (int i) { return i; };",
108731f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      lambdaExpr()));
108831f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper}
108931f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper
109031f7c08a0d2b140bf31a08894d1948649de53c15Daniel JasperTEST(Matcher, ForRange) {
10911a00fee3933066024a2398f9456e5d6bc74344b9Daniel Jasper  EXPECT_TRUE(matches("int as[] = { 1, 2, 3 };"
10921a00fee3933066024a2398f9456e5d6bc74344b9Daniel Jasper                      "void f() { for (auto &a : as); }",
109331f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      forRangeStmt()));
109431f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  EXPECT_TRUE(notMatches("void f() { for (int i; i<5; ++i); }",
109531f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                         forRangeStmt()));
109631f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper}
109731f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper
1098c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen HinesTEST(Matcher, SubstNonTypeTemplateParm) {
1099c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_FALSE(matches("template<int N>\n"
1100c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                       "struct A {  static const int n = 0; };\n"
1101c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                       "struct B : public A<42> {};",
1102c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                       substNonTypeTemplateParmExpr()));
1103c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_TRUE(matches("template<int N>\n"
1104c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                      "struct A {  static const int n = N; };\n"
1105c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                      "struct B : public A<42> {};",
1106c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                      substNonTypeTemplateParmExpr()));
1107c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines}
1108c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
110931f7c08a0d2b140bf31a08894d1948649de53c15Daniel JasperTEST(Matcher, UserDefinedLiteral) {
111031f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  EXPECT_TRUE(matches("constexpr char operator \"\" _inc (const char i) {"
111131f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      "  return i + 1;"
111231f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      "}"
111331f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      "char c = 'a'_inc;",
111431f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      userDefinedLiteral()));
111531f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper}
111631f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper
1117b54b7646b2d00a85d80e40adf7c49553f150c736Daniel JasperTEST(Matcher, FlowControl) {
1118b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() { while(true) { break; } }", breakStmt()));
1119b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() { while(true) { continue; } }",
1120b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper                      continueStmt()));
1121b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", gotoStmt()));
1122b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", labelStmt()));
1123b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() { return; }", returnStmt()));
1124b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper}
1125b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper
1126e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(HasType, MatchesAsString) {
1127e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(
1128e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }",
11292dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberCallExpr(on(hasType(asString("class Y *"))))));
1130e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("class X { void x(int x) {} };",
11312dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(0, hasType(asString("int"))))));
1132e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("namespace ns { struct A {}; }  struct B { ns::A a; };",
11332dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      fieldDecl(hasType(asString("ns::A")))));
1134e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("namespace { struct A {}; }  struct B { A a; };",
1135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      fieldDecl(hasType(asString("struct (anonymous namespace)::A")))));
1136e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1137e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
11384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, OverloadedOperatorCall) {
11392dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher OpCall = operatorCallExpr();
11404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Unary operator
11414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { }; "
11424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "bool operator!(Y x) { return false; }; "
11434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "Y y; bool c = !y;", OpCall));
11444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // No match -- special operators like "new", "delete"
11454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // FIXME: operator new takes size_t, for which we need stddef.h, for which
11464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // we need to figure out include paths in the test.
11474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // EXPECT_TRUE(NotMatches("#include <stddef.h>\n"
11484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  //             "class Y { }; "
11494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  //             "void *operator new(size_t size) { return 0; } "
11504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  //             "Y *y = new Y;", OpCall));
11514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { }; "
11524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "void operator delete(void *p) { } "
11534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "void a() {Y *y = new Y; delete y;}", OpCall));
11544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Binary operator
11554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { }; "
11564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "bool operator&&(Y x, Y y) { return true; }; "
11574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "Y a; Y b; bool c = a && b;",
11584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              OpCall));
11594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // No match -- normal operator, not an overloaded one.
11604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("bool x = true, y = true; bool t = x && y;", OpCall));
11614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int t = 5 << 2;", OpCall));
11624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
11634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, HasOperatorNameForOverloadedOperatorCall) {
11654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OpCallAndAnd =
11662dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      operatorCallExpr(hasOverloadedOperatorName("&&"));
11674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { }; "
11684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "bool operator&&(Y x, Y y) { return true; }; "
11694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "Y a; Y b; bool c = a && b;", OpCallAndAnd));
11704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OpCallLessLess =
11712dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      operatorCallExpr(hasOverloadedOperatorName("<<"));
11724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { }; "
11734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "bool operator&&(Y x, Y y) { return true; }; "
11744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "Y a; Y b; bool c = a && b;",
11754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              OpCallLessLess));
1176176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  StatementMatcher OpStarCall =
1177176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      operatorCallExpr(hasOverloadedOperatorName("*"));
1178176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("class Y; int operator*(Y &); void f(Y &y) { *y; }",
1179176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines              OpStarCall));
11806a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane  DeclarationMatcher ClassWithOpStar =
11816a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane    recordDecl(hasMethod(hasOverloadedOperatorName("*")));
11826a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane  EXPECT_TRUE(matches("class Y { int operator*(); };",
11836a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane                      ClassWithOpStar));
11846a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane  EXPECT_TRUE(notMatches("class Y { void myOperator(); };",
11856a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane              ClassWithOpStar)) ;
1186176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  DeclarationMatcher AnyOpStar = functionDecl(hasOverloadedOperatorName("*"));
1187176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("class Y; int operator*(Y &);", AnyOpStar));
1188176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("class Y { int operator*(); };", AnyOpStar));
11894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
11904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1191278057fd9f44684af832695cb01676c02a257b14Daniel JasperTEST(Matcher, NestedOverloadedOperatorCalls) {
1192278057fd9f44684af832695cb01676c02a257b14Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
1193278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "class Y { }; "
1194278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "Y& operator&&(Y& x, Y& y) { return x; }; "
1195278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "Y a; Y b; Y c; Y d = a && b && c;",
1196278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        operatorCallExpr(hasOverloadedOperatorName("&&")).bind("x"),
1197278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        new VerifyIdIsBoundTo<CXXOperatorCallExpr>("x", 2)));
1198278057fd9f44684af832695cb01676c02a257b14Daniel Jasper  EXPECT_TRUE(matches(
1199278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "class Y { }; "
1200278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "Y& operator&&(Y& x, Y& y) { return x; }; "
1201278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "Y a; Y b; Y c; Y d = a && b && c;",
1202278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        operatorCallExpr(hasParent(operatorCallExpr()))));
1203278057fd9f44684af832695cb01676c02a257b14Daniel Jasper  EXPECT_TRUE(matches(
1204278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "class Y { }; "
1205278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "Y& operator&&(Y& x, Y& y) { return x; }; "
1206278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "Y a; Y b; Y c; Y d = a && b && c;",
1207278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        operatorCallExpr(hasDescendant(operatorCallExpr()))));
1208278057fd9f44684af832695cb01676c02a257b14Daniel Jasper}
1209278057fd9f44684af832695cb01676c02a257b14Daniel Jasper
12104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ThisPointerType) {
12119f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek  StatementMatcher MethodOnY =
12122dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper    memberCallExpr(thisPointerType(recordDecl(hasName("Y"))));
12134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
12154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
12164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
12174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
12184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
12194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
12204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
12214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
12224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
12234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
12244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
12254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
12264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
12274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
12284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
12294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
12314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y {"
12324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  public: virtual void x();"
12334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};"
12344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X : public Y {"
12354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  public: virtual void x();"
12364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};"
12374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void z() { X *x; x->Y::x(); }", MethodOnY));
12384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
12394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, VariableUsage) {
12414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher Reference =
12422dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      declRefExpr(to(
12432dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          varDecl(hasInitializer(
12442dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberCallExpr(thisPointerType(recordDecl(hasName("Y"))))))));
12454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
12474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y {"
12484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      " public:"
12494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  bool x() const;"
12504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};"
12514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void z(const Y &y) {"
12524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  bool b = y.x();"
12534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  if (b) {}"
12544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "}", Reference));
12554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
12574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y {"
12584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      " public:"
12594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  bool x() const;"
12604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};"
12614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void z(const Y &y) {"
12624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  bool b = y.x();"
12634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "}", Reference));
12644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
12654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1266c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen HinesTEST(Matcher, VarDecl_Storage) {
1267c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  auto M = varDecl(hasName("X"), hasLocalStorage());
1268c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_TRUE(matches("void f() { int X; }", M));
1269c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_TRUE(notMatches("int X;", M));
1270c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_TRUE(notMatches("void f() { static int X; }", M));
1271c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
1272c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  M = varDecl(hasName("X"), hasGlobalStorage());
1273c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_TRUE(notMatches("void f() { int X; }", M));
1274c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_TRUE(matches("int X;", M));
1275c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_TRUE(matches("void f() { static int X; }", M));
1276c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines}
1277c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
12788cb9bf577e3cfe31f1f023ed3a978d726f136edcManuel KlimekTEST(Matcher, FindsVarDeclInFunctionParameter) {
12799bd2809085c2a84c980c40988896ee05065f14e4Daniel Jasper  EXPECT_TRUE(matches(
12809bd2809085c2a84c980c40988896ee05065f14e4Daniel Jasper      "void f(int i) {}",
12812dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("i"))));
12829bd2809085c2a84c980c40988896ee05065f14e4Daniel Jasper}
12839bd2809085c2a84c980c40988896ee05065f14e4Daniel Jasper
12844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, CalledVariable) {
12853680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher CallOnVariableY =
12863680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      memberCallExpr(on(declRefExpr(to(varDecl(hasName("y"))))));
12874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
12894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y { public: void x() { Y y; y.x(); } };", CallOnVariableY));
12904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
12914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y { public: void x() const { Y y; y.x(); } };", CallOnVariableY));
12924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
12934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y { public: void x(); };"
12944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X : public Y { void z() { X y; y.x(); } };", CallOnVariableY));
12954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
12964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y { public: void x(); };"
12974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X : public Y { void z() { X *y; y->x(); } };", CallOnVariableY));
12984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
12994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y { public: void x(); };"
13004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X : public Y { void z() { unsigned long y; ((X*)y)->x(); } };",
13014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      CallOnVariableY));
13024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1304e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UnaryExprOrTypeTraitExpr, MatchesSizeOfAndAlignOf) {
1305e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("void x() { int a = sizeof(a); }",
1306e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      unaryExprOrTypeTraitExpr()));
1307e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }",
1308e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                         alignOfExpr(anything())));
1309e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // FIXME: Uncomment once alignof is enabled.
1310e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // EXPECT_TRUE(matches("void x() { int a = alignof(a); }",
1311e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  //                     unaryExprOrTypeTraitExpr()));
1312e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // EXPECT_TRUE(notMatches("void x() { int a = alignof(a); }",
1313e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  //                        sizeOfExpr()));
1314e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1315e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
1316e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UnaryExpressionOrTypeTraitExpression, MatchesCorrectType) {
1317e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("void x() { int a = sizeof(a); }", sizeOfExpr(
1318e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      hasArgumentOfType(asString("int")))));
1319e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
1320e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      hasArgumentOfType(asString("float")))));
1321e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
1322e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "struct A {}; void x() { A a; int b = sizeof(a); }",
13232dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      sizeOfExpr(hasArgumentOfType(hasDeclaration(recordDecl(hasName("A")))))));
1324e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
13252dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      hasArgumentOfType(hasDeclaration(recordDecl(hasName("string")))))));
1326e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1327e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
13284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MemberExpression, DoesNotMatchClasses) {
13292dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class Y { void x() {} };", memberExpr()));
13304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MemberExpression, MatchesMemberFunctionCall) {
13332dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpr()));
13344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MemberExpression, MatchesVariable) {
13374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
13382dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class Y { void x() { this->y; } int y; };", memberExpr()));
13394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
13402dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class Y { void x() { y; } int y; };", memberExpr()));
13414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
13422dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class Y { void x() { Y y; y.y; } int y; };", memberExpr()));
13434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MemberExpression, MatchesStaticVariable) {
13464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
13472dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr()));
13484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
13492dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr()));
13504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { Y::y; } static int y; };",
13512dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr()));
13524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13546a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(IsInteger, MatchesIntegers) {
13552dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isInteger()))));
13562dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches(
13572dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      "long long i = 0; void f(long long) { }; void g() {f(i);}",
13582dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      callExpr(hasArgument(0, declRefExpr(
13592dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                                  to(varDecl(hasType(isInteger()))))))));
13606a12449ec8862211856447d3df4c082a346339f2Daniel Jasper}
13616a12449ec8862211856447d3df4c082a346339f2Daniel Jasper
13626a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(IsInteger, ReportsNoFalsePositives) {
13632dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("int *i;", varDecl(hasType(isInteger()))));
13646a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}",
13652dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      callExpr(hasArgument(0, declRefExpr(
13662dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          to(varDecl(hasType(isInteger()))))))));
13676a12449ec8862211856447d3df4c082a346339f2Daniel Jasper}
13686a12449ec8862211856447d3df4c082a346339f2Daniel Jasper
13694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsArrow, MatchesMemberVariablesViaArrow) {
13704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };",
13712dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
13724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { y; } int y; };",
13732dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
13744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };",
13752dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
13764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsArrow, MatchesStaticMemberVariablesViaArrow) {
13794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
13802dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
13814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
13822dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
13834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } static int y; };",
13842dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
13854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsArrow, MatchesMemberCallsViaArrow) {
13884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
13892dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
13904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { x(); } };",
13912dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
13924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",
13932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
13944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Callee, MatchesDeclarations) {
13972dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher CallMethodX = callExpr(callee(methodDecl(hasName("x"))));
13984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { x(); } };", CallMethodX));
14004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() {} };", CallMethodX));
14014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
14024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Callee, MatchesMemberExpressions) {
14044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
14052dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              callExpr(callee(memberExpr()))));
14064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14072dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      notMatches("class Y { void x() { this->x(); } };", callExpr(callee(callExpr()))));
14084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
14094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Function, MatchesFunctionDeclarations) {
14112dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher CallFunctionF = callExpr(callee(functionDecl(hasName("f"))));
14124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { f(); }", CallFunctionF));
14144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { }", CallFunctionF));
14154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1416651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getOS() !=
1417651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      llvm::Triple::Win32) {
1418651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // FIXME: Make this work for MSVC.
1419651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // Dependent contexts, but a non-dependent call.
1420651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    EXPECT_TRUE(matches("void f(); template <int N> void g() { f(); }",
1421651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                        CallFunctionF));
1422651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    EXPECT_TRUE(
1423651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        matches("void f(); template <int N> struct S { void g() { f(); } };",
1424651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                CallFunctionF));
1425651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
14264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Depedent calls don't match.
14284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("void f(int); template <typename T> void g(T t) { f(t); }",
14304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 CallFunctionF));
14314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("void f(int);"
14334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "template <typename T> struct S { void g(T t) { f(t); } };",
14344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 CallFunctionF));
14354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
14364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14378456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(FunctionTemplate, MatchesFunctionTemplateDeclarations) {
14388456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(
14398456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      matches("template <typename T> void f(T t) {}",
14402dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionTemplateDecl(hasName("f"))));
14418456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
14428456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
14438456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(FunctionTemplate, DoesNotMatchFunctionDeclarations) {
14448456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(
14458456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      notMatches("void f(double d); void f(int t) {}",
14462dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionTemplateDecl(hasName("f"))));
14478456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
14488456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
14498456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(FunctionTemplate, DoesNotMatchFunctionTemplateSpecializations) {
14508456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(
14518456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      notMatches("void g(); template <typename T> void f(T t) {}"
14528456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko                 "template <> void f(int t) { g(); }",
14532dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionTemplateDecl(hasName("f"),
14542dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                           hasDescendant(declRefExpr(to(
14552dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                               functionDecl(hasName("g"))))))));
14568456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
14578456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
14584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, Argument) {
14593680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher CallArgumentY = callExpr(
14603680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
14614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x(int) { int y; x(y); }", CallArgumentY));
14634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { void x(int) { int y; x(y); } };", CallArgumentY));
14654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x(int) { int z; x(z); }", CallArgumentY));
14664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14673680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher WrongIndex = callExpr(
14683680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
14694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x(int) { int y; x(y); }", WrongIndex));
14704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
14714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, AnyArgument) {
14733680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher CallArgumentY = callExpr(
14743680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasAnyArgument(declRefExpr(to(varDecl(hasName("y"))))));
14754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
14764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
14774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
14784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
14794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ArgumentCount) {
14813680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher Call1Arg = callExpr(argumentCountIs(1));
14824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg));
14844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg));
14854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg));
14864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
14874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
148836e29d6732814e958aea4b2f403cec63d7ed3116Daniel JasperTEST(Matcher, ParameterCount) {
148936e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper  DeclarationMatcher Function1Arg = functionDecl(parameterCountIs(1));
149036e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper  EXPECT_TRUE(matches("void f(int i) {}", Function1Arg));
149136e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper  EXPECT_TRUE(matches("class X { void f(int i) {} };", Function1Arg));
149236e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper  EXPECT_TRUE(notMatches("void f() {}", Function1Arg));
149336e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper  EXPECT_TRUE(notMatches("void f(int i, int j, int k) {}", Function1Arg));
149436e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper}
149536e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper
14964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, References) {
14972dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ReferenceClassX = varDecl(
14982dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      hasType(references(recordDecl(hasName("X")))));
14994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {}; void y(X y) { X &x = y; }",
15004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      ReferenceClassX));
15014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
15024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
15034b6730d40e7c603bd0e223d3fa8b56a0c88a324aMichael Han  // The match here is on the implicit copy constructor code for
15044b6730d40e7c603bd0e223d3fa8b56a0c88a324aMichael Han  // class X, not on code 'X x = y'.
15054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
15064b6730d40e7c603bd0e223d3fa8b56a0c88a324aMichael Han      matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
15074b6730d40e7c603bd0e223d3fa8b56a0c88a324aMichael Han  EXPECT_TRUE(
15084b6730d40e7c603bd0e223d3fa8b56a0c88a324aMichael Han      notMatches("class X {}; extern X x;", ReferenceClassX));
15094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
15104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
15114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
15124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15136a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin VaneTEST(QualType, hasCanonicalType) {
15146a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane  EXPECT_TRUE(notMatches("typedef int &int_ref;"
15156a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane                         "int a;"
15166a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane                         "int_ref b = a;",
15176a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane                         varDecl(hasType(qualType(referenceType())))));
15186a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane  EXPECT_TRUE(
15196a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane      matches("typedef int &int_ref;"
15206a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane              "int a;"
15216a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane              "int_ref b = a;",
15226a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane              varDecl(hasType(qualType(hasCanonicalType(referenceType()))))));
15236a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane}
15246a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane
15257b69cd09440976d6b93a0db661a770b2337be8d2Edwin VaneTEST(QualType, hasLocalQualifiers) {
15267b69cd09440976d6b93a0db661a770b2337be8d2Edwin Vane  EXPECT_TRUE(notMatches("typedef const int const_int; const_int i = 1;",
15277b69cd09440976d6b93a0db661a770b2337be8d2Edwin Vane                         varDecl(hasType(hasLocalQualifiers()))));
15287b69cd09440976d6b93a0db661a770b2337be8d2Edwin Vane  EXPECT_TRUE(matches("int *const j = nullptr;",
15297b69cd09440976d6b93a0db661a770b2337be8d2Edwin Vane                      varDecl(hasType(hasLocalQualifiers()))));
15307b69cd09440976d6b93a0db661a770b2337be8d2Edwin Vane  EXPECT_TRUE(matches("int *volatile k;",
15317b69cd09440976d6b93a0db661a770b2337be8d2Edwin Vane                      varDecl(hasType(hasLocalQualifiers()))));
15327b69cd09440976d6b93a0db661a770b2337be8d2Edwin Vane  EXPECT_TRUE(notMatches("int m;",
15337b69cd09440976d6b93a0db661a770b2337be8d2Edwin Vane                         varDecl(hasType(hasLocalQualifiers()))));
15347b69cd09440976d6b93a0db661a770b2337be8d2Edwin Vane}
15357b69cd09440976d6b93a0db661a770b2337be8d2Edwin Vane
15364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasParameter, CallsInnerMatcher) {
15374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { void x(int) {} };",
15382dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(0, varDecl()))));
15394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class X { void x(int) {} };",
15402dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(0, hasName("x")))));
15414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
15424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) {
15444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class X { void x(int) {} };",
15452dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(42, varDecl()))));
15464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
15474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasType, MatchesParameterVariableTypesStrictly) {
15494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { void x(X x) {} };",
15502dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
15514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class X { void x(const X &x) {} };",
15522dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
15534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { void x(const X *x) {} };",
15542dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(0,
15552dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                              hasType(pointsTo(recordDecl(hasName("X"))))))));
15564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { void x(const X &x) {} };",
15572dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(0,
15582dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                              hasType(references(recordDecl(hasName("X"))))))));
15594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
15604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyParameter, MatchesIndependentlyOfPosition) {
15624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y {}; class X { void x(X x, Y y) {} };",
15632dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
15644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y {}; class X { void x(Y y, X x) {} };",
15652dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
15664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
15674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1568e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Returns, MatchesReturnTypes) {
1569e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("class Y { int f() { return 1; } };",
15702dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      functionDecl(returns(asString("int")))));
1571e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("class Y { int f() { return 1; } };",
15722dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         functionDecl(returns(asString("float")))));
1573e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("class Y { Y getMe() { return *this; } };",
15742dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      functionDecl(returns(hasDeclaration(
15752dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          recordDecl(hasName("Y")))))));
1576e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1577e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
15788cc7efa2da2c6be43cbd3d09a9ae01353bb921d2Daniel JasperTEST(IsExternC, MatchesExternCFunctionDeclarations) {
15792dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("extern \"C\" void f() {}", functionDecl(isExternC())));
15802dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("extern \"C\" { void f() {} }",
15812dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              functionDecl(isExternC())));
15822dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("void f() {}", functionDecl(isExternC())));
15838cc7efa2da2c6be43cbd3d09a9ae01353bb921d2Daniel Jasper}
15848cc7efa2da2c6be43cbd3d09a9ae01353bb921d2Daniel Jasper
1585176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(IsDeleted, MatchesDeletedFunctionDeclarations) {
1586176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(
1587176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      notMatches("void Func();", functionDecl(hasName("Func"), isDeleted())));
1588176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("void Func() = delete;",
1589176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      functionDecl(hasName("Func"), isDeleted())));
1590176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
1591176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
15924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
15934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
15942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
15954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
15964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyParameter, DoesNotMatchThisPointer) {
15984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y {}; class X { void x() {} };",
15992dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasAnyParameter(hasType(pointsTo(
16002dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          recordDecl(hasName("X"))))))));
16014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1603651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(HasName, MatchesParameterVariableDeclarations) {
16044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y {}; class X { void x(int x) {} };",
16052dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasAnyParameter(hasName("x")))));
16064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
16072dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasAnyParameter(hasName("x")))));
16084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1610371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel JasperTEST(Matcher, MatchesClassTemplateSpecialization) {
1611371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(matches("template<typename T> struct A {};"
1612371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper                      "template<> struct A<int> {};",
16132dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      classTemplateSpecializationDecl()));
1614371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(matches("template<typename T> struct A {}; A<int> a;",
16152dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      classTemplateSpecializationDecl()));
1616371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(notMatches("template<typename T> struct A {};",
16172dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         classTemplateSpecializationDecl()));
1618371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper}
1619371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper
16201a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel KlimekTEST(DeclaratorDecl, MatchesDeclaratorDecls) {
16211a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek  EXPECT_TRUE(matches("int x;", declaratorDecl()));
16221a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek  EXPECT_TRUE(notMatches("class A {};", declaratorDecl()));
16231a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek}
16241a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek
16251a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel KlimekTEST(ParmVarDecl, MatchesParmVars) {
16261a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek  EXPECT_TRUE(matches("void f(int x);", parmVarDecl()));
16271a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek  EXPECT_TRUE(notMatches("void f();", parmVarDecl()));
16281a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek}
16291a68afd5bbecd05a3bb22854954aa4e5448c4470Manuel Klimek
1630371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel JasperTEST(Matcher, MatchesTypeTemplateArgument) {
1631371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(matches(
1632371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "template<typename T> struct B {};"
1633371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "B<int> b;",
16342dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToType(
1635371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper          asString("int"))))));
1636371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper}
1637371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper
1638371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel JasperTEST(Matcher, MatchesDeclarationReferenceTemplateArgument) {
1639371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(matches(
1640371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "struct B { int next; };"
1641371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "template<int(B::*next_ptr)> struct A {};"
1642371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "A<&B::next> a;",
16432dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      classTemplateSpecializationDecl(hasAnyTemplateArgument(
16442dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          refersToDeclaration(fieldDecl(hasName("next")))))));
1645aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper
1646aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper  EXPECT_TRUE(notMatches(
1647aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper      "template <typename T> struct A {};"
1648aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper      "A<int> a;",
1649aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper      classTemplateSpecializationDecl(hasAnyTemplateArgument(
1650aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper          refersToDeclaration(decl())))));
1651651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1652651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_TRUE(matches(
1653651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "struct B { int next; };"
1654651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "template<int(B::*next_ptr)> struct A {};"
1655651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "A<&B::next> a;",
1656651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      templateSpecializationType(hasAnyTemplateArgument(isExpr(
1657651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))));
1658651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1659651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_TRUE(notMatches(
1660651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "template <typename T> struct A {};"
1661651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "A<int> a;",
1662651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      templateSpecializationType(hasAnyTemplateArgument(
1663651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          refersToDeclaration(decl())))));
1664371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper}
1665371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper
1666371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel JasperTEST(Matcher, MatchesSpecificArgument) {
1667371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(matches(
1668371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "template<typename T, typename U> class A {};"
1669371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "A<bool, int> a;",
16702dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      classTemplateSpecializationDecl(hasTemplateArgument(
1671371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper          1, refersToType(asString("int"))))));
1672371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(notMatches(
1673371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "template<typename T, typename U> class A {};"
1674371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "A<int, bool> a;",
16752dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      classTemplateSpecializationDecl(hasTemplateArgument(
1676371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper          1, refersToType(asString("int"))))));
1677651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1678651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_TRUE(matches(
1679651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "template<typename T, typename U> class A {};"
1680651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "A<bool, int> a;",
1681651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      templateSpecializationType(hasTemplateArgument(
1682651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          1, refersToType(asString("int"))))));
1683651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_TRUE(notMatches(
1684651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "template<typename T, typename U> class A {};"
1685651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "A<int, bool> a;",
1686651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      templateSpecializationType(hasTemplateArgument(
1687651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          1, refersToType(asString("int"))))));
1688371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper}
1689371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper
1690176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(TemplateArgument, Matches) {
1691176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
1692176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      classTemplateSpecializationDecl(
1693176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                          hasAnyTemplateArgument(templateArgument()))));
1694176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches(
1695176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      "template<typename T> struct C {}; C<int> c;",
1696176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      templateSpecializationType(hasAnyTemplateArgument(templateArgument()))));
1697176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
1698176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1699176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(TemplateArgumentCountIs, Matches) {
1700176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(
1701176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      matches("template<typename T> struct C {}; C<int> c;",
1702176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines              classTemplateSpecializationDecl(templateArgumentCountIs(1))));
1703176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(
1704176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      notMatches("template<typename T> struct C {}; C<int> c;",
1705176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                 classTemplateSpecializationDecl(templateArgumentCountIs(2))));
1706176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1707176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
1708176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      templateSpecializationType(templateArgumentCountIs(1))));
1709176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(
1710176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      notMatches("template<typename T> struct C {}; C<int> c;",
1711176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                 templateSpecializationType(templateArgumentCountIs(2))));
1712176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
1713176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1714176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(IsIntegral, Matches) {
1715176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
1716176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      classTemplateSpecializationDecl(
1717176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                          hasAnyTemplateArgument(isIntegral()))));
1718176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("template<typename T> struct C {}; C<int> c;",
1719176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                         classTemplateSpecializationDecl(hasAnyTemplateArgument(
1720176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                             templateArgument(isIntegral())))));
1721176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
1722176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1723176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(RefersToIntegralType, Matches) {
1724176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
1725176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      classTemplateSpecializationDecl(
1726176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                          hasAnyTemplateArgument(refersToIntegralType(
1727176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                              asString("int"))))));
1728176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("template<unsigned T> struct C {}; C<42> c;",
1729176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                         classTemplateSpecializationDecl(hasAnyTemplateArgument(
1730176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                             refersToIntegralType(asString("int"))))));
1731176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
1732176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1733176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(EqualsIntegralValue, Matches) {
1734176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
1735176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      classTemplateSpecializationDecl(
1736176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                          hasAnyTemplateArgument(equalsIntegralValue("42")))));
1737176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("template<int T> struct C {}; C<-42> c;",
1738176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      classTemplateSpecializationDecl(
1739176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                          hasAnyTemplateArgument(equalsIntegralValue("-42")))));
1740176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("template<int T> struct C {}; C<-0042> c;",
1741176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      classTemplateSpecializationDecl(
1742176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                          hasAnyTemplateArgument(equalsIntegralValue("-34")))));
1743176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("template<int T> struct C {}; C<42> c;",
1744176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                         classTemplateSpecializationDecl(hasAnyTemplateArgument(
1745176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                             equalsIntegralValue("0042")))));
1746176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
1747176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1748f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel JasperTEST(Matcher, MatchesAccessSpecDecls) {
1749f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(matches("class C { public: int i; };", accessSpecDecl()));
1750f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(
1751f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      matches("class C { public: int i; };", accessSpecDecl(isPublic())));
1752f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(
1753f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      notMatches("class C { public: int i; };", accessSpecDecl(isProtected())));
1754f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(
1755f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      notMatches("class C { public: int i; };", accessSpecDecl(isPrivate())));
1756f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper
1757f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches("class C { int i; };", accessSpecDecl()));
1758f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper}
1759f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper
17605771a2f0830228ac50e3473740e24d9dca67b54fEdwin VaneTEST(Matcher, MatchesVirtualMethod) {
17615771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane  EXPECT_TRUE(matches("class X { virtual int f(); };",
17625771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane      methodDecl(isVirtual(), hasName("::X::f"))));
17635771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane  EXPECT_TRUE(notMatches("class X { int f(); };",
17645771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane      methodDecl(isVirtual())));
17655771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane}
17665771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane
1767651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(Matcher, MatchesPureMethod) {
1768651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_TRUE(matches("class X { virtual int f() = 0; };",
1769651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      methodDecl(isPure(), hasName("::X::f"))));
1770651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_TRUE(notMatches("class X { int f(); };",
1771651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      methodDecl(isPure())));
1772651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
1773651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
177432a6ebc63900b85780328c337787bb7adad2bcabEdwin VaneTEST(Matcher, MatchesConstMethod) {
177532a6ebc63900b85780328c337787bb7adad2bcabEdwin Vane  EXPECT_TRUE(matches("struct A { void foo() const; };",
177632a6ebc63900b85780328c337787bb7adad2bcabEdwin Vane                      methodDecl(isConst())));
177732a6ebc63900b85780328c337787bb7adad2bcabEdwin Vane  EXPECT_TRUE(notMatches("struct A { void foo(); };",
177832a6ebc63900b85780328c337787bb7adad2bcabEdwin Vane                         methodDecl(isConst())));
177932a6ebc63900b85780328c337787bb7adad2bcabEdwin Vane}
178032a6ebc63900b85780328c337787bb7adad2bcabEdwin Vane
17815771a2f0830228ac50e3473740e24d9dca67b54fEdwin VaneTEST(Matcher, MatchesOverridingMethod) {
17825771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane  EXPECT_TRUE(matches("class X { virtual int f(); }; "
17835771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane                      "class Y : public X { int f(); };",
17845771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane       methodDecl(isOverride(), hasName("::Y::f"))));
17855771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane  EXPECT_TRUE(notMatches("class X { virtual int f(); }; "
17865771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane                        "class Y : public X { int f(); };",
17875771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane       methodDecl(isOverride(), hasName("::X::f"))));
17885771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane  EXPECT_TRUE(notMatches("class X { int f(); }; "
17895771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane                         "class Y : public X { int f(); };",
17905771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane       methodDecl(isOverride())));
17915771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane  EXPECT_TRUE(notMatches("class X { int f(); int f(int); }; ",
17925771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane       methodDecl(isOverride())));
17933ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  EXPECT_TRUE(
17943ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      matches("template <typename Base> struct Y : Base { void f() override;};",
17953ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar              methodDecl(isOverride(), hasName("::Y::f"))));
17965771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane}
17975771a2f0830228ac50e3473740e24d9dca67b54fEdwin Vane
17984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ConstructorCall) {
17993680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher Constructor = constructExpr();
18004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(); }; void x() { X x; }", Constructor));
18034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(); }; void x() { X x = X(); }",
18054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
18064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { X x = 0; }",
18084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
18094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {}; void x(int) { X x; }", Constructor));
18104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
18114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ConstructorArgument) {
18133680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher Constructor = constructExpr(
18143680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
18154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { int y; X x(y); }",
18184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
18194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
18214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
18224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { int y; X x = y; }",
18244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
18254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int); }; void x() { int z; X x(z); }",
18274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 Constructor));
18284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18293680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher WrongIndex = constructExpr(
18303680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
18314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int); }; void x() { int y; X x(y); }",
18334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 WrongIndex));
18344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
18354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ConstructorArgumentCount) {
18373680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher Constructor1Arg = constructExpr(argumentCountIs(1));
18384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { X x(0); }",
18414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor1Arg));
18424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { X x = X(0); }",
18444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor1Arg));
18454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { X x = 0; }",
18474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor1Arg));
18484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
18504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 Constructor1Arg));
18514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
18524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1853651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(Matcher, ConstructorListInitialization) {
1854651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  StatementMatcher ConstructorListInit = constructExpr(isListInitialization());
1855651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1856651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_TRUE(
1857651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      matches("class X { public: X(int); }; void x() { X x{0}; }",
1858651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              ConstructorListInit));
1859651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_FALSE(
1860651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      matches("class X { public: X(int); }; void x() { X x(0); }",
1861651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              ConstructorListInit));
1862651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
1863651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
186470b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel KlimekTEST(Matcher,ThisExpr) {
186570b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel Klimek  EXPECT_TRUE(
186670b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel Klimek      matches("struct X { int a; int f () { return a; } };", thisExpr()));
186770b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel Klimek  EXPECT_TRUE(
186870b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel Klimek      notMatches("struct X { int f () { int a; return a; } };", thisExpr()));
186970b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel Klimek}
187070b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel Klimek
18714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, BindTemporaryExpression) {
18723680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher TempExpression = bindTemporaryExpr();
18734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  std::string ClassString = "class string { public: string(); ~string(); }; ";
18754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches(ClassString +
18784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "string GetStringByValue();"
18794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "void FunctionTakesString(string s);"
18804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "void run() { FunctionTakesString(GetStringByValue()); }",
18814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              TempExpression));
18824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches(ClassString +
18854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "string* GetStringPointer(); "
18864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "void FunctionTakesStringPtr(string* s);"
18874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "void run() {"
18884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "  string* s = GetStringPointer();"
18894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "  FunctionTakesStringPtr(GetStringPointer());"
18904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "  FunctionTakesStringPtr(s);"
18914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "}",
18924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 TempExpression));
18934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class no_dtor {};"
18964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "no_dtor GetObjByValue();"
18974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "void ConsumeObj(no_dtor param);"
18984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "void run() { ConsumeObj(GetObjByValue()); }",
18994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 TempExpression));
1900e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer}
1901e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer
1902e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam PanzerTEST(MaterializeTemporaryExpr, MatchesTemporary) {
1903e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer  std::string ClassString =
1904e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer      "class string { public: string(); int length(); }; ";
1905e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer
1906e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer  EXPECT_TRUE(
1907e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer      matches(ClassString +
1908e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer              "string GetStringByValue();"
1909e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer              "void FunctionTakesString(string s);"
1910e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer              "void run() { FunctionTakesString(GetStringByValue()); }",
1911e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer              materializeTemporaryExpr()));
1912e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer
1913e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer  EXPECT_TRUE(
1914e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer      notMatches(ClassString +
1915e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "string* GetStringPointer(); "
1916e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "void FunctionTakesStringPtr(string* s);"
1917e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "void run() {"
1918e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "  string* s = GetStringPointer();"
1919e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "  FunctionTakesStringPtr(GetStringPointer());"
1920e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "  FunctionTakesStringPtr(s);"
1921e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "}",
1922e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 materializeTemporaryExpr()));
1923e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer
1924e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer  EXPECT_TRUE(
1925e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer      notMatches(ClassString +
1926e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "string GetStringByValue();"
1927e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "void run() { int k = GetStringByValue().length(); }",
1928e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 materializeTemporaryExpr()));
1929e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer
1930e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer  EXPECT_TRUE(
1931e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer      notMatches(ClassString +
1932e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "string GetStringByValue();"
1933e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "void run() { GetStringByValue(); }",
1934e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 materializeTemporaryExpr()));
19354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
19364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ConstructorDeclaration, SimpleCase) {
19384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Foo { Foo(int i); };",
19392dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      constructorDecl(ofClass(hasName("Foo")))));
19404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Foo { Foo(int i); };",
19412dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         constructorDecl(ofClass(hasName("Bar")))));
19424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
19434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ConstructorDeclaration, IsImplicit) {
19454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // This one doesn't match because the constructor is not added by the
19464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // compiler (it is not needed).
19474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Foo { };",
19482dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         constructorDecl(isImplicit())));
19494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // The compiler added the implicit default constructor.
19504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
19512dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      constructorDecl(isImplicit())));
19524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Foo { Foo(){} };",
19532dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      constructorDecl(unless(isImplicit()))));
19546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // The compiler added an implicit assignment operator.
19556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  EXPECT_TRUE(matches("struct A { int x; } a = {0}, b = a; void f() { a = b; }",
19566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                      methodDecl(isImplicit(), hasName("operator="))));
19574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
19584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1959e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(DestructorDeclaration, MatchesVirtualDestructor) {
1960e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };",
19612dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      destructorDecl(ofClass(hasName("Foo")))));
1962e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1963e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
1964e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) {
19652dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class Foo {};",
19662dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         destructorDecl(ofClass(hasName("Foo")))));
1967e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1968e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
19694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyConstructorInitializer, SimpleCase) {
19704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
19714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Foo { Foo() { } };",
19722dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      constructorDecl(hasAnyConstructorInitializer(anything()))));
19734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
19744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Foo {"
19754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Foo() : foo_() { }"
19764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  int foo_;"
19774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};",
19782dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      constructorDecl(hasAnyConstructorInitializer(anything()))));
19794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
19804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyConstructorInitializer, ForField) {
19824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  static const char Code[] =
19834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Baz { };"
19844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Foo {"
19854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Foo() : foo_() { }"
19864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Baz foo_;"
19874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Baz bar_;"
19884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};";
19892dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches(Code, constructorDecl(hasAnyConstructorInitializer(
19902dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      forField(hasType(recordDecl(hasName("Baz"))))))));
19912dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches(Code, constructorDecl(hasAnyConstructorInitializer(
19924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      forField(hasName("foo_"))))));
19932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches(Code, constructorDecl(hasAnyConstructorInitializer(
19942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      forField(hasType(recordDecl(hasName("Bar"))))))));
19954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
19964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyConstructorInitializer, WithInitializer) {
19984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  static const char Code[] =
19994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Foo {"
20004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Foo() : foo_(0) { }"
20014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  int foo_;"
20024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};";
20032dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches(Code, constructorDecl(hasAnyConstructorInitializer(
20044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      withInitializer(integerLiteral(equals(0)))))));
20052dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches(Code, constructorDecl(hasAnyConstructorInitializer(
20064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      withInitializer(integerLiteral(equals(1)))))));
20074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
20084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyConstructorInitializer, IsWritten) {
20104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  static const char Code[] =
20114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "struct Bar { Bar(){} };"
20124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Foo {"
20134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Foo() : foo_() { }"
20144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Bar foo_;"
20154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Bar bar_;"
20164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};";
20172dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches(Code, constructorDecl(hasAnyConstructorInitializer(
20184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      allOf(forField(hasName("foo_")), isWritten())))));
20192dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches(Code, constructorDecl(hasAnyConstructorInitializer(
20204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      allOf(forField(hasName("bar_")), isWritten())))));
20212dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches(Code, constructorDecl(hasAnyConstructorInitializer(
20224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      allOf(forField(hasName("bar_")), unless(isWritten()))))));
20234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
20244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, NewExpression) {
20263680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher New = newExpr();
20274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { public: X(); }; void x() { new X; }", New));
20294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(); }; void x() { new X(); }", New));
20314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { new X(0); }", New));
20334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {}; void x(int) { new X; }", New));
20344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
20354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, NewExpressionArgument) {
20373680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher New = constructExpr(
20383680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
20394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { int y; new X(y); }",
20424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              New));
20434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { int y; new X(y); }",
20454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              New));
20464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int); }; void x() { int z; new X(z); }",
20484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 New));
20494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20503680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher WrongIndex = constructExpr(
20513680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
20524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int); }; void x() { int y; new X(y); }",
20544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 WrongIndex));
20554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
20564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, NewExpressionArgumentCount) {
20582dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher New = constructExpr(argumentCountIs(1));
20594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { new X(0); }", New));
20624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int, int); }; void x() { new X(0, 0); }",
20644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 New));
20654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
20664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2067e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Matcher, DeleteExpression) {
2068e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("struct A {}; void f(A* a) { delete a; }",
20692dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      deleteExpr()));
2070e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2071e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
20724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, DefaultArgument) {
20732dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher Arg = defaultArgExpr();
20744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x(int, int = 0) { int y; x(y); }", Arg));
20764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { void x(int, int = 0) { int y; x(y); } };", Arg));
20784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x(int, int = 0) { int y; x(y, 0); }", Arg));
20794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
20804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, StringLiterals) {
20823680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher Literal = stringLiteral();
20834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const char *s = \"string\";", Literal));
20844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // wide string
20854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const wchar_t *s = L\"string\";", Literal));
20864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // with escaped characters
20874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const char *s = \"\x05five\";", Literal));
20884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // no matching -- though the data type is the same, there is no string literal
20894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));
20904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
20914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, CharacterLiterals) {
20933680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher CharLiteral = characterLiteral();
20944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const char c = 'c';", CharLiteral));
20954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // wide character
20964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const char c = L'c';", CharLiteral));
20974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // wide character, Hex encoded, NOT MATCHED!
20984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("const wchar_t c = 0x2126;", CharLiteral));
20994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("const char c = 0x1;", CharLiteral));
21004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, IntegerLiterals) {
21033680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher HasIntLiteral = integerLiteral();
21044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = 10;", HasIntLiteral));
21054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = 0x1AB;", HasIntLiteral));
21064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = 10L;", HasIntLiteral));
21074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = 10U;", HasIntLiteral));
21084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Non-matching cases (character literals, float and double)
21104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int i = L'a';",
21114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                HasIntLiteral));  // this is actually a character
21124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                                  // literal cast to int
21134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int i = 'a';", HasIntLiteral));
21144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int i = 1e10;", HasIntLiteral));
21154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int i = 10.0;", HasIntLiteral));
21164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2118c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel JasperTEST(Matcher, FloatLiterals) {
2119c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel Jasper  StatementMatcher HasFloatLiteral = floatLiteral();
2120c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel Jasper  EXPECT_TRUE(matches("float i = 10.0;", HasFloatLiteral));
2121c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel Jasper  EXPECT_TRUE(matches("float i = 10.0f;", HasFloatLiteral));
2122c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel Jasper  EXPECT_TRUE(matches("double i = 10.0;", HasFloatLiteral));
2123c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel Jasper  EXPECT_TRUE(matches("double i = 10.0L;", HasFloatLiteral));
2124c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel Jasper  EXPECT_TRUE(matches("double i = 1e10;", HasFloatLiteral));
21250e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0))));
21260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0f))));
21270e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(
21280e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      matches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(5.0)))));
2129c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel Jasper
2130c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel Jasper  EXPECT_TRUE(notMatches("float i = 10;", HasFloatLiteral));
21310e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0))));
21320e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0f))));
21330e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(
21340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      notMatches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(6.0)))));
2135c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel Jasper}
2136c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel Jasper
213731f7c08a0d2b140bf31a08894d1948649de53c15Daniel JasperTEST(Matcher, NullPtrLiteral) {
213831f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  EXPECT_TRUE(matches("int* i = nullptr;", nullPtrLiteralExpr()));
213931f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper}
214031f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper
2141b54b7646b2d00a85d80e40adf7c49553f150c736Daniel JasperTEST(Matcher, AsmStatement) {
2142b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void foo() { __asm(\"mov al, 2\"); }", asmStmt()));
2143b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper}
2144b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper
21454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, Conditions) {
21464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher Condition = ifStmt(hasCondition(boolLiteral(equals(true))));
21474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { if (true) {} }", Condition));
21494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { if (false) {} }", Condition));
21504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { bool a = true; if (a) {} }", Condition));
21514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { if (true || false) {} }", Condition));
21524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { if (1) {} }", Condition));
21534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesTEST(IfStmt, ChildTraversalMatchers) {
21566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  EXPECT_TRUE(matches("void f() { if (false) true; else false; }",
21576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                      ifStmt(hasThen(boolLiteral(equals(true))))));
21586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  EXPECT_TRUE(notMatches("void f() { if (false) false; else true; }",
21596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                         ifStmt(hasThen(boolLiteral(equals(true))))));
21606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  EXPECT_TRUE(matches("void f() { if (false) false; else true; }",
21616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                      ifStmt(hasElse(boolLiteral(equals(true))))));
21626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  EXPECT_TRUE(notMatches("void f() { if (false) true; else false; }",
21636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                         ifStmt(hasElse(boolLiteral(equals(true))))));
21646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
21656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
21664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MatchBinaryOperator, HasOperatorName) {
21674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
21684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true || false; }", OperatorOr));
21704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
21714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MatchBinaryOperator, HasLHSAndHasRHS) {
21744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OperatorTrueFalse =
21754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      binaryOperator(hasLHS(boolLiteral(equals(true))),
21764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                     hasRHS(boolLiteral(equals(false))));
21774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true || false; }", OperatorTrueFalse));
21794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse));
21804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { false || true; }", OperatorTrueFalse));
21814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MatchBinaryOperator, HasEitherOperand) {
21844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher HasOperand =
21854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      binaryOperator(hasEitherOperand(boolLiteral(equals(false))));
21864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true || false; }", HasOperand));
21884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { false && true; }", HasOperand));
21894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand));
21904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, BinaryOperatorTypes) {
21934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Integration test that verifies the AST provides all binary operators in
21944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // a way we expect.
21954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // FIXME: Operator ','
21964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
21974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(","))));
21984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
21994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b; bool c = (b = true);",
22004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("="))));
22014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!="))));
22034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("=="))));
22054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("bool b = 1 < 2;", binaryOperator(hasOperatorName("<"))));
22064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<="))));
22084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<"))));
22104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 1; int j = (i <<= 2);",
22124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("<<="))));
22134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("bool b = 1 > 2;", binaryOperator(hasOperatorName(">"))));
22144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">="))));
22164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>"))));
22184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 1; int j = (i >>= 2);",
22204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName(">>="))));
22214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42 ^ 23;", binaryOperator(hasOperatorName("^"))));
22234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i ^= 42);",
22254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("^="))));
22264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42 % 23;", binaryOperator(hasOperatorName("%"))));
22284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i %= 42);",
22304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("%="))));
22314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 42  &23;", binaryOperator(hasOperatorName("&"))));
22334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = true && false;",
22354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("&&"))));
22364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = true; bool c = (b &= false);",
22384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("&="))));
22394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|"))));
22414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = true || false;",
22434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("||"))));
22444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = true; bool c = (b |= false);",
22464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("|="))));
22474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42  *23;", binaryOperator(hasOperatorName("*"))));
22494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i *= 23);",
22514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("*="))));
22524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42 / 23;", binaryOperator(hasOperatorName("/"))));
22544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i /= 23);",
22564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("/="))));
22574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42 + 23;", binaryOperator(hasOperatorName("+"))));
22594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i += 23);",
22614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("+="))));
22624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42 - 23;", binaryOperator(hasOperatorName("-"))));
22644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i -= 23);",
22664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("-="))));
22674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };",
22694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("->*"))));
22704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };",
22724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName(".*"))));
22734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Member expressions as operators are not supported in matches.
22754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("struct A { void x(A *a) { a->x(this); } };",
22774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 binaryOperator(hasOperatorName("->"))));
22784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Initializer assignments are not represented as operator equals.
22804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
22814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("bool b = true;", binaryOperator(hasOperatorName("="))));
22824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Array indexing is not represented as operator.
22844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int a[42]; void x() { a[23]; }", unaryOperator()));
22854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Overloaded operators do not match at all.
22874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
22884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "struct A { bool operator&&(const A &a) const { return false; } };"
22894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void x() { A a, b; a && b; }",
22904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      binaryOperator()));
22914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MatchUnaryOperator, HasOperatorName) {
22944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OperatorNot = unaryOperator(hasOperatorName("!"));
22954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { !true; } ", OperatorNot));
22974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
22984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MatchUnaryOperator, HasUnaryOperand) {
23014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OperatorOnFalse =
23024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      unaryOperator(hasUnaryOperand(boolLiteral(equals(false))));
23034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse));
23054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse));
23064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, UnaryOperatorTypes) {
23094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Integration test that verifies the AST provides all unary operators in
23104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // a way we expect.
23114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("bool b = !true;", unaryOperator(hasOperatorName("!"))));
23124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
23134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&"))));
23144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = ~ 1;", unaryOperator(hasOperatorName("~"))));
23154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
23164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool *p; bool b = *p;", unaryOperator(hasOperatorName("*"))));
23174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
23184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = +i;", unaryOperator(hasOperatorName("+"))));
23194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
23204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = -i;", unaryOperator(hasOperatorName("-"))));
23214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
23224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = ++i;", unaryOperator(hasOperatorName("++"))));
23234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
23244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = i++;", unaryOperator(hasOperatorName("++"))));
23254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
23264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = --i;", unaryOperator(hasOperatorName("--"))));
23274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
23284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = i--;", unaryOperator(hasOperatorName("--"))));
23294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // We don't match conversion operators.
23314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int i; double d = (double)i;", unaryOperator()));
23324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Function calls are not represented as operator.
23344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f(); void x() { f(); }", unaryOperator()));
23354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Overloaded operators do not match at all.
23374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // FIXME: We probably want to add that.
23384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
23394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "struct A { bool operator!() const { return false; } };"
23404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void x() { A a; !a; }", unaryOperator(hasOperatorName("!"))));
23414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ConditionalOperator) {
23444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher Conditional = conditionalOperator(
23454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      hasCondition(boolLiteral(equals(true))),
23464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      hasTrueExpression(boolLiteral(equals(false))));
23474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true ? false : true; }", Conditional));
23494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { false ? false : true; }", Conditional));
23504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { true ? true : false; }", Conditional));
23514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher ConditionalFalse = conditionalOperator(
23534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      hasFalseExpression(boolLiteral(equals(false))));
23544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
23564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
23574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("void x() { true ? false : true; }", ConditionalFalse));
23584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2360e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(ArraySubscriptMatchers, ArraySubscripts) {
2361e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("int i[2]; void f() { i[1] = 1; }",
2362e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      arraySubscriptExpr()));
2363e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("int i; void f() { i = 1; }",
2364e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                         arraySubscriptExpr()));
2365e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2366e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
2367e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(ArraySubscriptMatchers, ArrayIndex) {
2368e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
2369e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "int i[2]; void f() { i[1] = 1; }",
2370e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
2371e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
2372e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "int i[2]; void f() { 1[i] = 1; }",
2373e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
2374e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches(
2375e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "int i[2]; void f() { i[1] = 1; }",
2376e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      arraySubscriptExpr(hasIndex(integerLiteral(equals(0))))));
2377e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2378e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
2379e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(ArraySubscriptMatchers, MatchesArrayBase) {
2380e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
2381e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "int i[2]; void f() { i[1] = 2; }",
23822dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      arraySubscriptExpr(hasBase(implicitCastExpr(
23832dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasSourceExpression(declRefExpr()))))));
2384e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2385e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
23864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, HasNameSupportsNamespaces) {
23874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
23882dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("a::b::C"))));
23894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
23902dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("::a::b::C"))));
23914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
23922dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("b::C"))));
23934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
23942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("C"))));
23954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
23962dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("c::b::C"))));
23974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
23982dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("a::c::C"))));
23994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
24002dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("a::b::A"))));
24014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
24022dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("::C"))));
24034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
24042dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("::b::C"))));
24054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
24062dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("z::a::b::C"))));
24074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
24082dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("a+b::C"))));
24094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
24102dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("C"))));
24114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, HasNameSupportsOuterClasses) {
24144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24152dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class A { class B { class C; }; };",
24162dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("A::B::C"))));
24174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class A { class B { class C; }; };",
24192dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("::A::B::C"))));
24204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24212dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class A { class B { class C; }; };",
24222dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("B::C"))));
24234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24242dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class A { class B { class C; }; };",
24252dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("C"))));
24264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class A { class B { class C; }; };",
24282dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("c::B::C"))));
24294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class A { class B { class C; }; };",
24312dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("A::c::C"))));
24324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class A { class B { class C; }; };",
24342dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("A::B::A"))));
24354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24362dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      notMatches("class A { class B { class C; }; };",
24372dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("::C"))));
24384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class A { class B { class C; }; };",
24402dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("::B::C"))));
24414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
24422dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("z::A::B::C"))));
24434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class A { class B { class C; }; };",
24452dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("A+B::C"))));
24464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, IsDefinition) {
24494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher DefinitionOfClassA =
24502dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("A"), isDefinition());
24514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class A {};", DefinitionOfClassA));
24524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A;", DefinitionOfClassA));
24534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher DefinitionOfVariableA =
24552dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("a"), isDefinition());
24564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));
24574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));
24584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher DefinitionOfMethodA =
24602dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasName("a"), isDefinition());
24614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));
24624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));
24634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, OfClass) {
24662dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher Constructor = constructExpr(hasDeclaration(methodDecl(
24674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      ofClass(hasName("X")))));
24684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(); }; void x(int) { X x; }", Constructor));
24714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(); }; void x(int) { X x = X(); }",
24734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
24744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
24754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: Y(); }; void x(int) { Y y; }",
24764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 Constructor));
24774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, VisitsTemplateInstantiations) {
24804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
24814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class A { public: void x(); };"
24824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class B { public: void y() { T t; t.x(); } };"
24832dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      "void f() { B<A> b; b.y(); }",
24842dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      callExpr(callee(methodDecl(hasName("x"))))));
24854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
24874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class A { public: void x(); };"
24884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class C {"
24894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      " public:"
24904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  template <typename T> class B { public: void y() { T t; t.x(); } };"
24914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};"
24924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void f() {"
24934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  C::B<A> b; b.y();"
24942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      "}",
24952dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"),
24962dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 hasDescendant(callExpr(callee(methodDecl(hasName("x"))))))));
24974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2499e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Matcher, HandlesNullQualTypes) {
2500e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // FIXME: Add a Type matcher so we can replace uses of this
2501e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // variable with Type(True())
2502e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  const TypeMatcher AnyType = anything();
2503e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
2504e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // We don't really care whether this matcher succeeds; we're testing that
2505e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // it completes without crashing.
2506e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
2507e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "struct A { };"
2508e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "template <typename T>"
2509e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "void f(T t) {"
2510e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "  T local_t(t /* this becomes a null QualType in the AST */);"
2511e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "}"
2512e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "void g() {"
2513e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "  f(0);"
2514e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "}",
25152dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      expr(hasType(TypeMatcher(
2516e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper          anyOf(
2517e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper              TypeMatcher(hasDeclaration(anything())),
2518e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper              pointsTo(AnyType),
2519e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper              references(AnyType)
2520e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper              // Other QualType matchers should go here.
2521e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                ))))));
2522e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2523e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
25244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// For testing AST_MATCHER_P().
2525e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperAST_MATCHER_P(Decl, just, internal::Matcher<Decl>, AMatcher) {
25264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Make sure all special variables are used: node, match_finder,
25274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // bound_nodes_builder, and the parameter named 'AMatcher'.
25284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  return AMatcher.matches(Node, Finder, Builder);
25294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
25304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(AstMatcherPMacro, Works) {
25322dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher HasClassB = just(has(recordDecl(hasName("B")).bind("b")));
25334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
2535a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
25364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
2538a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("a")));
25394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
2541a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
25424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
25434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga NainarAST_POLYMORPHIC_MATCHER_P(polymorphicHas,
25453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                          AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt),
25463ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                          internal::Matcher<Decl>, AMatcher) {
25474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  return Finder->matchesChildOf(
2548a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek      Node, AMatcher, Builder,
25494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
25504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      ASTMatchFinder::BK_First);
25514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
25524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(AstPolymorphicMatcherPMacro, Works) {
25542dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher HasClassB =
25552dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      polymorphicHas(recordDecl(hasName("B")).bind("b"));
25564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
2558a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
25594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
2561a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("a")));
25624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
2564a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
25654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher StatementHasClassB =
25672dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      polymorphicHas(recordDecl(hasName("B")));
25684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { class B {}; }", StatementHasClassB));
25704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
25714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(For, FindsForLoops) {
25734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { for(;;); }", forStmt()));
25744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { if(true) for(;;); }", forStmt()));
25751a00fee3933066024a2398f9456e5d6bc74344b9Daniel Jasper  EXPECT_TRUE(notMatches("int as[] = { 1, 2, 3 };"
25761a00fee3933066024a2398f9456e5d6bc74344b9Daniel Jasper                         "void f() { for (auto &a : as); }",
257731f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                         forStmt()));
25784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
25794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25806a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(For, ForLoopInternals) {
25816a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(matches("void f(){ int i; for (; i < 3 ; ); }",
25826a12449ec8862211856447d3df4c082a346339f2Daniel Jasper                      forStmt(hasCondition(anything()))));
25836a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(matches("void f() { for (int i = 0; ;); }",
25846a12449ec8862211856447d3df4c082a346339f2Daniel Jasper                      forStmt(hasLoopInit(anything()))));
25856a12449ec8862211856447d3df4c082a346339f2Daniel Jasper}
25866a12449ec8862211856447d3df4c082a346339f2Daniel Jasper
2587651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(For, ForRangeLoopInternals) {
2588651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_TRUE(matches("void f(){ int a[] {1, 2}; for (int i : a); }",
2589651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                      forRangeStmt(hasLoopVariable(anything()))));
25906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  EXPECT_TRUE(matches(
25916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      "void f(){ int a[] {1, 2}; for (int i : a); }",
25926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      forRangeStmt(hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))))));
2593651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
2594651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
25956a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(For, NegativeForLoopInternals) {
25966a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }",
25972dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         forStmt(hasCondition(expr()))));
25986a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(notMatches("void f() {int i; for (; i < 4; ++i) {} }",
25996a12449ec8862211856447d3df4c082a346339f2Daniel Jasper                         forStmt(hasLoopInit(anything()))));
26006a12449ec8862211856447d3df4c082a346339f2Daniel Jasper}
26016a12449ec8862211856447d3df4c082a346339f2Daniel Jasper
26024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(For, ReportsNoFalsePositives) {
26034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { ; }", forStmt()));
26044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { if(true); }", forStmt()));
26054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
26064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
26074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(CompoundStatement, HandlesSimpleCases) {
26082dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("void f();", compoundStmt()));
26092dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("void f() {}", compoundStmt()));
26102dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("void f() {{}}", compoundStmt()));
26114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
26124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
26134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(CompoundStatement, DoesNotMatchEmptyStruct) {
26144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // It's not a compound statement just because there's "{}" in the source
26154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // text. This is an AST search, not grep.
26164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace n { struct S {}; }",
26172dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt()));
26184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("namespace n { struct S { void f() {{}} }; }",
26192dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt()));
26204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
26214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
26226a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(HasBody, FindsBodyOfForWhileDoLoops) {
26234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { for(;;) {} }",
26242dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              forStmt(hasBody(compoundStmt()))));
26254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { for(;;); }",
26262dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              forStmt(hasBody(compoundStmt()))));
26276a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(matches("void f() { while(true) {} }",
26282dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              whileStmt(hasBody(compoundStmt()))));
26296a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(matches("void f() { do {} while(true); }",
26302dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              doStmt(hasBody(compoundStmt()))));
26316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  EXPECT_TRUE(matches("void f() { int p[2]; for (auto x : p) {} }",
26326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines              forRangeStmt(hasBody(compoundStmt()))));
26334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
26344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
26354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
26364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // The simplest case: every compound statement is in a function
26374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // definition, and the function body itself must be a compound
26384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // statement.
26394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { for (;;); }",
26402dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(hasAnySubstatement(forStmt()))));
26414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
26424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
26434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnySubstatement, IsNotRecursive) {
26444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // It's really "has any immediate substatement".
26454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { if (true) for (;;); }",
26462dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(hasAnySubstatement(forStmt()))));
26474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
26484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
26494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnySubstatement, MatchesInNestedCompoundStatements) {
26504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { if (true) { for (;;); } }",
26512dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(hasAnySubstatement(forStmt()))));
26524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
26534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
26544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnySubstatement, FindsSubstatementBetweenOthers) {
26554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { 1; 2; 3; for (;;); 4; 5; 6; }",
26562dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(hasAnySubstatement(forStmt()))));
26574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
26584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
26594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) {
26604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { }",
26612dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(0))));
26624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() {}",
26632dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(1))));
26644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
26654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
26664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementCountIs, AppearsToMatchOnlyOneCount) {
26674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { 1; }",
26682dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(1))));
26694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { 1; }",
26702dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(0))));
26714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { 1; }",
26722dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(2))));
26734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
26744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
26754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementCountIs, WorksWithMultipleStatements) {
26764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { 1; 2; 3; }",
26772dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(3))));
26784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
26794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
26804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementCountIs, WorksWithNestedCompoundStatements) {
26814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
26822dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(1))));
26834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
26842dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(2))));
26854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
26862dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(3))));
26874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
26882dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(4))));
26894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
26904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
26914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Member, WorksInSimplestCase) {
26924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
26932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      memberExpr(member(hasName("first")))));
26944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
26954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
26964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Member, DoesNotMatchTheBaseExpression) {
26974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Don't pick out the wrong part of the member expression, this should
26984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // be checking the member (name) only.
26994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
27002dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         memberExpr(member(hasName("first")))));
27014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Member, MatchesInMemberFunctionCall) {
27044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() {"
27054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "  struct { void first() {}; } s;"
27064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "  s.first();"
27074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "};",
27082dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      memberExpr(member(hasName("first")))));
27094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2711c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel JasperTEST(Member, MatchesMember) {
2712c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper  EXPECT_TRUE(matches(
2713c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper      "struct A { int i; }; void f() { A a; a.i = 2; }",
2714c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper      memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
2715c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper  EXPECT_TRUE(notMatches(
2716c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper      "struct A { float f; }; void f() { A a; a.f = 2.0f; }",
2717c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper      memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
2718c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper}
2719c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper
2720f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel JasperTEST(Member, UnderstandsAccess) {
2721f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(matches(
2722f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "struct A { int i; };", fieldDecl(isPublic(), hasName("i"))));
2723f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches(
2724f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "struct A { int i; };", fieldDecl(isProtected(), hasName("i"))));
2725f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches(
2726f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "struct A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
2727f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper
2728f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches(
2729f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "class A { int i; };", fieldDecl(isPublic(), hasName("i"))));
2730f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches(
2731f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "class A { int i; };", fieldDecl(isProtected(), hasName("i"))));
2732f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(matches(
2733f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "class A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
2734f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper
2735f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches(
2736f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "class A { protected: int i; };", fieldDecl(isPublic(), hasName("i"))));
2737f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(matches("class A { protected: int i; };",
2738f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper                      fieldDecl(isProtected(), hasName("i"))));
2739f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches(
2740f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "class A { protected: int i; };", fieldDecl(isPrivate(), hasName("i"))));
2741f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper
2742f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  // Non-member decls have the AccessSpecifier AS_none and thus aren't matched.
2743f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches("int i;", varDecl(isPublic(), hasName("i"))));
2744f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches("int i;", varDecl(isProtected(), hasName("i"))));
2745f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches("int i;", varDecl(isPrivate(), hasName("i"))));
2746f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper}
2747f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper
2748671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri GribenkoTEST(Member, MatchesMemberAllocationFunction) {
274931f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  // Fails in C++11 mode
275031f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  EXPECT_TRUE(matchesConditionally(
275131f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper      "namespace std { typedef typeof(sizeof(int)) size_t; }"
275231f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper      "class X { void *operator new(std::size_t); };",
275331f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper      methodDecl(ofClass(hasName("X"))), true, "-std=gnu++98"));
2754671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri Gribenko
2755671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri Gribenko  EXPECT_TRUE(matches("class X { void operator delete(void*); };",
27562dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      methodDecl(ofClass(hasName("X")))));
2757671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri Gribenko
275831f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  // Fails in C++11 mode
275931f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  EXPECT_TRUE(matchesConditionally(
27602dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      "namespace std { typedef typeof(sizeof(int)) size_t; }"
27612dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      "class X { void operator delete[](void*, std::size_t); };",
276231f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper      methodDecl(ofClass(hasName("X"))), true, "-std=gnu++98"));
2763671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri Gribenko}
2764671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri Gribenko
27654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasObjectExpression, DoesNotMatchMember) {
27664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
27674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
27682dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
27694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasObjectExpression, MatchesBaseOfVariable) {
27724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
27734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "struct X { int m; }; void f(X x) { x.m; }",
27742dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
27754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
27764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "struct X { int m; }; void f(X* x) { x->m; }",
27772dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberExpr(hasObjectExpression(
27782dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasType(pointsTo(recordDecl(hasName("X"))))))));
27794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasObjectExpression,
27824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek     MatchesObjectExpressionOfImplicitlyFormedMemberExpression) {
27834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
27844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X {}; struct S { X m; void f() { this->m; } };",
27852dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberExpr(hasObjectExpression(
27862dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasType(pointsTo(recordDecl(hasName("S"))))))));
27874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
27884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X {}; struct S { X m; void f() { m; } };",
27892dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberExpr(hasObjectExpression(
27902dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasType(pointsTo(recordDecl(hasName("S"))))))));
27914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Field, DoesNotMatchNonFieldMembers) {
27942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class X { void m(); };", fieldDecl(hasName("m"))));
27952dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class X { class m {}; };", fieldDecl(hasName("m"))));
27962dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class X { enum { m }; };", fieldDecl(hasName("m"))));
27972dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class X { enum m {}; };", fieldDecl(hasName("m"))));
27984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Field, MatchesField) {
28012dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("class X { int m; };", fieldDecl(hasName("m"))));
28024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsConstQualified, MatchesConstInt) {
28054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const int i = 42;",
28062dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasType(isConstQualified()))));
28074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsConstQualified, MatchesConstPointer) {
28104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = 42; int* const p(&i);",
28112dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasType(isConstQualified()))));
28124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsConstQualified, MatchesThroughTypedef) {
28154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
28162dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasType(isConstQualified()))));
28174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p(0);",
28182dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasType(isConstQualified()))));
28194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsConstQualified, DoesNotMatchInappropriately) {
28224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
28232dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasType(isConstQualified()))));
28244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int const* p;",
28252dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasType(isConstQualified()))));
28264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2828089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(CastExpression, MatchesExplicitCasts) {
28293680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("char *p = reinterpret_cast<char *>(&p);",castExpr()));
28303680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("void *p = (void *)(&p);", castExpr()));
28313680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("char q, *p = const_cast<char *>(&q);", castExpr()));
28323680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("char c = char(0);", castExpr()));
2833089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2834089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(CastExpression, MatchesImplicitCasts) {
2835089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from int to char.
28363680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("char c = 0;", castExpr()));
2837089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from lvalue to rvalue.
28383680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("char c = 0, d = c;", castExpr()));
2839089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2840089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2841089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(CastExpression, DoesNotMatchNonCasts) {
28423680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(notMatches("char c = '0';", castExpr()));
28433680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(notMatches("char c, &q = c;", castExpr()));
28443680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(notMatches("int i = (0);", castExpr()));
28453680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
2846089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2847089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
28484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ReinterpretCast, MatchesSimpleCase) {
28494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("char* p = reinterpret_cast<char*>(&p);",
28503680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      reinterpretCastExpr()));
28514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ReinterpretCast, DoesNotMatchOtherCasts) {
28543680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(notMatches("char* p = (char*)(&p);", reinterpretCastExpr()));
28554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
28563680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                         reinterpretCastExpr()));
28574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void* p = static_cast<void*>(&p);",
28583680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                         reinterpretCastExpr()));
28594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
28604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                         "B b;"
28614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                         "D* p = dynamic_cast<D*>(&b);",
28623680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                         reinterpretCastExpr()));
28634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(FunctionalCast, MatchesSimpleCase) {
2866651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::string foo_class = "class Foo { public: Foo(const char*); };";
28674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",
28683680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      functionalCastExpr()));
28694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(FunctionalCast, DoesNotMatchOtherCasts) {
2872651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::string FooClass = "class Foo { public: Foo(const char*); };";
28734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
28744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",
28753680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                 functionalCastExpr()));
28764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
28774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches(FooClass + "void r() { Foo f = \"hello world\"; }",
28783680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                 functionalCastExpr()));
28794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DynamicCast, MatchesSimpleCase) {
28824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("struct B { virtual ~B() {} }; struct D : B {};"
28834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "B b;"
28844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "D* p = dynamic_cast<D*>(&b);",
28853680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      dynamicCastExpr()));
28864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StaticCast, MatchesSimpleCase) {
28894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void* p(static_cast<void*>(&p));",
28903680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      staticCastExpr()));
28914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StaticCast, DoesNotMatchOtherCasts) {
28943680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(notMatches("char* p = (char*)(&p);", staticCastExpr()));
28954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
28963680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                         staticCastExpr()));
28974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void* p = reinterpret_cast<char*>(&p);",
28983680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                         staticCastExpr()));
28994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
29004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                         "B b;"
29014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                         "D* p = dynamic_cast<D*>(&b);",
29023680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                         staticCastExpr()));
29034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2905e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel JasperTEST(CStyleCast, MatchesSimpleCase) {
2906e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper  EXPECT_TRUE(matches("int i = (int) 2.2f;", cStyleCastExpr()));
2907e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper}
2908e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper
2909e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel JasperTEST(CStyleCast, DoesNotMatchOtherCasts) {
2910e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper  EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);"
2911e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         "char q, *r = const_cast<char*>(&q);"
2912e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         "void* s = reinterpret_cast<char*>(&s);"
2913e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         "struct B { virtual ~B() {} }; struct D : B {};"
2914e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         "B b;"
2915e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         "D* t = dynamic_cast<D*>(&b);",
2916e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         cStyleCastExpr()));
2917e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper}
2918e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper
29194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasDestinationType, MatchesSimpleCase) {
29204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
29213680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      staticCastExpr(hasDestinationType(
29223680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          pointsTo(TypeMatcher(anything()))))));
29234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2925089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(HasImplicitDestinationType, MatchesSimpleCase) {
2926089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit const cast.
2927089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x; const int i = x;",
29283680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      implicitCastExpr(
29293680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          hasImplicitDestinationType(isInteger()))));
2930089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit array-to-pointer cast.
2931089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int arr[3]; int *p = arr;",
29323680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      implicitCastExpr(hasImplicitDestinationType(
29333680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          pointsTo(TypeMatcher(anything()))))));
2934089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2935089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2936089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(HasImplicitDestinationType, DoesNotMatchIncorrectly) {
2937089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from int to char.
2938089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char c = 0;",
29393680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      implicitCastExpr(hasImplicitDestinationType(
29403680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          unless(anything())))));
2941089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit array-to-pointer cast.
2942089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int arr[3]; int *p = arr;",
29433680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      implicitCastExpr(hasImplicitDestinationType(
29443680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          unless(anything())))));
2945089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2946089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2947089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(ImplicitCast, MatchesSimpleCase) {
2948089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit const cast.
2949089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0; const int y = x;",
29502dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(implicitCastExpr()))));
2951089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from int to char.
2952089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("char c = 0;",
29532dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(implicitCastExpr()))));
2954089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit array-to-pointer cast.
2955089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int arr[6]; int *p = arr;",
29562dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(implicitCastExpr()))));
2957089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2958089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2959089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(ImplicitCast, DoesNotMatchIncorrectly) {
29602dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  // This test verifies that implicitCastExpr() matches exactly when implicit casts
2961089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // are present, and that it ignores explicit and paren casts.
2962089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2963089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These two test cases have no casts.
2964089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x = 0;",
29652dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(implicitCastExpr()))));
2966089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x = 0, &y = x;",
29672dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(implicitCastExpr()))));
2968089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2969089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x = 0; double d = (double) x;",
29702dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(implicitCastExpr()))));
2971089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("const int *p; int *q = const_cast<int *>(p);",
29722dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(implicitCastExpr()))));
2973089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2974089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x = (0);",
29752dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(implicitCastExpr()))));
2976089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2977089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2978089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringImpCasts, MatchesImpCasts) {
2979089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test checks that ignoringImpCasts matches when implicit casts are
2980089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // present and its inner matcher alone does not match.
2981089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // Note that this test creates an implicit const cast.
2982089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0; const int y = x;",
29832dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringImpCasts(
29842dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          declRefExpr(to(varDecl(hasName("x")))))))));
2985089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implict cast from int to char.
2986089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("char x = 0;",
29872dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringImpCasts(
2988089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                          integerLiteral(equals(0)))))));
2989089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2990089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2991089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringImpCasts, DoesNotMatchIncorrectly) {
2992089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These tests verify that ignoringImpCasts does not match if the inner
2993089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // matcher does not match.
2994089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // Note that the first test creates an implicit const cast.
2995089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x; const int y = x;",
29962dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
2997089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
2998089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x; int y = x;",
29992dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
3000089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
3001089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3002089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These tests verify that ignoringImplictCasts does not look through explicit
3003089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // casts or parentheses.
3004089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
30052dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
30062dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
3007089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int i = (0);",
30082dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
30092dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
3010089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("float i = (float)0;",
30112dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
30122dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
3013089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("float i = float(0);",
30142dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
30152dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
3016089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3017089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3018089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringImpCasts, MatchesWithoutImpCasts) {
3019089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test verifies that expressions that do not have implicit casts
3020089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // still match the inner matcher.
3021089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0; int &y = x;",
30222dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringImpCasts(
30232dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          declRefExpr(to(varDecl(hasName("x")))))))));
3024089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3025089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3026089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenCasts, MatchesParenCasts) {
3027089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test checks that ignoringParenCasts matches when parentheses and/or
3028089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // casts are present and its inner matcher alone does not match.
3029089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = (0);",
30302dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
30312dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
3032089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = (((((0)))));",
30332dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
30342dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
3035089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3036089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implict cast from int to char in addition to the
3037089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // parentheses.
3038089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("char x = (0);",
30392dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
30402dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
3041089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3042089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("char x = (char)0;",
30432dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
30442dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
3045089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
30462dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
3047089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                          integerLiteral(equals(0)))))));
3048089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3049089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3050089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenCasts, MatchesWithoutParenCasts) {
3051089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test verifies that expressions that do not have any casts still match.
3052089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0;",
30532dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
30542dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
3055089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3056089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3057089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenCasts, DoesNotMatchIncorrectly) {
3058089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These tests verify that ignoringImpCasts does not match if the inner
3059089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // matcher does not match.
3060089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x = ((0));",
30612dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenCasts(
3062089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
3063089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3064089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from int to char in addition to the
3065089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // parentheses.
3066089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char x = ((0));",
30672dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenCasts(
3068089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
3069089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3070089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char *x = static_cast<char *>((0));",
30712dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenCasts(
3072089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
3073089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3074089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3075089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenAndImpCasts, MatchesParenImpCasts) {
3076089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test checks that ignoringParenAndImpCasts matches when
3077089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // parentheses and/or implicit casts are present and its inner matcher alone
3078089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // does not match.
3079089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // Note that this test creates an implicit const cast.
3080089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0; const int y = x;",
30812dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenImpCasts(
30822dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          declRefExpr(to(varDecl(hasName("x")))))))));
3083089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from int to char.
3084089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("const char x = (0);",
30852dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenImpCasts(
30862dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
3087089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3088089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3089089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenAndImpCasts, MatchesWithoutParenImpCasts) {
3090089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test verifies that expressions that do not have parentheses or
3091089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // implicit casts still match.
3092089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0; int &y = x;",
30932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenImpCasts(
30942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          declRefExpr(to(varDecl(hasName("x")))))))));
3095089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0;",
30962dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenImpCasts(
30972dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
3098089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3099089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3100089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenAndImpCasts, DoesNotMatchIncorrectly) {
3101089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These tests verify that ignoringParenImpCasts does not match if
3102089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // the inner matcher does not match.
3103089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast.
3104089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char c = ((3));",
31052dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenImpCasts(
3106089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
3107089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These tests verify that ignoringParenAndImplictCasts does not look
3108089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // through explicit casts.
3109089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("float y = (float(0));",
31102dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenImpCasts(
31112dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
3112089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("float y = (float)0;",
31132dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenImpCasts(
31142dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
3115089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
31162dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenImpCasts(
31172dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
3118089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
3119089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
3120715c9568ee5d75f25dab98229c87bcec880daf5dManuel KlimekTEST(HasSourceExpression, MatchesImplicitCasts) {
31214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
31224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "void r() {string a_string; URL url = a_string; }",
31233680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      implicitCastExpr(
31243680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          hasSourceExpression(constructExpr()))));
31254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
31264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
3127715c9568ee5d75f25dab98229c87bcec880daf5dManuel KlimekTEST(HasSourceExpression, MatchesExplicitCasts) {
3128715c9568ee5d75f25dab98229c87bcec880daf5dManuel Klimek  EXPECT_TRUE(matches("float x = static_cast<float>(42);",
31293680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      explicitCastExpr(
31302dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          hasSourceExpression(hasDescendant(
31313680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                              expr(integerLiteral()))))));
3132715c9568ee5d75f25dab98229c87bcec880daf5dManuel Klimek}
3133715c9568ee5d75f25dab98229c87bcec880daf5dManuel Klimek
31344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Statement, DoesNotMatchDeclarations) {
31352dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class X {};", stmt()));
31364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
31374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
31384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Statement, MatchesCompoundStatments) {
31392dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("void x() {}", stmt()));
31404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
31414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
31424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationStatement, DoesNotMatchCompoundStatements) {
31432dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("void x() {}", declStmt()));
31444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
31454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
31464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationStatement, MatchesVariableDeclarationStatements) {
31472dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("void x() { int a; }", declStmt()));
31484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
31494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
3150651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(ExprWithCleanups, MatchesExprWithCleanups) {
3151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_TRUE(matches("struct Foo { ~Foo(); };"
3152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                      "const Foo f = Foo();",
3153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                      varDecl(hasInitializer(exprWithCleanups()))));
3154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_FALSE(matches("struct Foo { };"
3155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                      "const Foo f = Foo();",
3156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                      varDecl(hasInitializer(exprWithCleanups()))));
3157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
3158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3159e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(InitListExpression, MatchesInitListExpression) {
3160e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("int a[] = { 1, 2 };",
3161e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      initListExpr(hasType(asString("int [2]")))));
3162e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };",
31632dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      initListExpr(hasType(recordDecl(hasName("B"))))));
31640e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(matches("struct S { S(void (*a)()); };"
31650e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                      "void f();"
31660e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                      "S s[1] = { &f };",
31670e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                      declRefExpr(to(functionDecl(hasName("f"))))));
31680e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(
31690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      matches("int i[1] = {42, [0] = 43};", integerLiteral(equals(42))));
3170e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
3171e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
3172e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UsingDeclaration, MatchesUsingDeclarations) {
3173e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("namespace X { int x; } using X::x;",
3174e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      usingDecl()));
3175e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
3176e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
3177e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UsingDeclaration, MatchesShadowUsingDelcarations) {
3178e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("namespace f { int a; } using f::a;",
3179e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      usingDecl(hasAnyUsingShadowDecl(hasName("a")))));
3180e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
3181e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
3182e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UsingDeclaration, MatchesSpecificTarget) {
3183e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
3184e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      usingDecl(hasAnyUsingShadowDecl(
31852dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          hasTargetDecl(functionDecl())))));
3186e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
3187e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                         usingDecl(hasAnyUsingShadowDecl(
31882dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             hasTargetDecl(functionDecl())))));
3189e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
3190e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
3191e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UsingDeclaration, ThroughUsingDeclaration) {
3192e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
3193e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "namespace a { void f(); } using a::f; void g() { f(); }",
31942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      declRefExpr(throughUsingDecl(anything()))));
3195e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches(
3196e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "namespace a { void f(); } using a::f; void g() { a::f(); }",
31972dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      declRefExpr(throughUsingDecl(anything()))));
3198e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
3199e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
3200176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(UsingDirectiveDeclaration, MatchesUsingNamespace) {
3201176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("namespace X { int x; } using namespace X;",
3202176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      usingDirectiveDecl()));
3203176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_FALSE(
3204176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      matches("namespace X { int x; } using X::x;", usingDirectiveDecl()));
3205176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
3206176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
3207425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam PanzerTEST(SingleDecl, IsSingleDecl) {
3208425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  StatementMatcher SingleDeclStmt =
32092dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      declStmt(hasSingleDecl(varDecl(hasInitializer(anything()))));
3210425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(matches("void f() {int a = 4;}", SingleDeclStmt));
3211425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(notMatches("void f() {int a;}", SingleDeclStmt));
3212425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
3213425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer                          SingleDeclStmt));
3214425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer}
3215425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer
3216425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam PanzerTEST(DeclStmt, ContainsDeclaration) {
32172dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher MatchesInit = varDecl(hasInitializer(anything()));
3218425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer
3219425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(matches("void f() {int a = 4;}",
32202dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      declStmt(containsDeclaration(0, MatchesInit))));
3221425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(matches("void f() {int a = 4, b = 3;}",
32222dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      declStmt(containsDeclaration(0, MatchesInit),
32232dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                               containsDeclaration(1, MatchesInit))));
3224425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  unsigned WrongIndex = 42;
3225425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
32262dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         declStmt(containsDeclaration(WrongIndex,
3227425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer                                                      MatchesInit))));
3228425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer}
3229425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer
3230425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam PanzerTEST(DeclCount, DeclCountIsCorrect) {
3231425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(matches("void f() {int i,j;}",
32322dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      declStmt(declCountIs(2))));
3233425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(notMatches("void f() {int i,j; int k;}",
32342dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         declStmt(declCountIs(3))));
3235425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(notMatches("void f() {int i,j, k, l;}",
32362dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         declStmt(declCountIs(3))));
3237425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer}
3238425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer
32394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(While, MatchesWhileLoops) {
32404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() {}", whileStmt()));
32414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { while(true); }", whileStmt()));
32424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { do {} while(true); }", whileStmt()));
32434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
32444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
32454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Do, MatchesDoLoops) {
32464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { do {} while(true); }", doStmt()));
32474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { do ; while(false); }", doStmt()));
32484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
32494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
32504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Do, DoesNotMatchWhileLoops) {
32514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { while(true) {} }", doStmt()));
32524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
32534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
32544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(SwitchCase, MatchesCase) {
32554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchCase()));
32564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchCase()));
32574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchCase()));
32584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { switch(42) {} }", switchCase()));
32594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
32604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
3261b54b7646b2d00a85d80e40adf7c49553f150c736Daniel JasperTEST(SwitchCase, MatchesSwitch) {
3262b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchStmt()));
3263b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchStmt()));
3264b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchStmt()));
3265b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(notMatches("void x() {}", switchStmt()));
3266b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper}
3267b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper
3268acf02715ab1aa1e5a791f20e0d1ca217af256823Peter CollingbourneTEST(SwitchCase, MatchesEachCase) {
3269acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne  EXPECT_TRUE(notMatches("void x() { switch(42); }",
3270acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne                         switchStmt(forEachSwitchCase(caseStmt()))));
3271acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne  EXPECT_TRUE(matches("void x() { switch(42) case 42:; }",
3272acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne                      switchStmt(forEachSwitchCase(caseStmt()))));
3273acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne  EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }",
3274acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne                      switchStmt(forEachSwitchCase(caseStmt()))));
3275acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne  EXPECT_TRUE(notMatches(
3276acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne      "void x() { if (1) switch(42) { case 42: switch (42) { default:; } } }",
3277acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne      ifStmt(has(switchStmt(forEachSwitchCase(defaultStmt()))))));
3278acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne  EXPECT_TRUE(matches("void x() { switch(42) { case 1+1: case 4:; } }",
3279acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne                      switchStmt(forEachSwitchCase(
3280acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne                          caseStmt(hasCaseConstant(integerLiteral()))))));
3281acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne  EXPECT_TRUE(notMatches("void x() { switch(42) { case 1+1: case 2+2:; } }",
3282acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne                         switchStmt(forEachSwitchCase(
3283acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne                             caseStmt(hasCaseConstant(integerLiteral()))))));
3284acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne  EXPECT_TRUE(notMatches("void x() { switch(42) { case 1 ... 2:; } }",
3285acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne                         switchStmt(forEachSwitchCase(
3286acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne                             caseStmt(hasCaseConstant(integerLiteral()))))));
3287acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne  EXPECT_TRUE(matchAndVerifyResultTrue(
3288acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne      "void x() { switch (42) { case 1: case 2: case 3: default:; } }",
3289acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne      switchStmt(forEachSwitchCase(caseStmt().bind("x"))),
3290acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne      new VerifyIdIsBoundTo<CaseStmt>("x", 3)));
3291acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne}
3292acf02715ab1aa1e5a791f20e0d1ca217af256823Peter Collingbourne
329306963013d1972f1f7a58875bb40976b60522700bManuel KlimekTEST(ForEachConstructorInitializer, MatchesInitializers) {
329406963013d1972f1f7a58875bb40976b60522700bManuel Klimek  EXPECT_TRUE(matches(
329506963013d1972f1f7a58875bb40976b60522700bManuel Klimek      "struct X { X() : i(42), j(42) {} int i, j; };",
329606963013d1972f1f7a58875bb40976b60522700bManuel Klimek      constructorDecl(forEachConstructorInitializer(ctorInitializer()))));
329706963013d1972f1f7a58875bb40976b60522700bManuel Klimek}
329806963013d1972f1f7a58875bb40976b60522700bManuel Klimek
3299b54b7646b2d00a85d80e40adf7c49553f150c736Daniel JasperTEST(ExceptionHandling, SimpleCases) {
3300b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", catchStmt()));
3301b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", tryStmt()));
3302b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(notMatches("void foo() try { } catch(int X) { }", throwExpr()));
3303b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void foo() try { throw; } catch(int X) { }",
3304b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper                      throwExpr()));
3305b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void foo() try { throw 5;} catch(int X) { }",
3306b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper                      throwExpr()));
3307b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper}
3308b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper
33094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasConditionVariableStatement, DoesNotMatchCondition) {
33104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
33114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void x() { if(true) {} }",
33122dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      ifStmt(hasConditionVariableStatement(declStmt()))));
33134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
33144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void x() { int x; if((x = 42)) {} }",
33152dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      ifStmt(hasConditionVariableStatement(declStmt()))));
33164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
33174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
33184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasConditionVariableStatement, MatchesConditionVariables) {
33194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
33204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void x() { if(int* a = 0) {} }",
33212dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      ifStmt(hasConditionVariableStatement(declStmt()))));
33224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
33234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
33244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEach, BindsOneNode) {
33254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
33262dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"), forEach(fieldDecl(hasName("x")).bind("x"))),
3327a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("x", 1)));
33284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
33294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
33304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEach, BindsMultipleNodes) {
33314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
33322dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"), forEach(fieldDecl().bind("f"))),
3333a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("f", 3)));
33344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
33354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
33364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEach, BindsRecursiveCombinations) {
33374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
33384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class C { class D { int x; int y; }; class E { int y; int z; }; };",
33392dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"),
33402dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 forEach(recordDecl(forEach(fieldDecl().bind("f"))))),
3341a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("f", 4)));
33424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
33434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
33444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEachDescendant, BindsOneNode) {
33454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
33462dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"),
33472dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 forEachDescendant(fieldDecl(hasName("x")).bind("x"))),
3348a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("x", 1)));
33494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
33504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
33515f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel JasperTEST(ForEachDescendant, NestedForEachDescendant) {
33525f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper  DeclarationMatcher m = recordDecl(
33535f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper      isDefinition(), decl().bind("x"), hasName("C"));
33545f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
33555f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper    "class A { class B { class C {}; }; };",
33565f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper    recordDecl(hasName("A"), anyOf(m, forEachDescendant(m))),
33575f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper    new VerifyIdIsBoundTo<Decl>("x", "C")));
33585f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper
3359054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // Check that a partial match of 'm' that binds 'x' in the
3360054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // first part of anyOf(m, anything()) will not overwrite the
3361054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // binding created by the earlier binding in the hasDescendant.
3362054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3363054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "class A { class B { class C {}; }; };",
3364054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      recordDecl(hasName("A"), allOf(hasDescendant(m), anyOf(m, anything()))),
3365054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", "C")));
33665f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper}
33675f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper
33684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEachDescendant, BindsMultipleNodes) {
33694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
33704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class C { class D { int x; int y; }; "
33714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "          class E { class F { int y; int z; }; }; };",
33722dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"), forEachDescendant(fieldDecl().bind("f"))),
3373a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("f", 4)));
33744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
33754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
33764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEachDescendant, BindsRecursiveCombinations) {
33774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
33784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class C { class D { "
33794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "          class E { class F { class G { int y; int z; }; }; }; }; };",
33802dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"), forEachDescendant(recordDecl(
33812dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          forEachDescendant(fieldDecl().bind("f"))))),
3382a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("f", 8)));
33834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
33844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
3385054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel KlimekTEST(ForEachDescendant, BindsCombinations) {
3386054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3387054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "void f() { if(true) {} if (true) {} while (true) {} if (true) {} while "
3388054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "(true) {} }",
3389054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      compoundStmt(forEachDescendant(ifStmt().bind("if")),
3390054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek                   forEachDescendant(whileStmt().bind("while"))),
3391054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<IfStmt>("if", 6)));
3392054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek}
3393054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek
3394054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel KlimekTEST(Has, DoesNotDeleteBindings) {
3395054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3396054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "class X { int a; };", recordDecl(decl().bind("x"), has(fieldDecl())),
3397054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
3398054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek}
3399054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek
3400054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel KlimekTEST(LoopingMatchers, DoNotOverwritePreviousMatchResultOnFailure) {
3401054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // Those matchers cover all the cases where an inner matcher is called
3402054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // and there is not a 1:1 relationship between the match of the outer
3403054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // matcher and the match of the inner matcher.
3404054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // The pattern to look for is:
3405054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  //   ... return InnerMatcher.matches(...); ...
3406054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // In which case no special handling is needed.
3407054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  //
3408054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // On the other hand, if there are multiple alternative matches
3409054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // (for example forEach*) or matches might be discarded (for example has*)
3410054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // the implementation must make sure that the discarded matches do not
3411054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // affect the bindings.
3412054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // When new such matchers are added, add a test here that:
3413054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // - matches a simple node, and binds it as the first thing in the matcher:
3414054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  //     recordDecl(decl().bind("x"), hasName("X")))
3415054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  // - uses the matcher under test afterwards in a way that not the first
3416054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  //   alternative is matched; for anyOf, that means the first branch
3417054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  //   would need to return false; for hasAncestor, it means that not
3418054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  //   the direct parent matches the inner matcher.
3419054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek
3420054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3421054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "class X { int y; };",
3422054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      recordDecl(
3423054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek          recordDecl().bind("x"), hasName("::X"),
3424054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek          anyOf(forEachDescendant(recordDecl(hasName("Y"))), anything())),
3425054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<CXXRecordDecl>("x", 1)));
3426054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3427054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "class X {};", recordDecl(recordDecl().bind("x"), hasName("::X"),
3428054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek                                anyOf(unless(anything()), anything())),
3429054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<CXXRecordDecl>("x", 1)));
3430054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3431054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "template<typename T1, typename T2> class X {}; X<float, int> x;",
3432054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      classTemplateSpecializationDecl(
3433054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek          decl().bind("x"),
3434054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek          hasAnyTemplateArgument(refersToType(asString("int")))),
3435054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
3436054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3437054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "class X { void f(); void g(); };",
3438054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      recordDecl(decl().bind("x"), hasMethod(hasName("g"))),
3439054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
3440054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3441054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "class X { X() : a(1), b(2) {} double a; int b; };",
3442054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      recordDecl(decl().bind("x"),
3443054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek                 has(constructorDecl(
3444054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek                     hasAnyConstructorInitializer(forField(hasName("b")))))),
3445054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
3446054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3447054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "void x(int, int) { x(0, 42); }",
3448054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      callExpr(expr().bind("x"), hasAnyArgument(integerLiteral(equals(42)))),
3449054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Expr>("x", 1)));
3450054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3451054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "void x(int, int y) {}",
3452054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      functionDecl(decl().bind("x"), hasAnyParameter(hasName("y"))),
3453054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
3454054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3455054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "void x() { return; if (true) {} }",
3456054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      functionDecl(decl().bind("x"),
3457054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek                   has(compoundStmt(hasAnySubstatement(ifStmt())))),
3458054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
3459054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3460054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "namespace X { void b(int); void b(); }"
3461054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "using X::b;",
3462054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      usingDecl(decl().bind("x"), hasAnyUsingShadowDecl(hasTargetDecl(
3463054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek                                      functionDecl(parameterCountIs(1))))),
3464054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
3465054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3466054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "class A{}; class B{}; class C : B, A {};",
3467054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      recordDecl(decl().bind("x"), isDerivedFrom("::A")),
3468054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
3469054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3470054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "class A{}; typedef A B; typedef A C; typedef A D;"
3471054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "class E : A {};",
3472054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      recordDecl(decl().bind("x"), isDerivedFrom("C")),
3473054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
3474054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3475054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "class A { class B { void f() {} }; };",
3476054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      functionDecl(decl().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
3477054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
3478054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3479054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "template <typename T> struct A { struct B {"
3480054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "  void f() { if(true) {} }"
3481054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "}; };"
3482054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "void t() { A<int>::B b; b.f(); }",
3483054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      ifStmt(stmt().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
3484054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Stmt>("x", 2)));
3485054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3486054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      "class A {};",
3487054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      recordDecl(hasName("::A"), decl().bind("x"), unless(hasName("fooble"))),
3488054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
348906963013d1972f1f7a58875bb40976b60522700bManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
349006963013d1972f1f7a58875bb40976b60522700bManuel Klimek      "class A { A() : s(), i(42) {} const char *s; int i; };",
349106963013d1972f1f7a58875bb40976b60522700bManuel Klimek      constructorDecl(hasName("::A::A"), decl().bind("x"),
349206963013d1972f1f7a58875bb40976b60522700bManuel Klimek                      forEachConstructorInitializer(forField(hasName("i")))),
349306963013d1972f1f7a58875bb40976b60522700bManuel Klimek      new VerifyIdIsBoundTo<Decl>("x", 1)));
3494054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek}
3495054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek
349611c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel JasperTEST(ForEachDescendant, BindsCorrectNodes) {
349711c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
349811c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      "class C { void f(); int i; };",
349911c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
350011c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("decl", 1)));
350111c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
350211c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      "class C { void f() {} int i; };",
350311c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
350411c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      new VerifyIdIsBoundTo<FunctionDecl>("decl", 1)));
350511c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper}
350611c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper
3507152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel KlimekTEST(FindAll, BindsNodeOnMatch) {
3508152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3509152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      "class A {};",
3510152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      recordDecl(hasName("::A"), findAll(recordDecl(hasName("::A")).bind("v"))),
3511152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      new VerifyIdIsBoundTo<CXXRecordDecl>("v", 1)));
3512152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek}
3513152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek
3514152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel KlimekTEST(FindAll, BindsDescendantNodeOnMatch) {
3515152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3516152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      "class A { int a; int b; };",
3517152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      recordDecl(hasName("::A"), findAll(fieldDecl().bind("v"))),
3518152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      new VerifyIdIsBoundTo<FieldDecl>("v", 2)));
3519152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek}
3520152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek
3521152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel KlimekTEST(FindAll, BindsNodeAndDescendantNodesOnOneMatch) {
3522152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3523152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      "class A { int a; int b; };",
3524152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      recordDecl(hasName("::A"),
3525152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek                 findAll(decl(anyOf(recordDecl(hasName("::A")).bind("v"),
3526152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek                                    fieldDecl().bind("v"))))),
3527152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      new VerifyIdIsBoundTo<Decl>("v", 3)));
3528152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek
3529152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3530152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      "class A { class B {}; class C {}; };",
3531152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("v"))),
3532152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      new VerifyIdIsBoundTo<CXXRecordDecl>("v", 3)));
3533152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek}
3534152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek
35357387673f83b8b37f660422947c9990778ba88193Manuel KlimekTEST(EachOf, TriggersForEachMatch) {
35367387673f83b8b37f660422947c9990778ba88193Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
35377387673f83b8b37f660422947c9990778ba88193Manuel Klimek      "class A { int a; int b; };",
35387387673f83b8b37f660422947c9990778ba88193Manuel Klimek      recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
35397387673f83b8b37f660422947c9990778ba88193Manuel Klimek                        has(fieldDecl(hasName("b")).bind("v")))),
35407387673f83b8b37f660422947c9990778ba88193Manuel Klimek      new VerifyIdIsBoundTo<FieldDecl>("v", 2)));
35417387673f83b8b37f660422947c9990778ba88193Manuel Klimek}
35427387673f83b8b37f660422947c9990778ba88193Manuel Klimek
35437387673f83b8b37f660422947c9990778ba88193Manuel KlimekTEST(EachOf, BehavesLikeAnyOfUnlessBothMatch) {
35447387673f83b8b37f660422947c9990778ba88193Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
35457387673f83b8b37f660422947c9990778ba88193Manuel Klimek      "class A { int a; int c; };",
35467387673f83b8b37f660422947c9990778ba88193Manuel Klimek      recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
35477387673f83b8b37f660422947c9990778ba88193Manuel Klimek                        has(fieldDecl(hasName("b")).bind("v")))),
35487387673f83b8b37f660422947c9990778ba88193Manuel Klimek      new VerifyIdIsBoundTo<FieldDecl>("v", 1)));
35497387673f83b8b37f660422947c9990778ba88193Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
35507387673f83b8b37f660422947c9990778ba88193Manuel Klimek      "class A { int c; int b; };",
35517387673f83b8b37f660422947c9990778ba88193Manuel Klimek      recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
35527387673f83b8b37f660422947c9990778ba88193Manuel Klimek                        has(fieldDecl(hasName("b")).bind("v")))),
35537387673f83b8b37f660422947c9990778ba88193Manuel Klimek      new VerifyIdIsBoundTo<FieldDecl>("v", 1)));
35547387673f83b8b37f660422947c9990778ba88193Manuel Klimek  EXPECT_TRUE(notMatches(
35557387673f83b8b37f660422947c9990778ba88193Manuel Klimek      "class A { int c; int d; };",
35567387673f83b8b37f660422947c9990778ba88193Manuel Klimek      recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
35577387673f83b8b37f660422947c9990778ba88193Manuel Klimek                        has(fieldDecl(hasName("b")).bind("v"))))));
35587387673f83b8b37f660422947c9990778ba88193Manuel Klimek}
35594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
35604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) {
35614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Make sure that we can both match the class by name (::X) and by the type
35624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // the template was instantiated with (via a field).
35634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
35644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
35654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X {}; class A {}; X<A> x;",
35662dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("::X"), isTemplateInstantiation())));
35674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
35684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
35694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X { T t; }; class A {}; X<A> x;",
35702dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isTemplateInstantiation(), hasDescendant(
35712dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          fieldDecl(hasType(recordDecl(hasName("A"))))))));
35724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
35734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
35744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) {
35754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
35764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
35772dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionDecl(hasParameter(0, hasType(recordDecl(hasName("A")))),
35784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek               isTemplateInstantiation())));
35794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
35804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
35814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) {
35824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
35834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X { T t; }; class A {};"
35844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template class X<A>;",
35852dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isTemplateInstantiation(), hasDescendant(
35862dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          fieldDecl(hasType(recordDecl(hasName("A"))))))));
35874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
35884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
35894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation,
35904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek     MatchesInstantiationOfPartiallySpecializedClassTemplate) {
35914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
35924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X {};"
35934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
35942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("::X"), isTemplateInstantiation())));
35954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
35964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
35974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation,
35984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek     MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
35994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
36004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class A {};"
36014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X {"
36024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  template <typename U> class Y { U u; };"
36034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Y<A> y;"
36044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};",
36052dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("::X::Y"), isTemplateInstantiation())));
36064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
36074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
36084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) {
36094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // FIXME: Figure out whether this makes sense. It doesn't affect the
36104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // normal use case as long as the uppermost instantiation always is marked
36114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // as template instantiation, but it might be confusing as a predicate.
36124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
36134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class A {};"
36144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X {"
36154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  template <typename U> class Y { U u; };"
36164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Y<T> y;"
36174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "}; X<A> x;",
36182dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
36194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
36204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
36214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) {
36224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
36234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X {}; class A {};"
36244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <> class X<A> {}; X<A> x;",
36252dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("::X"), isTemplateInstantiation())));
36264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
36274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
36284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) {
36294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
36304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class A {}; class Y { A a; };",
36312dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isTemplateInstantiation())));
36324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
36334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
3634176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(IsInstantiated, MatchesInstantiation) {
3635176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(
3636176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      matches("template<typename T> class A { T i; }; class Y { A<int> a; };",
3637176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines              recordDecl(isInstantiated())));
3638176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
3639176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
3640176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(IsInstantiated, NotMatchesDefinition) {
3641176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("template<typename T> class A { T i; };",
3642176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                         recordDecl(isInstantiated())));
3643176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
3644176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
3645176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(IsInTemplateInstantiation, MatchesInstantiationStmt) {
3646176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches("template<typename T> struct A { A() { T i; } };"
3647176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      "class Y { A<int> a; }; Y y;",
3648176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                      declStmt(isInTemplateInstantiation())));
3649176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
3650176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
3651176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(IsInTemplateInstantiation, NotMatchesDefinitionStmt) {
3652176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("template<typename T> struct A { void x() { T i; } };",
3653176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                         declStmt(isInTemplateInstantiation())));
3654176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
3655176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
3656176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(IsInstantiated, MatchesFunctionInstantiation) {
3657176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(
3658176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
3659176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines              functionDecl(isInstantiated())));
3660176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
3661176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
3662176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(IsInstantiated, NotMatchesFunctionDefinition) {
3663176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
3664176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                         varDecl(isInstantiated())));
3665176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
3666176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
3667176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(IsInTemplateInstantiation, MatchesFunctionInstantiationStmt) {
3668176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(
3669176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
3670176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines              declStmt(isInTemplateInstantiation())));
3671176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
3672176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
3673176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(IsInTemplateInstantiation, NotMatchesFunctionDefinitionStmt) {
3674176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
3675176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                         declStmt(isInTemplateInstantiation())));
3676176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
3677176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
3678176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(IsInTemplateInstantiation, Sharing) {
3679176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  auto Matcher = binaryOperator(unless(isInTemplateInstantiation()));
3680176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // FIXME: Node sharing is an implementation detail, exposing it is ugly
3681176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // and makes the matcher behave in non-obvious ways.
3682176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(notMatches(
3683176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      "int j; template<typename T> void A(T t) { j += 42; } void x() { A(0); }",
3684176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      Matcher));
3685176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_TRUE(matches(
3686176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      "int j; template<typename T> void A(T t) { j += t; } void x() { A(0); }",
3687176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      Matcher));
3688176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
3689176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
36908456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(IsExplicitTemplateSpecialization,
36918456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko     DoesNotMatchPrimaryTemplate) {
36928456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
36938456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> class X {};",
36942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isExplicitTemplateSpecialization())));
36958456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
36968456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> void f(T t);",
36972dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionDecl(isExplicitTemplateSpecialization())));
36988456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
36998456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
37008456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(IsExplicitTemplateSpecialization,
37018456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko     DoesNotMatchExplicitTemplateInstantiations) {
37028456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
37038456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> class X {};"
37048456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template class X<int>; extern template class X<long>;",
37052dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isExplicitTemplateSpecialization())));
37068456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
37078456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> void f(T t) {}"
37088456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template void f(int t); extern template void f(long t);",
37092dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionDecl(isExplicitTemplateSpecialization())));
37108456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
37118456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
37128456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(IsExplicitTemplateSpecialization,
37138456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko     DoesNotMatchImplicitTemplateInstantiations) {
37148456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
37158456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> class X {}; X<int> x;",
37162dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isExplicitTemplateSpecialization())));
37178456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
37188456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> void f(T t); void g() { f(10); }",
37192dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionDecl(isExplicitTemplateSpecialization())));
37208456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
37218456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
37228456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(IsExplicitTemplateSpecialization,
37238456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko     MatchesExplicitTemplateSpecializations) {
37248456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(matches(
37258456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> class X {};"
37268456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template<> class X<int> {};",
37272dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isExplicitTemplateSpecialization())));
37288456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(matches(
37298456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> void f(T t) {}"
37308456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template<> void f(int t) {}",
37312dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionDecl(isExplicitTemplateSpecialization())));
37328456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
37338456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
3734579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncenstor, MatchesDeclarationAncestors) {
3735579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
3736579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "class A { class B { class C {}; }; };",
3737579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("A"))))));
3738579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3739579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3740579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncenstor, FailsIfNoAncestorMatches) {
3741579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(notMatches(
3742579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "class A { class B { class C {}; }; };",
3743579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("X"))))));
3744579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3745579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3746579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, MatchesDeclarationsThatGetVisitedLater) {
3747579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
3748579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "class A { class B { void f() { C c; } class C {}; }; };",
3749579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      varDecl(hasName("c"), hasType(recordDecl(hasName("C"),
3750579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek          hasAncestor(recordDecl(hasName("A"))))))));
3751579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3752579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3753579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncenstor, MatchesStatementAncestors) {
3754579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
3755579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "void f() { if (true) { while (false) { 42; } } }",
37563680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      integerLiteral(equals(42), hasAncestor(ifStmt()))));
3757579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3758579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3759579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, DrillsThroughDifferentHierarchies) {
3760579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
3761579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "void f() { if (true) { int x = 42; } }",
37623680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      integerLiteral(equals(42), hasAncestor(functionDecl(hasName("f"))))));
3763579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3764579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3765579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, BindsRecursiveCombinations) {
3766579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3767579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "class C { class D { class E { class F { int y; }; }; }; };",
3768579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      fieldDecl(hasAncestor(recordDecl(hasAncestor(recordDecl().bind("r"))))),
3769a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<CXXRecordDecl>("r", 1)));
3770579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3771579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3772579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, BindsCombinationsWithHasDescendant) {
3773579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3774579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "class C { class D { class E { class F { int y; }; }; }; };",
3775579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      fieldDecl(hasAncestor(
3776579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek          decl(
3777579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek            hasDescendant(recordDecl(isDefinition(),
3778579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek                                     hasAncestor(recordDecl())))
3779579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek          ).bind("d")
3780579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      )),
3781a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<CXXRecordDecl>("d", "E")));
3782579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3783579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3784374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel KlimekTEST(HasAncestor, MatchesClosestAncestor) {
3785374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3786374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      "template <typename T> struct C {"
3787374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      "  void f(int) {"
3788374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      "    struct I { void g(T) { int x; } } i; i.g(42);"
3789374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      "  }"
3790374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      "};"
3791374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      "template struct C<int>;",
3792374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      varDecl(hasName("x"),
3793374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek              hasAncestor(functionDecl(hasParameter(
3794374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek                  0, varDecl(hasType(asString("int"))))).bind("f"))).bind("v"),
3795374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      new VerifyIdIsBoundTo<FunctionDecl>("f", "g", 2)));
3796374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek}
3797374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek
3798579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, MatchesInTemplateInstantiations) {
3799579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
3800579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "template <typename T> struct A { struct B { struct C { T t; }; }; }; "
3801579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "A<int>::B::C a;",
3802579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      fieldDecl(hasType(asString("int")),
3803579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek                hasAncestor(recordDecl(hasName("A"))))));
3804579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3805579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3806579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, MatchesInImplicitCode) {
3807579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
3808579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "struct X {}; struct A { A() {} X x; };",
3809579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      constructorDecl(
3810579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek          hasAnyConstructorInitializer(withInitializer(expr(
3811579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek              hasAncestor(recordDecl(hasName("A")))))))));
3812579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3813579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3814c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel JasperTEST(HasParent, MatchesOnlyParent) {
3815c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper  EXPECT_TRUE(matches(
3816c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      "void f() { if (true) { int x = 42; } }",
3817c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      compoundStmt(hasParent(ifStmt()))));
3818c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper  EXPECT_TRUE(notMatches(
3819c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      "void f() { for (;;) { int x = 42; } }",
3820c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      compoundStmt(hasParent(ifStmt()))));
3821c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper  EXPECT_TRUE(notMatches(
3822c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      "void f() { if (true) for (;;) { int x = 42; } }",
3823c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      compoundStmt(hasParent(ifStmt()))));
3824c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper}
3825c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper
382630ace3715015b4a9bc5fa538a6515481abed40f9Manuel KlimekTEST(HasAncestor, MatchesAllAncestors) {
382730ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek  EXPECT_TRUE(matches(
382830ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "template <typename T> struct C { static void f() { 42; } };"
382930ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "void t() { C<int>::f(); }",
383030ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      integerLiteral(
383130ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek          equals(42),
383230ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek          allOf(hasAncestor(recordDecl(isTemplateInstantiation())),
383330ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek                hasAncestor(recordDecl(unless(isTemplateInstantiation())))))));
383430ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek}
383530ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek
383630ace3715015b4a9bc5fa538a6515481abed40f9Manuel KlimekTEST(HasParent, MatchesAllParents) {
383730ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek  EXPECT_TRUE(matches(
383830ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "template <typename T> struct C { static void f() { 42; } };"
383930ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "void t() { C<int>::f(); }",
384030ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      integerLiteral(
384130ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek          equals(42),
384230ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek          hasParent(compoundStmt(hasParent(functionDecl(
384330ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek              hasParent(recordDecl(isTemplateInstantiation())))))))));
384430ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek  EXPECT_TRUE(matches(
384530ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "template <typename T> struct C { static void f() { 42; } };"
384630ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "void t() { C<int>::f(); }",
384730ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      integerLiteral(
384830ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek          equals(42),
384930ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek          hasParent(compoundStmt(hasParent(functionDecl(
385030ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek              hasParent(recordDecl(unless(isTemplateInstantiation()))))))))));
385130ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek  EXPECT_TRUE(matches(
385230ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "template <typename T> struct C { static void f() { 42; } };"
385330ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "void t() { C<int>::f(); }",
385430ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      integerLiteral(equals(42),
385530ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek                     hasParent(compoundStmt(allOf(
385630ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek                         hasParent(functionDecl(
385730ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek                             hasParent(recordDecl(isTemplateInstantiation())))),
385830ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek                         hasParent(functionDecl(hasParent(recordDecl(
385930ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek                             unless(isTemplateInstantiation())))))))))));
3860374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek  EXPECT_TRUE(
3861374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      notMatches("template <typename T> struct C { static void f() {} };"
3862374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek                 "void t() { C<int>::f(); }",
3863374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek                 compoundStmt(hasParent(recordDecl()))));
386430ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek}
386530ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek
3866c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen HinesTEST(HasParent, NoDuplicateParents) {
3867c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  class HasDuplicateParents : public BoundNodesCallback {
3868c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  public:
3869c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    bool run(const BoundNodes *Nodes) override { return false; }
3870c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    bool run(const BoundNodes *Nodes, ASTContext *Context) override {
3871c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      const Stmt *Node = Nodes->getNodeAs<Stmt>("node");
3872c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      std::set<const void *> Parents;
3873c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      for (const auto &Parent : Context->getParents(*Node)) {
3874c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines        if (!Parents.insert(Parent.getMemoizationData()).second) {
3875c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines          return true;
3876c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines        }
3877c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      }
3878c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      return false;
3879c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    }
3880c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  };
3881c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  EXPECT_FALSE(matchAndVerifyResultTrue(
3882c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      "template <typename T> int Foo() { return 1 + 2; }\n"
3883c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      "int x = Foo<int>() + Foo<unsigned>();",
3884c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      stmt().bind("node"), new HasDuplicateParents()));
3885c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines}
3886c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
3887ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesTypes) {
3888ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("struct S {};", qualType().bind("loc")));
3889ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3890ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
38910e2c34f92f00628d48968dfea096d36381f494cbStephen HinesTEST(TypeMatching, MatchesVoid) {
38920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(
38930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      matches("struct S { void func(); };", methodDecl(returns(voidType()))));
38940e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
38950e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
3896ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesArrayTypes) {
3897ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[] = {2,3};", arrayType()));
3898ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[42];", arrayType()));
3899ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("void f(int b) { int a[b]; }", arrayType()));
3900ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3901ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches("struct A {}; A a[7];",
3902ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                         arrayType(hasElementType(builtinType()))));
3903ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3904ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3905ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int const a[] = { 2, 3 };",
3906ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(arrayType(hasElementType(builtinType())))));
3907ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3908ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int const a[] = { 2, 3 };",
3909ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
3910ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3911ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "typedef const int T; T x[] = { 1, 2 };",
3912ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(isConstQualified(), arrayType())));
3913ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3914ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
3915ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int a[] = { 2, 3 };",
3916ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
3917ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
3918ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int a[] = { 2, 3 };",
3919ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(arrayType(hasElementType(isConstQualified(), builtinType())))));
3920ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
3921ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int const a[] = { 2, 3 };",
3922ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(arrayType(hasElementType(builtinType())),
3923ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper               unless(isConstQualified()))));
3924ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3925ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[2];",
3926ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                      constantArrayType(hasElementType(builtinType()))));
3927ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("const int a = 0;", qualType(isInteger())));
3928ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3929ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3930ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesComplexTypes) {
3931ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("_Complex float f;", complexType()));
3932ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3933ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "_Complex float f;",
3934ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    complexType(hasElementType(builtinType()))));
3935ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
3936ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "_Complex float f;",
3937ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    complexType(hasElementType(isInteger()))));
3938ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3939ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3940ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesConstantArrayTypes) {
3941ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[2];", constantArrayType()));
3942ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
3943ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "void f() { int a[] = { 2, 3 }; int b[a[0]]; }",
3944ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    constantArrayType(hasElementType(builtinType()))));
3945ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3946ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[42];", constantArrayType(hasSize(42))));
3947ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int b[2*21];", constantArrayType(hasSize(42))));
3948ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches("int c[41], d[43];", constantArrayType(hasSize(42))));
3949ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3950ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3951ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesDependentSizedArrayTypes) {
3952ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3953ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "template <typename T, int Size> class array { T data[Size]; };",
3954ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    dependentSizedArrayType()));
3955ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
3956ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "int a[42]; int b[] = { 2, 3 }; void f() { int c[b[0]]; }",
3957ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    dependentSizedArrayType()));
3958ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3959ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3960ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesIncompleteArrayType) {
3961ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[] = { 2, 3 };", incompleteArrayType()));
3962ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("void f(int a[]) {}", incompleteArrayType()));
3963ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3964ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches("int a[42]; void f() { int b[a[0]]; }",
3965ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                         incompleteArrayType()));
3966ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3967ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3968ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesVariableArrayType) {
3969ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("void f(int b) { int a[b]; }", variableArrayType()));
3970ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches("int a[] = {2, 3}; int b[42];", variableArrayType()));
3971ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3972ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3973ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "void f(int b) { int a[b]; }",
3974ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    variableArrayType(hasSizeExpr(ignoringImpCasts(declRefExpr(to(
3975ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      varDecl(hasName("b")))))))));
3976ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3977ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3978ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesAtomicTypes) {
3979651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getOS() !=
3980651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      llvm::Triple::Win32) {
3981651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // FIXME: Make this work for MSVC.
3982651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    EXPECT_TRUE(matches("_Atomic(int) i;", atomicType()));
3983651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3984651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    EXPECT_TRUE(matches("_Atomic(int) i;",
3985651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                        atomicType(hasValueType(isInteger()))));
3986651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    EXPECT_TRUE(notMatches("_Atomic(float) f;",
3987651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                           atomicType(hasValueType(isInteger()))));
3988651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
3989ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3990ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3991ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesAutoTypes) {
3992ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("auto i = 2;", autoType()));
3993ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int v[] = { 2, 3 }; void f() { for (int i : v) {} }",
3994ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                      autoType()));
3995ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
39969b1317531d376738fd6631291b0a04109c76a63bRichard Smith  // FIXME: Matching against the type-as-written can't work here, because the
39979b1317531d376738fd6631291b0a04109c76a63bRichard Smith  //        type as written was not deduced.
39989b1317531d376738fd6631291b0a04109c76a63bRichard Smith  //EXPECT_TRUE(matches("auto a = 1;",
39999b1317531d376738fd6631291b0a04109c76a63bRichard Smith  //                    autoType(hasDeducedType(isInteger()))));
40009b1317531d376738fd6631291b0a04109c76a63bRichard Smith  //EXPECT_TRUE(notMatches("auto b = 2.0;",
40019b1317531d376738fd6631291b0a04109c76a63bRichard Smith  //                       autoType(hasDeducedType(isInteger()))));
4002ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
4003ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4004a267cf6f87dc695143d65fc61ec1744564f55932Daniel JasperTEST(TypeMatching, MatchesFunctionTypes) {
4005a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("int (*f)(int);", functionType()));
4006a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f(int i) {}", functionType()));
4007a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper}
4008a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
400988be2fdec7a1375bc729a6499629532e7872f11aEdwin VaneTEST(TypeMatching, MatchesParenType) {
401088be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane  EXPECT_TRUE(
401188be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane      matches("int (*array)[4];", varDecl(hasType(pointsTo(parenType())))));
401288be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane  EXPECT_TRUE(notMatches("int *array[4];", varDecl(hasType(parenType()))));
401388be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane
401488be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane  EXPECT_TRUE(matches(
401588be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane      "int (*ptr_to_func)(int);",
401688be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane      varDecl(hasType(pointsTo(parenType(innerType(functionType())))))));
401788be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane  EXPECT_TRUE(notMatches(
401888be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane      "int (*ptr_to_array)[4];",
401988be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane      varDecl(hasType(pointsTo(parenType(innerType(functionType())))))));
402088be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane}
402188be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane
4022ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, PointerTypes) {
40231802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  // FIXME: Reactive when these tests can be more specific (not matching
40241802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  // implicit code on certain platforms), likely when we have hasDescendant for
40251802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  // Types/TypeLocs.
40261802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //EXPECT_TRUE(matchAndVerifyResultTrue(
40271802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    "int* a;",
40281802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    pointerTypeLoc(pointeeLoc(typeLoc().bind("loc"))),
40291802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    new VerifyIdIsBoundTo<TypeLoc>("loc", 1)));
40301802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //EXPECT_TRUE(matchAndVerifyResultTrue(
40311802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    "int* a;",
40321802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    pointerTypeLoc().bind("loc"),
40331802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    new VerifyIdIsBoundTo<TypeLoc>("loc", 1)));
4034ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
4035ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int** a;",
40365be093c0ef46c7749c942d0d9056af6dc3d591a4David Blaikie      loc(pointerType(pointee(qualType())))));
4037ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
4038ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int** a;",
4039ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      loc(pointerType(pointee(pointerType())))));
4040ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
4041ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int* b; int* * const a = &b;",
4042ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      loc(qualType(isConstQualified(), pointerType()))));
4043ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4044ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  std::string Fragment = "struct A { int i; }; int A::* ptr = &A::i;";
40451802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
40461802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(blockPointerType()))));
40471802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(matches(Fragment, varDecl(hasName("ptr"),
40481802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                        hasType(memberPointerType()))));
40491802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
40501802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(pointerType()))));
40511802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
40521802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(referenceType()))));
4053f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4054f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(lValueReferenceType()))));
4055f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4056f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(rValueReferenceType()))));
40571802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper
40581802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  Fragment = "int *ptr;";
40591802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
40601802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(blockPointerType()))));
40611802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
40621802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(memberPointerType()))));
40631802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(matches(Fragment, varDecl(hasName("ptr"),
40641802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                        hasType(pointerType()))));
40651802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
40661802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(referenceType()))));
40671802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper
40681802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  Fragment = "int a; int &ref = a;";
40691802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
40701802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(blockPointerType()))));
40711802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
40721802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(memberPointerType()))));
40731802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
40741802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(pointerType()))));
40751802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
40761802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                        hasType(referenceType()))));
4077f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
4078f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(lValueReferenceType()))));
4079f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4080f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(rValueReferenceType()))));
4081f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane
4082f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  Fragment = "int &&ref = 2;";
4083f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4084f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(blockPointerType()))));
4085f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4086f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(memberPointerType()))));
4087f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4088f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(pointerType()))));
4089f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
4090f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(referenceType()))));
4091f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4092f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(lValueReferenceType()))));
4093f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
4094f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(rValueReferenceType()))));
4095f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane}
4096f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane
4097f4b48042724d2253d0426cadcb93e24eeb47e264Edwin VaneTEST(TypeMatching, AutoRefTypes) {
4098f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  std::string Fragment = "auto a = 1;"
4099f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                         "auto b = a;"
4100f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                         "auto &c = a;"
4101f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                         "auto &&d = c;"
4102f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                         "auto &&e = 2;";
4103f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("a"),
4104f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(referenceType()))));
4105f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("b"),
4106f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(referenceType()))));
4107f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("c"),
4108f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(referenceType()))));
4109f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("c"),
4110f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(lValueReferenceType()))));
4111f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("c"),
4112f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(rValueReferenceType()))));
4113f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("d"),
4114f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(referenceType()))));
4115f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("d"),
4116f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(lValueReferenceType()))));
4117f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("d"),
4118f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(rValueReferenceType()))));
4119f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("e"),
4120f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(referenceType()))));
4121f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("e"),
4122f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(lValueReferenceType()))));
4123f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("e"),
4124f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(rValueReferenceType()))));
4125ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
4126ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4127ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, PointeeTypes) {
4128ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int b; int &a = b;",
4129ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                      referenceType(pointee(builtinType()))));
4130ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int *a;", pointerType(pointee(builtinType()))));
4131ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4132ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int *a;",
41335be093c0ef46c7749c942d0d9056af6dc3d591a4David Blaikie                      loc(pointerType(pointee(builtinType())))));
4134ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4135ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
4136ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int const *A;",
4137ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      pointerType(pointee(isConstQualified(), builtinType()))));
4138ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
4139ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int *A;",
4140ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      pointerType(pointee(isConstQualified(), builtinType()))));
4141ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
4142ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4143ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesPointersToConstTypes) {
4144ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int b; int * const a = &b;",
4145ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                      loc(pointerType())));
4146ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int b; int * const a = &b;",
41475be093c0ef46c7749c942d0d9056af6dc3d591a4David Blaikie                      loc(pointerType())));
4148ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
4149ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int b; const int * a = &b;",
41505be093c0ef46c7749c942d0d9056af6dc3d591a4David Blaikie      loc(pointerType(pointee(builtinType())))));
4151ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
4152ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int b; const int * a = &b;",
4153ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      pointerType(pointee(builtinType()))));
4154ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
4155ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
4156ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesTypedefTypes) {
41571802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(matches("typedef int X; X a;", varDecl(hasName("a"),
41581802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                                     hasType(typedefType()))));
4159ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
4160ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
41613abf77872ca6c520903f9174cf6cd89a50df2714Edwin VaneTEST(TypeMatching, MatchesTemplateSpecializationType) {
4162742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(matches("template <typename T> class A{}; A<int> a;",
41633abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane                      templateSpecializationType()));
41643abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane}
41653abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane
4166742d9e77e32f014194679575c97c6bb4fd0998c4Edwin VaneTEST(TypeMatching, MatchesRecordType) {
4167742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(matches("class C{}; C c;", recordType()));
41680cc798f29d489140dd81b558e9c052e9a83cce39Manuel Klimek  EXPECT_TRUE(matches("struct S{}; S s;",
41690cc798f29d489140dd81b558e9c052e9a83cce39Manuel Klimek                      recordType(hasDeclaration(recordDecl(hasName("S"))))));
41700cc798f29d489140dd81b558e9c052e9a83cce39Manuel Klimek  EXPECT_TRUE(notMatches("int i;",
41710cc798f29d489140dd81b558e9c052e9a83cce39Manuel Klimek                         recordType(hasDeclaration(recordDecl(hasName("S"))))));
4172742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane}
4173742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane
4174742d9e77e32f014194679575c97c6bb4fd0998c4Edwin VaneTEST(TypeMatching, MatchesElaboratedType) {
4175742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(matches(
4176742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "namespace N {"
4177742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  namespace M {"
4178742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "    class D {};"
4179742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  }"
4180742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "}"
4181742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "N::M::D d;", elaboratedType()));
4182742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(matches("class C {} c;", elaboratedType()));
4183742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(notMatches("class C {}; C c;", elaboratedType()));
4184742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane}
4185742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane
4186742d9e77e32f014194679575c97c6bb4fd0998c4Edwin VaneTEST(ElaboratedTypeNarrowing, hasQualifier) {
4187742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(matches(
4188742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "namespace N {"
4189742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  namespace M {"
4190742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "    class D {};"
4191742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  }"
4192742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "}"
4193742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "N::M::D d;",
4194742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
4195742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(notMatches(
4196742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "namespace M {"
4197742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  class D {};"
4198742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "}"
4199742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "M::D d;",
4200742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
4201aec89ac22e1876bb1cfff9062c882a622bc84510Edwin Vane  EXPECT_TRUE(notMatches(
4202aec89ac22e1876bb1cfff9062c882a622bc84510Edwin Vane    "struct D {"
4203aec89ac22e1876bb1cfff9062c882a622bc84510Edwin Vane    "} d;",
4204aec89ac22e1876bb1cfff9062c882a622bc84510Edwin Vane    elaboratedType(hasQualifier(nestedNameSpecifier()))));
4205742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane}
4206742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane
4207742d9e77e32f014194679575c97c6bb4fd0998c4Edwin VaneTEST(ElaboratedTypeNarrowing, namesType) {
4208742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(matches(
4209742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "namespace N {"
4210742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  namespace M {"
4211742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "    class D {};"
4212742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  }"
4213742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "}"
4214742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "N::M::D d;",
4215742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    elaboratedType(elaboratedType(namesType(recordType(
4216742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane        hasDeclaration(namedDecl(hasName("D")))))))));
4217742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(notMatches(
4218742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "namespace M {"
4219742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  class D {};"
4220742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "}"
4221742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "M::D d;",
4222742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    elaboratedType(elaboratedType(namesType(typedefType())))));
4223742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane}
4224742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane
4225a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, MatchesNestedNameSpecifiers) {
4226a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;",
4227a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper                      nestedNameSpecifier()));
4228a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("template <typename T> class A { typename T::B b; };",
4229a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper                      nestedNameSpecifier()));
4230a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("struct A { void f(); }; void A::f() {}",
4231a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper                      nestedNameSpecifier()));
4232a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
4233a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches(
4234a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    "struct A { static void f() {} }; void g() { A::f(); }",
4235a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    nestedNameSpecifier()));
4236a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(notMatches(
4237a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    "struct A { static void f() {} }; void g(A* a) { a->f(); }",
4238a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    nestedNameSpecifier()));
4239a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
4240a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
4241b54b7646b2d00a85d80e40adf7c49553f150c736Daniel JasperTEST(NullStatement, SimpleCases) {
4242b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() {int i;;}", nullStmt()));
4243b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(notMatches("void f() {int i;}", nullStmt()));
4244b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper}
4245b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper
4246a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, MatchesTypes) {
4247a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  NestedNameSpecifierMatcher Matcher = nestedNameSpecifier(
4248a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    specifiesType(hasDeclaration(recordDecl(hasName("A")))));
4249a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("struct A { struct B {}; }; A::B b;", Matcher));
4250a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("struct A { struct B { struct C {}; }; }; A::B::C c;",
4251a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper                      Matcher));
4252a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(notMatches("namespace A { struct B {}; } A::B b;", Matcher));
4253a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
4254a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
4255a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, MatchesNamespaceDecls) {
4256a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  NestedNameSpecifierMatcher Matcher = nestedNameSpecifier(
4257a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    specifiesNamespace(hasName("ns")));
4258a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;", Matcher));
4259a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(notMatches("namespace xx { struct A {}; } xx::A a;", Matcher));
4260a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(notMatches("struct ns { struct A {}; }; ns::A a;", Matcher));
4261a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
4262a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
4263a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, BindsNestedNameSpecifiers) {
4264a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
4265a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      "namespace ns { struct E { struct B {}; }; } ns::E::B b;",
4266a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      nestedNameSpecifier(specifiesType(asString("struct ns::E"))).bind("nns"),
4267a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifier>("nns", "ns::struct E::")));
4268a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
4269a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
4270a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, BindsNestedNameSpecifierLocs) {
4271a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
4272a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      "namespace ns { struct B {}; } ns::B b;",
4273a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      loc(nestedNameSpecifier()).bind("loc"),
4274a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("loc", 1)));
4275a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
4276a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
4277a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, MatchesNestedNameSpecifierPrefixes) {
4278a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches(
4279a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      "struct A { struct B { struct C {}; }; }; A::B::C c;",
4280a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      nestedNameSpecifier(hasPrefix(specifiesType(asString("struct A"))))));
4281a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches(
4282a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      "struct A { struct B { struct C {}; }; }; A::B::C c;",
4283ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      nestedNameSpecifierLoc(hasPrefix(
4284ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper          specifiesTypeLoc(loc(qualType(asString("struct A"))))))));
4285a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
4286a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
4287d1ce3c178b9c648687591b190e0d252124fc2459Daniel JasperTEST(NNS, DescendantsOfNestedNameSpecifiers) {
4288d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  std::string Fragment =
4289d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "namespace a { struct A { struct B { struct C {}; }; }; };"
4290d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "void f() { a::A::B::C c; }";
4291d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
4292d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4293d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
4294d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                          hasDescendant(nestedNameSpecifier(
4295d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                              specifiesNamespace(hasName("a")))))));
4296d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(notMatches(
4297d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4298d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
4299d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                          has(nestedNameSpecifier(
4300d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                              specifiesNamespace(hasName("a")))))));
4301d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
4302d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4303d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifier(specifiesType(asString("struct a::A")),
4304d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                          has(nestedNameSpecifier(
4305d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                              specifiesNamespace(hasName("a")))))));
4306d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
4307d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  // Not really useful because a NestedNameSpecifier can af at most one child,
4308d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  // but to complete the interface.
4309d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
4310d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4311d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
4312d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                          forEach(nestedNameSpecifier().bind("x"))),
4313d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifier>("x", 1)));
4314d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper}
4315d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
4316d1ce3c178b9c648687591b190e0d252124fc2459Daniel JasperTEST(NNS, NestedNameSpecifiersAsDescendants) {
4317d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  std::string Fragment =
4318d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "namespace a { struct A { struct B { struct C {}; }; }; };"
4319d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "void f() { a::A::B::C c; }";
4320d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
4321d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4322d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      decl(hasDescendant(nestedNameSpecifier(specifiesType(
4323d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper          asString("struct a::A")))))));
4324d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
4325d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4326d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      functionDecl(hasName("f"),
4327d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                   forEachDescendant(nestedNameSpecifier().bind("x"))),
4328d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      // Nested names: a, a::A and a::A::B.
4329d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifier>("x", 3)));
4330d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper}
4331d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
4332d1ce3c178b9c648687591b190e0d252124fc2459Daniel JasperTEST(NNSLoc, DescendantsOfNestedNameSpecifierLocs) {
4333d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  std::string Fragment =
4334d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "namespace a { struct A { struct B { struct C {}; }; }; };"
4335d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "void f() { a::A::B::C c; }";
4336d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
4337d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4338d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
4339d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                             hasDescendant(loc(nestedNameSpecifier(
4340d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                                 specifiesNamespace(hasName("a"))))))));
4341d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(notMatches(
4342d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4343d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
4344d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                             has(loc(nestedNameSpecifier(
4345d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                                 specifiesNamespace(hasName("a"))))))));
4346d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
4347d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4348d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A"))),
4349d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                             has(loc(nestedNameSpecifier(
4350d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                                 specifiesNamespace(hasName("a"))))))));
4351d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
4352d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
4353d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4354d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
4355d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                             forEach(nestedNameSpecifierLoc().bind("x"))),
4356d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("x", 1)));
4357d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper}
4358d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
4359d1ce3c178b9c648687591b190e0d252124fc2459Daniel JasperTEST(NNSLoc, NestedNameSpecifierLocsAsDescendants) {
4360d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  std::string Fragment =
4361d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "namespace a { struct A { struct B { struct C {}; }; }; };"
4362d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "void f() { a::A::B::C c; }";
4363d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
4364d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4365d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      decl(hasDescendant(loc(nestedNameSpecifier(specifiesType(
4366d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper          asString("struct a::A"))))))));
4367d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
4368d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
4369d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      functionDecl(hasName("f"),
4370d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                   forEachDescendant(nestedNameSpecifierLoc().bind("x"))),
4371d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      // Nested names: a, a::A and a::A::B.
4372d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("x", 3)));
4373d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper}
4374d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
437560969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimektemplate <typename T> class VerifyMatchOnNode : public BoundNodesCallback {
43763e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimekpublic:
4377cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek  VerifyMatchOnNode(StringRef Id, const internal::Matcher<T> &InnerMatcher,
4378cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek                    StringRef InnerId)
4379cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek      : Id(Id), InnerMatcher(InnerMatcher), InnerId(InnerId) {
4380452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper  }
4381452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper
438233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  bool run(const BoundNodes *Nodes) override { return false; }
438360969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek
438433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  bool run(const BoundNodes *Nodes, ASTContext *Context) override {
43853e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek    const T *Node = Nodes->getNodeAs<T>(Id);
4386176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return selectFirst<T>(InnerId, match(InnerMatcher, *Node, *Context)) !=
4387176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines           nullptr;
43883e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek  }
43893e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimekprivate:
43903e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek  std::string Id;
43913e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek  internal::Matcher<T> InnerMatcher;
4392cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek  std::string InnerId;
43933e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek};
43943e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek
43953e2aa99e992b89bd421ac2a6bf79307114d257fcManuel KlimekTEST(MatchFinder, CanMatchDeclarationsRecursively) {
439660969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
439760969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
439860969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      new VerifyMatchOnNode<clang::Decl>(
4399cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "X", decl(hasDescendant(recordDecl(hasName("X::Y")).bind("Y"))),
4400cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "Y")));
440160969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse(
440260969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
440360969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      new VerifyMatchOnNode<clang::Decl>(
4404cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "X", decl(hasDescendant(recordDecl(hasName("X::Z")).bind("Z"))),
4405cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "Z")));
44063e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek}
44073e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek
44083e2aa99e992b89bd421ac2a6bf79307114d257fcManuel KlimekTEST(MatchFinder, CanMatchStatementsRecursively) {
440960969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
441060969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
4411cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek      new VerifyMatchOnNode<clang::Stmt>(
4412cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "if", stmt(hasDescendant(forStmt().bind("for"))), "for")));
441360969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse(
441460969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
4415cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek      new VerifyMatchOnNode<clang::Stmt>(
4416cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "if", stmt(hasDescendant(declStmt().bind("decl"))), "decl")));
441760969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek}
441860969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek
441960969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel KlimekTEST(MatchFinder, CanMatchSingleNodesRecursively) {
442060969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
442160969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
442260969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      new VerifyMatchOnNode<clang::Decl>(
4423cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "X", recordDecl(has(recordDecl(hasName("X::Y")).bind("Y"))), "Y")));
442460969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse(
442560969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
442660969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      new VerifyMatchOnNode<clang::Decl>(
4427cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "X", recordDecl(has(recordDecl(hasName("X::Z")).bind("Z"))), "Z")));
44283e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek}
44293e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek
4430fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimektemplate <typename T>
4431fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimekclass VerifyAncestorHasChildIsEqual : public BoundNodesCallback {
4432fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimekpublic:
443333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  bool run(const BoundNodes *Nodes) override { return false; }
4434fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek
443533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  bool run(const BoundNodes *Nodes, ASTContext *Context) override {
4436fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek    const T *Node = Nodes->getNodeAs<T>("");
4437fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek    return verify(*Nodes, *Context, Node);
4438fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek  }
4439fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek
4440fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek  bool verify(const BoundNodes &Nodes, ASTContext &Context, const Stmt *Node) {
44416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // Use the original typed pointer to verify we can pass pointers to subtypes
44426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // to equalsNode.
44436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    const T *TypedNode = cast<T>(Node);
4444176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return selectFirst<T>(
44456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines               "", match(stmt(hasParent(
44466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                             stmt(has(stmt(equalsNode(TypedNode)))).bind(""))),
4447c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                         *Node, Context)) != nullptr;
4448fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek  }
4449fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek  bool verify(const BoundNodes &Nodes, ASTContext &Context, const Decl *Node) {
44506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // Use the original typed pointer to verify we can pass pointers to subtypes
44516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // to equalsNode.
44526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    const T *TypedNode = cast<T>(Node);
4453176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return selectFirst<T>(
44546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines               "", match(decl(hasParent(
44556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                             decl(has(decl(equalsNode(TypedNode)))).bind(""))),
4456c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                         *Node, Context)) != nullptr;
4457fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek  }
4458fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek};
4459fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek
4460fa37c5ca61af275a329386407e58cf70f4d9f596Manuel KlimekTEST(IsEqualTo, MatchesNodesByIdentity) {
4461fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
4462fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek      "class X { class Y {}; };", recordDecl(hasName("::X::Y")).bind(""),
44636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      new VerifyAncestorHasChildIsEqual<CXXRecordDecl>()));
44646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  EXPECT_TRUE(matchAndVerifyResultTrue(
44656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      "void f() { if (true) if(true) {} }", ifStmt().bind(""),
44666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      new VerifyAncestorHasChildIsEqual<IfStmt>()));
4467fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek}
4468fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek
4469176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(MatchFinder, CheckProfiling) {
4470176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  MatchFinder::MatchFinderOptions Options;
4471176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  llvm::StringMap<llvm::TimeRecord> Records;
4472176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Options.CheckProfiling.emplace(Records);
4473176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  MatchFinder Finder(std::move(Options));
4474176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4475176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  struct NamedCallback : public MatchFinder::MatchCallback {
4476176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    void run(const MatchFinder::MatchResult &Result) override {}
4477176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    StringRef getID() const override { return "MyID"; }
4478176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  } Callback;
4479176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Finder.addMatcher(decl(), &Callback);
4480176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  std::unique_ptr<FrontendActionFactory> Factory(
4481176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      newFrontendActionFactory(&Finder));
4482176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
4483176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4484176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_EQ(1u, Records.size());
4485176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  EXPECT_EQ("MyID", Records.begin()->getKey());
4486176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
4487176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4488e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimekclass VerifyStartOfTranslationUnit : public MatchFinder::MatchCallback {
4489e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimekpublic:
4490e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  VerifyStartOfTranslationUnit() : Called(false) {}
449133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  void run(const MatchFinder::MatchResult &Result) override {
4492e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek    EXPECT_TRUE(Called);
4493e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  }
449433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  void onStartOfTranslationUnit() override { Called = true; }
4495e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  bool Called;
4496e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek};
4497e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek
4498e579328ec9a95acc7f181e04c58a747ba001d80fManuel KlimekTEST(MatchFinder, InterceptsStartOfTranslationUnit) {
4499e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  MatchFinder Finder;
4500e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  VerifyStartOfTranslationUnit VerifyCallback;
4501e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  Finder.addMatcher(decl(), &VerifyCallback);
4502651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<FrontendActionFactory> Factory(
4503651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      newFrontendActionFactory(&Finder));
4504e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
4505e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  EXPECT_TRUE(VerifyCallback.Called);
450651fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne
450751fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne  VerifyCallback.Called = false;
4508651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<ASTUnit> AST(tooling::buildASTFromCode("int x;"));
450951fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne  ASSERT_TRUE(AST.get());
451051fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne  Finder.matchAST(AST->getASTContext());
451151fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne  EXPECT_TRUE(VerifyCallback.Called);
4512e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek}
4513e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek
45148f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourneclass VerifyEndOfTranslationUnit : public MatchFinder::MatchCallback {
45158f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbournepublic:
45168f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne  VerifyEndOfTranslationUnit() : Called(false) {}
451733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  void run(const MatchFinder::MatchResult &Result) override {
45188f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne    EXPECT_FALSE(Called);
45198f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne  }
452033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  void onEndOfTranslationUnit() override { Called = true; }
45218f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne  bool Called;
45228f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne};
45238f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne
45248f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter CollingbourneTEST(MatchFinder, InterceptsEndOfTranslationUnit) {
45258f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne  MatchFinder Finder;
45268f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne  VerifyEndOfTranslationUnit VerifyCallback;
45278f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne  Finder.addMatcher(decl(), &VerifyCallback);
4528651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<FrontendActionFactory> Factory(
4529651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      newFrontendActionFactory(&Finder));
45308f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne  ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
45318f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne  EXPECT_TRUE(VerifyCallback.Called);
453251fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne
453351fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne  VerifyCallback.Called = false;
4534651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<ASTUnit> AST(tooling::buildASTFromCode("int x;"));
453551fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne  ASSERT_TRUE(AST.get());
453651fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne  Finder.matchAST(AST->getASTContext());
453751fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne  EXPECT_TRUE(VerifyCallback.Called);
45388f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne}
45398f9e590f78b1b05c36c2a14d68c4b9f9acbb891aPeter Collingbourne
4540cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel KlimekTEST(EqualsBoundNodeMatcher, QualType) {
4541cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek  EXPECT_TRUE(matches(
4542cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "int i = 1;", varDecl(hasType(qualType().bind("type")),
4543cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                            hasInitializer(ignoringParenImpCasts(
4544cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                                hasType(qualType(equalsBoundNode("type"))))))));
4545cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek  EXPECT_TRUE(notMatches("int i = 1.f;",
4546cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                         varDecl(hasType(qualType().bind("type")),
4547cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                                 hasInitializer(ignoringParenImpCasts(hasType(
4548cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                                     qualType(equalsBoundNode("type"))))))));
4549cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek}
4550cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek
4551cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel KlimekTEST(EqualsBoundNodeMatcher, NonMatchingTypes) {
4552cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek  EXPECT_TRUE(notMatches(
4553cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "int i = 1;", varDecl(namedDecl(hasName("i")).bind("name"),
4554cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                            hasInitializer(ignoringParenImpCasts(
4555cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                                hasType(qualType(equalsBoundNode("type"))))))));
4556cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek}
4557cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek
4558cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel KlimekTEST(EqualsBoundNodeMatcher, Stmt) {
4559cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek  EXPECT_TRUE(
4560cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      matches("void f() { if(true) {} }",
4561cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek              stmt(allOf(ifStmt().bind("if"),
4562cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                         hasParent(stmt(has(stmt(equalsBoundNode("if")))))))));
4563cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek
4564cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek  EXPECT_TRUE(notMatches(
4565cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "void f() { if(true) { if (true) {} } }",
4566cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      stmt(allOf(ifStmt().bind("if"), has(stmt(equalsBoundNode("if")))))));
4567cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek}
4568cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek
4569cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel KlimekTEST(EqualsBoundNodeMatcher, Decl) {
4570cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek  EXPECT_TRUE(matches(
4571cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "class X { class Y {}; };",
4572cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      decl(allOf(recordDecl(hasName("::X::Y")).bind("record"),
4573cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                 hasParent(decl(has(decl(equalsBoundNode("record")))))))));
4574cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek
4575cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek  EXPECT_TRUE(notMatches("class X { class Y {}; };",
4576cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                         decl(allOf(recordDecl(hasName("::X")).bind("record"),
4577cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                                    has(decl(equalsBoundNode("record")))))));
4578cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek}
4579cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek
4580cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel KlimekTEST(EqualsBoundNodeMatcher, Type) {
4581cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek  EXPECT_TRUE(matches(
4582cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "class X { int a; int b; };",
4583cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      recordDecl(
4584cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek          has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
4585cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek          has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
4586cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek
4587cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek  EXPECT_TRUE(notMatches(
4588cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "class X { int a; double b; };",
4589cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      recordDecl(
4590cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek          has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
4591cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek          has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
4592cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek}
4593cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek
4594cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel KlimekTEST(EqualsBoundNodeMatcher, UsingForEachDescendant) {
4595cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
4596cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "int f() {"
4597cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "  if (1) {"
4598cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "    int i = 9;"
4599cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "  }"
4600cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "  int j = 10;"
4601cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "  {"
4602cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "    float k = 9.0;"
4603cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "  }"
4604cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "  return 0;"
4605cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "}",
4606cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      // Look for variable declarations within functions whose type is the same
4607cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      // as the function return type.
4608cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      functionDecl(returns(qualType().bind("type")),
4609cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                   forEachDescendant(varDecl(hasType(
4610cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek                       qualType(equalsBoundNode("type")))).bind("decl"))),
4611cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      // Only i and j should match, not k.
4612cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      new VerifyIdIsBoundTo<VarDecl>("decl", 2)));
4613cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek}
4614cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek
4615cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel KlimekTEST(EqualsBoundNodeMatcher, FiltersMatchedCombinations) {
4616cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
4617cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "void f() {"
4618cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "  int x;"
4619cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "  double d;"
4620cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "  x = d + x - d + x;"
4621cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      "}",
4622cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      functionDecl(
4623cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek          hasName("f"), forEachDescendant(varDecl().bind("d")),
4624cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek          forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d")))))),
4625cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek      new VerifyIdIsBoundTo<VarDecl>("d", 5)));
4626cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek}
4627cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek
4628651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(EqualsBoundNodeMatcher, UnlessDescendantsOfAncestorsMatch) {
4629651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_TRUE(matchAndVerifyResultTrue(
4630651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "struct StringRef { int size() const; const char* data() const; };"
4631651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "void f(StringRef v) {"
4632651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "  v.data();"
4633651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "}",
4634651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      memberCallExpr(
4635651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          callee(methodDecl(hasName("data"))),
4636651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          on(declRefExpr(to(varDecl(hasType(recordDecl(hasName("StringRef"))))
4637651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                .bind("var")))),
4638651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          unless(hasAncestor(stmt(hasDescendant(memberCallExpr(
4639651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              callee(methodDecl(anyOf(hasName("size"), hasName("length")))),
4640651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
4641651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          .bind("data"),
4642651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      new VerifyIdIsBoundTo<Expr>("data", 1)));
4643651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4644651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  EXPECT_FALSE(matches(
4645651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "struct StringRef { int size() const; const char* data() const; };"
4646651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "void f(StringRef v) {"
4647651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "  v.data();"
4648651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "  v.size();"
4649651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "}",
4650651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      memberCallExpr(
4651651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          callee(methodDecl(hasName("data"))),
4652651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          on(declRefExpr(to(varDecl(hasType(recordDecl(hasName("StringRef"))))
4653651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                .bind("var")))),
4654651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          unless(hasAncestor(stmt(hasDescendant(memberCallExpr(
4655651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              callee(methodDecl(anyOf(hasName("size"), hasName("length")))),
4656651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
4657651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          .bind("data")));
4658651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
4659651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
46600e2c34f92f00628d48968dfea096d36381f494cbStephen HinesTEST(TypeDefDeclMatcher, Match) {
46610e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(matches("typedef int typedefDeclTest;",
46620e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                      typedefDecl(hasName("typedefDeclTest"))));
46630e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
46640e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
46650e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// FIXME: Figure out how to specify paths so the following tests pass on Windows.
46660e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#ifndef LLVM_ON_WIN32
46670e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
46680e2c34f92f00628d48968dfea096d36381f494cbStephen HinesTEST(Matcher, IsExpansionInMainFileMatcher) {
46690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(matches("class X {};",
46700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                      recordDecl(hasName("X"), isExpansionInMainFile())));
46710e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(notMatches("", recordDecl(isExpansionInMainFile())));
46720e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  FileContentMappings M;
46730e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  M.push_back(std::make_pair("/other", "class X {};"));
46740e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(matchesConditionally("#include <other>\n",
46750e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                   recordDecl(isExpansionInMainFile()), false,
46760e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                   "-isystem/", M));
46770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
46780e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
46790e2c34f92f00628d48968dfea096d36381f494cbStephen HinesTEST(Matcher, IsExpansionInSystemHeader) {
46800e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  FileContentMappings M;
46810e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  M.push_back(std::make_pair("/other", "class X {};"));
46820e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(matchesConditionally(
46830e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      "#include \"other\"\n", recordDecl(isExpansionInSystemHeader()), true,
46840e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      "-isystem/", M));
46850e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(matchesConditionally("#include \"other\"\n",
46860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                   recordDecl(isExpansionInSystemHeader()),
46870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                   false, "-I/", M));
46880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(notMatches("class X {};",
46890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                         recordDecl(isExpansionInSystemHeader())));
46900e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(notMatches("", recordDecl(isExpansionInSystemHeader())));
46910e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
46920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
46930e2c34f92f00628d48968dfea096d36381f494cbStephen HinesTEST(Matcher, IsExpansionInFileMatching) {
46940e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  FileContentMappings M;
46950e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  M.push_back(std::make_pair("/foo", "class A {};"));
46960e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  M.push_back(std::make_pair("/bar", "class B {};"));
46970e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(matchesConditionally(
46980e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      "#include <foo>\n"
46990e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      "#include <bar>\n"
47000e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      "class X {};",
47010e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      recordDecl(isExpansionInFileMatching("b.*"), hasName("B")), true,
47020e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      "-isystem/", M));
47030e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EXPECT_TRUE(matchesConditionally(
47040e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      "#include <foo>\n"
47050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      "#include <bar>\n"
47060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      "class X {};",
47070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      recordDecl(isExpansionInFileMatching("f.*"), hasName("X")), false,
47080e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      "-isystem/", M));
47090e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
47100e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
47110e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#endif // LLVM_ON_WIN32
47120e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
47133ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
47143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga NainarTEST(ObjCMessageExprMatcher, SimpleExprs) {
47153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // don't find ObjCMessageExpr where none are present
47163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  EXPECT_TRUE(notMatchesObjC("", objcMessageExpr(anything())));
47173ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
47183ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  std::string Objc1String =
47193ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  "@interface Str "
47203ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  " - (Str *)uppercaseString:(Str *)str;"
47213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  "@end "
47223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  "@interface foo "
47233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  "- (void)meth:(Str *)text;"
47243ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  "@end "
47253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  " "
47263ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  "@implementation foo "
47273ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  "- (void) meth:(Str *)text { "
47283ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  "  [self contents];"
47293ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  "  Str *up = [text uppercaseString];"
47303ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  "} "
47313ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  "@end ";
47323ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  EXPECT_TRUE(matchesObjC(
47333ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      Objc1String,
47343ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      objcMessageExpr(anything())));
47353ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  EXPECT_TRUE(matchesObjC(
47363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      Objc1String,
47373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      objcMessageExpr(hasSelector("contents"))));
47383ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  EXPECT_TRUE(matchesObjC(
47393ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      Objc1String,
47403ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      objcMessageExpr(matchesSelector("cont*"))));
47413ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  EXPECT_FALSE(matchesObjC(
47423ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      Objc1String,
47433ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      objcMessageExpr(matchesSelector("?cont*"))));
47443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  EXPECT_TRUE(notMatchesObjC(
47453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      Objc1String,
47463ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      objcMessageExpr(hasSelector("contents"), hasNullSelector())));
47473ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  EXPECT_TRUE(matchesObjC(
47483ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      Objc1String,
47493ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      objcMessageExpr(hasSelector("contents"), hasUnarySelector())));
47503ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  EXPECT_TRUE(matchesObjC(
47513ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      Objc1String,
47523ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      objcMessageExpr(matchesSelector("uppercase*"),
47533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                      argumentCountIs(0)
47543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                      )));
47553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
47563ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar}
47573ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
47584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek} // end namespace ast_matchers
47594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek} // end namespace clang
4760