ASTMatchersTest.cpp revision 88be2fdec7a1375bc729a6499629532e7872f11a
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"
154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#include "gtest/gtest.h"
164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimeknamespace clang {
184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimeknamespace ast_matchers {
194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2078a0ce4ed3d6cf3ad98e1b07fb1cd43b47793598Benjamin Kramer#if GTEST_HAS_DEATH_TEST
214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasNameDeathTest, DiesOnEmptyName) {
224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  ASSERT_DEBUG_DEATH({
232dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper    DeclarationMatcher HasEmptyName = recordDecl(hasName(""));
244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    EXPECT_TRUE(notMatches("class X {};", HasEmptyName));
254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  }, "");
264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(HasNameDeathTest, DiesOnEmptyPattern) {
29e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  ASSERT_DEBUG_DEATH({
302dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      DeclarationMatcher HasEmptyName = recordDecl(matchesName(""));
31e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      EXPECT_TRUE(notMatches("class X {};", HasEmptyName));
32e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper    }, "");
33e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
34e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsDerivedFromDeathTest, DiesOnEmptyBaseName) {
364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  ASSERT_DEBUG_DEATH({
372dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper    DeclarationMatcher IsDerivedFromEmpty = recordDecl(isDerivedFrom(""));
384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    EXPECT_TRUE(notMatches("class X {};", IsDerivedFromEmpty));
394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  }, "");
404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
4178a0ce4ed3d6cf3ad98e1b07fb1cd43b47793598Benjamin Kramer#endif
424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
43715c9568ee5d75f25dab98229c87bcec880daf5dManuel KlimekTEST(Decl, MatchesDeclarations) {
44715c9568ee5d75f25dab98229c87bcec880daf5dManuel Klimek  EXPECT_TRUE(notMatches("", decl(usingDecl())));
45715c9568ee5d75f25dab98229c87bcec880daf5dManuel Klimek  EXPECT_TRUE(matches("namespace x { class X {}; } using x::X;",
46715c9568ee5d75f25dab98229c87bcec880daf5dManuel Klimek                      decl(usingDecl())));
47715c9568ee5d75f25dab98229c87bcec880daf5dManuel Klimek}
48715c9568ee5d75f25dab98229c87bcec880daf5dManuel Klimek
494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(NameableDeclaration, MatchesVariousDecls) {
502dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher NamedX = namedDecl(hasName("X"));
514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("typedef int X;", NamedX));
524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int X;", NamedX));
534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class foo { virtual void X(); };", NamedX));
544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", NamedX));
554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void foo() { int X; }", NamedX));
564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("namespace X { }", NamedX));
57e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("enum X { A, B, C };", NamedX));
584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("#define X 1", NamedX));
604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
62e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(NameableDeclaration, REMatchesVariousDecls) {
632dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher NamedX = namedDecl(matchesName("::X"));
64e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("typedef int Xa;", NamedX));
65e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("int Xb;", NamedX));
66e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("class foo { virtual void Xc(); };", NamedX));
67e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("void foo() try { } catch(int Xdef) { }", NamedX));
68e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("void foo() { int Xgh; }", NamedX));
69e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("namespace Xij { }", NamedX));
70e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("enum X { A, B, C };", NamedX));
71e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
72e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("#define Xkl 1", NamedX));
73e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
742dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher StartsWithNo = namedDecl(matchesName("::no"));
75e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("int no_foo;", StartsWithNo));
76e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("class foo { virtual void nobody(); };", StartsWithNo));
77e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
782dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher Abc = namedDecl(matchesName("a.*b.*c"));
79e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("int abc;", Abc));
80e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("int aFOObBARc;", Abc));
81e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("int cab;", Abc));
82e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("int cabc;", Abc));
83ec33b6f64480df41a6add1f112c7321ba96de378Manuel Klimek
84ec33b6f64480df41a6add1f112c7321ba96de378Manuel Klimek  DeclarationMatcher StartsWithK = namedDecl(matchesName(":k[^:]*$"));
85ec33b6f64480df41a6add1f112c7321ba96de378Manuel Klimek  EXPECT_TRUE(matches("int k;", StartsWithK));
86ec33b6f64480df41a6add1f112c7321ba96de378Manuel Klimek  EXPECT_TRUE(matches("int kAbc;", StartsWithK));
87ec33b6f64480df41a6add1f112c7321ba96de378Manuel Klimek  EXPECT_TRUE(matches("namespace x { int kTest; }", StartsWithK));
88ec33b6f64480df41a6add1f112c7321ba96de378Manuel Klimek  EXPECT_TRUE(matches("class C { int k; };", StartsWithK));
89ec33b6f64480df41a6add1f112c7321ba96de378Manuel Klimek  EXPECT_TRUE(notMatches("class C { int ckc; };", StartsWithK));
90e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
91e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, MatchClass) {
932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ClassMatcher(recordDecl());
94e265c877934dd24d11d85e991ede7d0742178495Manuel Klimek#if !defined(_MSC_VER)
954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_FALSE(matches("", ClassMatcher));
96e265c877934dd24d11d85e991ede7d0742178495Manuel Klimek#else
97e265c877934dd24d11d85e991ede7d0742178495Manuel Klimek  // Matches class type_info.
98e265c877934dd24d11d85e991ede7d0742178495Manuel Klimek  EXPECT_TRUE(matches("", ClassMatcher));
99e265c877934dd24d11d85e991ede7d0742178495Manuel Klimek#endif
1004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1012dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ClassX = recordDecl(recordDecl(hasName("X")));
1024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X;", ClassX));
1034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {};", ClassX));
1044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("template<class T> class X {};", ClassX));
1054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("", ClassX));
1064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
1074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, ClassIsDerived) {
1092dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher IsDerivedFromX = recordDecl(isDerivedFrom("X"));
1104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsDerivedFromX));
11276dafa7e6487c0b51fadebd16bdefe0e0e23d595Daniel Jasper  EXPECT_TRUE(notMatches("class X {};", IsDerivedFromX));
11376dafa7e6487c0b51fadebd16bdefe0e0e23d595Daniel Jasper  EXPECT_TRUE(notMatches("class X;", IsDerivedFromX));
1144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y;", IsDerivedFromX));
1154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("", IsDerivedFromX));
1164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11763d88728d862f8a69b3291e533d193d1d8513f5aDaniel Jasper  DeclarationMatcher IsAX = recordDecl(isSameOrDerivedFrom("X"));
11876dafa7e6487c0b51fadebd16bdefe0e0e23d595Daniel Jasper
11976dafa7e6487c0b51fadebd16bdefe0e0e23d595Daniel Jasper  EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsAX));
12076dafa7e6487c0b51fadebd16bdefe0e0e23d595Daniel Jasper  EXPECT_TRUE(matches("class X {};", IsAX));
12176dafa7e6487c0b51fadebd16bdefe0e0e23d595Daniel Jasper  EXPECT_TRUE(matches("class X;", IsAX));
12276dafa7e6487c0b51fadebd16bdefe0e0e23d595Daniel Jasper  EXPECT_TRUE(notMatches("class Y;", IsAX));
12376dafa7e6487c0b51fadebd16bdefe0e0e23d595Daniel Jasper  EXPECT_TRUE(notMatches("", IsAX));
12476dafa7e6487c0b51fadebd16bdefe0e0e23d595Daniel Jasper
1254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher ZIsDerivedFromX =
1262dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("Z"), isDerivedFrom("X"));
1274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; class Y : public X {}; class Z : public Y {};",
1294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZIsDerivedFromX));
1304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {};"
1324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "template<class T> class Y : public X {};"
1334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "class Z : public Y<int> {};", ZIsDerivedFromX));
1344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {}; template<class T> class Z : public X {};",
1354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      ZIsDerivedFromX));
1364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("template<class T> class X {}; "
1384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "template<class T> class Z : public X<T> {};",
1394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZIsDerivedFromX));
1404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("template<class T, class U=T> class X {}; "
1424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "template<class T> class Z : public X<T> {};",
1434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZIsDerivedFromX));
1444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("template<class X> class A { class Z : public X {}; };",
1464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 ZIsDerivedFromX));
1474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("template<class X> class A { public: class Z : public X {}; }; "
1494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "class X{}; void y() { A<X>::Z z; }", ZIsDerivedFromX));
1504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("template <class T> class X {}; "
1524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "template<class Y> class A { class Z : public X<Y> {}; };",
1534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZIsDerivedFromX));
1544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("template<template<class T> class X> class A { "
1564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "  class Z : public X<int> {}; };", ZIsDerivedFromX));
1574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("template<template<class T> class X> class A { "
1594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "  public: class Z : public X<int> {}; }; "
1604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "template<class T> class X {}; void y() { A<X>::Z z; }",
1614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZIsDerivedFromX));
1624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("template<class X> class A { class Z : public X::D {}; };",
1644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 ZIsDerivedFromX));
1654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("template<class X> class A { public: "
1674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "  class Z : public X::D {}; }; "
1684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "class Y { public: class X {}; typedef X D; }; "
1694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "void y() { A<Y>::Z z; }", ZIsDerivedFromX));
1704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; typedef X Y; class Z : public Y {};",
1724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZIsDerivedFromX));
1734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("template<class T> class Y { typedef typename T::U X; "
1754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "  class Z : public X {}; };", ZIsDerivedFromX));
1764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {}; class Z : public ::X {};",
1774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      ZIsDerivedFromX));
1784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("template<class T> class X {}; "
1804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                "template<class T> class A { class Z : public X<T>::D {}; };",
1814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                ZIsDerivedFromX));
1824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("template<class T> class X { public: typedef X<T> D; }; "
1844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "template<class T> class A { public: "
1854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "  class Z : public X<T>::D {}; }; void y() { A<int>::Z z; }",
1864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZIsDerivedFromX));
1874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("template<class X> class A { class Z : public X::D::E {}; };",
1894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 ZIsDerivedFromX));
1904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; typedef X V; typedef V W; class Z : public W {};",
1924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZIsDerivedFromX));
1934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; class Y : public X {}; "
1954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "typedef Y V; typedef V W; class Z : public W {};",
1964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZIsDerivedFromX));
1974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
1984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("template<class T, class U> class X {}; "
1994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "template<class T> class A { class Z : public X<T, int> {}; };",
2004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZIsDerivedFromX));
2014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("template<class X> class D { typedef X A; typedef A B; "
2034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "  typedef B C; class Z : public C {}; };",
2044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 ZIsDerivedFromX));
2054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; typedef X A; typedef A B; "
2074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "class Z : public B {};", ZIsDerivedFromX));
2084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; typedef X A; typedef A B; typedef B C; "
2104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "class Z : public C {};", ZIsDerivedFromX));
2114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class U {}; typedef U X; typedef X V; "
2134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "class Z : public V {};", ZIsDerivedFromX));
2144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Base {}; typedef Base X; "
2164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "class Z : public Base {};", ZIsDerivedFromX));
2174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Base {}; typedef Base Base2; typedef Base2 X; "
2194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "class Z : public Base {};", ZIsDerivedFromX));
2204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Base {}; class Base2 {}; typedef Base2 X; "
2224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "class Z : public Base {};", ZIsDerivedFromX));
2234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class A {}; typedef A X; typedef A Y; "
2254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "class Z : public Y {};", ZIsDerivedFromX));
2264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("template <typename T> class Z;"
2284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "template <> class Z<void> {};"
2294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "template <typename T> class Z : public Z<void> {};",
2304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 IsDerivedFromX));
2314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
2324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("template <typename T> class X;"
2334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "template <> class X<void> {};"
2344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "template <typename T> class X : public X<void> {};",
2354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              IsDerivedFromX));
2364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
2374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X {};"
2384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class Z;"
2394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <> class Z<void> {};"
2404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class Z : public Z<void>, public X {};",
2414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      ZIsDerivedFromX));
242987c2f590fade75245e32807ee83c31483e02d8aManuel Klimek  EXPECT_TRUE(
243987c2f590fade75245e32807ee83c31483e02d8aManuel Klimek      notMatches("template<int> struct X;"
244987c2f590fade75245e32807ee83c31483e02d8aManuel Klimek                 "template<int i> struct X : public X<i-1> {};",
245987c2f590fade75245e32807ee83c31483e02d8aManuel Klimek                 recordDecl(isDerivedFrom(recordDecl(hasName("Some"))))));
246987c2f590fade75245e32807ee83c31483e02d8aManuel Klimek  EXPECT_TRUE(matches(
247987c2f590fade75245e32807ee83c31483e02d8aManuel Klimek      "struct A {};"
248987c2f590fade75245e32807ee83c31483e02d8aManuel Klimek      "template<int> struct X;"
249987c2f590fade75245e32807ee83c31483e02d8aManuel Klimek      "template<int i> struct X : public X<i-1> {};"
250987c2f590fade75245e32807ee83c31483e02d8aManuel Klimek      "template<> struct X<0> : public A {};"
251987c2f590fade75245e32807ee83c31483e02d8aManuel Klimek      "struct B : public X<42> {};",
252987c2f590fade75245e32807ee83c31483e02d8aManuel Klimek      recordDecl(hasName("B"), isDerivedFrom(recordDecl(hasName("A"))))));
2534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // FIXME: Once we have better matchers for template type matching,
2554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // get rid of the Variable(...) matching and match the right template
2564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // declarations directly.
2574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  const char *RecursiveTemplateOneParameter =
2584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Base1 {}; class Base2 {};"
2594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class Z;"
2604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <> class Z<void> : public Base1 {};"
2614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <> class Z<int> : public Base2 {};"
2624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <> class Z<float> : public Z<void> {};"
2634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <> class Z<double> : public Z<int> {};"
2644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class Z : public Z<float>, public Z<double> {};"
2654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void f() { Z<float> z_float; Z<double> z_double; Z<char> z_char; }";
2664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
2674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      RecursiveTemplateOneParameter,
2682dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("z_float"),
2692dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              hasInitializer(hasType(recordDecl(isDerivedFrom("Base1")))))));
2704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
2714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      RecursiveTemplateOneParameter,
2722dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("z_float"),
2732dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              hasInitializer(hasType(recordDecl(isDerivedFrom("Base2")))))));
2744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
2754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      RecursiveTemplateOneParameter,
2762dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("z_char"),
2772dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              hasInitializer(hasType(recordDecl(isDerivedFrom("Base1"),
2782dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                                                isDerivedFrom("Base2")))))));
2794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  const char *RecursiveTemplateTwoParameters =
2814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Base1 {}; class Base2 {};"
2824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T1, typename T2> class Z;"
2834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class Z<void, T> : public Base1 {};"
2844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class Z<int, T> : public Base2 {};"
2854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class Z<float, T> : public Z<void, T> {};"
2864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class Z<double, T> : public Z<int, T> {};"
2874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T1, typename T2> class Z : "
2884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    public Z<float, T2>, public Z<double, T2> {};"
2894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void f() { Z<float, void> z_float; Z<double, void> z_double; "
2904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "           Z<char, void> z_char; }";
2914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
2924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      RecursiveTemplateTwoParameters,
2932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("z_float"),
2942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              hasInitializer(hasType(recordDecl(isDerivedFrom("Base1")))))));
2954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
2964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      RecursiveTemplateTwoParameters,
2972dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("z_float"),
2982dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              hasInitializer(hasType(recordDecl(isDerivedFrom("Base2")))))));
2994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
3004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      RecursiveTemplateTwoParameters,
3012dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("z_char"),
3022dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              hasInitializer(hasType(recordDecl(isDerivedFrom("Base1"),
3032dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                                                isDerivedFrom("Base2")))))));
30420b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper  EXPECT_TRUE(matches(
30520b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper      "namespace ns { class X {}; class Y : public X {}; }",
3062dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isDerivedFrom("::ns::X"))));
30720b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper  EXPECT_TRUE(notMatches(
30820b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper      "class X {}; class Y : public X {};",
3092dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isDerivedFrom("::ns::X"))));
31020b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper
31120b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper  EXPECT_TRUE(matches(
31220b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper      "class X {}; class Y : public X {};",
3132dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isDerivedFrom(recordDecl(hasName("X")).bind("test")))));
3144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
3154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
3166a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin VaneTEST(DeclarationMatcher, hasMethod) {
3176a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane  EXPECT_TRUE(matches("class A { void func(); };",
3186a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane                      recordDecl(hasMethod(hasName("func")))));
3196a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane  EXPECT_TRUE(notMatches("class A { void func(); };",
3206a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane                         recordDecl(hasMethod(isPublic()))));
3216a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane}
3226a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane
32308f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel JasperTEST(DeclarationMatcher, ClassDerivedFromDependentTemplateSpecialization) {
32408f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper  EXPECT_TRUE(matches(
32508f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper     "template <typename T> struct A {"
32608f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper     "  template <typename T2> struct F {};"
32708f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper     "};"
32808f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper     "template <typename T> struct B : A<T>::template F<T> {};"
32908f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper     "B<int> b;",
33008f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper     recordDecl(hasName("B"), isDerivedFrom(recordDecl()))));
33108f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper}
33208f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper
333742d9e77e32f014194679575c97c6bb4fd0998c4Edwin VaneTEST(DeclarationMatcher, hasDeclContext) {
334742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(matches(
335742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane      "namespace N {"
336742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane      "  namespace M {"
337742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane      "    class D {};"
338742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane      "  }"
339742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane      "}",
340742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane      recordDecl(hasDeclContext(namedDecl(hasName("M"))))));
341742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(notMatches(
342742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane      "namespace N {"
343742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane      "  namespace M {"
344742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane      "    class D {};"
345742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane      "  }"
346742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane      "}",
347742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane      recordDecl(hasDeclContext(namedDecl(hasName("N"))))));
348742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane}
349742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane
3508456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(ClassTemplate, DoesNotMatchClass) {
3512dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ClassX = classTemplateDecl(hasName("X"));
3528456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches("class X;", ClassX));
3538456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches("class X {};", ClassX));
3548456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
3558456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
3568456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(ClassTemplate, MatchesClassTemplate) {
3572dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ClassX = classTemplateDecl(hasName("X"));
3588456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(matches("template<typename T> class X {};", ClassX));
3598456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(matches("class Z { template<class T> class X {}; };", ClassX));
3608456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
3618456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
3628456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(ClassTemplate, DoesNotMatchClassTemplateExplicitSpecialization) {
3638456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches("template<typename T> class X { };"
3648456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko                         "template<> class X<int> { int a; };",
3652dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              classTemplateDecl(hasName("X"),
3662dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                                hasDescendant(fieldDecl(hasName("a"))))));
3678456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
3688456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
3698456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(ClassTemplate, DoesNotMatchClassTemplatePartialSpecialization) {
3708456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches("template<typename T, typename U> class X { };"
3718456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko                         "template<typename T> class X<T, int> { int a; };",
3722dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              classTemplateDecl(hasName("X"),
3732dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                                hasDescendant(fieldDecl(hasName("a"))))));
3748456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
3758456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
3766a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(AllOf, AllOverloadsWork) {
3776a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  const char Program[] =
3787f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane      "struct T { };"
3797f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane      "int f(int, T*, int, int);"
3807f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane      "void g(int x) { T t; f(x, &t, 3, 4); }";
3816a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(matches(Program,
3822dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      callExpr(allOf(callee(functionDecl(hasName("f"))),
3832dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                     hasArgument(0, declRefExpr(to(varDecl())))))));
3846a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(matches(Program,
3852dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      callExpr(allOf(callee(functionDecl(hasName("f"))),
3862dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                     hasArgument(0, declRefExpr(to(varDecl()))),
3872dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                     hasArgument(1, hasType(pointsTo(
3882dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                                        recordDecl(hasName("T")))))))));
3897f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane  EXPECT_TRUE(matches(Program,
3907f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane      callExpr(allOf(callee(functionDecl(hasName("f"))),
3917f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane                     hasArgument(0, declRefExpr(to(varDecl()))),
3927f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane                     hasArgument(1, hasType(pointsTo(
3937f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane                                        recordDecl(hasName("T"))))),
3947f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane                     hasArgument(2, integerLiteral(equals(3)))))));
3957f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane  EXPECT_TRUE(matches(Program,
3967f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane      callExpr(allOf(callee(functionDecl(hasName("f"))),
3977f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane                     hasArgument(0, declRefExpr(to(varDecl()))),
3987f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane                     hasArgument(1, hasType(pointsTo(
3997f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane                                        recordDecl(hasName("T"))))),
4007f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane                     hasArgument(2, integerLiteral(equals(3))),
4017f43fcf5d9406788ce95c9f3b785e0a6bc75a7f7Edwin Vane                     hasArgument(3, integerLiteral(equals(4)))))));
4026a12449ec8862211856447d3df4c082a346339f2Daniel Jasper}
4036a12449ec8862211856447d3df4c082a346339f2Daniel Jasper
4044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, MatchAnyOf) {
4054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher YOrZDerivedFromX =
4062dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(anyOf(hasName("Y"), allOf(isDerivedFrom("X"), hasName("Z"))));
4074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
4084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; class Z : public X {};", YOrZDerivedFromX));
4094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y {};", YOrZDerivedFromX));
4104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
4114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X {}; class W : public X {};", YOrZDerivedFromX));
4124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Z {};", YOrZDerivedFromX));
4134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
414ff2fcb8db242a54f72bbb4e5595261e12672ed66Daniel Jasper  DeclarationMatcher XOrYOrZOrU =
4152dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U")));
416ff2fcb8db242a54f72bbb4e5595261e12672ed66Daniel Jasper  EXPECT_TRUE(matches("class X {};", XOrYOrZOrU));
417ff2fcb8db242a54f72bbb4e5595261e12672ed66Daniel Jasper  EXPECT_TRUE(notMatches("class V {};", XOrYOrZOrU));
418ff2fcb8db242a54f72bbb4e5595261e12672ed66Daniel Jasper
4194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher XOrYOrZOrUOrV =
4202dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U"),
4212dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                       hasName("V")));
4224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {};", XOrYOrZOrUOrV));
4234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y {};", XOrYOrZOrUOrV));
4244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Z {};", XOrYOrZOrUOrV));
4254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class U {};", XOrYOrZOrUOrV));
4264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class V {};", XOrYOrZOrUOrV));
4274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A {};", XOrYOrZOrUOrV));
4284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
4294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
4304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, MatchHas) {
4312dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher HasClassX = recordDecl(has(recordDecl(hasName("X"))));
4324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { class X {}; };", HasClassX));
4334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {};", HasClassX));
4344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
4354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher YHasClassX =
4362dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("Y"), has(recordDecl(hasName("X"))));
4374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { class X {}; };", YHasClassX));
4384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class X {};", YHasClassX));
4394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
4404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { class Z { class X {}; }; };", YHasClassX));
4414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
4424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
4434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, MatchHasRecursiveAllOf) {
4444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher Recursive =
4452dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper    recordDecl(
4462dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      has(recordDecl(
4472dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper        has(recordDecl(hasName("X"))),
4482dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper        has(recordDecl(hasName("Y"))),
4494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek        hasName("Z"))),
4502dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      has(recordDecl(
4512dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper        has(recordDecl(hasName("A"))),
4522dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper        has(recordDecl(hasName("B"))),
4534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek        hasName("C"))),
4544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      hasName("F"));
4554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
4564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
4574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class F {"
4584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class Z {"
4594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class X {};"
4604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class Y {};"
4614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
4624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class C {"
4634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class A {};"
4644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class B {};"
4654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
4664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};", Recursive));
4674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
4684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
4694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class F {"
4704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class Z {"
4714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class A {};"
4724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class X {};"
4734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class Y {};"
4744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
4754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class C {"
4764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class X {};"
4774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class A {};"
4784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class B {};"
4794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
4804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};", Recursive));
4814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
4824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
4834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class O1 {"
4844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class O2 {"
4854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class F {"
4864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      class Z {"
4874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class A {};"
4884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class X {};"
4894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class Y {};"
4904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      };"
4914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      class C {"
4924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class X {};"
4934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class A {};"
4944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class B {};"
4954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      };"
4964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    };"
4974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
4984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};", Recursive));
4994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
5004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, MatchHasRecursiveAnyOf) {
5024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher Recursive =
5032dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
5044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          anyOf(
5052dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              has(recordDecl(
5064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                  anyOf(
5072dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      has(recordDecl(
5084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                          hasName("X"))),
5092dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      has(recordDecl(
5104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                          hasName("Y"))),
5114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      hasName("Z")))),
5122dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              has(recordDecl(
5134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                  anyOf(
5144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      hasName("C"),
5152dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      has(recordDecl(
5164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                          hasName("A"))),
5172dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      has(recordDecl(
5184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                          hasName("B")))))),
5194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              hasName("F")));
5204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class F {};", Recursive));
5224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Z {};", Recursive));
5234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class C {};", Recursive));
5244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class M { class N { class X {}; }; };", Recursive));
5254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class M { class N { class B {}; }; };", Recursive));
5264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
5274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class O1 { class O2 {"
5284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "  class M { class N { class B {}; }; }; "
5294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "}; };", Recursive));
5304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
5314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, MatchNot) {
5334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher NotClassX =
5342dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
5354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          isDerivedFrom("Y"),
5364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          unless(hasName("X")));
5374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("", NotClassX));
5384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y {};", NotClassX));
5394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y {}; class Z : public Y {};", NotClassX));
5404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y {}; class X : public Y {};", NotClassX));
5414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
5424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y {}; class Z {}; class X : public Y {};",
5434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 NotClassX));
5444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher ClassXHasNotClassY =
5462dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
5474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          hasName("X"),
5482dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          has(recordDecl(hasName("Z"))),
5494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          unless(
5502dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              has(recordDecl(hasName("Y")))));
5514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { class Z {}; };", ClassXHasNotClassY));
5524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class X { class Y {}; class Z {}; };",
5534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                         ClassXHasNotClassY));
5544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
5554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, HasDescendant) {
5574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher ZDescendantClassX =
5582dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
5592dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasDescendant(recordDecl(hasName("X"))),
5604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          hasName("Z"));
5614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Z { class X {}; };", ZDescendantClassX));
5624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
5634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Z { class Y { class X {}; }; };", ZDescendantClassX));
5644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
5654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Z { class A { class Y { class X {}; }; }; };",
5664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZDescendantClassX));
5674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
5684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Z { class A { class B { class Y { class X {}; }; }; }; };",
5694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZDescendantClassX));
5704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Z {};", ZDescendantClassX));
5714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher ZDescendantClassXHasClassY =
5732dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
5742dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasDescendant(recordDecl(has(recordDecl(hasName("Y"))),
5754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                              hasName("X"))),
5764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          hasName("Z"));
5774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Z { class X { class Y {}; }; };",
5784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZDescendantClassXHasClassY));
5794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
5804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Z { class A { class B { class X { class Y {}; }; }; }; };",
5814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZDescendantClassXHasClassY));
5824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
5834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Z {"
5844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class A {"
5854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class B {"
5864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      class X {"
5874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class C {"
5884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "          class Y {};"
5894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        };"
5904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      };"
5914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    }; "
5924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
5934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};", ZDescendantClassXHasClassY));
5944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher ZDescendantClassXDescendantClassY =
5962dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
5972dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasDescendant(recordDecl(hasDescendant(recordDecl(hasName("Y"))),
5982dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                                   hasName("X"))),
5994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          hasName("Z"));
6004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
6014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Z { class A { class X { class B { class Y {}; }; }; }; };",
6024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZDescendantClassXDescendantClassY));
6034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
6044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Z {"
6054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class A {"
6064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class X {"
6074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      class B {"
6084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class Y {};"
6094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      };"
6104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      class Y {};"
6114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    };"
6124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
6134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};", ZDescendantClassXDescendantClassY));
6144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
6154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
616a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper// Implements a run method that returns whether BoundNodes contains a
617a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper// Decl bound to Id that can be dynamically cast to T.
618a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper// Optionally checks that the check succeeded a specific number of times.
619a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jaspertemplate <typename T>
620a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasperclass VerifyIdIsBoundTo : public BoundNodesCallback {
621a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasperpublic:
622a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Create an object that checks that a node of type \c T was bound to \c Id.
623a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Does not check for a certain number of matches.
624a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  explicit VerifyIdIsBoundTo(llvm::StringRef Id)
625a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    : Id(Id), ExpectedCount(-1), Count(0) {}
626a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
627a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Create an object that checks that a node of type \c T was bound to \c Id.
628a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Checks that there were exactly \c ExpectedCount matches.
629a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  VerifyIdIsBoundTo(llvm::StringRef Id, int ExpectedCount)
630a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    : Id(Id), ExpectedCount(ExpectedCount), Count(0) {}
631a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
632a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Create an object that checks that a node of type \c T was bound to \c Id.
633a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Checks that there was exactly one match with the name \c ExpectedName.
634a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Note that \c T must be a NamedDecl for this to work.
635374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek  VerifyIdIsBoundTo(llvm::StringRef Id, llvm::StringRef ExpectedName,
636374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek                    int ExpectedCount = 1)
637374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      : Id(Id), ExpectedCount(ExpectedCount), Count(0),
638374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek        ExpectedName(ExpectedName) {}
639a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
640a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  ~VerifyIdIsBoundTo() {
641a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    if (ExpectedCount != -1)
642a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      EXPECT_EQ(ExpectedCount, Count);
643a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    if (!ExpectedName.empty())
644a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      EXPECT_EQ(ExpectedName, Name);
645a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  }
646a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
647a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  virtual bool run(const BoundNodes *Nodes) {
648a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    if (Nodes->getNodeAs<T>(Id)) {
649a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      ++Count;
650a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      if (const NamedDecl *Named = Nodes->getNodeAs<NamedDecl>(Id)) {
651a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper        Name = Named->getNameAsString();
652a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      } else if (const NestedNameSpecifier *NNS =
653a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                 Nodes->getNodeAs<NestedNameSpecifier>(Id)) {
654a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper        llvm::raw_string_ostream OS(Name);
655a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper        NNS->print(OS, PrintingPolicy(LangOptions()));
656a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      }
657a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      return true;
658a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    }
659a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    return false;
660a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  }
661a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
662452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper  virtual bool run(const BoundNodes *Nodes, ASTContext *Context) {
663452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper    return run(Nodes);
664452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper  }
665452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper
666a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasperprivate:
667a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  const std::string Id;
668a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  const int ExpectedCount;
669a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  int Count;
670a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  const std::string ExpectedName;
671a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  std::string Name;
672a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper};
673a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
674a267cf6f87dc695143d65fc61ec1744564f55932Daniel JasperTEST(HasDescendant, MatchesDescendantTypes) {
675a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int i = 3; }",
676a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      decl(hasDescendant(loc(builtinType())))));
677a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int i = 3; }",
678a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      stmt(hasDescendant(builtinType()))));
679a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
680a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int i = 3; }",
681a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      stmt(hasDescendant(loc(builtinType())))));
682a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int i = 3; }",
683a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      stmt(hasDescendant(qualType(builtinType())))));
684a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
685a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(notMatches("void f() { float f = 2.0f; }",
686a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                         stmt(hasDescendant(isInteger()))));
687a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
688a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
689a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      "void f() { int a; float c; int d; int e; }",
690a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      functionDecl(forEachDescendant(
691a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper          varDecl(hasDescendant(isInteger())).bind("x"))),
692a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      new VerifyIdIsBoundTo<Decl>("x", 3)));
693a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper}
694a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
695a267cf6f87dc695143d65fc61ec1744564f55932Daniel JasperTEST(HasDescendant, MatchesDescendantsOfTypes) {
696a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int*** i; }",
697a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      qualType(hasDescendant(builtinType()))));
698a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int*** i; }",
699a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      qualType(hasDescendant(
700a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                          pointerType(pointee(builtinType()))))));
701a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int*** i; }",
7025be093c0ef46c7749c942d0d9056af6dc3d591a4David Blaikie                      typeLoc(hasDescendant(loc(builtinType())))));
703a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
704a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
705a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      "void f() { int*** i; }",
706a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      qualType(asString("int ***"), forEachDescendant(pointerType().bind("x"))),
707a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      new VerifyIdIsBoundTo<Type>("x", 2)));
708a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper}
709a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
710a267cf6f87dc695143d65fc61ec1744564f55932Daniel JasperTEST(Has, MatchesChildrenOfTypes) {
711a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("int i;",
712a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      varDecl(hasName("i"), has(isInteger()))));
713a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(notMatches("int** i;",
714a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                         varDecl(hasName("i"), has(isInteger()))));
715a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
716a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      "int (*f)(float, int);",
717a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      qualType(functionType(), forEach(qualType(isInteger()).bind("x"))),
718a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      new VerifyIdIsBoundTo<QualType>("x", 2)));
719a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper}
720a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
721a267cf6f87dc695143d65fc61ec1744564f55932Daniel JasperTEST(Has, MatchesChildTypes) {
722a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches(
723a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      "int* i;",
724a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      varDecl(hasName("i"), hasType(qualType(has(builtinType()))))));
725a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(notMatches(
726a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      "int* i;",
727a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      varDecl(hasName("i"), hasType(qualType(has(pointerType()))))));
728a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper}
729a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
730e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Enum, DoesNotMatchClasses) {
731e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("class X {};", enumDecl(hasName("X"))));
732e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
733e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
734e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Enum, MatchesEnums) {
735e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("enum X {};", enumDecl(hasName("X"))));
736e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
737e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
738e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(EnumConstant, Matches) {
7392dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher Matcher = enumConstantDecl(hasName("A"));
740e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("enum X{ A };", Matcher));
741e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("enum X{ B };", Matcher));
742e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("enum X {};", Matcher));
743e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
744e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
7454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementMatcher, Has) {
7464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher HasVariableI =
7472dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      expr(hasType(pointsTo(recordDecl(hasName("X")))),
7482dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper           has(declRefExpr(to(varDecl(hasName("i"))))));
7494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
7514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X; X *x(int); void c() { int i; x(i); }", HasVariableI));
7524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
7534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X; X *x(int); void c() { int i; x(42); }", HasVariableI));
7544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
7554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementMatcher, HasDescendant) {
7574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher HasDescendantVariableI =
7582dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      expr(hasType(pointsTo(recordDecl(hasName("X")))),
7592dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper           hasDescendant(declRefExpr(to(varDecl(hasName("i"))))));
7604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
7624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X; X *x(bool); bool b(int); void c() { int i; x(b(i)); }",
7634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      HasDescendantVariableI));
7644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
7654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X; X *x(bool); bool b(int); void c() { int i; x(b(42)); }",
7664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      HasDescendantVariableI));
7674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
7684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(TypeMatcher, MatchesClassType) {
7702dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  TypeMatcher TypeA = hasDeclaration(recordDecl(hasName("A")));
7714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class A { public: A *a; };", TypeA));
7734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A {};", TypeA));
7744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7752dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  TypeMatcher TypeDerivedFromA = hasDeclaration(recordDecl(isDerivedFrom("A")));
7764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class A {}; class B : public A { public: B *b; };",
7784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              TypeDerivedFromA));
7794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A {};", TypeA));
7804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  TypeMatcher TypeAHasClassB = hasDeclaration(
7822dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("A"), has(recordDecl(hasName("B")))));
7834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
7854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class A { public: A *a; class B {}; };", TypeAHasClassB));
7864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
7874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, BindMatchedNodes) {
7892dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ClassX = has(recordDecl(hasName("::X")).bind("x"));
7904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class X {};",
792a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      ClassX, new VerifyIdIsBoundTo<CXXRecordDecl>("x")));
7934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse("class X {};",
795a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      ClassX, new VerifyIdIsBoundTo<CXXRecordDecl>("other-id")));
7964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  TypeMatcher TypeAHasClassB = hasDeclaration(
7982dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("A"), has(recordDecl(hasName("B")).bind("b"))));
7994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class A { public: A *a; class B {}; };",
8014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      TypeAHasClassB,
802a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<Decl>("b")));
8034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8042dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher MethodX =
8052dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      callExpr(callee(methodDecl(hasName("x")))).bind("x");
8064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class A { void x() { x(); } };",
8084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      MethodX,
809a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<CXXMemberCallExpr>("x")));
810e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
811e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
812e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Matcher, BindTheSameNameInAlternatives) {
813e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  StatementMatcher matcher = anyOf(
814e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      binaryOperator(hasOperatorName("+"),
8152dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                     hasLHS(expr().bind("x")),
816e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                     hasRHS(integerLiteral(equals(0)))),
817e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      binaryOperator(hasOperatorName("+"),
818e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                     hasLHS(integerLiteral(equals(0))),
8192dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                     hasRHS(expr().bind("x"))));
820e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
821e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
822e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      // The first branch of the matcher binds x to 0 but then fails.
823e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      // The second branch binds x to f() and succeeds.
824e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "int f() { return 0 + f(); }",
825e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      matcher,
826a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<CallExpr>("x")));
8274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
8284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
82966341c596f93d0c6475d839db94072b8ebd1cf5bManuel KlimekTEST(Matcher, BindsIDForMemoizedResults) {
83066341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek  // Using the same matcher in two match expressions will make memoization
83166341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek  // kick in.
83266341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek  DeclarationMatcher ClassX = recordDecl(hasName("X")).bind("x");
83366341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
83466341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek      "class A { class B { class X {}; }; };",
83566341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek      DeclarationMatcher(anyOf(
83666341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek          recordDecl(hasName("A"), hasDescendant(ClassX)),
83766341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek          recordDecl(hasName("B"), hasDescendant(ClassX)))),
838a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<Decl>("x", 2)));
83966341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek}
84066341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek
841189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel JasperTEST(HasDeclaration, HasDeclarationOfEnumType) {
842189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper  EXPECT_TRUE(matches("enum X {}; void y(X *x) { x; }",
843189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper                      expr(hasType(pointsTo(
844189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper                          qualType(hasDeclaration(enumDecl(hasName("X")))))))));
845189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper}
846189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper
847b45083d08377a8b9528401fdafd7210e78895dbeEdwin VaneTEST(HasDeclaration, HasGetDeclTraitTest) {
848b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane  EXPECT_TRUE(internal::has_getDecl<TypedefType>::value);
849b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane  EXPECT_TRUE(internal::has_getDecl<RecordType>::value);
850b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane  EXPECT_FALSE(internal::has_getDecl<TemplateSpecializationType>::value);
851b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane}
852b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane
853523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin VaneTEST(HasDeclaration, HasDeclarationOfTypeWithDecl) {
854523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane  EXPECT_TRUE(matches("typedef int X; X a;",
855523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane                      varDecl(hasName("a"),
856523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane                              hasType(typedefType(hasDeclaration(decl()))))));
857523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane
858523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane  // FIXME: Add tests for other types with getDecl() (e.g. RecordType)
859523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane}
860523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane
8613abf77872ca6c520903f9174cf6cd89a50df2714Edwin VaneTEST(HasDeclaration, HasDeclarationOfTemplateSpecializationType) {
8623abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane  EXPECT_TRUE(matches("template <typename T> class A {}; A<int> a;",
8633abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane                      varDecl(hasType(templateSpecializationType(
8643abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane                          hasDeclaration(namedDecl(hasName("A"))))))));
8653abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane}
8663abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane
8674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasType, TakesQualTypeMatcherAndMatchesExpr) {
8682dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
8694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8702dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX))));
8714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X {}; void y(X *x) { x; }",
8732dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 expr(hasType(ClassX))));
8744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; void y(X *x) { x; }",
8762dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              expr(hasType(pointsTo(ClassX)))));
8774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
8784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasType, TakesQualTypeMatcherAndMatchesValueDecl) {
8802dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
8814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8822dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX))));
8834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8842dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX))));
8854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; void y() { X *x; }",
8872dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              varDecl(hasType(pointsTo(ClassX)))));
8884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
8894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasType, TakesDeclMatcherAndMatchesExpr) {
8912dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ClassX = recordDecl(hasName("X"));
8924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX))));
8944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X {}; void y(X *x) { x; }",
8962dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 expr(hasType(ClassX))));
8974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
8984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasType, TakesDeclMatcherAndMatchesValueDecl) {
9002dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ClassX = recordDecl(hasName("X"));
9014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
9022dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX))));
9034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
9042dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX))));
9054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
9064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, Call) {
9084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // FIXME: Do we want to overload Call() to directly take
909e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // Matcher<Decl>, too?
9102dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher MethodX = callExpr(hasDeclaration(methodDecl(hasName("x"))));
9114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { x(); } };", MethodX));
9134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() {} };", MethodX));
9144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9152dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher MethodOnY =
9162dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberCallExpr(on(hasType(recordDecl(hasName("Y")))));
9174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
9194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
9204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
9214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
9224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
9234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
9244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
9254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
9264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 MethodOnY));
9274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
9284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
9294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 MethodOnY));
9304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
9314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
9324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 MethodOnY));
9334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher MethodOnYPointer =
9352dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberCallExpr(on(hasType(pointsTo(recordDecl(hasName("Y"))))));
9364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
9384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
9394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnYPointer));
9404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
9414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
9424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnYPointer));
9434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
9444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
9454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnYPointer));
9464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
9474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
9484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 MethodOnYPointer));
9494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
9504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
9514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 MethodOnYPointer));
9524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
9534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
95431f7c08a0d2b140bf31a08894d1948649de53c15Daniel JasperTEST(Matcher, Lambda) {
95531f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  EXPECT_TRUE(matches("auto f = [&] (int i) { return i; };",
95631f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      lambdaExpr()));
95731f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper}
95831f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper
95931f7c08a0d2b140bf31a08894d1948649de53c15Daniel JasperTEST(Matcher, ForRange) {
9601a00fee3933066024a2398f9456e5d6bc74344b9Daniel Jasper  EXPECT_TRUE(matches("int as[] = { 1, 2, 3 };"
9611a00fee3933066024a2398f9456e5d6bc74344b9Daniel Jasper                      "void f() { for (auto &a : as); }",
96231f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      forRangeStmt()));
96331f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  EXPECT_TRUE(notMatches("void f() { for (int i; i<5; ++i); }",
96431f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                         forRangeStmt()));
96531f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper}
96631f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper
96731f7c08a0d2b140bf31a08894d1948649de53c15Daniel JasperTEST(Matcher, UserDefinedLiteral) {
96831f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  EXPECT_TRUE(matches("constexpr char operator \"\" _inc (const char i) {"
96931f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      "  return i + 1;"
97031f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      "}"
97131f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      "char c = 'a'_inc;",
97231f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      userDefinedLiteral()));
97331f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper}
97431f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper
975b54b7646b2d00a85d80e40adf7c49553f150c736Daniel JasperTEST(Matcher, FlowControl) {
976b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() { while(true) { break; } }", breakStmt()));
977b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() { while(true) { continue; } }",
978b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper                      continueStmt()));
979b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", gotoStmt()));
980b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", labelStmt()));
981b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() { return; }", returnStmt()));
982b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper}
983b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper
984e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(HasType, MatchesAsString) {
985e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(
986e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }",
9872dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberCallExpr(on(hasType(asString("class Y *"))))));
988e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("class X { void x(int x) {} };",
9892dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(0, hasType(asString("int"))))));
990e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("namespace ns { struct A {}; }  struct B { ns::A a; };",
9912dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      fieldDecl(hasType(asString("ns::A")))));
992e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("namespace { struct A {}; }  struct B { A a; };",
9932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      fieldDecl(hasType(asString("struct <anonymous>::A")))));
994e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
995e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
9964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, OverloadedOperatorCall) {
9972dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher OpCall = operatorCallExpr();
9984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Unary operator
9994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { }; "
10004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "bool operator!(Y x) { return false; }; "
10014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "Y y; bool c = !y;", OpCall));
10024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // No match -- special operators like "new", "delete"
10034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // FIXME: operator new takes size_t, for which we need stddef.h, for which
10044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // we need to figure out include paths in the test.
10054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // EXPECT_TRUE(NotMatches("#include <stddef.h>\n"
10064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  //             "class Y { }; "
10074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  //             "void *operator new(size_t size) { return 0; } "
10084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  //             "Y *y = new Y;", OpCall));
10094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { }; "
10104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "void operator delete(void *p) { } "
10114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "void a() {Y *y = new Y; delete y;}", OpCall));
10124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Binary operator
10134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { }; "
10144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "bool operator&&(Y x, Y y) { return true; }; "
10154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "Y a; Y b; bool c = a && b;",
10164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              OpCall));
10174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // No match -- normal operator, not an overloaded one.
10184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("bool x = true, y = true; bool t = x && y;", OpCall));
10194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int t = 5 << 2;", OpCall));
10204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
10214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, HasOperatorNameForOverloadedOperatorCall) {
10234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OpCallAndAnd =
10242dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      operatorCallExpr(hasOverloadedOperatorName("&&"));
10254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { }; "
10264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "bool operator&&(Y x, Y y) { return true; }; "
10274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "Y a; Y b; bool c = a && b;", OpCallAndAnd));
10284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OpCallLessLess =
10292dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      operatorCallExpr(hasOverloadedOperatorName("<<"));
10304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { }; "
10314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "bool operator&&(Y x, Y y) { return true; }; "
10324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "Y a; Y b; bool c = a && b;",
10334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              OpCallLessLess));
10346a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane  DeclarationMatcher ClassWithOpStar =
10356a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane    recordDecl(hasMethod(hasOverloadedOperatorName("*")));
10366a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane  EXPECT_TRUE(matches("class Y { int operator*(); };",
10376a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane                      ClassWithOpStar));
10386a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane  EXPECT_TRUE(notMatches("class Y { void myOperator(); };",
10396a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane              ClassWithOpStar)) ;
10404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
10414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1042278057fd9f44684af832695cb01676c02a257b14Daniel JasperTEST(Matcher, NestedOverloadedOperatorCalls) {
1043278057fd9f44684af832695cb01676c02a257b14Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
1044278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "class Y { }; "
1045278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "Y& operator&&(Y& x, Y& y) { return x; }; "
1046278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "Y a; Y b; Y c; Y d = a && b && c;",
1047278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        operatorCallExpr(hasOverloadedOperatorName("&&")).bind("x"),
1048278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        new VerifyIdIsBoundTo<CXXOperatorCallExpr>("x", 2)));
1049278057fd9f44684af832695cb01676c02a257b14Daniel Jasper  EXPECT_TRUE(matches(
1050278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "class Y { }; "
1051278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "Y& operator&&(Y& x, Y& y) { return x; }; "
1052278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "Y a; Y b; Y c; Y d = a && b && c;",
1053278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        operatorCallExpr(hasParent(operatorCallExpr()))));
1054278057fd9f44684af832695cb01676c02a257b14Daniel Jasper  EXPECT_TRUE(matches(
1055278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "class Y { }; "
1056278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "Y& operator&&(Y& x, Y& y) { return x; }; "
1057278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "Y a; Y b; Y c; Y d = a && b && c;",
1058278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        operatorCallExpr(hasDescendant(operatorCallExpr()))));
1059278057fd9f44684af832695cb01676c02a257b14Daniel Jasper}
1060278057fd9f44684af832695cb01676c02a257b14Daniel Jasper
10614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ThisPointerType) {
10629f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek  StatementMatcher MethodOnY =
10632dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper    memberCallExpr(thisPointerType(recordDecl(hasName("Y"))));
10644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
10674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
10684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
10704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
10714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
10734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
10744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
10764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
10774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
10794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
10804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
10824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y {"
10834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  public: virtual void x();"
10844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};"
10854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X : public Y {"
10864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  public: virtual void x();"
10874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};"
10884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void z() { X *x; x->Y::x(); }", MethodOnY));
10894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
10904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, VariableUsage) {
10924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher Reference =
10932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      declRefExpr(to(
10942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          varDecl(hasInitializer(
10952dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberCallExpr(thisPointerType(recordDecl(hasName("Y"))))))));
10964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
10984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y {"
10994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      " public:"
11004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  bool x() const;"
11014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};"
11024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void z(const Y &y) {"
11034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  bool b = y.x();"
11044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  if (b) {}"
11054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "}", Reference));
11064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
11084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y {"
11094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      " public:"
11104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  bool x() const;"
11114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};"
11124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void z(const Y &y) {"
11134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  bool b = y.x();"
11144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "}", Reference));
11154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
11164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11178cb9bf577e3cfe31f1f023ed3a978d726f136edcManuel KlimekTEST(Matcher, FindsVarDeclInFunctionParameter) {
11189bd2809085c2a84c980c40988896ee05065f14e4Daniel Jasper  EXPECT_TRUE(matches(
11199bd2809085c2a84c980c40988896ee05065f14e4Daniel Jasper      "void f(int i) {}",
11202dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("i"))));
11219bd2809085c2a84c980c40988896ee05065f14e4Daniel Jasper}
11229bd2809085c2a84c980c40988896ee05065f14e4Daniel Jasper
11234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, CalledVariable) {
11243680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher CallOnVariableY =
11253680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      memberCallExpr(on(declRefExpr(to(varDecl(hasName("y"))))));
11264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
11284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y { public: void x() { Y y; y.x(); } };", CallOnVariableY));
11294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
11304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y { public: void x() const { Y y; y.x(); } };", CallOnVariableY));
11314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
11324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y { public: void x(); };"
11334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X : public Y { void z() { X y; y.x(); } };", CallOnVariableY));
11344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
11354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y { public: void x(); };"
11364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X : public Y { void z() { X *y; y->x(); } };", CallOnVariableY));
11374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
11384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y { public: void x(); };"
11394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X : public Y { void z() { unsigned long y; ((X*)y)->x(); } };",
11404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      CallOnVariableY));
11414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
11424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1143e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UnaryExprOrTypeTraitExpr, MatchesSizeOfAndAlignOf) {
1144e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("void x() { int a = sizeof(a); }",
1145e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      unaryExprOrTypeTraitExpr()));
1146e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }",
1147e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                         alignOfExpr(anything())));
1148e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // FIXME: Uncomment once alignof is enabled.
1149e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // EXPECT_TRUE(matches("void x() { int a = alignof(a); }",
1150e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  //                     unaryExprOrTypeTraitExpr()));
1151e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // EXPECT_TRUE(notMatches("void x() { int a = alignof(a); }",
1152e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  //                        sizeOfExpr()));
1153e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1154e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
1155e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UnaryExpressionOrTypeTraitExpression, MatchesCorrectType) {
1156e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("void x() { int a = sizeof(a); }", sizeOfExpr(
1157e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      hasArgumentOfType(asString("int")))));
1158e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
1159e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      hasArgumentOfType(asString("float")))));
1160e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
1161e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "struct A {}; void x() { A a; int b = sizeof(a); }",
11622dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      sizeOfExpr(hasArgumentOfType(hasDeclaration(recordDecl(hasName("A")))))));
1163e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
11642dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      hasArgumentOfType(hasDeclaration(recordDecl(hasName("string")))))));
1165e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1166e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
11674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MemberExpression, DoesNotMatchClasses) {
11682dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class Y { void x() {} };", memberExpr()));
11694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
11704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MemberExpression, MatchesMemberFunctionCall) {
11722dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpr()));
11734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
11744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MemberExpression, MatchesVariable) {
11764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
11772dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class Y { void x() { this->y; } int y; };", memberExpr()));
11784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
11792dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class Y { void x() { y; } int y; };", memberExpr()));
11804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
11812dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class Y { void x() { Y y; y.y; } int y; };", memberExpr()));
11824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
11834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MemberExpression, MatchesStaticVariable) {
11854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
11862dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr()));
11874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
11882dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr()));
11894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { Y::y; } static int y; };",
11902dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr()));
11914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
11924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11936a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(IsInteger, MatchesIntegers) {
11942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isInteger()))));
11952dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches(
11962dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      "long long i = 0; void f(long long) { }; void g() {f(i);}",
11972dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      callExpr(hasArgument(0, declRefExpr(
11982dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                                  to(varDecl(hasType(isInteger()))))))));
11996a12449ec8862211856447d3df4c082a346339f2Daniel Jasper}
12006a12449ec8862211856447d3df4c082a346339f2Daniel Jasper
12016a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(IsInteger, ReportsNoFalsePositives) {
12022dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("int *i;", varDecl(hasType(isInteger()))));
12036a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}",
12042dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      callExpr(hasArgument(0, declRefExpr(
12052dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          to(varDecl(hasType(isInteger()))))))));
12066a12449ec8862211856447d3df4c082a346339f2Daniel Jasper}
12076a12449ec8862211856447d3df4c082a346339f2Daniel Jasper
12084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsArrow, MatchesMemberVariablesViaArrow) {
12094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };",
12102dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
12114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { y; } int y; };",
12122dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
12134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };",
12142dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
12154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
12164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsArrow, MatchesStaticMemberVariablesViaArrow) {
12184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
12192dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
12204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
12212dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
12224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } static int y; };",
12232dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
12244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
12254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsArrow, MatchesMemberCallsViaArrow) {
12274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
12282dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
12294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { x(); } };",
12302dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
12314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",
12322dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
12334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
12344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Callee, MatchesDeclarations) {
12362dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher CallMethodX = callExpr(callee(methodDecl(hasName("x"))));
12374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { x(); } };", CallMethodX));
12394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() {} };", CallMethodX));
12404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
12414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Callee, MatchesMemberExpressions) {
12434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
12442dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              callExpr(callee(memberExpr()))));
12454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
12462dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      notMatches("class Y { void x() { this->x(); } };", callExpr(callee(callExpr()))));
12474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
12484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Function, MatchesFunctionDeclarations) {
12502dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher CallFunctionF = callExpr(callee(functionDecl(hasName("f"))));
12514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { f(); }", CallFunctionF));
12534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { }", CallFunctionF));
12544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1255e265c877934dd24d11d85e991ede7d0742178495Manuel Klimek#if !defined(_MSC_VER)
1256e265c877934dd24d11d85e991ede7d0742178495Manuel Klimek  // FIXME: Make this work for MSVC.
12574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Dependent contexts, but a non-dependent call.
12584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f(); template <int N> void g() { f(); }",
12594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      CallFunctionF));
12604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
12614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("void f(); template <int N> struct S { void g() { f(); } };",
12624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              CallFunctionF));
1263e265c877934dd24d11d85e991ede7d0742178495Manuel Klimek#endif
12644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Depedent calls don't match.
12664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
12674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("void f(int); template <typename T> void g(T t) { f(t); }",
12684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 CallFunctionF));
12694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
12704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("void f(int);"
12714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "template <typename T> struct S { void g(T t) { f(t); } };",
12724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 CallFunctionF));
12734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
12744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12758456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(FunctionTemplate, MatchesFunctionTemplateDeclarations) {
12768456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(
12778456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      matches("template <typename T> void f(T t) {}",
12782dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionTemplateDecl(hasName("f"))));
12798456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
12808456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
12818456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(FunctionTemplate, DoesNotMatchFunctionDeclarations) {
12828456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(
12838456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      notMatches("void f(double d); void f(int t) {}",
12842dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionTemplateDecl(hasName("f"))));
12858456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
12868456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
12878456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(FunctionTemplate, DoesNotMatchFunctionTemplateSpecializations) {
12888456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(
12898456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      notMatches("void g(); template <typename T> void f(T t) {}"
12908456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko                 "template <> void f(int t) { g(); }",
12912dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionTemplateDecl(hasName("f"),
12922dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                           hasDescendant(declRefExpr(to(
12932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                               functionDecl(hasName("g"))))))));
12948456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
12958456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
12964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, Argument) {
12973680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher CallArgumentY = callExpr(
12983680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
12994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x(int) { int y; x(y); }", CallArgumentY));
13014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
13024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { void x(int) { int y; x(y); } };", CallArgumentY));
13034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x(int) { int z; x(z); }", CallArgumentY));
13044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13053680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher WrongIndex = callExpr(
13063680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
13074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x(int) { int y; x(y); }", WrongIndex));
13084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, AnyArgument) {
13113680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher CallArgumentY = callExpr(
13123680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasAnyArgument(declRefExpr(to(varDecl(hasName("y"))))));
13134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
13144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
13154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
13164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ArgumentCount) {
13193680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher Call1Arg = callExpr(argumentCountIs(1));
13204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg));
13224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg));
13234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg));
13244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
132636e29d6732814e958aea4b2f403cec63d7ed3116Daniel JasperTEST(Matcher, ParameterCount) {
132736e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper  DeclarationMatcher Function1Arg = functionDecl(parameterCountIs(1));
132836e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper  EXPECT_TRUE(matches("void f(int i) {}", Function1Arg));
132936e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper  EXPECT_TRUE(matches("class X { void f(int i) {} };", Function1Arg));
133036e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper  EXPECT_TRUE(notMatches("void f() {}", Function1Arg));
133136e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper  EXPECT_TRUE(notMatches("void f(int i, int j, int k) {}", Function1Arg));
133236e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper}
133336e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper
13344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, References) {
13352dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ReferenceClassX = varDecl(
13362dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      hasType(references(recordDecl(hasName("X")))));
13374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {}; void y(X y) { X &x = y; }",
13384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      ReferenceClassX));
13394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
13404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
13414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
13424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
13434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
13444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
13454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13476a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin VaneTEST(QualType, hasCanonicalType) {
13486a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane  EXPECT_TRUE(notMatches("typedef int &int_ref;"
13496a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane                         "int a;"
13506a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane                         "int_ref b = a;",
13516a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane                         varDecl(hasType(qualType(referenceType())))));
13526a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane  EXPECT_TRUE(
13536a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane      matches("typedef int &int_ref;"
13546a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane              "int a;"
13556a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane              "int_ref b = a;",
13566a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane              varDecl(hasType(qualType(hasCanonicalType(referenceType()))))));
13576a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane}
13586a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane
13594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasParameter, CallsInnerMatcher) {
13604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { void x(int) {} };",
13612dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(0, varDecl()))));
13624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class X { void x(int) {} };",
13632dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(0, hasName("x")))));
13644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) {
13674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class X { void x(int) {} };",
13682dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(42, varDecl()))));
13694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasType, MatchesParameterVariableTypesStrictly) {
13724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { void x(X x) {} };",
13732dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
13744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class X { void x(const X &x) {} };",
13752dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
13764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { void x(const X *x) {} };",
13772dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(0,
13782dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                              hasType(pointsTo(recordDecl(hasName("X"))))))));
13794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { void x(const X &x) {} };",
13802dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(0,
13812dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                              hasType(references(recordDecl(hasName("X"))))))));
13824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyParameter, MatchesIndependentlyOfPosition) {
13854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y {}; class X { void x(X x, Y y) {} };",
13862dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
13874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y {}; class X { void x(Y y, X x) {} };",
13882dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
13894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1391e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Returns, MatchesReturnTypes) {
1392e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("class Y { int f() { return 1; } };",
13932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      functionDecl(returns(asString("int")))));
1394e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("class Y { int f() { return 1; } };",
13952dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         functionDecl(returns(asString("float")))));
1396e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("class Y { Y getMe() { return *this; } };",
13972dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      functionDecl(returns(hasDeclaration(
13982dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          recordDecl(hasName("Y")))))));
1399e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1400e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
14018cc7efa2da2c6be43cbd3d09a9ae01353bb921d2Daniel JasperTEST(IsExternC, MatchesExternCFunctionDeclarations) {
14022dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("extern \"C\" void f() {}", functionDecl(isExternC())));
14032dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("extern \"C\" { void f() {} }",
14042dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              functionDecl(isExternC())));
14052dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("void f() {}", functionDecl(isExternC())));
14068cc7efa2da2c6be43cbd3d09a9ae01353bb921d2Daniel Jasper}
14078cc7efa2da2c6be43cbd3d09a9ae01353bb921d2Daniel Jasper
14084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
14094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
14102dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
14114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
14124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyParameter, DoesNotMatchThisPointer) {
14144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y {}; class X { void x() {} };",
14152dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasAnyParameter(hasType(pointsTo(
14162dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          recordDecl(hasName("X"))))))));
14174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
14184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasName, MatchesParameterVariableDeclartions) {
14204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y {}; class X { void x(int x) {} };",
14212dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasAnyParameter(hasName("x")))));
14224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
14232dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasAnyParameter(hasName("x")))));
14244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
14254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1426371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel JasperTEST(Matcher, MatchesClassTemplateSpecialization) {
1427371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(matches("template<typename T> struct A {};"
1428371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper                      "template<> struct A<int> {};",
14292dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      classTemplateSpecializationDecl()));
1430371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(matches("template<typename T> struct A {}; A<int> a;",
14312dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      classTemplateSpecializationDecl()));
1432371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(notMatches("template<typename T> struct A {};",
14332dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         classTemplateSpecializationDecl()));
1434371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper}
1435371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper
1436371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel JasperTEST(Matcher, MatchesTypeTemplateArgument) {
1437371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(matches(
1438371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "template<typename T> struct B {};"
1439371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "B<int> b;",
14402dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToType(
1441371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper          asString("int"))))));
1442371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper}
1443371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper
1444371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel JasperTEST(Matcher, MatchesDeclarationReferenceTemplateArgument) {
1445371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(matches(
1446371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "struct B { int next; };"
1447371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "template<int(B::*next_ptr)> struct A {};"
1448371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "A<&B::next> a;",
14492dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      classTemplateSpecializationDecl(hasAnyTemplateArgument(
14502dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          refersToDeclaration(fieldDecl(hasName("next")))))));
1451aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper
1452aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper  EXPECT_TRUE(notMatches(
1453aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper      "template <typename T> struct A {};"
1454aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper      "A<int> a;",
1455aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper      classTemplateSpecializationDecl(hasAnyTemplateArgument(
1456aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper          refersToDeclaration(decl())))));
1457371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper}
1458371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper
1459371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel JasperTEST(Matcher, MatchesSpecificArgument) {
1460371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(matches(
1461371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "template<typename T, typename U> class A {};"
1462371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "A<bool, int> a;",
14632dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      classTemplateSpecializationDecl(hasTemplateArgument(
1464371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper          1, refersToType(asString("int"))))));
1465371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(notMatches(
1466371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "template<typename T, typename U> class A {};"
1467371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "A<int, bool> a;",
14682dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      classTemplateSpecializationDecl(hasTemplateArgument(
1469371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper          1, refersToType(asString("int"))))));
1470371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper}
1471371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper
1472f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel JasperTEST(Matcher, MatchesAccessSpecDecls) {
1473f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(matches("class C { public: int i; };", accessSpecDecl()));
1474f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(
1475f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      matches("class C { public: int i; };", accessSpecDecl(isPublic())));
1476f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(
1477f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      notMatches("class C { public: int i; };", accessSpecDecl(isProtected())));
1478f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(
1479f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      notMatches("class C { public: int i; };", accessSpecDecl(isPrivate())));
1480f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper
1481f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches("class C { int i; };", accessSpecDecl()));
1482f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper}
1483f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper
14844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ConstructorCall) {
14853680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher Constructor = constructExpr();
14864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(); }; void x() { X x; }", Constructor));
14894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(); }; void x() { X x = X(); }",
14914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
14924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { X x = 0; }",
14944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
14954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {}; void x(int) { X x; }", Constructor));
14964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
14974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ConstructorArgument) {
14993680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher Constructor = constructExpr(
15003680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
15014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
15034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { int y; X x(y); }",
15044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
15054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
15064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
15074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
15084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
15094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { int y; X x = y; }",
15104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
15114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
15124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int); }; void x() { int z; X x(z); }",
15134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 Constructor));
15144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15153680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher WrongIndex = constructExpr(
15163680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
15174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
15184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int); }; void x() { int y; X x(y); }",
15194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 WrongIndex));
15204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
15214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ConstructorArgumentCount) {
15233680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher Constructor1Arg = constructExpr(argumentCountIs(1));
15244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
15264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { X x(0); }",
15274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor1Arg));
15284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
15294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { X x = X(0); }",
15304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor1Arg));
15314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
15324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { X x = 0; }",
15334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor1Arg));
15344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
15354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
15364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 Constructor1Arg));
15374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
15384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
153970b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel KlimekTEST(Matcher,ThisExpr) {
154070b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel Klimek  EXPECT_TRUE(
154170b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel Klimek      matches("struct X { int a; int f () { return a; } };", thisExpr()));
154270b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel Klimek  EXPECT_TRUE(
154370b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel Klimek      notMatches("struct X { int f () { int a; return a; } };", thisExpr()));
154470b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel Klimek}
154570b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel Klimek
15464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, BindTemporaryExpression) {
15473680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher TempExpression = bindTemporaryExpr();
15484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  std::string ClassString = "class string { public: string(); ~string(); }; ";
15504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
15524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches(ClassString +
15534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "string GetStringByValue();"
15544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "void FunctionTakesString(string s);"
15554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "void run() { FunctionTakesString(GetStringByValue()); }",
15564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              TempExpression));
15574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
15594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches(ClassString +
15604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "string* GetStringPointer(); "
15614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "void FunctionTakesStringPtr(string* s);"
15624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "void run() {"
15634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "  string* s = GetStringPointer();"
15644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "  FunctionTakesStringPtr(GetStringPointer());"
15654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "  FunctionTakesStringPtr(s);"
15664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "}",
15674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 TempExpression));
15684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
15704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class no_dtor {};"
15714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "no_dtor GetObjByValue();"
15724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "void ConsumeObj(no_dtor param);"
15734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "void run() { ConsumeObj(GetObjByValue()); }",
15744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 TempExpression));
1575e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer}
1576e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer
1577e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam PanzerTEST(MaterializeTemporaryExpr, MatchesTemporary) {
1578e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer  std::string ClassString =
1579e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer      "class string { public: string(); int length(); }; ";
1580e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer
1581e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer  EXPECT_TRUE(
1582e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer      matches(ClassString +
1583e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer              "string GetStringByValue();"
1584e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer              "void FunctionTakesString(string s);"
1585e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer              "void run() { FunctionTakesString(GetStringByValue()); }",
1586e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer              materializeTemporaryExpr()));
1587e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer
1588e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer  EXPECT_TRUE(
1589e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer      notMatches(ClassString +
1590e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "string* GetStringPointer(); "
1591e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "void FunctionTakesStringPtr(string* s);"
1592e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "void run() {"
1593e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "  string* s = GetStringPointer();"
1594e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "  FunctionTakesStringPtr(GetStringPointer());"
1595e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "  FunctionTakesStringPtr(s);"
1596e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "}",
1597e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 materializeTemporaryExpr()));
1598e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer
1599e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer  EXPECT_TRUE(
1600e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer      notMatches(ClassString +
1601e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "string GetStringByValue();"
1602e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "void run() { int k = GetStringByValue().length(); }",
1603e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 materializeTemporaryExpr()));
1604e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer
1605e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer  EXPECT_TRUE(
1606e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer      notMatches(ClassString +
1607e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "string GetStringByValue();"
1608e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "void run() { GetStringByValue(); }",
1609e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 materializeTemporaryExpr()));
16104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ConstructorDeclaration, SimpleCase) {
16134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Foo { Foo(int i); };",
16142dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      constructorDecl(ofClass(hasName("Foo")))));
16154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Foo { Foo(int i); };",
16162dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         constructorDecl(ofClass(hasName("Bar")))));
16174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ConstructorDeclaration, IsImplicit) {
16204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // This one doesn't match because the constructor is not added by the
16214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // compiler (it is not needed).
16224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Foo { };",
16232dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         constructorDecl(isImplicit())));
16244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // The compiler added the implicit default constructor.
16254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
16262dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      constructorDecl(isImplicit())));
16274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Foo { Foo(){} };",
16282dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      constructorDecl(unless(isImplicit()))));
16294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1631e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(DestructorDeclaration, MatchesVirtualDestructor) {
1632e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };",
16332dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      destructorDecl(ofClass(hasName("Foo")))));
1634e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1635e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
1636e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) {
16372dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class Foo {};",
16382dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         destructorDecl(ofClass(hasName("Foo")))));
1639e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1640e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
16414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyConstructorInitializer, SimpleCase) {
16424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
16434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Foo { Foo() { } };",
16442dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      constructorDecl(hasAnyConstructorInitializer(anything()))));
16454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
16464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Foo {"
16474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Foo() : foo_() { }"
16484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  int foo_;"
16494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};",
16502dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      constructorDecl(hasAnyConstructorInitializer(anything()))));
16514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyConstructorInitializer, ForField) {
16544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  static const char Code[] =
16554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Baz { };"
16564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Foo {"
16574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Foo() : foo_() { }"
16584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Baz foo_;"
16594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Baz bar_;"
16604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};";
16612dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches(Code, constructorDecl(hasAnyConstructorInitializer(
16622dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      forField(hasType(recordDecl(hasName("Baz"))))))));
16632dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches(Code, constructorDecl(hasAnyConstructorInitializer(
16644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      forField(hasName("foo_"))))));
16652dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches(Code, constructorDecl(hasAnyConstructorInitializer(
16662dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      forField(hasType(recordDecl(hasName("Bar"))))))));
16674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyConstructorInitializer, WithInitializer) {
16704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  static const char Code[] =
16714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Foo {"
16724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Foo() : foo_(0) { }"
16734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  int foo_;"
16744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};";
16752dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches(Code, constructorDecl(hasAnyConstructorInitializer(
16764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      withInitializer(integerLiteral(equals(0)))))));
16772dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches(Code, constructorDecl(hasAnyConstructorInitializer(
16784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      withInitializer(integerLiteral(equals(1)))))));
16794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyConstructorInitializer, IsWritten) {
16824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  static const char Code[] =
16834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "struct Bar { Bar(){} };"
16844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Foo {"
16854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Foo() : foo_() { }"
16864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Bar foo_;"
16874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Bar bar_;"
16884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};";
16892dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches(Code, constructorDecl(hasAnyConstructorInitializer(
16904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      allOf(forField(hasName("foo_")), isWritten())))));
16912dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches(Code, constructorDecl(hasAnyConstructorInitializer(
16924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      allOf(forField(hasName("bar_")), isWritten())))));
16932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches(Code, constructorDecl(hasAnyConstructorInitializer(
16944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      allOf(forField(hasName("bar_")), unless(isWritten()))))));
16954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, NewExpression) {
16983680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher New = newExpr();
16994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
17004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { public: X(); }; void x() { new X; }", New));
17014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(); }; void x() { new X(); }", New));
17034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { new X(0); }", New));
17054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {}; void x(int) { new X; }", New));
17064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
17074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
17084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, NewExpressionArgument) {
17093680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher New = constructExpr(
17103680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
17114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
17124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { int y; new X(y); }",
17144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              New));
17154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { int y; new X(y); }",
17174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              New));
17184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int); }; void x() { int z; new X(z); }",
17204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 New));
17214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
17223680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher WrongIndex = constructExpr(
17233680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
17244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int); }; void x() { int y; new X(y); }",
17264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 WrongIndex));
17274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
17284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
17294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, NewExpressionArgumentCount) {
17302dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher New = constructExpr(argumentCountIs(1));
17314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
17324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { new X(0); }", New));
17344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int, int); }; void x() { new X(0, 0); }",
17364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 New));
17374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
17384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1739e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Matcher, DeleteExpression) {
1740e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("struct A {}; void f(A* a) { delete a; }",
17412dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      deleteExpr()));
1742e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1743e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
17444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, DefaultArgument) {
17452dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher Arg = defaultArgExpr();
17464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
17474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x(int, int = 0) { int y; x(y); }", Arg));
17484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { void x(int, int = 0) { int y; x(y); } };", Arg));
17504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x(int, int = 0) { int y; x(y, 0); }", Arg));
17514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
17524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
17534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, StringLiterals) {
17543680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher Literal = stringLiteral();
17554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const char *s = \"string\";", Literal));
17564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // wide string
17574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const wchar_t *s = L\"string\";", Literal));
17584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // with escaped characters
17594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const char *s = \"\x05five\";", Literal));
17604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // no matching -- though the data type is the same, there is no string literal
17614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));
17624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
17634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
17644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, CharacterLiterals) {
17653680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher CharLiteral = characterLiteral();
17664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const char c = 'c';", CharLiteral));
17674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // wide character
17684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const char c = L'c';", CharLiteral));
17694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // wide character, Hex encoded, NOT MATCHED!
17704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("const wchar_t c = 0x2126;", CharLiteral));
17714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("const char c = 0x1;", CharLiteral));
17724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
17734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
17744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, IntegerLiterals) {
17753680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher HasIntLiteral = integerLiteral();
17764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = 10;", HasIntLiteral));
17774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = 0x1AB;", HasIntLiteral));
17784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = 10L;", HasIntLiteral));
17794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = 10U;", HasIntLiteral));
17804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
17814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Non-matching cases (character literals, float and double)
17824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int i = L'a';",
17834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                HasIntLiteral));  // this is actually a character
17844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                                  // literal cast to int
17854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int i = 'a';", HasIntLiteral));
17864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int i = 1e10;", HasIntLiteral));
17874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int i = 10.0;", HasIntLiteral));
17884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
17894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
179031f7c08a0d2b140bf31a08894d1948649de53c15Daniel JasperTEST(Matcher, NullPtrLiteral) {
179131f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  EXPECT_TRUE(matches("int* i = nullptr;", nullPtrLiteralExpr()));
179231f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper}
179331f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper
1794b54b7646b2d00a85d80e40adf7c49553f150c736Daniel JasperTEST(Matcher, AsmStatement) {
1795b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void foo() { __asm(\"mov al, 2\"); }", asmStmt()));
1796b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper}
1797b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper
17984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, Conditions) {
17994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher Condition = ifStmt(hasCondition(boolLiteral(equals(true))));
18004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { if (true) {} }", Condition));
18024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { if (false) {} }", Condition));
18034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { bool a = true; if (a) {} }", Condition));
18044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { if (true || false) {} }", Condition));
18054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { if (1) {} }", Condition));
18064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
18074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MatchBinaryOperator, HasOperatorName) {
18094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
18104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true || false; }", OperatorOr));
18124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
18134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
18144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MatchBinaryOperator, HasLHSAndHasRHS) {
18164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OperatorTrueFalse =
18174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      binaryOperator(hasLHS(boolLiteral(equals(true))),
18184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                     hasRHS(boolLiteral(equals(false))));
18194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true || false; }", OperatorTrueFalse));
18214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse));
18224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { false || true; }", OperatorTrueFalse));
18234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
18244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MatchBinaryOperator, HasEitherOperand) {
18264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher HasOperand =
18274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      binaryOperator(hasEitherOperand(boolLiteral(equals(false))));
18284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true || false; }", HasOperand));
18304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { false && true; }", HasOperand));
18314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand));
18324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
18334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, BinaryOperatorTypes) {
18354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Integration test that verifies the AST provides all binary operators in
18364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // a way we expect.
18374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // FIXME: Operator ','
18384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(","))));
18404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b; bool c = (b = true);",
18424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("="))));
18434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!="))));
18454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("=="))));
18474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("bool b = 1 < 2;", binaryOperator(hasOperatorName("<"))));
18484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<="))));
18504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<"))));
18524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 1; int j = (i <<= 2);",
18544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("<<="))));
18554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("bool b = 1 > 2;", binaryOperator(hasOperatorName(">"))));
18564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">="))));
18584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>"))));
18604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 1; int j = (i >>= 2);",
18624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName(">>="))));
18634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42 ^ 23;", binaryOperator(hasOperatorName("^"))));
18654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i ^= 42);",
18674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("^="))));
18684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42 % 23;", binaryOperator(hasOperatorName("%"))));
18704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i %= 42);",
18724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("%="))));
18734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 42  &23;", binaryOperator(hasOperatorName("&"))));
18754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = true && false;",
18774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("&&"))));
18784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = true; bool c = (b &= false);",
18804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("&="))));
18814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|"))));
18834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = true || false;",
18854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("||"))));
18864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = true; bool c = (b |= false);",
18884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("|="))));
18894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42  *23;", binaryOperator(hasOperatorName("*"))));
18914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i *= 23);",
18934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("*="))));
18944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42 / 23;", binaryOperator(hasOperatorName("/"))));
18964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i /= 23);",
18984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("/="))));
18994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42 + 23;", binaryOperator(hasOperatorName("+"))));
19014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i += 23);",
19034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("+="))));
19044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42 - 23;", binaryOperator(hasOperatorName("-"))));
19064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i -= 23);",
19084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("-="))));
19094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };",
19114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("->*"))));
19124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };",
19144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName(".*"))));
19154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Member expressions as operators are not supported in matches.
19174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("struct A { void x(A *a) { a->x(this); } };",
19194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 binaryOperator(hasOperatorName("->"))));
19204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Initializer assignments are not represented as operator equals.
19224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("bool b = true;", binaryOperator(hasOperatorName("="))));
19244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Array indexing is not represented as operator.
19264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int a[42]; void x() { a[23]; }", unaryOperator()));
19274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Overloaded operators do not match at all.
19294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
19304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "struct A { bool operator&&(const A &a) const { return false; } };"
19314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void x() { A a, b; a && b; }",
19324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      binaryOperator()));
19334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
19344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MatchUnaryOperator, HasOperatorName) {
19364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OperatorNot = unaryOperator(hasOperatorName("!"));
19374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { !true; } ", OperatorNot));
19394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
19404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
19414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MatchUnaryOperator, HasUnaryOperand) {
19434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OperatorOnFalse =
19444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      unaryOperator(hasUnaryOperand(boolLiteral(equals(false))));
19454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse));
19474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse));
19484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
19494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, UnaryOperatorTypes) {
19514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Integration test that verifies the AST provides all unary operators in
19524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // a way we expect.
19534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("bool b = !true;", unaryOperator(hasOperatorName("!"))));
19544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&"))));
19564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = ~ 1;", unaryOperator(hasOperatorName("~"))));
19574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool *p; bool b = *p;", unaryOperator(hasOperatorName("*"))));
19594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = +i;", unaryOperator(hasOperatorName("+"))));
19614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = -i;", unaryOperator(hasOperatorName("-"))));
19634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = ++i;", unaryOperator(hasOperatorName("++"))));
19654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = i++;", unaryOperator(hasOperatorName("++"))));
19674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = --i;", unaryOperator(hasOperatorName("--"))));
19694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = i--;", unaryOperator(hasOperatorName("--"))));
19714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // We don't match conversion operators.
19734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int i; double d = (double)i;", unaryOperator()));
19744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Function calls are not represented as operator.
19764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f(); void x() { f(); }", unaryOperator()));
19774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Overloaded operators do not match at all.
19794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // FIXME: We probably want to add that.
19804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
19814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "struct A { bool operator!() const { return false; } };"
19824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void x() { A a; !a; }", unaryOperator(hasOperatorName("!"))));
19834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
19844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ConditionalOperator) {
19864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher Conditional = conditionalOperator(
19874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      hasCondition(boolLiteral(equals(true))),
19884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      hasTrueExpression(boolLiteral(equals(false))));
19894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true ? false : true; }", Conditional));
19914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { false ? false : true; }", Conditional));
19924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { true ? true : false; }", Conditional));
19934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher ConditionalFalse = conditionalOperator(
19954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      hasFalseExpression(boolLiteral(equals(false))));
19964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
19984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("void x() { true ? false : true; }", ConditionalFalse));
20004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
20014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2002e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(ArraySubscriptMatchers, ArraySubscripts) {
2003e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("int i[2]; void f() { i[1] = 1; }",
2004e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      arraySubscriptExpr()));
2005e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("int i; void f() { i = 1; }",
2006e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                         arraySubscriptExpr()));
2007e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2008e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
2009e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(ArraySubscriptMatchers, ArrayIndex) {
2010e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
2011e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "int i[2]; void f() { i[1] = 1; }",
2012e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
2013e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
2014e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "int i[2]; void f() { 1[i] = 1; }",
2015e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
2016e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches(
2017e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "int i[2]; void f() { i[1] = 1; }",
2018e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      arraySubscriptExpr(hasIndex(integerLiteral(equals(0))))));
2019e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2020e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
2021e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(ArraySubscriptMatchers, MatchesArrayBase) {
2022e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
2023e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "int i[2]; void f() { i[1] = 2; }",
20242dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      arraySubscriptExpr(hasBase(implicitCastExpr(
20252dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasSourceExpression(declRefExpr()))))));
2026e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2027e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
20284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, HasNameSupportsNamespaces) {
20294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
20302dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("a::b::C"))));
20314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
20322dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("::a::b::C"))));
20334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
20342dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("b::C"))));
20354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
20362dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("C"))));
20374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
20382dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("c::b::C"))));
20394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
20402dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("a::c::C"))));
20414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
20422dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("a::b::A"))));
20434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
20442dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("::C"))));
20454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
20462dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("::b::C"))));
20474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
20482dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("z::a::b::C"))));
20494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
20502dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("a+b::C"))));
20514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
20522dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("C"))));
20534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
20544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, HasNameSupportsOuterClasses) {
20564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20572dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class A { class B { class C; }; };",
20582dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("A::B::C"))));
20594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class A { class B { class C; }; };",
20612dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("::A::B::C"))));
20624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20632dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class A { class B { class C; }; };",
20642dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("B::C"))));
20654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20662dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class A { class B { class C; }; };",
20672dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("C"))));
20684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class A { class B { class C; }; };",
20702dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("c::B::C"))));
20714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class A { class B { class C; }; };",
20732dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("A::c::C"))));
20744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class A { class B { class C; }; };",
20762dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("A::B::A"))));
20774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20782dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      notMatches("class A { class B { class C; }; };",
20792dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("::C"))));
20804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class A { class B { class C; }; };",
20822dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("::B::C"))));
20834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
20842dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("z::A::B::C"))));
20854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class A { class B { class C; }; };",
20872dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("A+B::C"))));
20884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
20894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, IsDefinition) {
20914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher DefinitionOfClassA =
20922dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("A"), isDefinition());
20934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class A {};", DefinitionOfClassA));
20944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A;", DefinitionOfClassA));
20954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher DefinitionOfVariableA =
20972dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("a"), isDefinition());
20984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));
20994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));
21004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher DefinitionOfMethodA =
21022dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasName("a"), isDefinition());
21034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));
21044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));
21054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, OfClass) {
21082dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher Constructor = constructExpr(hasDeclaration(methodDecl(
21094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      ofClass(hasName("X")))));
21104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
21124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(); }; void x(int) { X x; }", Constructor));
21134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
21144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(); }; void x(int) { X x = X(); }",
21154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
21164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
21174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: Y(); }; void x(int) { Y y; }",
21184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 Constructor));
21194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, VisitsTemplateInstantiations) {
21224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
21234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class A { public: void x(); };"
21244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class B { public: void y() { T t; t.x(); } };"
21252dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      "void f() { B<A> b; b.y(); }",
21262dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      callExpr(callee(methodDecl(hasName("x"))))));
21274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
21294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class A { public: void x(); };"
21304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class C {"
21314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      " public:"
21324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  template <typename T> class B { public: void y() { T t; t.x(); } };"
21334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};"
21344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void f() {"
21354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  C::B<A> b; b.y();"
21362dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      "}",
21372dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"),
21382dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 hasDescendant(callExpr(callee(methodDecl(hasName("x"))))))));
21394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2141e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Matcher, HandlesNullQualTypes) {
2142e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // FIXME: Add a Type matcher so we can replace uses of this
2143e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // variable with Type(True())
2144e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  const TypeMatcher AnyType = anything();
2145e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
2146e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // We don't really care whether this matcher succeeds; we're testing that
2147e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // it completes without crashing.
2148e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
2149e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "struct A { };"
2150e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "template <typename T>"
2151e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "void f(T t) {"
2152e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "  T local_t(t /* this becomes a null QualType in the AST */);"
2153e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "}"
2154e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "void g() {"
2155e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "  f(0);"
2156e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "}",
21572dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      expr(hasType(TypeMatcher(
2158e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper          anyOf(
2159e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper              TypeMatcher(hasDeclaration(anything())),
2160e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper              pointsTo(AnyType),
2161e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper              references(AnyType)
2162e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper              // Other QualType matchers should go here.
2163e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                ))))));
2164e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2165e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
21664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// For testing AST_MATCHER_P().
2167e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperAST_MATCHER_P(Decl, just, internal::Matcher<Decl>, AMatcher) {
21684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Make sure all special variables are used: node, match_finder,
21694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // bound_nodes_builder, and the parameter named 'AMatcher'.
21704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  return AMatcher.matches(Node, Finder, Builder);
21714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(AstMatcherPMacro, Works) {
21742dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher HasClassB = just(has(recordDecl(hasName("B")).bind("b")));
21754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
2177a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
21784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
2180a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("a")));
21814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
2183a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
21844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekAST_POLYMORPHIC_MATCHER_P(
2187e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper    polymorphicHas, internal::Matcher<Decl>, AMatcher) {
2188e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  TOOLING_COMPILE_ASSERT((llvm::is_same<NodeType, Decl>::value) ||
2189e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                         (llvm::is_same<NodeType, Stmt>::value),
21904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                         assert_node_type_is_accessible);
21914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  return Finder->matchesChildOf(
2192a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek      Node, AMatcher, Builder,
21934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
21944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      ASTMatchFinder::BK_First);
21954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(AstPolymorphicMatcherPMacro, Works) {
21982dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher HasClassB =
21992dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      polymorphicHas(recordDecl(hasName("B")).bind("b"));
22004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
2202a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
22034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
2205a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("a")));
22064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
2208a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
22094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher StatementHasClassB =
22112dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      polymorphicHas(recordDecl(hasName("B")));
22124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { class B {}; }", StatementHasClassB));
22144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(For, FindsForLoops) {
22174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { for(;;); }", forStmt()));
22184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { if(true) for(;;); }", forStmt()));
22191a00fee3933066024a2398f9456e5d6bc74344b9Daniel Jasper  EXPECT_TRUE(notMatches("int as[] = { 1, 2, 3 };"
22201a00fee3933066024a2398f9456e5d6bc74344b9Daniel Jasper                         "void f() { for (auto &a : as); }",
222131f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                         forStmt()));
22224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22246a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(For, ForLoopInternals) {
22256a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(matches("void f(){ int i; for (; i < 3 ; ); }",
22266a12449ec8862211856447d3df4c082a346339f2Daniel Jasper                      forStmt(hasCondition(anything()))));
22276a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(matches("void f() { for (int i = 0; ;); }",
22286a12449ec8862211856447d3df4c082a346339f2Daniel Jasper                      forStmt(hasLoopInit(anything()))));
22296a12449ec8862211856447d3df4c082a346339f2Daniel Jasper}
22306a12449ec8862211856447d3df4c082a346339f2Daniel Jasper
22316a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(For, NegativeForLoopInternals) {
22326a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }",
22332dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         forStmt(hasCondition(expr()))));
22346a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(notMatches("void f() {int i; for (; i < 4; ++i) {} }",
22356a12449ec8862211856447d3df4c082a346339f2Daniel Jasper                         forStmt(hasLoopInit(anything()))));
22366a12449ec8862211856447d3df4c082a346339f2Daniel Jasper}
22376a12449ec8862211856447d3df4c082a346339f2Daniel Jasper
22384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(For, ReportsNoFalsePositives) {
22394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { ; }", forStmt()));
22404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { if(true); }", forStmt()));
22414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(CompoundStatement, HandlesSimpleCases) {
22442dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("void f();", compoundStmt()));
22452dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("void f() {}", compoundStmt()));
22462dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("void f() {{}}", compoundStmt()));
22474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(CompoundStatement, DoesNotMatchEmptyStruct) {
22504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // It's not a compound statement just because there's "{}" in the source
22514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // text. This is an AST search, not grep.
22524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace n { struct S {}; }",
22532dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt()));
22544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("namespace n { struct S { void f() {{}} }; }",
22552dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt()));
22564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22586a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(HasBody, FindsBodyOfForWhileDoLoops) {
22594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { for(;;) {} }",
22602dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              forStmt(hasBody(compoundStmt()))));
22614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { for(;;); }",
22622dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              forStmt(hasBody(compoundStmt()))));
22636a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(matches("void f() { while(true) {} }",
22642dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              whileStmt(hasBody(compoundStmt()))));
22656a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(matches("void f() { do {} while(true); }",
22662dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              doStmt(hasBody(compoundStmt()))));
22674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
22704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // The simplest case: every compound statement is in a function
22714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // definition, and the function body itself must be a compound
22724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // statement.
22734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { for (;;); }",
22742dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(hasAnySubstatement(forStmt()))));
22754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnySubstatement, IsNotRecursive) {
22784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // It's really "has any immediate substatement".
22794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { if (true) for (;;); }",
22802dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(hasAnySubstatement(forStmt()))));
22814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnySubstatement, MatchesInNestedCompoundStatements) {
22844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { if (true) { for (;;); } }",
22852dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(hasAnySubstatement(forStmt()))));
22864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnySubstatement, FindsSubstatementBetweenOthers) {
22894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { 1; 2; 3; for (;;); 4; 5; 6; }",
22902dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(hasAnySubstatement(forStmt()))));
22914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) {
22944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { }",
22952dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(0))));
22964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() {}",
22972dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(1))));
22984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementCountIs, AppearsToMatchOnlyOneCount) {
23014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { 1; }",
23022dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(1))));
23034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { 1; }",
23042dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(0))));
23054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { 1; }",
23062dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(2))));
23074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementCountIs, WorksWithMultipleStatements) {
23104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { 1; 2; 3; }",
23112dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(3))));
23124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementCountIs, WorksWithNestedCompoundStatements) {
23154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
23162dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(1))));
23174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
23182dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(2))));
23194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
23202dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(3))));
23214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
23222dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(4))));
23234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Member, WorksInSimplestCase) {
23264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
23272dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      memberExpr(member(hasName("first")))));
23284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Member, DoesNotMatchTheBaseExpression) {
23314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Don't pick out the wrong part of the member expression, this should
23324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // be checking the member (name) only.
23334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
23342dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         memberExpr(member(hasName("first")))));
23354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Member, MatchesInMemberFunctionCall) {
23384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() {"
23394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "  struct { void first() {}; } s;"
23404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "  s.first();"
23414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "};",
23422dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      memberExpr(member(hasName("first")))));
23434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2345c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel JasperTEST(Member, MatchesMember) {
2346c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper  EXPECT_TRUE(matches(
2347c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper      "struct A { int i; }; void f() { A a; a.i = 2; }",
2348c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper      memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
2349c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper  EXPECT_TRUE(notMatches(
2350c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper      "struct A { float f; }; void f() { A a; a.f = 2.0f; }",
2351c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper      memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
2352c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper}
2353c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper
2354f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel JasperTEST(Member, UnderstandsAccess) {
2355f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(matches(
2356f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "struct A { int i; };", fieldDecl(isPublic(), hasName("i"))));
2357f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches(
2358f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "struct A { int i; };", fieldDecl(isProtected(), hasName("i"))));
2359f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches(
2360f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "struct A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
2361f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper
2362f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches(
2363f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "class A { int i; };", fieldDecl(isPublic(), hasName("i"))));
2364f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches(
2365f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "class A { int i; };", fieldDecl(isProtected(), hasName("i"))));
2366f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(matches(
2367f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "class A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
2368f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper
2369f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches(
2370f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "class A { protected: int i; };", fieldDecl(isPublic(), hasName("i"))));
2371f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(matches("class A { protected: int i; };",
2372f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper                      fieldDecl(isProtected(), hasName("i"))));
2373f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches(
2374f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper      "class A { protected: int i; };", fieldDecl(isPrivate(), hasName("i"))));
2375f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper
2376f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  // Non-member decls have the AccessSpecifier AS_none and thus aren't matched.
2377f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches("int i;", varDecl(isPublic(), hasName("i"))));
2378f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches("int i;", varDecl(isProtected(), hasName("i"))));
2379f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper  EXPECT_TRUE(notMatches("int i;", varDecl(isPrivate(), hasName("i"))));
2380f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper}
2381f3197e9eb02120522c1f60f88dacc1cfe5b210f0Daniel Jasper
2382671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri GribenkoTEST(Member, MatchesMemberAllocationFunction) {
238331f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  // Fails in C++11 mode
238431f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  EXPECT_TRUE(matchesConditionally(
238531f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper      "namespace std { typedef typeof(sizeof(int)) size_t; }"
238631f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper      "class X { void *operator new(std::size_t); };",
238731f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper      methodDecl(ofClass(hasName("X"))), true, "-std=gnu++98"));
2388671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri Gribenko
2389671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri Gribenko  EXPECT_TRUE(matches("class X { void operator delete(void*); };",
23902dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      methodDecl(ofClass(hasName("X")))));
2391671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri Gribenko
239231f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  // Fails in C++11 mode
239331f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  EXPECT_TRUE(matchesConditionally(
23942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      "namespace std { typedef typeof(sizeof(int)) size_t; }"
23952dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      "class X { void operator delete[](void*, std::size_t); };",
239631f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper      methodDecl(ofClass(hasName("X"))), true, "-std=gnu++98"));
2397671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri Gribenko}
2398671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri Gribenko
23994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasObjectExpression, DoesNotMatchMember) {
24004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
24014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
24022dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
24034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasObjectExpression, MatchesBaseOfVariable) {
24064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
24074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "struct X { int m; }; void f(X x) { x.m; }",
24082dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
24094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
24104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "struct X { int m; }; void f(X* x) { x->m; }",
24112dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberExpr(hasObjectExpression(
24122dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasType(pointsTo(recordDecl(hasName("X"))))))));
24134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasObjectExpression,
24164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek     MatchesObjectExpressionOfImplicitlyFormedMemberExpression) {
24174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
24184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X {}; struct S { X m; void f() { this->m; } };",
24192dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberExpr(hasObjectExpression(
24202dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasType(pointsTo(recordDecl(hasName("S"))))))));
24214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
24224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X {}; struct S { X m; void f() { m; } };",
24232dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberExpr(hasObjectExpression(
24242dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasType(pointsTo(recordDecl(hasName("S"))))))));
24254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Field, DoesNotMatchNonFieldMembers) {
24282dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class X { void m(); };", fieldDecl(hasName("m"))));
24292dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class X { class m {}; };", fieldDecl(hasName("m"))));
24302dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class X { enum { m }; };", fieldDecl(hasName("m"))));
24312dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class X { enum m {}; };", fieldDecl(hasName("m"))));
24324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Field, MatchesField) {
24352dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("class X { int m; };", fieldDecl(hasName("m"))));
24364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsConstQualified, MatchesConstInt) {
24394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const int i = 42;",
24402dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasType(isConstQualified()))));
24414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsConstQualified, MatchesConstPointer) {
24444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = 42; int* const p(&i);",
24452dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasType(isConstQualified()))));
24464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsConstQualified, MatchesThroughTypedef) {
24494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
24502dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasType(isConstQualified()))));
24514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p(0);",
24522dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasType(isConstQualified()))));
24534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsConstQualified, DoesNotMatchInappropriately) {
24564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
24572dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasType(isConstQualified()))));
24584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int const* p;",
24592dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasType(isConstQualified()))));
24604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2462089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(CastExpression, MatchesExplicitCasts) {
24633680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("char *p = reinterpret_cast<char *>(&p);",castExpr()));
24643680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("void *p = (void *)(&p);", castExpr()));
24653680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("char q, *p = const_cast<char *>(&q);", castExpr()));
24663680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("char c = char(0);", castExpr()));
2467089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2468089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(CastExpression, MatchesImplicitCasts) {
2469089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from int to char.
24703680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("char c = 0;", castExpr()));
2471089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from lvalue to rvalue.
24723680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("char c = 0, d = c;", castExpr()));
2473089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2474089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2475089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(CastExpression, DoesNotMatchNonCasts) {
24763680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(notMatches("char c = '0';", castExpr()));
24773680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(notMatches("char c, &q = c;", castExpr()));
24783680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(notMatches("int i = (0);", castExpr()));
24793680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
2480089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2481089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
24824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ReinterpretCast, MatchesSimpleCase) {
24834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("char* p = reinterpret_cast<char*>(&p);",
24843680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      reinterpretCastExpr()));
24854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ReinterpretCast, DoesNotMatchOtherCasts) {
24883680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(notMatches("char* p = (char*)(&p);", reinterpretCastExpr()));
24894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
24903680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                         reinterpretCastExpr()));
24914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void* p = static_cast<void*>(&p);",
24923680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                         reinterpretCastExpr()));
24934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
24944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                         "B b;"
24954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                         "D* p = dynamic_cast<D*>(&b);",
24963680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                         reinterpretCastExpr()));
24974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(FunctionalCast, MatchesSimpleCase) {
25004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  std::string foo_class = "class Foo { public: Foo(char*); };";
25014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",
25023680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      functionalCastExpr()));
25034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
25044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(FunctionalCast, DoesNotMatchOtherCasts) {
25064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  std::string FooClass = "class Foo { public: Foo(char*); };";
25074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
25084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",
25093680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                 functionalCastExpr()));
25104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
25114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches(FooClass + "void r() { Foo f = \"hello world\"; }",
25123680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                 functionalCastExpr()));
25134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
25144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DynamicCast, MatchesSimpleCase) {
25164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("struct B { virtual ~B() {} }; struct D : B {};"
25174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "B b;"
25184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "D* p = dynamic_cast<D*>(&b);",
25193680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      dynamicCastExpr()));
25204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
25214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StaticCast, MatchesSimpleCase) {
25234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void* p(static_cast<void*>(&p));",
25243680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      staticCastExpr()));
25254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
25264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
25274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StaticCast, DoesNotMatchOtherCasts) {
25283680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(notMatches("char* p = (char*)(&p);", staticCastExpr()));
25294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
25303680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                         staticCastExpr()));
25314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void* p = reinterpret_cast<char*>(&p);",
25323680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                         staticCastExpr()));
25334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
25344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                         "B b;"
25354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                         "D* p = dynamic_cast<D*>(&b);",
25363680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                         staticCastExpr()));
25374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
25384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2539e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel JasperTEST(CStyleCast, MatchesSimpleCase) {
2540e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper  EXPECT_TRUE(matches("int i = (int) 2.2f;", cStyleCastExpr()));
2541e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper}
2542e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper
2543e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel JasperTEST(CStyleCast, DoesNotMatchOtherCasts) {
2544e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper  EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);"
2545e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         "char q, *r = const_cast<char*>(&q);"
2546e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         "void* s = reinterpret_cast<char*>(&s);"
2547e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         "struct B { virtual ~B() {} }; struct D : B {};"
2548e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         "B b;"
2549e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         "D* t = dynamic_cast<D*>(&b);",
2550e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         cStyleCastExpr()));
2551e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper}
2552e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper
25534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasDestinationType, MatchesSimpleCase) {
25544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
25553680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      staticCastExpr(hasDestinationType(
25563680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          pointsTo(TypeMatcher(anything()))))));
25574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
25584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2559089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(HasImplicitDestinationType, MatchesSimpleCase) {
2560089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit const cast.
2561089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x; const int i = x;",
25623680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      implicitCastExpr(
25633680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          hasImplicitDestinationType(isInteger()))));
2564089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit array-to-pointer cast.
2565089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int arr[3]; int *p = arr;",
25663680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      implicitCastExpr(hasImplicitDestinationType(
25673680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          pointsTo(TypeMatcher(anything()))))));
2568089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2569089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2570089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(HasImplicitDestinationType, DoesNotMatchIncorrectly) {
2571089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from int to char.
2572089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char c = 0;",
25733680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      implicitCastExpr(hasImplicitDestinationType(
25743680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          unless(anything())))));
2575089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit array-to-pointer cast.
2576089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int arr[3]; int *p = arr;",
25773680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      implicitCastExpr(hasImplicitDestinationType(
25783680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          unless(anything())))));
2579089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2580089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2581089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(ImplicitCast, MatchesSimpleCase) {
2582089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit const cast.
2583089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0; const int y = x;",
25842dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(implicitCastExpr()))));
2585089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from int to char.
2586089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("char c = 0;",
25872dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(implicitCastExpr()))));
2588089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit array-to-pointer cast.
2589089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int arr[6]; int *p = arr;",
25902dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(implicitCastExpr()))));
2591089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2592089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2593089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(ImplicitCast, DoesNotMatchIncorrectly) {
25942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  // This test verifies that implicitCastExpr() matches exactly when implicit casts
2595089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // are present, and that it ignores explicit and paren casts.
2596089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2597089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These two test cases have no casts.
2598089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x = 0;",
25992dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(implicitCastExpr()))));
2600089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x = 0, &y = x;",
26012dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(implicitCastExpr()))));
2602089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2603089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x = 0; double d = (double) x;",
26042dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(implicitCastExpr()))));
2605089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("const int *p; int *q = const_cast<int *>(p);",
26062dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(implicitCastExpr()))));
2607089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2608089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x = (0);",
26092dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(implicitCastExpr()))));
2610089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2611089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2612089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringImpCasts, MatchesImpCasts) {
2613089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test checks that ignoringImpCasts matches when implicit casts are
2614089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // present and its inner matcher alone does not match.
2615089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // Note that this test creates an implicit const cast.
2616089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0; const int y = x;",
26172dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringImpCasts(
26182dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          declRefExpr(to(varDecl(hasName("x")))))))));
2619089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implict cast from int to char.
2620089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("char x = 0;",
26212dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringImpCasts(
2622089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                          integerLiteral(equals(0)))))));
2623089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2624089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2625089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringImpCasts, DoesNotMatchIncorrectly) {
2626089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These tests verify that ignoringImpCasts does not match if the inner
2627089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // matcher does not match.
2628089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // Note that the first test creates an implicit const cast.
2629089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x; const int y = x;",
26302dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
2631089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
2632089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x; int y = x;",
26332dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
2634089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
2635089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2636089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These tests verify that ignoringImplictCasts does not look through explicit
2637089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // casts or parentheses.
2638089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
26392dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
26402dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
2641089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int i = (0);",
26422dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
26432dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
2644089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("float i = (float)0;",
26452dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
26462dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
2647089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("float i = float(0);",
26482dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
26492dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
2650089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2651089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2652089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringImpCasts, MatchesWithoutImpCasts) {
2653089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test verifies that expressions that do not have implicit casts
2654089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // still match the inner matcher.
2655089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0; int &y = x;",
26562dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringImpCasts(
26572dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          declRefExpr(to(varDecl(hasName("x")))))))));
2658089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2659089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2660089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenCasts, MatchesParenCasts) {
2661089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test checks that ignoringParenCasts matches when parentheses and/or
2662089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // casts are present and its inner matcher alone does not match.
2663089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = (0);",
26642dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
26652dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
2666089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = (((((0)))));",
26672dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
26682dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
2669089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2670089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implict cast from int to char in addition to the
2671089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // parentheses.
2672089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("char x = (0);",
26732dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
26742dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
2675089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2676089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("char x = (char)0;",
26772dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
26782dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
2679089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
26802dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
2681089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                          integerLiteral(equals(0)))))));
2682089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2683089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2684089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenCasts, MatchesWithoutParenCasts) {
2685089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test verifies that expressions that do not have any casts still match.
2686089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0;",
26872dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
26882dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
2689089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2690089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2691089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenCasts, DoesNotMatchIncorrectly) {
2692089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These tests verify that ignoringImpCasts does not match if the inner
2693089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // matcher does not match.
2694089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x = ((0));",
26952dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenCasts(
2696089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
2697089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2698089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from int to char in addition to the
2699089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // parentheses.
2700089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char x = ((0));",
27012dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenCasts(
2702089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
2703089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2704089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char *x = static_cast<char *>((0));",
27052dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenCasts(
2706089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
2707089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2708089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2709089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenAndImpCasts, MatchesParenImpCasts) {
2710089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test checks that ignoringParenAndImpCasts matches when
2711089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // parentheses and/or implicit casts are present and its inner matcher alone
2712089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // does not match.
2713089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // Note that this test creates an implicit const cast.
2714089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0; const int y = x;",
27152dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenImpCasts(
27162dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          declRefExpr(to(varDecl(hasName("x")))))))));
2717089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from int to char.
2718089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("const char x = (0);",
27192dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenImpCasts(
27202dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
2721089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2722089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2723089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenAndImpCasts, MatchesWithoutParenImpCasts) {
2724089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test verifies that expressions that do not have parentheses or
2725089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // implicit casts still match.
2726089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0; int &y = x;",
27272dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenImpCasts(
27282dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          declRefExpr(to(varDecl(hasName("x")))))))));
2729089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0;",
27302dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenImpCasts(
27312dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
2732089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2733089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2734089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenAndImpCasts, DoesNotMatchIncorrectly) {
2735089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These tests verify that ignoringParenImpCasts does not match if
2736089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // the inner matcher does not match.
2737089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast.
2738089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char c = ((3));",
27392dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenImpCasts(
2740089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
2741089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These tests verify that ignoringParenAndImplictCasts does not look
2742089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // through explicit casts.
2743089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("float y = (float(0));",
27442dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenImpCasts(
27452dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
2746089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("float y = (float)0;",
27472dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenImpCasts(
27482dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
2749089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
27502dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenImpCasts(
27512dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
2752089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2753089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2754715c9568ee5d75f25dab98229c87bcec880daf5dManuel KlimekTEST(HasSourceExpression, MatchesImplicitCasts) {
27554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
27564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "void r() {string a_string; URL url = a_string; }",
27573680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      implicitCastExpr(
27583680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          hasSourceExpression(constructExpr()))));
27594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2761715c9568ee5d75f25dab98229c87bcec880daf5dManuel KlimekTEST(HasSourceExpression, MatchesExplicitCasts) {
2762715c9568ee5d75f25dab98229c87bcec880daf5dManuel Klimek  EXPECT_TRUE(matches("float x = static_cast<float>(42);",
27633680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      explicitCastExpr(
27642dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          hasSourceExpression(hasDescendant(
27653680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                              expr(integerLiteral()))))));
2766715c9568ee5d75f25dab98229c87bcec880daf5dManuel Klimek}
2767715c9568ee5d75f25dab98229c87bcec880daf5dManuel Klimek
27684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Statement, DoesNotMatchDeclarations) {
27692dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class X {};", stmt()));
27704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Statement, MatchesCompoundStatments) {
27732dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("void x() {}", stmt()));
27744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationStatement, DoesNotMatchCompoundStatements) {
27772dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("void x() {}", declStmt()));
27784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationStatement, MatchesVariableDeclarationStatements) {
27812dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("void x() { int a; }", declStmt()));
27824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2784e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(InitListExpression, MatchesInitListExpression) {
2785e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("int a[] = { 1, 2 };",
2786e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      initListExpr(hasType(asString("int [2]")))));
2787e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };",
27882dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      initListExpr(hasType(recordDecl(hasName("B"))))));
2789e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2790e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
2791e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UsingDeclaration, MatchesUsingDeclarations) {
2792e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("namespace X { int x; } using X::x;",
2793e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      usingDecl()));
2794e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2795e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
2796e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UsingDeclaration, MatchesShadowUsingDelcarations) {
2797e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("namespace f { int a; } using f::a;",
2798e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      usingDecl(hasAnyUsingShadowDecl(hasName("a")))));
2799e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2800e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
2801e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UsingDeclaration, MatchesSpecificTarget) {
2802e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
2803e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      usingDecl(hasAnyUsingShadowDecl(
28042dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          hasTargetDecl(functionDecl())))));
2805e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
2806e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                         usingDecl(hasAnyUsingShadowDecl(
28072dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             hasTargetDecl(functionDecl())))));
2808e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2809e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
2810e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UsingDeclaration, ThroughUsingDeclaration) {
2811e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
2812e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "namespace a { void f(); } using a::f; void g() { f(); }",
28132dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      declRefExpr(throughUsingDecl(anything()))));
2814e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches(
2815e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "namespace a { void f(); } using a::f; void g() { a::f(); }",
28162dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      declRefExpr(throughUsingDecl(anything()))));
2817e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2818e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
2819425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam PanzerTEST(SingleDecl, IsSingleDecl) {
2820425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  StatementMatcher SingleDeclStmt =
28212dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      declStmt(hasSingleDecl(varDecl(hasInitializer(anything()))));
2822425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(matches("void f() {int a = 4;}", SingleDeclStmt));
2823425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(notMatches("void f() {int a;}", SingleDeclStmt));
2824425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
2825425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer                          SingleDeclStmt));
2826425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer}
2827425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer
2828425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam PanzerTEST(DeclStmt, ContainsDeclaration) {
28292dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher MatchesInit = varDecl(hasInitializer(anything()));
2830425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer
2831425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(matches("void f() {int a = 4;}",
28322dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      declStmt(containsDeclaration(0, MatchesInit))));
2833425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(matches("void f() {int a = 4, b = 3;}",
28342dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      declStmt(containsDeclaration(0, MatchesInit),
28352dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                               containsDeclaration(1, MatchesInit))));
2836425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  unsigned WrongIndex = 42;
2837425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
28382dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         declStmt(containsDeclaration(WrongIndex,
2839425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer                                                      MatchesInit))));
2840425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer}
2841425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer
2842425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam PanzerTEST(DeclCount, DeclCountIsCorrect) {
2843425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(matches("void f() {int i,j;}",
28442dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      declStmt(declCountIs(2))));
2845425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(notMatches("void f() {int i,j; int k;}",
28462dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         declStmt(declCountIs(3))));
2847425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(notMatches("void f() {int i,j, k, l;}",
28482dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         declStmt(declCountIs(3))));
2849425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer}
2850425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer
28514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(While, MatchesWhileLoops) {
28524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() {}", whileStmt()));
28534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { while(true); }", whileStmt()));
28544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { do {} while(true); }", whileStmt()));
28554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Do, MatchesDoLoops) {
28584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { do {} while(true); }", doStmt()));
28594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { do ; while(false); }", doStmt()));
28604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Do, DoesNotMatchWhileLoops) {
28634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { while(true) {} }", doStmt()));
28644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(SwitchCase, MatchesCase) {
28674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchCase()));
28684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchCase()));
28694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchCase()));
28704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { switch(42) {} }", switchCase()));
28714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2873b54b7646b2d00a85d80e40adf7c49553f150c736Daniel JasperTEST(SwitchCase, MatchesSwitch) {
2874b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchStmt()));
2875b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchStmt()));
2876b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchStmt()));
2877b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(notMatches("void x() {}", switchStmt()));
2878b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper}
2879b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper
2880b54b7646b2d00a85d80e40adf7c49553f150c736Daniel JasperTEST(ExceptionHandling, SimpleCases) {
2881b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", catchStmt()));
2882b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", tryStmt()));
2883b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(notMatches("void foo() try { } catch(int X) { }", throwExpr()));
2884b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void foo() try { throw; } catch(int X) { }",
2885b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper                      throwExpr()));
2886b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void foo() try { throw 5;} catch(int X) { }",
2887b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper                      throwExpr()));
2888b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper}
2889b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper
28904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasConditionVariableStatement, DoesNotMatchCondition) {
28914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
28924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void x() { if(true) {} }",
28932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      ifStmt(hasConditionVariableStatement(declStmt()))));
28944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
28954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void x() { int x; if((x = 42)) {} }",
28962dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      ifStmt(hasConditionVariableStatement(declStmt()))));
28974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasConditionVariableStatement, MatchesConditionVariables) {
29004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
29014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void x() { if(int* a = 0) {} }",
29022dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      ifStmt(hasConditionVariableStatement(declStmt()))));
29034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
29054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEach, BindsOneNode) {
29064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
29072dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"), forEach(fieldDecl(hasName("x")).bind("x"))),
2908a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("x", 1)));
29094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
29114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEach, BindsMultipleNodes) {
29124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
29132dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"), forEach(fieldDecl().bind("f"))),
2914a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("f", 3)));
29154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
29174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEach, BindsRecursiveCombinations) {
29184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
29194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class C { class D { int x; int y; }; class E { int y; int z; }; };",
29202dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"),
29212dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 forEach(recordDecl(forEach(fieldDecl().bind("f"))))),
2922a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("f", 4)));
29234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
29254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEachDescendant, BindsOneNode) {
29264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
29272dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"),
29282dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 forEachDescendant(fieldDecl(hasName("x")).bind("x"))),
2929a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("x", 1)));
29304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
29325f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel JasperTEST(ForEachDescendant, NestedForEachDescendant) {
29335f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper  DeclarationMatcher m = recordDecl(
29345f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper      isDefinition(), decl().bind("x"), hasName("C"));
29355f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
29365f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper    "class A { class B { class C {}; }; };",
29375f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper    recordDecl(hasName("A"), anyOf(m, forEachDescendant(m))),
29385f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper    new VerifyIdIsBoundTo<Decl>("x", "C")));
29395f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper
29405f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper  // FIXME: This is not really a useful matcher, but the result is still
29415f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper  // surprising (currently binds "A").
29425f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper  //EXPECT_TRUE(matchAndVerifyResultTrue(
29435f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper  //  "class A { class B { class C {}; }; };",
29445f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper  //  recordDecl(hasName("A"), allOf(hasDescendant(m), anyOf(m, anything()))),
29455f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper  //  new VerifyIdIsBoundTo<Decl>("x", "C")));
29465f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper}
29475f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper
29484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEachDescendant, BindsMultipleNodes) {
29494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
29504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class C { class D { int x; int y; }; "
29514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "          class E { class F { int y; int z; }; }; };",
29522dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"), forEachDescendant(fieldDecl().bind("f"))),
2953a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("f", 4)));
29544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
29564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEachDescendant, BindsRecursiveCombinations) {
29574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
29584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class C { class D { "
29594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "          class E { class F { class G { int y; int z; }; }; }; }; };",
29602dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"), forEachDescendant(recordDecl(
29612dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          forEachDescendant(fieldDecl().bind("f"))))),
2962a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("f", 8)));
29634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
296511c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel JasperTEST(ForEachDescendant, BindsCorrectNodes) {
296611c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
296711c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      "class C { void f(); int i; };",
296811c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
296911c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("decl", 1)));
297011c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
297111c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      "class C { void f() {} int i; };",
297211c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
297311c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      new VerifyIdIsBoundTo<FunctionDecl>("decl", 1)));
297411c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper}
297511c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper
2976152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel KlimekTEST(FindAll, BindsNodeOnMatch) {
2977152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
2978152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      "class A {};",
2979152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      recordDecl(hasName("::A"), findAll(recordDecl(hasName("::A")).bind("v"))),
2980152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      new VerifyIdIsBoundTo<CXXRecordDecl>("v", 1)));
2981152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek}
2982152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek
2983152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel KlimekTEST(FindAll, BindsDescendantNodeOnMatch) {
2984152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
2985152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      "class A { int a; int b; };",
2986152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      recordDecl(hasName("::A"), findAll(fieldDecl().bind("v"))),
2987152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      new VerifyIdIsBoundTo<FieldDecl>("v", 2)));
2988152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek}
2989152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek
2990152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel KlimekTEST(FindAll, BindsNodeAndDescendantNodesOnOneMatch) {
2991152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
2992152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      "class A { int a; int b; };",
2993152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      recordDecl(hasName("::A"),
2994152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek                 findAll(decl(anyOf(recordDecl(hasName("::A")).bind("v"),
2995152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek                                    fieldDecl().bind("v"))))),
2996152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      new VerifyIdIsBoundTo<Decl>("v", 3)));
2997152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek
2998152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
2999152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      "class A { class B {}; class C {}; };",
3000152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("v"))),
3001152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek      new VerifyIdIsBoundTo<CXXRecordDecl>("v", 3)));
3002152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek}
3003152ea0e4711f7aed75f6a1d1995b0bd94eb31c98Manuel Klimek
30047387673f83b8b37f660422947c9990778ba88193Manuel KlimekTEST(EachOf, TriggersForEachMatch) {
30057387673f83b8b37f660422947c9990778ba88193Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
30067387673f83b8b37f660422947c9990778ba88193Manuel Klimek      "class A { int a; int b; };",
30077387673f83b8b37f660422947c9990778ba88193Manuel Klimek      recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
30087387673f83b8b37f660422947c9990778ba88193Manuel Klimek                        has(fieldDecl(hasName("b")).bind("v")))),
30097387673f83b8b37f660422947c9990778ba88193Manuel Klimek      new VerifyIdIsBoundTo<FieldDecl>("v", 2)));
30107387673f83b8b37f660422947c9990778ba88193Manuel Klimek}
30117387673f83b8b37f660422947c9990778ba88193Manuel Klimek
30127387673f83b8b37f660422947c9990778ba88193Manuel KlimekTEST(EachOf, BehavesLikeAnyOfUnlessBothMatch) {
30137387673f83b8b37f660422947c9990778ba88193Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
30147387673f83b8b37f660422947c9990778ba88193Manuel Klimek      "class A { int a; int c; };",
30157387673f83b8b37f660422947c9990778ba88193Manuel Klimek      recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
30167387673f83b8b37f660422947c9990778ba88193Manuel Klimek                        has(fieldDecl(hasName("b")).bind("v")))),
30177387673f83b8b37f660422947c9990778ba88193Manuel Klimek      new VerifyIdIsBoundTo<FieldDecl>("v", 1)));
30187387673f83b8b37f660422947c9990778ba88193Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
30197387673f83b8b37f660422947c9990778ba88193Manuel Klimek      "class A { int c; int b; };",
30207387673f83b8b37f660422947c9990778ba88193Manuel Klimek      recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
30217387673f83b8b37f660422947c9990778ba88193Manuel Klimek                        has(fieldDecl(hasName("b")).bind("v")))),
30227387673f83b8b37f660422947c9990778ba88193Manuel Klimek      new VerifyIdIsBoundTo<FieldDecl>("v", 1)));
30237387673f83b8b37f660422947c9990778ba88193Manuel Klimek  EXPECT_TRUE(notMatches(
30247387673f83b8b37f660422947c9990778ba88193Manuel Klimek      "class A { int c; int d; };",
30257387673f83b8b37f660422947c9990778ba88193Manuel Klimek      recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
30267387673f83b8b37f660422947c9990778ba88193Manuel Klimek                        has(fieldDecl(hasName("b")).bind("v"))))));
30277387673f83b8b37f660422947c9990778ba88193Manuel Klimek}
30284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
30294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) {
30304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Make sure that we can both match the class by name (::X) and by the type
30314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // the template was instantiated with (via a field).
30324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
30334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
30344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X {}; class A {}; X<A> x;",
30352dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("::X"), isTemplateInstantiation())));
30364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
30374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
30384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X { T t; }; class A {}; X<A> x;",
30392dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isTemplateInstantiation(), hasDescendant(
30402dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          fieldDecl(hasType(recordDecl(hasName("A"))))))));
30414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
30424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
30434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) {
30444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
30454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
30462dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionDecl(hasParameter(0, hasType(recordDecl(hasName("A")))),
30474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek               isTemplateInstantiation())));
30484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
30494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
30504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) {
30514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
30524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X { T t; }; class A {};"
30534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template class X<A>;",
30542dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isTemplateInstantiation(), hasDescendant(
30552dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          fieldDecl(hasType(recordDecl(hasName("A"))))))));
30564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
30574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
30584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation,
30594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek     MatchesInstantiationOfPartiallySpecializedClassTemplate) {
30604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
30614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X {};"
30624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
30632dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("::X"), isTemplateInstantiation())));
30644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
30654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
30664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation,
30674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek     MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
30684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
30694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class A {};"
30704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X {"
30714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  template <typename U> class Y { U u; };"
30724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Y<A> y;"
30734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};",
30742dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("::X::Y"), isTemplateInstantiation())));
30754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
30764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
30774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) {
30784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // FIXME: Figure out whether this makes sense. It doesn't affect the
30794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // normal use case as long as the uppermost instantiation always is marked
30804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // as template instantiation, but it might be confusing as a predicate.
30814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
30824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class A {};"
30834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X {"
30844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  template <typename U> class Y { U u; };"
30854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Y<T> y;"
30864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "}; X<A> x;",
30872dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
30884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
30894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
30904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) {
30914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
30924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X {}; class A {};"
30934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <> class X<A> {}; X<A> x;",
30942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("::X"), isTemplateInstantiation())));
30954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
30964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
30974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) {
30984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
30994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class A {}; class Y { A a; };",
31002dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isTemplateInstantiation())));
31014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
31024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
31038456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(IsExplicitTemplateSpecialization,
31048456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko     DoesNotMatchPrimaryTemplate) {
31058456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
31068456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> class X {};",
31072dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isExplicitTemplateSpecialization())));
31088456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
31098456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> void f(T t);",
31102dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionDecl(isExplicitTemplateSpecialization())));
31118456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
31128456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
31138456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(IsExplicitTemplateSpecialization,
31148456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko     DoesNotMatchExplicitTemplateInstantiations) {
31158456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
31168456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> class X {};"
31178456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template class X<int>; extern template class X<long>;",
31182dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isExplicitTemplateSpecialization())));
31198456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
31208456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> void f(T t) {}"
31218456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template void f(int t); extern template void f(long t);",
31222dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionDecl(isExplicitTemplateSpecialization())));
31238456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
31248456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
31258456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(IsExplicitTemplateSpecialization,
31268456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko     DoesNotMatchImplicitTemplateInstantiations) {
31278456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
31288456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> class X {}; X<int> x;",
31292dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isExplicitTemplateSpecialization())));
31308456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
31318456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> void f(T t); void g() { f(10); }",
31322dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionDecl(isExplicitTemplateSpecialization())));
31338456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
31348456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
31358456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(IsExplicitTemplateSpecialization,
31368456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko     MatchesExplicitTemplateSpecializations) {
31378456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(matches(
31388456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> class X {};"
31398456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template<> class X<int> {};",
31402dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isExplicitTemplateSpecialization())));
31418456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(matches(
31428456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> void f(T t) {}"
31438456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template<> void f(int t) {}",
31442dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionDecl(isExplicitTemplateSpecialization())));
31458456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
31468456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
3147579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncenstor, MatchesDeclarationAncestors) {
3148579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
3149579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "class A { class B { class C {}; }; };",
3150579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("A"))))));
3151579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3152579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3153579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncenstor, FailsIfNoAncestorMatches) {
3154579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(notMatches(
3155579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "class A { class B { class C {}; }; };",
3156579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("X"))))));
3157579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3158579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3159579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, MatchesDeclarationsThatGetVisitedLater) {
3160579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
3161579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "class A { class B { void f() { C c; } class C {}; }; };",
3162579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      varDecl(hasName("c"), hasType(recordDecl(hasName("C"),
3163579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek          hasAncestor(recordDecl(hasName("A"))))))));
3164579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3165579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3166579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncenstor, MatchesStatementAncestors) {
3167579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
3168579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "void f() { if (true) { while (false) { 42; } } }",
31693680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      integerLiteral(equals(42), hasAncestor(ifStmt()))));
3170579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3171579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3172579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, DrillsThroughDifferentHierarchies) {
3173579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
3174579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "void f() { if (true) { int x = 42; } }",
31753680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      integerLiteral(equals(42), hasAncestor(functionDecl(hasName("f"))))));
3176579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3177579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3178579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, BindsRecursiveCombinations) {
3179579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3180579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "class C { class D { class E { class F { int y; }; }; }; };",
3181579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      fieldDecl(hasAncestor(recordDecl(hasAncestor(recordDecl().bind("r"))))),
3182a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<CXXRecordDecl>("r", 1)));
3183579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3184579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3185579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, BindsCombinationsWithHasDescendant) {
3186579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3187579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "class C { class D { class E { class F { int y; }; }; }; };",
3188579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      fieldDecl(hasAncestor(
3189579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek          decl(
3190579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek            hasDescendant(recordDecl(isDefinition(),
3191579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek                                     hasAncestor(recordDecl())))
3192579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek          ).bind("d")
3193579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      )),
3194a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<CXXRecordDecl>("d", "E")));
3195579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3196579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3197374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel KlimekTEST(HasAncestor, MatchesClosestAncestor) {
3198374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3199374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      "template <typename T> struct C {"
3200374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      "  void f(int) {"
3201374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      "    struct I { void g(T) { int x; } } i; i.g(42);"
3202374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      "  }"
3203374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      "};"
3204374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      "template struct C<int>;",
3205374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      varDecl(hasName("x"),
3206374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek              hasAncestor(functionDecl(hasParameter(
3207374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek                  0, varDecl(hasType(asString("int"))))).bind("f"))).bind("v"),
3208374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      new VerifyIdIsBoundTo<FunctionDecl>("f", "g", 2)));
3209374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek}
3210374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek
3211579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, MatchesInTemplateInstantiations) {
3212579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
3213579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "template <typename T> struct A { struct B { struct C { T t; }; }; }; "
3214579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "A<int>::B::C a;",
3215579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      fieldDecl(hasType(asString("int")),
3216579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek                hasAncestor(recordDecl(hasName("A"))))));
3217579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3218579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3219579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, MatchesInImplicitCode) {
3220579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
3221579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "struct X {}; struct A { A() {} X x; };",
3222579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      constructorDecl(
3223579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek          hasAnyConstructorInitializer(withInitializer(expr(
3224579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek              hasAncestor(recordDecl(hasName("A")))))))));
3225579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3226579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3227c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel JasperTEST(HasParent, MatchesOnlyParent) {
3228c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper  EXPECT_TRUE(matches(
3229c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      "void f() { if (true) { int x = 42; } }",
3230c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      compoundStmt(hasParent(ifStmt()))));
3231c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper  EXPECT_TRUE(notMatches(
3232c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      "void f() { for (;;) { int x = 42; } }",
3233c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      compoundStmt(hasParent(ifStmt()))));
3234c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper  EXPECT_TRUE(notMatches(
3235c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      "void f() { if (true) for (;;) { int x = 42; } }",
3236c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      compoundStmt(hasParent(ifStmt()))));
3237c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper}
3238c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper
323930ace3715015b4a9bc5fa538a6515481abed40f9Manuel KlimekTEST(HasAncestor, MatchesAllAncestors) {
324030ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek  EXPECT_TRUE(matches(
324130ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "template <typename T> struct C { static void f() { 42; } };"
324230ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "void t() { C<int>::f(); }",
324330ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      integerLiteral(
324430ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek          equals(42),
324530ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek          allOf(hasAncestor(recordDecl(isTemplateInstantiation())),
324630ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek                hasAncestor(recordDecl(unless(isTemplateInstantiation())))))));
324730ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek}
324830ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek
324930ace3715015b4a9bc5fa538a6515481abed40f9Manuel KlimekTEST(HasParent, MatchesAllParents) {
325030ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek  EXPECT_TRUE(matches(
325130ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "template <typename T> struct C { static void f() { 42; } };"
325230ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "void t() { C<int>::f(); }",
325330ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      integerLiteral(
325430ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek          equals(42),
325530ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek          hasParent(compoundStmt(hasParent(functionDecl(
325630ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek              hasParent(recordDecl(isTemplateInstantiation())))))))));
325730ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek  EXPECT_TRUE(matches(
325830ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "template <typename T> struct C { static void f() { 42; } };"
325930ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "void t() { C<int>::f(); }",
326030ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      integerLiteral(
326130ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek          equals(42),
326230ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek          hasParent(compoundStmt(hasParent(functionDecl(
326330ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek              hasParent(recordDecl(unless(isTemplateInstantiation()))))))))));
326430ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek  EXPECT_TRUE(matches(
326530ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "template <typename T> struct C { static void f() { 42; } };"
326630ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "void t() { C<int>::f(); }",
326730ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      integerLiteral(equals(42),
326830ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek                     hasParent(compoundStmt(allOf(
326930ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek                         hasParent(functionDecl(
327030ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek                             hasParent(recordDecl(isTemplateInstantiation())))),
327130ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek                         hasParent(functionDecl(hasParent(recordDecl(
327230ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek                             unless(isTemplateInstantiation())))))))))));
3273374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek  EXPECT_TRUE(
3274374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek      notMatches("template <typename T> struct C { static void f() {} };"
3275374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek                 "void t() { C<int>::f(); }",
3276374516c8ec4f0fcf5a8b65ef9cf029f862d11096Manuel Klimek                 compoundStmt(hasParent(recordDecl()))));
327730ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek}
327830ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek
3279ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesTypes) {
3280ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("struct S {};", qualType().bind("loc")));
3281ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3282ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3283ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesArrayTypes) {
3284ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[] = {2,3};", arrayType()));
3285ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[42];", arrayType()));
3286ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("void f(int b) { int a[b]; }", arrayType()));
3287ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3288ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches("struct A {}; A a[7];",
3289ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                         arrayType(hasElementType(builtinType()))));
3290ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3291ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3292ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int const a[] = { 2, 3 };",
3293ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(arrayType(hasElementType(builtinType())))));
3294ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3295ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int const a[] = { 2, 3 };",
3296ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
3297ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3298ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "typedef const int T; T x[] = { 1, 2 };",
3299ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(isConstQualified(), arrayType())));
3300ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3301ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
3302ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int a[] = { 2, 3 };",
3303ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
3304ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
3305ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int a[] = { 2, 3 };",
3306ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(arrayType(hasElementType(isConstQualified(), builtinType())))));
3307ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
3308ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int const a[] = { 2, 3 };",
3309ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(arrayType(hasElementType(builtinType())),
3310ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper               unless(isConstQualified()))));
3311ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3312ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[2];",
3313ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                      constantArrayType(hasElementType(builtinType()))));
3314ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("const int a = 0;", qualType(isInteger())));
3315ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3316ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3317ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesComplexTypes) {
3318ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("_Complex float f;", complexType()));
3319ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3320ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "_Complex float f;",
3321ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    complexType(hasElementType(builtinType()))));
3322ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
3323ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "_Complex float f;",
3324ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    complexType(hasElementType(isInteger()))));
3325ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3326ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3327ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesConstantArrayTypes) {
3328ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[2];", constantArrayType()));
3329ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
3330ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "void f() { int a[] = { 2, 3 }; int b[a[0]]; }",
3331ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    constantArrayType(hasElementType(builtinType()))));
3332ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3333ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[42];", constantArrayType(hasSize(42))));
3334ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int b[2*21];", constantArrayType(hasSize(42))));
3335ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches("int c[41], d[43];", constantArrayType(hasSize(42))));
3336ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3337ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3338ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesDependentSizedArrayTypes) {
3339ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3340ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "template <typename T, int Size> class array { T data[Size]; };",
3341ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    dependentSizedArrayType()));
3342ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
3343ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "int a[42]; int b[] = { 2, 3 }; void f() { int c[b[0]]; }",
3344ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    dependentSizedArrayType()));
3345ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3346ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3347ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesIncompleteArrayType) {
3348ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[] = { 2, 3 };", incompleteArrayType()));
3349ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("void f(int a[]) {}", incompleteArrayType()));
3350ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3351ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches("int a[42]; void f() { int b[a[0]]; }",
3352ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                         incompleteArrayType()));
3353ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3354ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3355ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesVariableArrayType) {
3356ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("void f(int b) { int a[b]; }", variableArrayType()));
3357ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches("int a[] = {2, 3}; int b[42];", variableArrayType()));
3358ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3359ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3360ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "void f(int b) { int a[b]; }",
3361ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    variableArrayType(hasSizeExpr(ignoringImpCasts(declRefExpr(to(
3362ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      varDecl(hasName("b")))))))));
3363ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3364ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3365ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesAtomicTypes) {
3366ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("_Atomic(int) i;", atomicType()));
3367ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3368ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("_Atomic(int) i;",
3369ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                      atomicType(hasValueType(isInteger()))));
3370ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches("_Atomic(float) f;",
3371ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                         atomicType(hasValueType(isInteger()))));
3372ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3373ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3374ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesAutoTypes) {
3375ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("auto i = 2;", autoType()));
3376ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int v[] = { 2, 3 }; void f() { for (int i : v) {} }",
3377ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                      autoType()));
3378ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3379ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("auto a = 1;",
3380ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                      autoType(hasDeducedType(isInteger()))));
3381ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches("auto b = 2.0;",
3382ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                         autoType(hasDeducedType(isInteger()))));
3383ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3384ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3385a267cf6f87dc695143d65fc61ec1744564f55932Daniel JasperTEST(TypeMatching, MatchesFunctionTypes) {
3386a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("int (*f)(int);", functionType()));
3387a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f(int i) {}", functionType()));
3388a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper}
3389a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
339088be2fdec7a1375bc729a6499629532e7872f11aEdwin VaneTEST(TypeMatching, MatchesParenType) {
339188be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane  EXPECT_TRUE(
339288be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane      matches("int (*array)[4];", varDecl(hasType(pointsTo(parenType())))));
339388be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane  EXPECT_TRUE(notMatches("int *array[4];", varDecl(hasType(parenType()))));
339488be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane
339588be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane  EXPECT_TRUE(matches(
339688be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane      "int (*ptr_to_func)(int);",
339788be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane      varDecl(hasType(pointsTo(parenType(innerType(functionType())))))));
339888be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane  EXPECT_TRUE(notMatches(
339988be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane      "int (*ptr_to_array)[4];",
340088be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane      varDecl(hasType(pointsTo(parenType(innerType(functionType())))))));
340188be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane}
340288be2fdec7a1375bc729a6499629532e7872f11aEdwin Vane
3403ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, PointerTypes) {
34041802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  // FIXME: Reactive when these tests can be more specific (not matching
34051802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  // implicit code on certain platforms), likely when we have hasDescendant for
34061802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  // Types/TypeLocs.
34071802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //EXPECT_TRUE(matchAndVerifyResultTrue(
34081802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    "int* a;",
34091802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    pointerTypeLoc(pointeeLoc(typeLoc().bind("loc"))),
34101802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    new VerifyIdIsBoundTo<TypeLoc>("loc", 1)));
34111802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //EXPECT_TRUE(matchAndVerifyResultTrue(
34121802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    "int* a;",
34131802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    pointerTypeLoc().bind("loc"),
34141802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    new VerifyIdIsBoundTo<TypeLoc>("loc", 1)));
3415ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3416ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int** a;",
34175be093c0ef46c7749c942d0d9056af6dc3d591a4David Blaikie      loc(pointerType(pointee(qualType())))));
3418ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3419ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int** a;",
3420ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      loc(pointerType(pointee(pointerType())))));
3421ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3422ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int* b; int* * const a = &b;",
3423ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      loc(qualType(isConstQualified(), pointerType()))));
3424ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3425ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  std::string Fragment = "struct A { int i; }; int A::* ptr = &A::i;";
34261802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
34271802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(blockPointerType()))));
34281802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(matches(Fragment, varDecl(hasName("ptr"),
34291802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                        hasType(memberPointerType()))));
34301802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
34311802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(pointerType()))));
34321802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
34331802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(referenceType()))));
3434f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
3435f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(lValueReferenceType()))));
3436f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
3437f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(rValueReferenceType()))));
34381802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper
34391802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  Fragment = "int *ptr;";
34401802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
34411802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(blockPointerType()))));
34421802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
34431802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(memberPointerType()))));
34441802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(matches(Fragment, varDecl(hasName("ptr"),
34451802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                        hasType(pointerType()))));
34461802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
34471802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(referenceType()))));
34481802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper
34491802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  Fragment = "int a; int &ref = a;";
34501802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
34511802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(blockPointerType()))));
34521802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
34531802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(memberPointerType()))));
34541802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
34551802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(pointerType()))));
34561802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
34571802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                        hasType(referenceType()))));
3458f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
3459f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(lValueReferenceType()))));
3460f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
3461f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(rValueReferenceType()))));
3462f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane
3463f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  Fragment = "int &&ref = 2;";
3464f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
3465f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(blockPointerType()))));
3466f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
3467f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(memberPointerType()))));
3468f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
3469f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(pointerType()))));
3470f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
3471f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(referenceType()))));
3472f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
3473f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(lValueReferenceType()))));
3474f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
3475f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(rValueReferenceType()))));
3476f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane}
3477f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane
3478f4b48042724d2253d0426cadcb93e24eeb47e264Edwin VaneTEST(TypeMatching, AutoRefTypes) {
3479f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  std::string Fragment = "auto a = 1;"
3480f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                         "auto b = a;"
3481f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                         "auto &c = a;"
3482f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                         "auto &&d = c;"
3483f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                         "auto &&e = 2;";
3484f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("a"),
3485f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(referenceType()))));
3486f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("b"),
3487f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(referenceType()))));
3488f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("c"),
3489f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(referenceType()))));
3490f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("c"),
3491f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(lValueReferenceType()))));
3492f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("c"),
3493f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(rValueReferenceType()))));
3494f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("d"),
3495f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(referenceType()))));
3496f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("d"),
3497f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(lValueReferenceType()))));
3498f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("d"),
3499f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(rValueReferenceType()))));
3500f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("e"),
3501f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(referenceType()))));
3502f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("e"),
3503f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                           hasType(lValueReferenceType()))));
3504f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane  EXPECT_TRUE(matches(Fragment, varDecl(hasName("e"),
3505f4b48042724d2253d0426cadcb93e24eeb47e264Edwin Vane                                        hasType(rValueReferenceType()))));
3506ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3507ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3508ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, PointeeTypes) {
3509ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int b; int &a = b;",
3510ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                      referenceType(pointee(builtinType()))));
3511ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int *a;", pointerType(pointee(builtinType()))));
3512ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3513ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int *a;",
35145be093c0ef46c7749c942d0d9056af6dc3d591a4David Blaikie                      loc(pointerType(pointee(builtinType())))));
3515ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3516ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3517ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int const *A;",
3518ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      pointerType(pointee(isConstQualified(), builtinType()))));
3519ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
3520ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int *A;",
3521ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      pointerType(pointee(isConstQualified(), builtinType()))));
3522ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3523ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3524ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesPointersToConstTypes) {
3525ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int b; int * const a = &b;",
3526ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                      loc(pointerType())));
3527ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int b; int * const a = &b;",
35285be093c0ef46c7749c942d0d9056af6dc3d591a4David Blaikie                      loc(pointerType())));
3529ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3530ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int b; const int * a = &b;",
35315be093c0ef46c7749c942d0d9056af6dc3d591a4David Blaikie      loc(pointerType(pointee(builtinType())))));
3532ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3533ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int b; const int * a = &b;",
3534ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      pointerType(pointee(builtinType()))));
3535ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3536ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3537ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesTypedefTypes) {
35381802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(matches("typedef int X; X a;", varDecl(hasName("a"),
35391802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                                     hasType(typedefType()))));
3540ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3541ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
35423abf77872ca6c520903f9174cf6cd89a50df2714Edwin VaneTEST(TypeMatching, MatchesTemplateSpecializationType) {
3543742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(matches("template <typename T> class A{}; A<int> a;",
35443abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane                      templateSpecializationType()));
35453abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane}
35463abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane
3547742d9e77e32f014194679575c97c6bb4fd0998c4Edwin VaneTEST(TypeMatching, MatchesRecordType) {
3548742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(matches("class C{}; C c;", recordType()));
35490cc798f29d489140dd81b558e9c052e9a83cce39Manuel Klimek  EXPECT_TRUE(matches("struct S{}; S s;",
35500cc798f29d489140dd81b558e9c052e9a83cce39Manuel Klimek                      recordType(hasDeclaration(recordDecl(hasName("S"))))));
35510cc798f29d489140dd81b558e9c052e9a83cce39Manuel Klimek  EXPECT_TRUE(notMatches("int i;",
35520cc798f29d489140dd81b558e9c052e9a83cce39Manuel Klimek                         recordType(hasDeclaration(recordDecl(hasName("S"))))));
3553742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane}
3554742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane
3555742d9e77e32f014194679575c97c6bb4fd0998c4Edwin VaneTEST(TypeMatching, MatchesElaboratedType) {
3556742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(matches(
3557742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "namespace N {"
3558742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  namespace M {"
3559742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "    class D {};"
3560742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  }"
3561742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "}"
3562742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "N::M::D d;", elaboratedType()));
3563742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(matches("class C {} c;", elaboratedType()));
3564742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(notMatches("class C {}; C c;", elaboratedType()));
3565742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane}
3566742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane
3567742d9e77e32f014194679575c97c6bb4fd0998c4Edwin VaneTEST(ElaboratedTypeNarrowing, hasQualifier) {
3568742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(matches(
3569742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "namespace N {"
3570742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  namespace M {"
3571742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "    class D {};"
3572742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  }"
3573742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "}"
3574742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "N::M::D d;",
3575742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
3576742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(notMatches(
3577742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "namespace M {"
3578742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  class D {};"
3579742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "}"
3580742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "M::D d;",
3581742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
3582aec89ac22e1876bb1cfff9062c882a622bc84510Edwin Vane  EXPECT_TRUE(notMatches(
3583aec89ac22e1876bb1cfff9062c882a622bc84510Edwin Vane    "struct D {"
3584aec89ac22e1876bb1cfff9062c882a622bc84510Edwin Vane    "} d;",
3585aec89ac22e1876bb1cfff9062c882a622bc84510Edwin Vane    elaboratedType(hasQualifier(nestedNameSpecifier()))));
3586742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane}
3587742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane
3588742d9e77e32f014194679575c97c6bb4fd0998c4Edwin VaneTEST(ElaboratedTypeNarrowing, namesType) {
3589742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(matches(
3590742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "namespace N {"
3591742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  namespace M {"
3592742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "    class D {};"
3593742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  }"
3594742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "}"
3595742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "N::M::D d;",
3596742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    elaboratedType(elaboratedType(namesType(recordType(
3597742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane        hasDeclaration(namedDecl(hasName("D")))))))));
3598742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane  EXPECT_TRUE(notMatches(
3599742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "namespace M {"
3600742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "  class D {};"
3601742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "}"
3602742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    "M::D d;",
3603742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane    elaboratedType(elaboratedType(namesType(typedefType())))));
3604742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane}
3605742d9e77e32f014194679575c97c6bb4fd0998c4Edwin Vane
3606a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, MatchesNestedNameSpecifiers) {
3607a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;",
3608a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper                      nestedNameSpecifier()));
3609a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("template <typename T> class A { typename T::B b; };",
3610a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper                      nestedNameSpecifier()));
3611a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("struct A { void f(); }; void A::f() {}",
3612a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper                      nestedNameSpecifier()));
3613a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
3614a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches(
3615a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    "struct A { static void f() {} }; void g() { A::f(); }",
3616a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    nestedNameSpecifier()));
3617a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(notMatches(
3618a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    "struct A { static void f() {} }; void g(A* a) { a->f(); }",
3619a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    nestedNameSpecifier()));
3620a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
3621a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
3622b54b7646b2d00a85d80e40adf7c49553f150c736Daniel JasperTEST(NullStatement, SimpleCases) {
3623b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() {int i;;}", nullStmt()));
3624b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(notMatches("void f() {int i;}", nullStmt()));
3625b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper}
3626b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper
3627a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, MatchesTypes) {
3628a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  NestedNameSpecifierMatcher Matcher = nestedNameSpecifier(
3629a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    specifiesType(hasDeclaration(recordDecl(hasName("A")))));
3630a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("struct A { struct B {}; }; A::B b;", Matcher));
3631a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("struct A { struct B { struct C {}; }; }; A::B::C c;",
3632a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper                      Matcher));
3633a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(notMatches("namespace A { struct B {}; } A::B b;", Matcher));
3634a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
3635a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
3636a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, MatchesNamespaceDecls) {
3637a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  NestedNameSpecifierMatcher Matcher = nestedNameSpecifier(
3638a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    specifiesNamespace(hasName("ns")));
3639a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;", Matcher));
3640a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(notMatches("namespace xx { struct A {}; } xx::A a;", Matcher));
3641a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(notMatches("struct ns { struct A {}; }; ns::A a;", Matcher));
3642a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
3643a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
3644a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, BindsNestedNameSpecifiers) {
3645a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
3646a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      "namespace ns { struct E { struct B {}; }; } ns::E::B b;",
3647a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      nestedNameSpecifier(specifiesType(asString("struct ns::E"))).bind("nns"),
3648a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifier>("nns", "ns::struct E::")));
3649a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
3650a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
3651a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, BindsNestedNameSpecifierLocs) {
3652a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
3653a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      "namespace ns { struct B {}; } ns::B b;",
3654a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      loc(nestedNameSpecifier()).bind("loc"),
3655a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("loc", 1)));
3656a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
3657a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
3658a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, MatchesNestedNameSpecifierPrefixes) {
3659a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches(
3660a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      "struct A { struct B { struct C {}; }; }; A::B::C c;",
3661a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      nestedNameSpecifier(hasPrefix(specifiesType(asString("struct A"))))));
3662a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches(
3663a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      "struct A { struct B { struct C {}; }; }; A::B::C c;",
3664ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      nestedNameSpecifierLoc(hasPrefix(
3665ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper          specifiesTypeLoc(loc(qualType(asString("struct A"))))))));
3666a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
3667a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
3668d1ce3c178b9c648687591b190e0d252124fc2459Daniel JasperTEST(NNS, DescendantsOfNestedNameSpecifiers) {
3669d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  std::string Fragment =
3670d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "namespace a { struct A { struct B { struct C {}; }; }; };"
3671d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "void f() { a::A::B::C c; }";
3672d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
3673d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3674d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
3675d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                          hasDescendant(nestedNameSpecifier(
3676d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                              specifiesNamespace(hasName("a")))))));
3677d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(notMatches(
3678d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3679d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
3680d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                          has(nestedNameSpecifier(
3681d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                              specifiesNamespace(hasName("a")))))));
3682d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
3683d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3684d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifier(specifiesType(asString("struct a::A")),
3685d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                          has(nestedNameSpecifier(
3686d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                              specifiesNamespace(hasName("a")))))));
3687d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
3688d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  // Not really useful because a NestedNameSpecifier can af at most one child,
3689d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  // but to complete the interface.
3690d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
3691d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3692d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
3693d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                          forEach(nestedNameSpecifier().bind("x"))),
3694d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifier>("x", 1)));
3695d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper}
3696d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
3697d1ce3c178b9c648687591b190e0d252124fc2459Daniel JasperTEST(NNS, NestedNameSpecifiersAsDescendants) {
3698d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  std::string Fragment =
3699d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "namespace a { struct A { struct B { struct C {}; }; }; };"
3700d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "void f() { a::A::B::C c; }";
3701d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
3702d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3703d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      decl(hasDescendant(nestedNameSpecifier(specifiesType(
3704d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper          asString("struct a::A")))))));
3705d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
3706d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3707d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      functionDecl(hasName("f"),
3708d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                   forEachDescendant(nestedNameSpecifier().bind("x"))),
3709d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      // Nested names: a, a::A and a::A::B.
3710d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifier>("x", 3)));
3711d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper}
3712d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
3713d1ce3c178b9c648687591b190e0d252124fc2459Daniel JasperTEST(NNSLoc, DescendantsOfNestedNameSpecifierLocs) {
3714d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  std::string Fragment =
3715d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "namespace a { struct A { struct B { struct C {}; }; }; };"
3716d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "void f() { a::A::B::C c; }";
3717d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
3718d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3719d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
3720d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                             hasDescendant(loc(nestedNameSpecifier(
3721d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                                 specifiesNamespace(hasName("a"))))))));
3722d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(notMatches(
3723d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3724d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
3725d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                             has(loc(nestedNameSpecifier(
3726d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                                 specifiesNamespace(hasName("a"))))))));
3727d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
3728d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3729d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A"))),
3730d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                             has(loc(nestedNameSpecifier(
3731d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                                 specifiesNamespace(hasName("a"))))))));
3732d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
3733d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
3734d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3735d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
3736d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                             forEach(nestedNameSpecifierLoc().bind("x"))),
3737d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("x", 1)));
3738d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper}
3739d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
3740d1ce3c178b9c648687591b190e0d252124fc2459Daniel JasperTEST(NNSLoc, NestedNameSpecifierLocsAsDescendants) {
3741d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  std::string Fragment =
3742d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "namespace a { struct A { struct B { struct C {}; }; }; };"
3743d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "void f() { a::A::B::C c; }";
3744d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
3745d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3746d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      decl(hasDescendant(loc(nestedNameSpecifier(specifiesType(
3747d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper          asString("struct a::A"))))))));
3748d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
3749d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3750d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      functionDecl(hasName("f"),
3751d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                   forEachDescendant(nestedNameSpecifierLoc().bind("x"))),
3752d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      // Nested names: a, a::A and a::A::B.
3753d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("x", 3)));
3754d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper}
3755d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
375660969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimektemplate <typename T> class VerifyMatchOnNode : public BoundNodesCallback {
37573e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimekpublic:
3758cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek  VerifyMatchOnNode(StringRef Id, const internal::Matcher<T> &InnerMatcher,
3759cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek                    StringRef InnerId)
3760cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek      : Id(Id), InnerMatcher(InnerMatcher), InnerId(InnerId) {
3761452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper  }
3762452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper
376360969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  virtual bool run(const BoundNodes *Nodes) { return false; }
376460969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek
37653e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek  virtual bool run(const BoundNodes *Nodes, ASTContext *Context) {
37663e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek    const T *Node = Nodes->getNodeAs<T>(Id);
3767cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek    return selectFirst<const T>(InnerId,
3768cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek                                match(InnerMatcher, *Node, *Context)) != NULL;
37693e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek  }
37703e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimekprivate:
37713e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek  std::string Id;
37723e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek  internal::Matcher<T> InnerMatcher;
3773cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek  std::string InnerId;
37743e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek};
37753e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek
37763e2aa99e992b89bd421ac2a6bf79307114d257fcManuel KlimekTEST(MatchFinder, CanMatchDeclarationsRecursively) {
377760969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
377860969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
377960969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      new VerifyMatchOnNode<clang::Decl>(
3780cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "X", decl(hasDescendant(recordDecl(hasName("X::Y")).bind("Y"))),
3781cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "Y")));
378260969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse(
378360969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
378460969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      new VerifyMatchOnNode<clang::Decl>(
3785cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "X", decl(hasDescendant(recordDecl(hasName("X::Z")).bind("Z"))),
3786cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "Z")));
37873e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek}
37883e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek
37893e2aa99e992b89bd421ac2a6bf79307114d257fcManuel KlimekTEST(MatchFinder, CanMatchStatementsRecursively) {
379060969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
379160969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
3792cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek      new VerifyMatchOnNode<clang::Stmt>(
3793cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "if", stmt(hasDescendant(forStmt().bind("for"))), "for")));
379460969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse(
379560969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
3796cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek      new VerifyMatchOnNode<clang::Stmt>(
3797cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "if", stmt(hasDescendant(declStmt().bind("decl"))), "decl")));
379860969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek}
379960969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek
380060969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel KlimekTEST(MatchFinder, CanMatchSingleNodesRecursively) {
380160969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
380260969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
380360969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      new VerifyMatchOnNode<clang::Decl>(
3804cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "X", recordDecl(has(recordDecl(hasName("X::Y")).bind("Y"))), "Y")));
380560969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse(
380660969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
380760969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      new VerifyMatchOnNode<clang::Decl>(
3808cf87bffc346244f0ed8eae7fffb52a0f03cd0413Manuel Klimek          "X", recordDecl(has(recordDecl(hasName("X::Z")).bind("Z"))), "Z")));
38093e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek}
38103e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek
3811fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimektemplate <typename T>
3812fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimekclass VerifyAncestorHasChildIsEqual : public BoundNodesCallback {
3813fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimekpublic:
3814fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek  virtual bool run(const BoundNodes *Nodes) { return false; }
3815fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek
3816fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek  virtual bool run(const BoundNodes *Nodes, ASTContext *Context) {
3817fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek    const T *Node = Nodes->getNodeAs<T>("");
3818fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek    return verify(*Nodes, *Context, Node);
3819fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek  }
3820fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek
3821fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek  bool verify(const BoundNodes &Nodes, ASTContext &Context, const Stmt *Node) {
3822fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek    return selectFirst<const T>(
3823fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek        "", match(stmt(hasParent(stmt(has(stmt(equalsNode(Node)))).bind(""))),
3824fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek                  *Node, Context)) != NULL;
3825fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek  }
3826fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek  bool verify(const BoundNodes &Nodes, ASTContext &Context, const Decl *Node) {
3827fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek    return selectFirst<const T>(
3828fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek        "", match(decl(hasParent(decl(has(decl(equalsNode(Node)))).bind(""))),
3829fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek                  *Node, Context)) != NULL;
3830fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek  }
3831fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek};
3832fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek
3833fa37c5ca61af275a329386407e58cf70f4d9f596Manuel KlimekTEST(IsEqualTo, MatchesNodesByIdentity) {
3834fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3835fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek      "class X { class Y {}; };", recordDecl(hasName("::X::Y")).bind(""),
3836fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek      new VerifyAncestorHasChildIsEqual<Decl>()));
3837fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek  EXPECT_TRUE(
3838fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek      matchAndVerifyResultTrue("void f() { if(true) {} }", ifStmt().bind(""),
3839fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek                               new VerifyAncestorHasChildIsEqual<Stmt>()));
3840fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek}
3841fa37c5ca61af275a329386407e58cf70f4d9f596Manuel Klimek
3842e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimekclass VerifyStartOfTranslationUnit : public MatchFinder::MatchCallback {
3843e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimekpublic:
3844e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  VerifyStartOfTranslationUnit() : Called(false) {}
3845e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  virtual void run(const MatchFinder::MatchResult &Result) {
3846e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek    EXPECT_TRUE(Called);
3847e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  }
3848e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  virtual void onStartOfTranslationUnit() {
3849e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek    Called = true;
3850e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  }
3851e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  bool Called;
3852e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek};
3853e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek
3854e579328ec9a95acc7f181e04c58a747ba001d80fManuel KlimekTEST(MatchFinder, InterceptsStartOfTranslationUnit) {
3855e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  MatchFinder Finder;
3856e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  VerifyStartOfTranslationUnit VerifyCallback;
3857e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  Finder.addMatcher(decl(), &VerifyCallback);
3858e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  OwningPtr<FrontendActionFactory> Factory(newFrontendActionFactory(&Finder));
3859e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
3860e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  EXPECT_TRUE(VerifyCallback.Called);
3861e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek}
3862e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek
38634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek} // end namespace ast_matchers
38644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek} // end namespace clang
3865