ASTMatchersTest.cpp revision 7387673f83b8b37f660422947c9990778ba88193
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
31608f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel JasperTEST(DeclarationMatcher, ClassDerivedFromDependentTemplateSpecialization) {
31708f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper  EXPECT_TRUE(matches(
31808f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper     "template <typename T> struct A {"
31908f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper     "  template <typename T2> struct F {};"
32008f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper     "};"
32108f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper     "template <typename T> struct B : A<T>::template F<T> {};"
32208f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper     "B<int> b;",
32308f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper     recordDecl(hasName("B"), isDerivedFrom(recordDecl()))));
32408f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper}
32508f0c53175bba899e7af6c6cc2cab25caf64ef2aDaniel Jasper
3268456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(ClassTemplate, DoesNotMatchClass) {
3272dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ClassX = classTemplateDecl(hasName("X"));
3288456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches("class X;", ClassX));
3298456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches("class X {};", ClassX));
3308456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
3318456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
3328456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(ClassTemplate, MatchesClassTemplate) {
3332dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ClassX = classTemplateDecl(hasName("X"));
3348456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(matches("template<typename T> class X {};", ClassX));
3358456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(matches("class Z { template<class T> class X {}; };", ClassX));
3368456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
3378456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
3388456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(ClassTemplate, DoesNotMatchClassTemplateExplicitSpecialization) {
3398456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches("template<typename T> class X { };"
3408456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko                         "template<> class X<int> { int a; };",
3412dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              classTemplateDecl(hasName("X"),
3422dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                                hasDescendant(fieldDecl(hasName("a"))))));
3438456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
3448456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
3458456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(ClassTemplate, DoesNotMatchClassTemplatePartialSpecialization) {
3468456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches("template<typename T, typename U> class X { };"
3478456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko                         "template<typename T> class X<T, int> { int a; };",
3482dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              classTemplateDecl(hasName("X"),
3492dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                                hasDescendant(fieldDecl(hasName("a"))))));
3508456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
3518456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
3526a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(AllOf, AllOverloadsWork) {
3536a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  const char Program[] =
3546a12449ec8862211856447d3df4c082a346339f2Daniel Jasper      "struct T { }; int f(int, T*); void g(int x) { T t; f(x, &t); }";
3556a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(matches(Program,
3562dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      callExpr(allOf(callee(functionDecl(hasName("f"))),
3572dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                     hasArgument(0, declRefExpr(to(varDecl())))))));
3586a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(matches(Program,
3592dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      callExpr(allOf(callee(functionDecl(hasName("f"))),
3602dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                     hasArgument(0, declRefExpr(to(varDecl()))),
3612dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                     hasArgument(1, hasType(pointsTo(
3622dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                                        recordDecl(hasName("T")))))))));
3636a12449ec8862211856447d3df4c082a346339f2Daniel Jasper}
3646a12449ec8862211856447d3df4c082a346339f2Daniel Jasper
3654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, MatchAnyOf) {
3664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher YOrZDerivedFromX =
3672dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(anyOf(hasName("Y"), allOf(isDerivedFrom("X"), hasName("Z"))));
3684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
3694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; class Z : public X {};", YOrZDerivedFromX));
3704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y {};", YOrZDerivedFromX));
3714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
3724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X {}; class W : public X {};", YOrZDerivedFromX));
3734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Z {};", YOrZDerivedFromX));
3744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
375ff2fcb8db242a54f72bbb4e5595261e12672ed66Daniel Jasper  DeclarationMatcher XOrYOrZOrU =
3762dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U")));
377ff2fcb8db242a54f72bbb4e5595261e12672ed66Daniel Jasper  EXPECT_TRUE(matches("class X {};", XOrYOrZOrU));
378ff2fcb8db242a54f72bbb4e5595261e12672ed66Daniel Jasper  EXPECT_TRUE(notMatches("class V {};", XOrYOrZOrU));
379ff2fcb8db242a54f72bbb4e5595261e12672ed66Daniel Jasper
3804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher XOrYOrZOrUOrV =
3812dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U"),
3822dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                       hasName("V")));
3834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {};", XOrYOrZOrUOrV));
3844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y {};", XOrYOrZOrUOrV));
3854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Z {};", XOrYOrZOrUOrV));
3864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class U {};", XOrYOrZOrUOrV));
3874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class V {};", XOrYOrZOrUOrV));
3884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A {};", XOrYOrZOrUOrV));
3894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
3904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
3914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, MatchHas) {
3922dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher HasClassX = recordDecl(has(recordDecl(hasName("X"))));
3934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { class X {}; };", HasClassX));
3944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {};", HasClassX));
3954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
3964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher YHasClassX =
3972dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("Y"), has(recordDecl(hasName("X"))));
3984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { class X {}; };", YHasClassX));
3994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class X {};", YHasClassX));
4004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
4014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { class Z { class X {}; }; };", YHasClassX));
4024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
4034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
4044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, MatchHasRecursiveAllOf) {
4054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher Recursive =
4062dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper    recordDecl(
4072dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      has(recordDecl(
4082dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper        has(recordDecl(hasName("X"))),
4092dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper        has(recordDecl(hasName("Y"))),
4104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek        hasName("Z"))),
4112dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      has(recordDecl(
4122dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper        has(recordDecl(hasName("A"))),
4132dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper        has(recordDecl(hasName("B"))),
4144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek        hasName("C"))),
4154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      hasName("F"));
4164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
4174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
4184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class F {"
4194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class Z {"
4204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class X {};"
4214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class Y {};"
4224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
4234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class C {"
4244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class A {};"
4254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class B {};"
4264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
4274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};", Recursive));
4284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
4294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
4304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class F {"
4314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class Z {"
4324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class A {};"
4334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class X {};"
4344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class Y {};"
4354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
4364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class C {"
4374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class X {};"
4384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class A {};"
4394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class B {};"
4404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
4414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};", Recursive));
4424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
4434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
4444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class O1 {"
4454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class O2 {"
4464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class F {"
4474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      class Z {"
4484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class A {};"
4494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class X {};"
4504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class Y {};"
4514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      };"
4524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      class C {"
4534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class X {};"
4544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class A {};"
4554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class B {};"
4564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      };"
4574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    };"
4584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
4594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};", Recursive));
4604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
4614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
4624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, MatchHasRecursiveAnyOf) {
4634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher Recursive =
4642dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
4654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          anyOf(
4662dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              has(recordDecl(
4674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                  anyOf(
4682dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      has(recordDecl(
4694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                          hasName("X"))),
4702dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      has(recordDecl(
4714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                          hasName("Y"))),
4724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      hasName("Z")))),
4732dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              has(recordDecl(
4744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                  anyOf(
4754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      hasName("C"),
4762dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      has(recordDecl(
4774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                          hasName("A"))),
4782dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      has(recordDecl(
4794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                          hasName("B")))))),
4804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              hasName("F")));
4814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
4824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class F {};", Recursive));
4834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Z {};", Recursive));
4844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class C {};", Recursive));
4854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class M { class N { class X {}; }; };", Recursive));
4864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class M { class N { class B {}; }; };", Recursive));
4874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
4884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class O1 { class O2 {"
4894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "  class M { class N { class B {}; }; }; "
4904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "}; };", Recursive));
4914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
4924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
4934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, MatchNot) {
4944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher NotClassX =
4952dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
4964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          isDerivedFrom("Y"),
4974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          unless(hasName("X")));
4984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("", NotClassX));
4994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y {};", NotClassX));
5004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y {}; class Z : public Y {};", NotClassX));
5014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y {}; class X : public Y {};", NotClassX));
5024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
5034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y {}; class Z {}; class X : public Y {};",
5044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 NotClassX));
5054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher ClassXHasNotClassY =
5072dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
5084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          hasName("X"),
5092dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          has(recordDecl(hasName("Z"))),
5104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          unless(
5112dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              has(recordDecl(hasName("Y")))));
5124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { class Z {}; };", ClassXHasNotClassY));
5134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class X { class Y {}; class Z {}; };",
5144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                         ClassXHasNotClassY));
5154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
5164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationMatcher, HasDescendant) {
5184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher ZDescendantClassX =
5192dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
5202dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasDescendant(recordDecl(hasName("X"))),
5214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          hasName("Z"));
5224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Z { class X {}; };", ZDescendantClassX));
5234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
5244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Z { class Y { class X {}; }; };", ZDescendantClassX));
5254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
5264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Z { class A { class Y { class X {}; }; }; };",
5274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZDescendantClassX));
5284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
5294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Z { class A { class B { class Y { class X {}; }; }; }; };",
5304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZDescendantClassX));
5314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Z {};", ZDescendantClassX));
5324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher ZDescendantClassXHasClassY =
5342dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
5352dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasDescendant(recordDecl(has(recordDecl(hasName("Y"))),
5364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                              hasName("X"))),
5374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          hasName("Z"));
5384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Z { class X { class Y {}; }; };",
5394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZDescendantClassXHasClassY));
5404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
5414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Z { class A { class B { class X { class Y {}; }; }; }; };",
5424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZDescendantClassXHasClassY));
5434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
5444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Z {"
5454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class A {"
5464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class B {"
5474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      class X {"
5484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class C {"
5494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "          class Y {};"
5504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        };"
5514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      };"
5524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    }; "
5534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
5544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};", ZDescendantClassXHasClassY));
5554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
5564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher ZDescendantClassXDescendantClassY =
5572dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(
5582dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasDescendant(recordDecl(hasDescendant(recordDecl(hasName("Y"))),
5592dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                                   hasName("X"))),
5604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek          hasName("Z"));
5614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
5624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Z { class A { class X { class B { class Y {}; }; }; }; };",
5634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              ZDescendantClassXDescendantClassY));
5644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
5654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Z {"
5664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  class A {"
5674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    class X {"
5684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      class B {"
5694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "        class Y {};"
5704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      };"
5714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "      class Y {};"
5724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "    };"
5734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  };"
5744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};", ZDescendantClassXDescendantClassY));
5754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
5764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
577a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper// Implements a run method that returns whether BoundNodes contains a
578a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper// Decl bound to Id that can be dynamically cast to T.
579a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper// Optionally checks that the check succeeded a specific number of times.
580a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jaspertemplate <typename T>
581a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasperclass VerifyIdIsBoundTo : public BoundNodesCallback {
582a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasperpublic:
583a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Create an object that checks that a node of type \c T was bound to \c Id.
584a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Does not check for a certain number of matches.
585a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  explicit VerifyIdIsBoundTo(llvm::StringRef Id)
586a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    : Id(Id), ExpectedCount(-1), Count(0) {}
587a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
588a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Create an object that checks that a node of type \c T was bound to \c Id.
589a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Checks that there were exactly \c ExpectedCount matches.
590a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  VerifyIdIsBoundTo(llvm::StringRef Id, int ExpectedCount)
591a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    : Id(Id), ExpectedCount(ExpectedCount), Count(0) {}
592a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
593a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Create an object that checks that a node of type \c T was bound to \c Id.
594a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Checks that there was exactly one match with the name \c ExpectedName.
595a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  // Note that \c T must be a NamedDecl for this to work.
596a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  VerifyIdIsBoundTo(llvm::StringRef Id, llvm::StringRef ExpectedName)
597a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    : Id(Id), ExpectedCount(1), Count(0), ExpectedName(ExpectedName) {}
598a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
599a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  ~VerifyIdIsBoundTo() {
600a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    if (ExpectedCount != -1)
601a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      EXPECT_EQ(ExpectedCount, Count);
602a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    if (!ExpectedName.empty())
603a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      EXPECT_EQ(ExpectedName, Name);
604a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  }
605a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
606a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  virtual bool run(const BoundNodes *Nodes) {
607a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    if (Nodes->getNodeAs<T>(Id)) {
608a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      ++Count;
609a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      if (const NamedDecl *Named = Nodes->getNodeAs<NamedDecl>(Id)) {
610a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper        Name = Named->getNameAsString();
611a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      } else if (const NestedNameSpecifier *NNS =
612a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                 Nodes->getNodeAs<NestedNameSpecifier>(Id)) {
613a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper        llvm::raw_string_ostream OS(Name);
614a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper        NNS->print(OS, PrintingPolicy(LangOptions()));
615a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      }
616a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      return true;
617a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    }
618a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper    return false;
619a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  }
620a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
621452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper  virtual bool run(const BoundNodes *Nodes, ASTContext *Context) {
622452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper    return run(Nodes);
623452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper  }
624452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper
625a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasperprivate:
626a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  const std::string Id;
627a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  const int ExpectedCount;
628a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  int Count;
629a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  const std::string ExpectedName;
630a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  std::string Name;
631a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper};
632a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
633a267cf6f87dc695143d65fc61ec1744564f55932Daniel JasperTEST(HasDescendant, MatchesDescendantTypes) {
634a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int i = 3; }",
635a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      decl(hasDescendant(loc(builtinType())))));
636a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int i = 3; }",
637a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      stmt(hasDescendant(builtinType()))));
638a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
639a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int i = 3; }",
640a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      stmt(hasDescendant(loc(builtinType())))));
641a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int i = 3; }",
642a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      stmt(hasDescendant(qualType(builtinType())))));
643a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
644a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(notMatches("void f() { float f = 2.0f; }",
645a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                         stmt(hasDescendant(isInteger()))));
646a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
647a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
648a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      "void f() { int a; float c; int d; int e; }",
649a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      functionDecl(forEachDescendant(
650a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper          varDecl(hasDescendant(isInteger())).bind("x"))),
651a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      new VerifyIdIsBoundTo<Decl>("x", 3)));
652a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper}
653a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
654a267cf6f87dc695143d65fc61ec1744564f55932Daniel JasperTEST(HasDescendant, MatchesDescendantsOfTypes) {
655a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int*** i; }",
656a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      qualType(hasDescendant(builtinType()))));
657a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int*** i; }",
658a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      qualType(hasDescendant(
659a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                          pointerType(pointee(builtinType()))))));
660a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f() { int*** i; }",
661a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      typeLoc(hasDescendant(builtinTypeLoc()))));
662a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
663a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
664a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      "void f() { int*** i; }",
665a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      qualType(asString("int ***"), forEachDescendant(pointerType().bind("x"))),
666a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      new VerifyIdIsBoundTo<Type>("x", 2)));
667a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper}
668a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
669a267cf6f87dc695143d65fc61ec1744564f55932Daniel JasperTEST(Has, MatchesChildrenOfTypes) {
670a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("int i;",
671a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                      varDecl(hasName("i"), has(isInteger()))));
672a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(notMatches("int** i;",
673a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper                         varDecl(hasName("i"), has(isInteger()))));
674a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
675a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      "int (*f)(float, int);",
676a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      qualType(functionType(), forEach(qualType(isInteger()).bind("x"))),
677a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      new VerifyIdIsBoundTo<QualType>("x", 2)));
678a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper}
679a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
680a267cf6f87dc695143d65fc61ec1744564f55932Daniel JasperTEST(Has, MatchesChildTypes) {
681a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches(
682a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      "int* i;",
683a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      varDecl(hasName("i"), hasType(qualType(has(builtinType()))))));
684a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(notMatches(
685a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      "int* i;",
686a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper      varDecl(hasName("i"), hasType(qualType(has(pointerType()))))));
687a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper}
688a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
689e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Enum, DoesNotMatchClasses) {
690e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("class X {};", enumDecl(hasName("X"))));
691e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
692e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
693e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Enum, MatchesEnums) {
694e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("enum X {};", enumDecl(hasName("X"))));
695e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
696e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
697e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(EnumConstant, Matches) {
6982dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher Matcher = enumConstantDecl(hasName("A"));
699e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("enum X{ A };", Matcher));
700e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("enum X{ B };", Matcher));
701e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("enum X {};", Matcher));
702e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
703e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
7044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementMatcher, Has) {
7054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher HasVariableI =
7062dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      expr(hasType(pointsTo(recordDecl(hasName("X")))),
7072dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper           has(declRefExpr(to(varDecl(hasName("i"))))));
7084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
7104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X; X *x(int); void c() { int i; x(i); }", HasVariableI));
7114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
7124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X; X *x(int); void c() { int i; x(42); }", HasVariableI));
7134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
7144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementMatcher, HasDescendant) {
7164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher HasDescendantVariableI =
7172dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      expr(hasType(pointsTo(recordDecl(hasName("X")))),
7182dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper           hasDescendant(declRefExpr(to(varDecl(hasName("i"))))));
7194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
7214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X; X *x(bool); bool b(int); void c() { int i; x(b(i)); }",
7224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      HasDescendantVariableI));
7234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
7244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X; X *x(bool); bool b(int); void c() { int i; x(b(42)); }",
7254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      HasDescendantVariableI));
7264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
7274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(TypeMatcher, MatchesClassType) {
7292dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  TypeMatcher TypeA = hasDeclaration(recordDecl(hasName("A")));
7304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class A { public: A *a; };", TypeA));
7324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A {};", TypeA));
7334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7342dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  TypeMatcher TypeDerivedFromA = hasDeclaration(recordDecl(isDerivedFrom("A")));
7354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class A {}; class B : public A { public: B *b; };",
7374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              TypeDerivedFromA));
7384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A {};", TypeA));
7394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  TypeMatcher TypeAHasClassB = hasDeclaration(
7412dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("A"), has(recordDecl(hasName("B")))));
7424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
7444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class A { public: A *a; class B {}; };", TypeAHasClassB));
7454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
7464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, BindMatchedNodes) {
7482dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ClassX = has(recordDecl(hasName("::X")).bind("x"));
7494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class X {};",
751a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      ClassX, new VerifyIdIsBoundTo<CXXRecordDecl>("x")));
7524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse("class X {};",
754a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      ClassX, new VerifyIdIsBoundTo<CXXRecordDecl>("other-id")));
7554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  TypeMatcher TypeAHasClassB = hasDeclaration(
7572dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("A"), has(recordDecl(hasName("B")).bind("b"))));
7584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class A { public: A *a; class B {}; };",
7604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      TypeAHasClassB,
761a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<Decl>("b")));
7624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7632dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher MethodX =
7642dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      callExpr(callee(methodDecl(hasName("x")))).bind("x");
7654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
7664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class A { void x() { x(); } };",
7674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      MethodX,
768a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<CXXMemberCallExpr>("x")));
769e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
770e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
771e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Matcher, BindTheSameNameInAlternatives) {
772e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  StatementMatcher matcher = anyOf(
773e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      binaryOperator(hasOperatorName("+"),
7742dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                     hasLHS(expr().bind("x")),
775e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                     hasRHS(integerLiteral(equals(0)))),
776e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      binaryOperator(hasOperatorName("+"),
777e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                     hasLHS(integerLiteral(equals(0))),
7782dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                     hasRHS(expr().bind("x"))));
779e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
780e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
781e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      // The first branch of the matcher binds x to 0 but then fails.
782e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      // The second branch binds x to f() and succeeds.
783e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "int f() { return 0 + f(); }",
784e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      matcher,
785a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<CallExpr>("x")));
7864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
7874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
78866341c596f93d0c6475d839db94072b8ebd1cf5bManuel KlimekTEST(Matcher, BindsIDForMemoizedResults) {
78966341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek  // Using the same matcher in two match expressions will make memoization
79066341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek  // kick in.
79166341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek  DeclarationMatcher ClassX = recordDecl(hasName("X")).bind("x");
79266341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
79366341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek      "class A { class B { class X {}; }; };",
79466341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek      DeclarationMatcher(anyOf(
79566341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek          recordDecl(hasName("A"), hasDescendant(ClassX)),
79666341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek          recordDecl(hasName("B"), hasDescendant(ClassX)))),
797a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<Decl>("x", 2)));
79866341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek}
79966341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek
800189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel JasperTEST(HasDeclaration, HasDeclarationOfEnumType) {
801189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper  EXPECT_TRUE(matches("enum X {}; void y(X *x) { x; }",
802189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper                      expr(hasType(pointsTo(
803189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper                          qualType(hasDeclaration(enumDecl(hasName("X")))))))));
804189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper}
805189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper
8064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasType, TakesQualTypeMatcherAndMatchesExpr) {
8072dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
8084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8092dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX))));
8104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X {}; void y(X *x) { x; }",
8122dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 expr(hasType(ClassX))));
8134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; void y(X *x) { x; }",
8152dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              expr(hasType(pointsTo(ClassX)))));
8164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
8174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasType, TakesQualTypeMatcherAndMatchesValueDecl) {
8192dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
8204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8212dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX))));
8224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8232dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX))));
8244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; void y() { X *x; }",
8262dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              varDecl(hasType(pointsTo(ClassX)))));
8274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
8284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasType, TakesDeclMatcherAndMatchesExpr) {
8302dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ClassX = recordDecl(hasName("X"));
8314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8322dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX))));
8334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X {}; void y(X *x) { x; }",
8352dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 expr(hasType(ClassX))));
8364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
8374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasType, TakesDeclMatcherAndMatchesValueDecl) {
8392dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ClassX = recordDecl(hasName("X"));
8404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8412dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX))));
8424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8432dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX))));
8444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
8454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, Call) {
8474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // FIXME: Do we want to overload Call() to directly take
848e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // Matcher<Decl>, too?
8492dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher MethodX = callExpr(hasDeclaration(methodDecl(hasName("x"))));
8504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { x(); } };", MethodX));
8524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() {} };", MethodX));
8534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8542dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher MethodOnY =
8552dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberCallExpr(on(hasType(recordDecl(hasName("Y")))));
8564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
8594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
8604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
8624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
8634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
8654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 MethodOnY));
8664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
8684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 MethodOnY));
8694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
8714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 MethodOnY));
8724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher MethodOnYPointer =
8742dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberCallExpr(on(hasType(pointsTo(recordDecl(hasName("Y"))))));
8754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
8764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
8784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnYPointer));
8794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
8814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnYPointer));
8824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
8844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnYPointer));
8854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
8874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 MethodOnYPointer));
8884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
8894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
8904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 MethodOnYPointer));
8914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
8924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
89331f7c08a0d2b140bf31a08894d1948649de53c15Daniel JasperTEST(Matcher, Lambda) {
89431f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  EXPECT_TRUE(matches("auto f = [&] (int i) { return i; };",
89531f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      lambdaExpr()));
89631f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper}
89731f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper
89831f7c08a0d2b140bf31a08894d1948649de53c15Daniel JasperTEST(Matcher, ForRange) {
8991a00fee3933066024a2398f9456e5d6bc74344b9Daniel Jasper  EXPECT_TRUE(matches("int as[] = { 1, 2, 3 };"
9001a00fee3933066024a2398f9456e5d6bc74344b9Daniel Jasper                      "void f() { for (auto &a : as); }",
90131f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      forRangeStmt()));
90231f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  EXPECT_TRUE(notMatches("void f() { for (int i; i<5; ++i); }",
90331f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                         forRangeStmt()));
90431f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper}
90531f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper
90631f7c08a0d2b140bf31a08894d1948649de53c15Daniel JasperTEST(Matcher, UserDefinedLiteral) {
90731f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  EXPECT_TRUE(matches("constexpr char operator \"\" _inc (const char i) {"
90831f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      "  return i + 1;"
90931f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      "}"
91031f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      "char c = 'a'_inc;",
91131f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                      userDefinedLiteral()));
91231f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper}
91331f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper
914b54b7646b2d00a85d80e40adf7c49553f150c736Daniel JasperTEST(Matcher, FlowControl) {
915b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() { while(true) { break; } }", breakStmt()));
916b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() { while(true) { continue; } }",
917b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper                      continueStmt()));
918b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", gotoStmt()));
919b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", labelStmt()));
920b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() { return; }", returnStmt()));
921b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper}
922b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper
923e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(HasType, MatchesAsString) {
924e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(
925e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }",
9262dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberCallExpr(on(hasType(asString("class Y *"))))));
927e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("class X { void x(int x) {} };",
9282dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(0, hasType(asString("int"))))));
929e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("namespace ns { struct A {}; }  struct B { ns::A a; };",
9302dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      fieldDecl(hasType(asString("ns::A")))));
931e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("namespace { struct A {}; }  struct B { A a; };",
9322dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      fieldDecl(hasType(asString("struct <anonymous>::A")))));
933e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
934e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
9354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, OverloadedOperatorCall) {
9362dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher OpCall = operatorCallExpr();
9374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Unary operator
9384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { }; "
9394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "bool operator!(Y x) { return false; }; "
9404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "Y y; bool c = !y;", OpCall));
9414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // No match -- special operators like "new", "delete"
9424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // FIXME: operator new takes size_t, for which we need stddef.h, for which
9434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // we need to figure out include paths in the test.
9444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // EXPECT_TRUE(NotMatches("#include <stddef.h>\n"
9454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  //             "class Y { }; "
9464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  //             "void *operator new(size_t size) { return 0; } "
9474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  //             "Y *y = new Y;", OpCall));
9484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { }; "
9494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "void operator delete(void *p) { } "
9504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "void a() {Y *y = new Y; delete y;}", OpCall));
9514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Binary operator
9524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { }; "
9534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "bool operator&&(Y x, Y y) { return true; }; "
9544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "Y a; Y b; bool c = a && b;",
9554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              OpCall));
9564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // No match -- normal operator, not an overloaded one.
9574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("bool x = true, y = true; bool t = x && y;", OpCall));
9584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int t = 5 << 2;", OpCall));
9594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
9604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, HasOperatorNameForOverloadedOperatorCall) {
9624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OpCallAndAnd =
9632dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      operatorCallExpr(hasOverloadedOperatorName("&&"));
9644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { }; "
9654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "bool operator&&(Y x, Y y) { return true; }; "
9664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "Y a; Y b; bool c = a && b;", OpCallAndAnd));
9674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OpCallLessLess =
9682dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      operatorCallExpr(hasOverloadedOperatorName("<<"));
9694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { }; "
9704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "bool operator&&(Y x, Y y) { return true; }; "
9714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "Y a; Y b; bool c = a && b;",
9724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              OpCallLessLess));
9734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
9744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
975278057fd9f44684af832695cb01676c02a257b14Daniel JasperTEST(Matcher, NestedOverloadedOperatorCalls) {
976278057fd9f44684af832695cb01676c02a257b14Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
977278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "class Y { }; "
978278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "Y& operator&&(Y& x, Y& y) { return x; }; "
979278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "Y a; Y b; Y c; Y d = a && b && c;",
980278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        operatorCallExpr(hasOverloadedOperatorName("&&")).bind("x"),
981278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        new VerifyIdIsBoundTo<CXXOperatorCallExpr>("x", 2)));
982278057fd9f44684af832695cb01676c02a257b14Daniel Jasper  EXPECT_TRUE(matches(
983278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "class Y { }; "
984278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "Y& operator&&(Y& x, Y& y) { return x; }; "
985278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "Y a; Y b; Y c; Y d = a && b && c;",
986278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        operatorCallExpr(hasParent(operatorCallExpr()))));
987278057fd9f44684af832695cb01676c02a257b14Daniel Jasper  EXPECT_TRUE(matches(
988278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "class Y { }; "
989278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "Y& operator&&(Y& x, Y& y) { return x; }; "
990278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        "Y a; Y b; Y c; Y d = a && b && c;",
991278057fd9f44684af832695cb01676c02a257b14Daniel Jasper        operatorCallExpr(hasDescendant(operatorCallExpr()))));
992278057fd9f44684af832695cb01676c02a257b14Daniel Jasper}
993278057fd9f44684af832695cb01676c02a257b14Daniel Jasper
9944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ThisPointerType) {
9959f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek  StatementMatcher MethodOnY =
9962dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper    memberCallExpr(thisPointerType(recordDecl(hasName("Y"))));
9974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
9984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
9994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
10004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
10014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
10034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
10044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
10064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
10074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
10094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
10104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
10114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
10124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              MethodOnY));
10134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
10154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y {"
10164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  public: virtual void x();"
10174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};"
10184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X : public Y {"
10194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  public: virtual void x();"
10204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};"
10214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void z() { X *x; x->Y::x(); }", MethodOnY));
10224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
10234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, VariableUsage) {
10254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher Reference =
10262dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      declRefExpr(to(
10272dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          varDecl(hasInitializer(
10282dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberCallExpr(thisPointerType(recordDecl(hasName("Y"))))))));
10294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
10314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y {"
10324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      " public:"
10334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  bool x() const;"
10344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};"
10354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void z(const Y &y) {"
10364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  bool b = y.x();"
10374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  if (b) {}"
10384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "}", Reference));
10394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
10414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y {"
10424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      " public:"
10434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  bool x() const;"
10444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};"
10454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void z(const Y &y) {"
10464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  bool b = y.x();"
10474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "}", Reference));
10484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
10494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10508cb9bf577e3cfe31f1f023ed3a978d726f136edcManuel KlimekTEST(Matcher, FindsVarDeclInFunctionParameter) {
10519bd2809085c2a84c980c40988896ee05065f14e4Daniel Jasper  EXPECT_TRUE(matches(
10529bd2809085c2a84c980c40988896ee05065f14e4Daniel Jasper      "void f(int i) {}",
10532dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("i"))));
10549bd2809085c2a84c980c40988896ee05065f14e4Daniel Jasper}
10559bd2809085c2a84c980c40988896ee05065f14e4Daniel Jasper
10564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, CalledVariable) {
10573680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher CallOnVariableY =
10583680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      memberCallExpr(on(declRefExpr(to(varDecl(hasName("y"))))));
10594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
10614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y { public: void x() { Y y; y.x(); } };", CallOnVariableY));
10624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
10634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y { public: void x() const { Y y; y.x(); } };", CallOnVariableY));
10644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
10654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y { public: void x(); };"
10664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X : public Y { void z() { X y; y.x(); } };", CallOnVariableY));
10674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
10684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y { public: void x(); };"
10694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X : public Y { void z() { X *y; y->x(); } };", CallOnVariableY));
10704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
10714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Y { public: void x(); };"
10724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X : public Y { void z() { unsigned long y; ((X*)y)->x(); } };",
10734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      CallOnVariableY));
10744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
10754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1076e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UnaryExprOrTypeTraitExpr, MatchesSizeOfAndAlignOf) {
1077e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("void x() { int a = sizeof(a); }",
1078e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      unaryExprOrTypeTraitExpr()));
1079e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }",
1080e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                         alignOfExpr(anything())));
1081e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // FIXME: Uncomment once alignof is enabled.
1082e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // EXPECT_TRUE(matches("void x() { int a = alignof(a); }",
1083e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  //                     unaryExprOrTypeTraitExpr()));
1084e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // EXPECT_TRUE(notMatches("void x() { int a = alignof(a); }",
1085e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  //                        sizeOfExpr()));
1086e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1087e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
1088e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UnaryExpressionOrTypeTraitExpression, MatchesCorrectType) {
1089e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("void x() { int a = sizeof(a); }", sizeOfExpr(
1090e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      hasArgumentOfType(asString("int")))));
1091e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
1092e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      hasArgumentOfType(asString("float")))));
1093e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
1094e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "struct A {}; void x() { A a; int b = sizeof(a); }",
10952dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      sizeOfExpr(hasArgumentOfType(hasDeclaration(recordDecl(hasName("A")))))));
1096e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
10972dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      hasArgumentOfType(hasDeclaration(recordDecl(hasName("string")))))));
1098e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1099e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
11004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MemberExpression, DoesNotMatchClasses) {
11012dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class Y { void x() {} };", memberExpr()));
11024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
11034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MemberExpression, MatchesMemberFunctionCall) {
11052dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpr()));
11064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
11074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MemberExpression, MatchesVariable) {
11094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
11102dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class Y { void x() { this->y; } int y; };", memberExpr()));
11114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
11122dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class Y { void x() { y; } int y; };", memberExpr()));
11134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
11142dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class Y { void x() { Y y; y.y; } int y; };", memberExpr()));
11154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
11164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MemberExpression, MatchesStaticVariable) {
11184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
11192dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr()));
11204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
11212dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr()));
11224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { Y::y; } static int y; };",
11232dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr()));
11244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
11254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11266a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(IsInteger, MatchesIntegers) {
11272dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isInteger()))));
11282dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches(
11292dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      "long long i = 0; void f(long long) { }; void g() {f(i);}",
11302dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      callExpr(hasArgument(0, declRefExpr(
11312dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                                  to(varDecl(hasType(isInteger()))))))));
11326a12449ec8862211856447d3df4c082a346339f2Daniel Jasper}
11336a12449ec8862211856447d3df4c082a346339f2Daniel Jasper
11346a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(IsInteger, ReportsNoFalsePositives) {
11352dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("int *i;", varDecl(hasType(isInteger()))));
11366a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}",
11372dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      callExpr(hasArgument(0, declRefExpr(
11382dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          to(varDecl(hasType(isInteger()))))))));
11396a12449ec8862211856447d3df4c082a346339f2Daniel Jasper}
11406a12449ec8862211856447d3df4c082a346339f2Daniel Jasper
11414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsArrow, MatchesMemberVariablesViaArrow) {
11424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };",
11432dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
11444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { y; } int y; };",
11452dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
11464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };",
11472dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
11484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
11494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsArrow, MatchesStaticMemberVariablesViaArrow) {
11514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
11522dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
11534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
11542dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
11554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } static int y; };",
11562dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
11574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
11584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsArrow, MatchesMemberCallsViaArrow) {
11604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
11612dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
11624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { x(); } };",
11632dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
11644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",
11652dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              memberExpr(isArrow())));
11664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
11674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Callee, MatchesDeclarations) {
11692dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher CallMethodX = callExpr(callee(methodDecl(hasName("x"))));
11704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { x(); } };", CallMethodX));
11724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y { void x() {} };", CallMethodX));
11734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
11744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Callee, MatchesMemberExpressions) {
11764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
11772dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              callExpr(callee(memberExpr()))));
11784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
11792dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      notMatches("class Y { void x() { this->x(); } };", callExpr(callee(callExpr()))));
11804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
11814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Function, MatchesFunctionDeclarations) {
11832dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher CallFunctionF = callExpr(callee(functionDecl(hasName("f"))));
11844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { f(); }", CallFunctionF));
11864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { }", CallFunctionF));
11874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1188e265c877934dd24d11d85e991ede7d0742178495Manuel Klimek#if !defined(_MSC_VER)
1189e265c877934dd24d11d85e991ede7d0742178495Manuel Klimek  // FIXME: Make this work for MSVC.
11904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Dependent contexts, but a non-dependent call.
11914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f(); template <int N> void g() { f(); }",
11924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      CallFunctionF));
11934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
11944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("void f(); template <int N> struct S { void g() { f(); } };",
11954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              CallFunctionF));
1196e265c877934dd24d11d85e991ede7d0742178495Manuel Klimek#endif
11974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
11984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Depedent calls don't match.
11994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
12004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("void f(int); template <typename T> void g(T t) { f(t); }",
12014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 CallFunctionF));
12024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
12034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("void f(int);"
12044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "template <typename T> struct S { void g(T t) { f(t); } };",
12054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 CallFunctionF));
12064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
12074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12088456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(FunctionTemplate, MatchesFunctionTemplateDeclarations) {
12098456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(
12108456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      matches("template <typename T> void f(T t) {}",
12112dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionTemplateDecl(hasName("f"))));
12128456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
12138456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
12148456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(FunctionTemplate, DoesNotMatchFunctionDeclarations) {
12158456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(
12168456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      notMatches("void f(double d); void f(int t) {}",
12172dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionTemplateDecl(hasName("f"))));
12188456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
12198456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
12208456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(FunctionTemplate, DoesNotMatchFunctionTemplateSpecializations) {
12218456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(
12228456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      notMatches("void g(); template <typename T> void f(T t) {}"
12238456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko                 "template <> void f(int t) { g(); }",
12242dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionTemplateDecl(hasName("f"),
12252dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                           hasDescendant(declRefExpr(to(
12262dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                               functionDecl(hasName("g"))))))));
12278456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
12288456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
12294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, Argument) {
12303680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher CallArgumentY = callExpr(
12313680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
12324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x(int) { int y; x(y); }", CallArgumentY));
12344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
12354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { void x(int) { int y; x(y); } };", CallArgumentY));
12364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x(int) { int z; x(z); }", CallArgumentY));
12374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12383680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher WrongIndex = callExpr(
12393680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
12404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x(int) { int y; x(y); }", WrongIndex));
12414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
12424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, AnyArgument) {
12443680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher CallArgumentY = callExpr(
12453680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasAnyArgument(declRefExpr(to(varDecl(hasName("y"))))));
12464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
12474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
12484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
12494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
12504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ArgumentCount) {
12523680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher Call1Arg = callExpr(argumentCountIs(1));
12534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg));
12554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg));
12564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg));
12574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
12584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
125936e29d6732814e958aea4b2f403cec63d7ed3116Daniel JasperTEST(Matcher, ParameterCount) {
126036e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper  DeclarationMatcher Function1Arg = functionDecl(parameterCountIs(1));
126136e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper  EXPECT_TRUE(matches("void f(int i) {}", Function1Arg));
126236e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper  EXPECT_TRUE(matches("class X { void f(int i) {} };", Function1Arg));
126336e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper  EXPECT_TRUE(notMatches("void f() {}", Function1Arg));
126436e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper  EXPECT_TRUE(notMatches("void f(int i, int j, int k) {}", Function1Arg));
126536e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper}
126636e29d6732814e958aea4b2f403cec63d7ed3116Daniel Jasper
12674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, References) {
12682dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher ReferenceClassX = varDecl(
12692dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      hasType(references(recordDecl(hasName("X")))));
12704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {}; void y(X y) { X &x = y; }",
12714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      ReferenceClassX));
12724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
12734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
12744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
12754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
12764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
12774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
12784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
12794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasParameter, CallsInnerMatcher) {
12814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { void x(int) {} };",
12822dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(0, varDecl()))));
12834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class X { void x(int) {} };",
12842dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(0, hasName("x")))));
12854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
12864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) {
12884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class X { void x(int) {} };",
12892dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(42, varDecl()))));
12904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
12914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
12924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasType, MatchesParameterVariableTypesStrictly) {
12934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { void x(X x) {} };",
12942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
12954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class X { void x(const X &x) {} };",
12962dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
12974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { void x(const X *x) {} };",
12982dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(0,
12992dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                              hasType(pointsTo(recordDecl(hasName("X"))))))));
13004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { void x(const X &x) {} };",
13012dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasParameter(0,
13022dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                              hasType(references(recordDecl(hasName("X"))))))));
13034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyParameter, MatchesIndependentlyOfPosition) {
13064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y {}; class X { void x(X x, Y y) {} };",
13072dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
13084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y {}; class X { void x(Y y, X x) {} };",
13092dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
13104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1312e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Returns, MatchesReturnTypes) {
1313e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("class Y { int f() { return 1; } };",
13142dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      functionDecl(returns(asString("int")))));
1315e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("class Y { int f() { return 1; } };",
13162dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         functionDecl(returns(asString("float")))));
1317e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("class Y { Y getMe() { return *this; } };",
13182dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      functionDecl(returns(hasDeclaration(
13192dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          recordDecl(hasName("Y")))))));
1320e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1321e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
13228cc7efa2da2c6be43cbd3d09a9ae01353bb921d2Daniel JasperTEST(IsExternC, MatchesExternCFunctionDeclarations) {
13232dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("extern \"C\" void f() {}", functionDecl(isExternC())));
13242dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("extern \"C\" { void f() {} }",
13252dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              functionDecl(isExternC())));
13262dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("void f() {}", functionDecl(isExternC())));
13278cc7efa2da2c6be43cbd3d09a9ae01353bb921d2Daniel Jasper}
13288cc7efa2da2c6be43cbd3d09a9ae01353bb921d2Daniel Jasper
13294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
13304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
13312dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
13324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyParameter, DoesNotMatchThisPointer) {
13354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y {}; class X { void x() {} };",
13362dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasAnyParameter(hasType(pointsTo(
13372dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          recordDecl(hasName("X"))))))));
13384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasName, MatchesParameterVariableDeclartions) {
13414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Y {}; class X { void x(int x) {} };",
13422dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasAnyParameter(hasName("x")))));
13434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
13442dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasAnyParameter(hasName("x")))));
13454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
13464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1347371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel JasperTEST(Matcher, MatchesClassTemplateSpecialization) {
1348371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(matches("template<typename T> struct A {};"
1349371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper                      "template<> struct A<int> {};",
13502dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      classTemplateSpecializationDecl()));
1351371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(matches("template<typename T> struct A {}; A<int> a;",
13522dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      classTemplateSpecializationDecl()));
1353371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(notMatches("template<typename T> struct A {};",
13542dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         classTemplateSpecializationDecl()));
1355371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper}
1356371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper
1357371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel JasperTEST(Matcher, MatchesTypeTemplateArgument) {
1358371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(matches(
1359371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "template<typename T> struct B {};"
1360371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "B<int> b;",
13612dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToType(
1362371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper          asString("int"))))));
1363371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper}
1364371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper
1365371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel JasperTEST(Matcher, MatchesDeclarationReferenceTemplateArgument) {
1366371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(matches(
1367371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "struct B { int next; };"
1368371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "template<int(B::*next_ptr)> struct A {};"
1369371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "A<&B::next> a;",
13702dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      classTemplateSpecializationDecl(hasAnyTemplateArgument(
13712dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          refersToDeclaration(fieldDecl(hasName("next")))))));
1372aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper
1373aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper  EXPECT_TRUE(notMatches(
1374aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper      "template <typename T> struct A {};"
1375aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper      "A<int> a;",
1376aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper      classTemplateSpecializationDecl(hasAnyTemplateArgument(
1377aaa8e45b8e392a1f1b7498e2f00c6ed66d41119aDaniel Jasper          refersToDeclaration(decl())))));
1378371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper}
1379371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper
1380371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel JasperTEST(Matcher, MatchesSpecificArgument) {
1381371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(matches(
1382371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "template<typename T, typename U> class A {};"
1383371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "A<bool, int> a;",
13842dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      classTemplateSpecializationDecl(hasTemplateArgument(
1385371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper          1, refersToType(asString("int"))))));
1386371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper  EXPECT_TRUE(notMatches(
1387371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "template<typename T, typename U> class A {};"
1388371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper      "A<int, bool> a;",
13892dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      classTemplateSpecializationDecl(hasTemplateArgument(
1390371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper          1, refersToType(asString("int"))))));
1391371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper}
1392371f9391329d488d9bc4098adc7f5cf73aede1c1Daniel Jasper
13934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ConstructorCall) {
13943680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher Constructor = constructExpr();
13954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
13964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
13974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(); }; void x() { X x; }", Constructor));
13984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
13994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(); }; void x() { X x = X(); }",
14004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
14014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { X x = 0; }",
14034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
14044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {}; void x(int) { X x; }", Constructor));
14054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
14064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ConstructorArgument) {
14083680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher Constructor = constructExpr(
14093680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
14104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { int y; X x(y); }",
14134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
14144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
14164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
14174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { int y; X x = y; }",
14194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
14204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int); }; void x() { int z; X x(z); }",
14224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 Constructor));
14234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14243680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher WrongIndex = constructExpr(
14253680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
14264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int); }; void x() { int y; X x(y); }",
14284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 WrongIndex));
14294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
14304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ConstructorArgumentCount) {
14323680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher Constructor1Arg = constructExpr(argumentCountIs(1));
14334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { X x(0); }",
14364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor1Arg));
14374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { X x = X(0); }",
14394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor1Arg));
14404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { X x = 0; }",
14424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor1Arg));
14434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
14454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 Constructor1Arg));
14464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
14474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
144870b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel KlimekTEST(Matcher,ThisExpr) {
144970b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel Klimek  EXPECT_TRUE(
145070b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel Klimek      matches("struct X { int a; int f () { return a; } };", thisExpr()));
145170b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel Klimek  EXPECT_TRUE(
145270b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel Klimek      notMatches("struct X { int f () { int a; return a; } };", thisExpr()));
145370b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel Klimek}
145470b9db9879c1cb8b8ca7d6c9809e35361cab83dcManuel Klimek
14554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, BindTemporaryExpression) {
14563680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher TempExpression = bindTemporaryExpr();
14574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  std::string ClassString = "class string { public: string(); ~string(); }; ";
14594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches(ClassString +
14624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "string GetStringByValue();"
14634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "void FunctionTakesString(string s);"
14644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              "void run() { FunctionTakesString(GetStringByValue()); }",
14654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              TempExpression));
14664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches(ClassString +
14694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "string* GetStringPointer(); "
14704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "void FunctionTakesStringPtr(string* s);"
14714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "void run() {"
14724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "  string* s = GetStringPointer();"
14734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "  FunctionTakesStringPtr(GetStringPointer());"
14744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "  FunctionTakesStringPtr(s);"
14754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "}",
14764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 TempExpression));
14774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
14784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
14794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class no_dtor {};"
14804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "no_dtor GetObjByValue();"
14814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "void ConsumeObj(no_dtor param);"
14824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 "void run() { ConsumeObj(GetObjByValue()); }",
14834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 TempExpression));
1484e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer}
1485e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer
1486e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam PanzerTEST(MaterializeTemporaryExpr, MatchesTemporary) {
1487e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer  std::string ClassString =
1488e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer      "class string { public: string(); int length(); }; ";
1489e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer
1490e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer  EXPECT_TRUE(
1491e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer      matches(ClassString +
1492e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer              "string GetStringByValue();"
1493e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer              "void FunctionTakesString(string s);"
1494e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer              "void run() { FunctionTakesString(GetStringByValue()); }",
1495e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer              materializeTemporaryExpr()));
1496e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer
1497e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer  EXPECT_TRUE(
1498e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer      notMatches(ClassString +
1499e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "string* GetStringPointer(); "
1500e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "void FunctionTakesStringPtr(string* s);"
1501e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "void run() {"
1502e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "  string* s = GetStringPointer();"
1503e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "  FunctionTakesStringPtr(GetStringPointer());"
1504e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "  FunctionTakesStringPtr(s);"
1505e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "}",
1506e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 materializeTemporaryExpr()));
1507e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer
1508e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer  EXPECT_TRUE(
1509e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer      notMatches(ClassString +
1510e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "string GetStringByValue();"
1511e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "void run() { int k = GetStringByValue().length(); }",
1512e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 materializeTemporaryExpr()));
1513e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer
1514e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer  EXPECT_TRUE(
1515e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer      notMatches(ClassString +
1516e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "string GetStringByValue();"
1517e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 "void run() { GetStringByValue(); }",
1518e16acd3817e501ee2bcf5f631b6911021fa88ba7Sam Panzer                 materializeTemporaryExpr()));
15194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
15204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ConstructorDeclaration, SimpleCase) {
15224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Foo { Foo(int i); };",
15232dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      constructorDecl(ofClass(hasName("Foo")))));
15244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Foo { Foo(int i); };",
15252dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         constructorDecl(ofClass(hasName("Bar")))));
15264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
15274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ConstructorDeclaration, IsImplicit) {
15294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // This one doesn't match because the constructor is not added by the
15304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // compiler (it is not needed).
15314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class Foo { };",
15322dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         constructorDecl(isImplicit())));
15334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // The compiler added the implicit default constructor.
15344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
15352dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      constructorDecl(isImplicit())));
15364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class Foo { Foo(){} };",
15372dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      constructorDecl(unless(isImplicit()))));
15384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
15394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1540e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(DestructorDeclaration, MatchesVirtualDestructor) {
1541e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };",
15422dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      destructorDecl(ofClass(hasName("Foo")))));
1543e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1544e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
1545e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) {
15462dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class Foo {};",
15472dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         destructorDecl(ofClass(hasName("Foo")))));
1548e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1549e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
15504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyConstructorInitializer, SimpleCase) {
15514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
15524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Foo { Foo() { } };",
15532dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      constructorDecl(hasAnyConstructorInitializer(anything()))));
15544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
15554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Foo {"
15564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Foo() : foo_() { }"
15574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  int foo_;"
15584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};",
15592dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      constructorDecl(hasAnyConstructorInitializer(anything()))));
15604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
15614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyConstructorInitializer, ForField) {
15634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  static const char Code[] =
15644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Baz { };"
15654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Foo {"
15664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Foo() : foo_() { }"
15674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Baz foo_;"
15684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Baz bar_;"
15694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};";
15702dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches(Code, constructorDecl(hasAnyConstructorInitializer(
15712dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      forField(hasType(recordDecl(hasName("Baz"))))))));
15722dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches(Code, constructorDecl(hasAnyConstructorInitializer(
15734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      forField(hasName("foo_"))))));
15742dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches(Code, constructorDecl(hasAnyConstructorInitializer(
15752dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      forField(hasType(recordDecl(hasName("Bar"))))))));
15764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
15774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyConstructorInitializer, WithInitializer) {
15794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  static const char Code[] =
15804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Foo {"
15814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Foo() : foo_(0) { }"
15824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  int foo_;"
15834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};";
15842dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches(Code, constructorDecl(hasAnyConstructorInitializer(
15854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      withInitializer(integerLiteral(equals(0)))))));
15862dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches(Code, constructorDecl(hasAnyConstructorInitializer(
15874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      withInitializer(integerLiteral(equals(1)))))));
15884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
15894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
15904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnyConstructorInitializer, IsWritten) {
15914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  static const char Code[] =
15924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "struct Bar { Bar(){} };"
15934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class Foo {"
15944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Foo() : foo_() { }"
15954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Bar foo_;"
15964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Bar bar_;"
15974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};";
15982dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches(Code, constructorDecl(hasAnyConstructorInitializer(
15994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      allOf(forField(hasName("foo_")), isWritten())))));
16002dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches(Code, constructorDecl(hasAnyConstructorInitializer(
16014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      allOf(forField(hasName("bar_")), isWritten())))));
16022dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches(Code, constructorDecl(hasAnyConstructorInitializer(
16034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      allOf(forField(hasName("bar_")), unless(isWritten()))))));
16044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, NewExpression) {
16073680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher New = newExpr();
16084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X { public: X(); }; void x() { new X; }", New));
16104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
16114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(); }; void x() { new X(); }", New));
16124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
16134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { new X(0); }", New));
16144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class X {}; void x(int) { new X; }", New));
16154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, NewExpressionArgument) {
16183680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher New = constructExpr(
16193680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
16204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
16224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { int y; new X(y); }",
16234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              New));
16244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
16254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { int y; new X(y); }",
16264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              New));
16274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
16284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int); }; void x() { int z; new X(z); }",
16294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 New));
16304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16313680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher WrongIndex = constructExpr(
16323680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
16334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
16344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int); }; void x() { int y; new X(y); }",
16354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 WrongIndex));
16364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, NewExpressionArgumentCount) {
16392dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher New = constructExpr(argumentCountIs(1));
16404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
16424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(int); }; void x() { new X(0); }", New));
16434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
16444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class X { public: X(int, int); }; void x() { new X(0, 0); }",
16454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 New));
16464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1648e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Matcher, DeleteExpression) {
1649e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("struct A {}; void f(A* a) { delete a; }",
16502dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      deleteExpr()));
1651e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1652e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
16534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, DefaultArgument) {
16542dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher Arg = defaultArgExpr();
16554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x(int, int = 0) { int y; x(y); }", Arg));
16574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
16584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { void x(int, int = 0) { int y; x(y); } };", Arg));
16594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x(int, int = 0) { int y; x(y, 0); }", Arg));
16604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, StringLiterals) {
16633680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher Literal = stringLiteral();
16644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const char *s = \"string\";", Literal));
16654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // wide string
16664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const wchar_t *s = L\"string\";", Literal));
16674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // with escaped characters
16684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const char *s = \"\x05five\";", Literal));
16694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // no matching -- though the data type is the same, there is no string literal
16704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));
16714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, CharacterLiterals) {
16743680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher CharLiteral = characterLiteral();
16754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const char c = 'c';", CharLiteral));
16764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // wide character
16774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const char c = L'c';", CharLiteral));
16784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // wide character, Hex encoded, NOT MATCHED!
16794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("const wchar_t c = 0x2126;", CharLiteral));
16804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("const char c = 0x1;", CharLiteral));
16814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, IntegerLiterals) {
16843680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  StatementMatcher HasIntLiteral = integerLiteral();
16854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = 10;", HasIntLiteral));
16864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = 0x1AB;", HasIntLiteral));
16874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = 10L;", HasIntLiteral));
16884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = 10U;", HasIntLiteral));
16894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
16904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Non-matching cases (character literals, float and double)
16914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int i = L'a';",
16924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                HasIntLiteral));  // this is actually a character
16934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                                  // literal cast to int
16944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int i = 'a';", HasIntLiteral));
16954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int i = 1e10;", HasIntLiteral));
16964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int i = 10.0;", HasIntLiteral));
16974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
16984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
169931f7c08a0d2b140bf31a08894d1948649de53c15Daniel JasperTEST(Matcher, NullPtrLiteral) {
170031f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  EXPECT_TRUE(matches("int* i = nullptr;", nullPtrLiteralExpr()));
170131f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper}
170231f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper
1703b54b7646b2d00a85d80e40adf7c49553f150c736Daniel JasperTEST(Matcher, AsmStatement) {
1704b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void foo() { __asm(\"mov al, 2\"); }", asmStmt()));
1705b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper}
1706b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper
17074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, Conditions) {
17084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher Condition = ifStmt(hasCondition(boolLiteral(equals(true))));
17094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
17104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { if (true) {} }", Condition));
17114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { if (false) {} }", Condition));
17124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { bool a = true; if (a) {} }", Condition));
17134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { if (true || false) {} }", Condition));
17144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { if (1) {} }", Condition));
17154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
17164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
17174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MatchBinaryOperator, HasOperatorName) {
17184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
17194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
17204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true || false; }", OperatorOr));
17214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
17224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
17234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
17244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MatchBinaryOperator, HasLHSAndHasRHS) {
17254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OperatorTrueFalse =
17264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      binaryOperator(hasLHS(boolLiteral(equals(true))),
17274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                     hasRHS(boolLiteral(equals(false))));
17284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
17294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true || false; }", OperatorTrueFalse));
17304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse));
17314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { false || true; }", OperatorTrueFalse));
17324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
17334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
17344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MatchBinaryOperator, HasEitherOperand) {
17354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher HasOperand =
17364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      binaryOperator(hasEitherOperand(boolLiteral(equals(false))));
17374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
17384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true || false; }", HasOperand));
17394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { false && true; }", HasOperand));
17404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand));
17414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
17424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
17434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, BinaryOperatorTypes) {
17444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Integration test that verifies the AST provides all binary operators in
17454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // a way we expect.
17464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // FIXME: Operator ','
17474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(","))));
17494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b; bool c = (b = true);",
17514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("="))));
17524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!="))));
17544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("=="))));
17564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("bool b = 1 < 2;", binaryOperator(hasOperatorName("<"))));
17574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<="))));
17594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<"))));
17614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 1; int j = (i <<= 2);",
17634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("<<="))));
17644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("bool b = 1 > 2;", binaryOperator(hasOperatorName(">"))));
17654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">="))));
17674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>"))));
17694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 1; int j = (i >>= 2);",
17714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName(">>="))));
17724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42 ^ 23;", binaryOperator(hasOperatorName("^"))));
17744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i ^= 42);",
17764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("^="))));
17774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42 % 23;", binaryOperator(hasOperatorName("%"))));
17794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i %= 42);",
17814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("%="))));
17824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 42  &23;", binaryOperator(hasOperatorName("&"))));
17844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = true && false;",
17864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("&&"))));
17874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = true; bool c = (b &= false);",
17894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("&="))));
17904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|"))));
17924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = true || false;",
17944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("||"))));
17954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b = true; bool c = (b |= false);",
17974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("|="))));
17984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
17994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42  *23;", binaryOperator(hasOperatorName("*"))));
18004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i *= 23);",
18024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("*="))));
18034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42 / 23;", binaryOperator(hasOperatorName("/"))));
18054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i /= 23);",
18074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("/="))));
18084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42 + 23;", binaryOperator(hasOperatorName("+"))));
18104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i += 23);",
18124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("+="))));
18134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42 - 23;", binaryOperator(hasOperatorName("-"))));
18154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i = 42; int j = (i -= 23);",
18174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("-="))));
18184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };",
18204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName("->*"))));
18214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };",
18234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              binaryOperator(hasOperatorName(".*"))));
18244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Member expressions as operators are not supported in matches.
18264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("struct A { void x(A *a) { a->x(this); } };",
18284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 binaryOperator(hasOperatorName("->"))));
18294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Initializer assignments are not represented as operator equals.
18314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("bool b = true;", binaryOperator(hasOperatorName("="))));
18334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Array indexing is not represented as operator.
18354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int a[42]; void x() { a[23]; }", unaryOperator()));
18364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Overloaded operators do not match at all.
18384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
18394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "struct A { bool operator&&(const A &a) const { return false; } };"
18404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void x() { A a, b; a && b; }",
18414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      binaryOperator()));
18424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
18434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MatchUnaryOperator, HasOperatorName) {
18454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OperatorNot = unaryOperator(hasOperatorName("!"));
18464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { !true; } ", OperatorNot));
18484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
18494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
18504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(MatchUnaryOperator, HasUnaryOperand) {
18524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher OperatorOnFalse =
18534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      unaryOperator(hasUnaryOperand(boolLiteral(equals(false))));
18544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse));
18564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse));
18574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
18584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, UnaryOperatorTypes) {
18604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Integration test that verifies the AST provides all unary operators in
18614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // a way we expect.
18624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("bool b = !true;", unaryOperator(hasOperatorName("!"))));
18634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&"))));
18654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = ~ 1;", unaryOperator(hasOperatorName("~"))));
18664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("bool *p; bool b = *p;", unaryOperator(hasOperatorName("*"))));
18684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = +i;", unaryOperator(hasOperatorName("+"))));
18704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = -i;", unaryOperator(hasOperatorName("-"))));
18724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = ++i;", unaryOperator(hasOperatorName("++"))));
18744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = i++;", unaryOperator(hasOperatorName("++"))));
18764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = --i;", unaryOperator(hasOperatorName("--"))));
18784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
18794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("int i; int j = i--;", unaryOperator(hasOperatorName("--"))));
18804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // We don't match conversion operators.
18824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int i; double d = (double)i;", unaryOperator()));
18834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Function calls are not represented as operator.
18854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f(); void x() { f(); }", unaryOperator()));
18864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Overloaded operators do not match at all.
18884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // FIXME: We probably want to add that.
18894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
18904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "struct A { bool operator!() const { return false; } };"
18914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void x() { A a; !a; }", unaryOperator(hasOperatorName("!"))));
18924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
18934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, ConditionalOperator) {
18954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher Conditional = conditionalOperator(
18964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      hasCondition(boolLiteral(equals(true))),
18974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      hasTrueExpression(boolLiteral(equals(false))));
18984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
18994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true ? false : true; }", Conditional));
19004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { false ? false : true; }", Conditional));
19014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { true ? true : false; }", Conditional));
19024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher ConditionalFalse = conditionalOperator(
19044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      hasFalseExpression(boolLiteral(equals(false))));
19054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
19074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("void x() { true ? false : true; }", ConditionalFalse));
19094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
19104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1911e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(ArraySubscriptMatchers, ArraySubscripts) {
1912e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("int i[2]; void f() { i[1] = 1; }",
1913e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      arraySubscriptExpr()));
1914e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("int i; void f() { i = 1; }",
1915e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                         arraySubscriptExpr()));
1916e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1917e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
1918e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(ArraySubscriptMatchers, ArrayIndex) {
1919e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
1920e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "int i[2]; void f() { i[1] = 1; }",
1921e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
1922e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
1923e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "int i[2]; void f() { 1[i] = 1; }",
1924e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
1925e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches(
1926e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "int i[2]; void f() { i[1] = 1; }",
1927e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      arraySubscriptExpr(hasIndex(integerLiteral(equals(0))))));
1928e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1929e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
1930e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(ArraySubscriptMatchers, MatchesArrayBase) {
1931e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
1932e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "int i[2]; void f() { i[1] = 2; }",
19332dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      arraySubscriptExpr(hasBase(implicitCastExpr(
19342dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasSourceExpression(declRefExpr()))))));
1935e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
1936e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
19374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, HasNameSupportsNamespaces) {
19384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
19392dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("a::b::C"))));
19404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
19412dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("::a::b::C"))));
19424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
19432dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("b::C"))));
19444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
19452dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("C"))));
19464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
19472dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("c::b::C"))));
19484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
19492dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("a::c::C"))));
19504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
19512dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("a::b::A"))));
19524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
19532dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("::C"))));
19544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
19552dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("::b::C"))));
19564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
19572dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("z::a::b::C"))));
19584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
19592dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("a+b::C"))));
19604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
19612dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("C"))));
19624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
19634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, HasNameSupportsOuterClasses) {
19654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19662dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class A { class B { class C; }; };",
19672dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("A::B::C"))));
19684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class A { class B { class C; }; };",
19702dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("::A::B::C"))));
19714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19722dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class A { class B { class C; }; };",
19732dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("B::C"))));
19744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19752dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      matches("class A { class B { class C; }; };",
19762dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("C"))));
19774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class A { class B { class C; }; };",
19792dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("c::B::C"))));
19804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class A { class B { class C; }; };",
19822dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("A::c::C"))));
19834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class A { class B { class C; }; };",
19852dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("A::B::A"))));
19864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19872dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      notMatches("class A { class B { class C; }; };",
19882dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("::C"))));
19894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class A { class B { class C; }; };",
19912dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("::B::C"))));
19924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
19932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              recordDecl(hasName("z::A::B::C"))));
19944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
19954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class A { class B { class C; }; };",
19962dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 recordDecl(hasName("A+B::C"))));
19974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
19984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
19994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, IsDefinition) {
20004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher DefinitionOfClassA =
20012dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("A"), isDefinition());
20024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class A {};", DefinitionOfClassA));
20034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A;", DefinitionOfClassA));
20044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher DefinitionOfVariableA =
20062dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      varDecl(hasName("a"), isDefinition());
20074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));
20084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));
20094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  DeclarationMatcher DefinitionOfMethodA =
20112dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      methodDecl(hasName("a"), isDefinition());
20124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));
20134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));
20144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
20154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, OfClass) {
20172dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  StatementMatcher Constructor = constructExpr(hasDeclaration(methodDecl(
20184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      ofClass(hasName("X")))));
20194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(); }; void x(int) { X x; }", Constructor));
20224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      matches("class X { public: X(); }; void x(int) { X x = X(); }",
20244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek              Constructor));
20254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
20264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches("class Y { public: Y(); }; void x(int) { Y y; }",
20274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                 Constructor));
20284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
20294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Matcher, VisitsTemplateInstantiations) {
20314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
20324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class A { public: void x(); };"
20334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class B { public: void y() { T t; t.x(); } };"
20342dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      "void f() { B<A> b; b.y(); }",
20352dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      callExpr(callee(methodDecl(hasName("x"))))));
20364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
20384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class A { public: void x(); };"
20394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class C {"
20404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      " public:"
20414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  template <typename T> class B { public: void y() { T t; t.x(); } };"
20424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};"
20434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void f() {"
20444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  C::B<A> b; b.y();"
20452dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      "}",
20462dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"),
20472dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 hasDescendant(callExpr(callee(methodDecl(hasName("x"))))))));
20484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
20494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2050e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(Matcher, HandlesNullQualTypes) {
2051e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // FIXME: Add a Type matcher so we can replace uses of this
2052e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // variable with Type(True())
2053e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  const TypeMatcher AnyType = anything();
2054e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
2055e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // We don't really care whether this matcher succeeds; we're testing that
2056e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  // it completes without crashing.
2057e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
2058e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "struct A { };"
2059e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "template <typename T>"
2060e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "void f(T t) {"
2061e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "  T local_t(t /* this becomes a null QualType in the AST */);"
2062e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "}"
2063e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "void g() {"
2064e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "  f(0);"
2065e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "}",
20662dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      expr(hasType(TypeMatcher(
2067e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper          anyOf(
2068e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper              TypeMatcher(hasDeclaration(anything())),
2069e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper              pointsTo(AnyType),
2070e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper              references(AnyType)
2071e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper              // Other QualType matchers should go here.
2072e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                ))))));
2073e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2074e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
20754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// For testing AST_MATCHER_P().
2076e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperAST_MATCHER_P(Decl, just, internal::Matcher<Decl>, AMatcher) {
20774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Make sure all special variables are used: node, match_finder,
20784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // bound_nodes_builder, and the parameter named 'AMatcher'.
20794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  return AMatcher.matches(Node, Finder, Builder);
20804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
20814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(AstMatcherPMacro, Works) {
20832dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher HasClassB = just(has(recordDecl(hasName("B")).bind("b")));
20844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
2086a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
20874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
2089a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("a")));
20904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
2092a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
20934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
20944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
20954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekAST_POLYMORPHIC_MATCHER_P(
2096e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper    polymorphicHas, internal::Matcher<Decl>, AMatcher) {
2097e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  TOOLING_COMPILE_ASSERT((llvm::is_same<NodeType, Decl>::value) ||
2098e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                         (llvm::is_same<NodeType, Stmt>::value),
20994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                         assert_node_type_is_accessible);
21004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  return Finder->matchesChildOf(
2101a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek      Node, AMatcher, Builder,
21024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
21034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      ASTMatchFinder::BK_First);
21044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(AstPolymorphicMatcherPMacro, Works) {
21072dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher HasClassB =
21082dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      polymorphicHas(recordDecl(hasName("B")).bind("b"));
21094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
2111a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
21124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
2114a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("a")));
21154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
2117a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
21184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  StatementMatcher StatementHasClassB =
21202dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      polymorphicHas(recordDecl(hasName("B")));
21214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { class B {}; }", StatementHasClassB));
21234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(For, FindsForLoops) {
21264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { for(;;); }", forStmt()));
21274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { if(true) for(;;); }", forStmt()));
21281a00fee3933066024a2398f9456e5d6bc74344b9Daniel Jasper  EXPECT_TRUE(notMatches("int as[] = { 1, 2, 3 };"
21291a00fee3933066024a2398f9456e5d6bc74344b9Daniel Jasper                         "void f() { for (auto &a : as); }",
213031f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper                         forStmt()));
21314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21336a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(For, ForLoopInternals) {
21346a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(matches("void f(){ int i; for (; i < 3 ; ); }",
21356a12449ec8862211856447d3df4c082a346339f2Daniel Jasper                      forStmt(hasCondition(anything()))));
21366a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(matches("void f() { for (int i = 0; ;); }",
21376a12449ec8862211856447d3df4c082a346339f2Daniel Jasper                      forStmt(hasLoopInit(anything()))));
21386a12449ec8862211856447d3df4c082a346339f2Daniel Jasper}
21396a12449ec8862211856447d3df4c082a346339f2Daniel Jasper
21406a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(For, NegativeForLoopInternals) {
21416a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }",
21422dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         forStmt(hasCondition(expr()))));
21436a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(notMatches("void f() {int i; for (; i < 4; ++i) {} }",
21446a12449ec8862211856447d3df4c082a346339f2Daniel Jasper                         forStmt(hasLoopInit(anything()))));
21456a12449ec8862211856447d3df4c082a346339f2Daniel Jasper}
21466a12449ec8862211856447d3df4c082a346339f2Daniel Jasper
21474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(For, ReportsNoFalsePositives) {
21484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { ; }", forStmt()));
21494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { if(true); }", forStmt()));
21504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(CompoundStatement, HandlesSimpleCases) {
21532dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("void f();", compoundStmt()));
21542dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("void f() {}", compoundStmt()));
21552dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("void f() {{}}", compoundStmt()));
21564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(CompoundStatement, DoesNotMatchEmptyStruct) {
21594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // It's not a compound statement just because there's "{}" in the source
21604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // text. This is an AST search, not grep.
21614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("namespace n { struct S {}; }",
21622dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt()));
21634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("namespace n { struct S { void f() {{}} }; }",
21642dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt()));
21654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21676a12449ec8862211856447d3df4c082a346339f2Daniel JasperTEST(HasBody, FindsBodyOfForWhileDoLoops) {
21684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { for(;;) {} }",
21692dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              forStmt(hasBody(compoundStmt()))));
21704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { for(;;); }",
21712dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              forStmt(hasBody(compoundStmt()))));
21726a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(matches("void f() { while(true) {} }",
21732dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              whileStmt(hasBody(compoundStmt()))));
21746a12449ec8862211856447d3df4c082a346339f2Daniel Jasper  EXPECT_TRUE(matches("void f() { do {} while(true); }",
21752dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              doStmt(hasBody(compoundStmt()))));
21764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
21794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // The simplest case: every compound statement is in a function
21804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // definition, and the function body itself must be a compound
21814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // statement.
21824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { for (;;); }",
21832dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(hasAnySubstatement(forStmt()))));
21844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnySubstatement, IsNotRecursive) {
21874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // It's really "has any immediate substatement".
21884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { if (true) for (;;); }",
21892dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(hasAnySubstatement(forStmt()))));
21904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnySubstatement, MatchesInNestedCompoundStatements) {
21934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { if (true) { for (;;); } }",
21942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(hasAnySubstatement(forStmt()))));
21954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
21964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
21974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasAnySubstatement, FindsSubstatementBetweenOthers) {
21984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { 1; 2; 3; for (;;); 4; 5; 6; }",
21992dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(hasAnySubstatement(forStmt()))));
22004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) {
22034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { }",
22042dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(0))));
22054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() {}",
22062dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(1))));
22074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementCountIs, AppearsToMatchOnlyOneCount) {
22104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { 1; }",
22112dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(1))));
22124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { 1; }",
22132dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(0))));
22144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { 1; }",
22152dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(2))));
22164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementCountIs, WorksWithMultipleStatements) {
22194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { 1; 2; 3; }",
22202dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(3))));
22214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StatementCountIs, WorksWithNestedCompoundStatements) {
22244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
22252dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(1))));
22264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
22272dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(2))));
22284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
22292dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(3))));
22304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
22312dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper              compoundStmt(statementCountIs(4))));
22324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Member, WorksInSimplestCase) {
22354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
22362dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      memberExpr(member(hasName("first")))));
22374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Member, DoesNotMatchTheBaseExpression) {
22404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Don't pick out the wrong part of the member expression, this should
22414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // be checking the member (name) only.
22424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
22432dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         memberExpr(member(hasName("first")))));
22444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Member, MatchesInMemberFunctionCall) {
22474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void f() {"
22484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "  struct { void first() {}; } s;"
22494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "  s.first();"
22504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "};",
22512dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      memberExpr(member(hasName("first")))));
22524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2254c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel JasperTEST(Member, MatchesMember) {
2255c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper  EXPECT_TRUE(matches(
2256c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper      "struct A { int i; }; void f() { A a; a.i = 2; }",
2257c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper      memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
2258c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper  EXPECT_TRUE(notMatches(
2259c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper      "struct A { float f; }; void f() { A a; a.f = 2.0f; }",
2260c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper      memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
2261c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper}
2262c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper
2263671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri GribenkoTEST(Member, MatchesMemberAllocationFunction) {
226431f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  // Fails in C++11 mode
226531f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  EXPECT_TRUE(matchesConditionally(
226631f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper      "namespace std { typedef typeof(sizeof(int)) size_t; }"
226731f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper      "class X { void *operator new(std::size_t); };",
226831f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper      methodDecl(ofClass(hasName("X"))), true, "-std=gnu++98"));
2269671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri Gribenko
2270671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri Gribenko  EXPECT_TRUE(matches("class X { void operator delete(void*); };",
22712dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      methodDecl(ofClass(hasName("X")))));
2272671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri Gribenko
227331f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  // Fails in C++11 mode
227431f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  EXPECT_TRUE(matchesConditionally(
22752dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      "namespace std { typedef typeof(sizeof(int)) size_t; }"
22762dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      "class X { void operator delete[](void*, std::size_t); };",
227731f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper      methodDecl(ofClass(hasName("X"))), true, "-std=gnu++98"));
2278671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri Gribenko}
2279671a045cc61cabe0b5fee0d8a93337e771156e11Dmitri Gribenko
22804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasObjectExpression, DoesNotMatchMember) {
22814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
22824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
22832dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
22844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasObjectExpression, MatchesBaseOfVariable) {
22874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
22884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "struct X { int m; }; void f(X x) { x.m; }",
22892dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
22904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
22914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "struct X { int m; }; void f(X* x) { x->m; }",
22922dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberExpr(hasObjectExpression(
22932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasType(pointsTo(recordDecl(hasName("X"))))))));
22944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
22954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
22964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasObjectExpression,
22974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek     MatchesObjectExpressionOfImplicitlyFormedMemberExpression) {
22984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
22994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X {}; struct S { X m; void f() { this->m; } };",
23002dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberExpr(hasObjectExpression(
23012dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasType(pointsTo(recordDecl(hasName("S"))))))));
23024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
23034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X {}; struct S { X m; void f() { m; } };",
23042dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      memberExpr(hasObjectExpression(
23052dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          hasType(pointsTo(recordDecl(hasName("S"))))))));
23064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Field, DoesNotMatchNonFieldMembers) {
23092dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class X { void m(); };", fieldDecl(hasName("m"))));
23102dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class X { class m {}; };", fieldDecl(hasName("m"))));
23112dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class X { enum { m }; };", fieldDecl(hasName("m"))));
23122dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class X { enum m {}; };", fieldDecl(hasName("m"))));
23134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Field, MatchesField) {
23162dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("class X { int m; };", fieldDecl(hasName("m"))));
23174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsConstQualified, MatchesConstInt) {
23204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("const int i = 42;",
23212dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasType(isConstQualified()))));
23224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsConstQualified, MatchesConstPointer) {
23254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("int i = 42; int* const p(&i);",
23262dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasType(isConstQualified()))));
23274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsConstQualified, MatchesThroughTypedef) {
23304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
23312dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasType(isConstQualified()))));
23324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p(0);",
23332dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasType(isConstQualified()))));
23344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsConstQualified, DoesNotMatchInappropriately) {
23374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
23382dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasType(isConstQualified()))));
23394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("int const* p;",
23402dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasType(isConstQualified()))));
23414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2343089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(CastExpression, MatchesExplicitCasts) {
23443680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("char *p = reinterpret_cast<char *>(&p);",castExpr()));
23453680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("void *p = (void *)(&p);", castExpr()));
23463680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("char q, *p = const_cast<char *>(&q);", castExpr()));
23473680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("char c = char(0);", castExpr()));
2348089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2349089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(CastExpression, MatchesImplicitCasts) {
2350089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from int to char.
23513680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("char c = 0;", castExpr()));
2352089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from lvalue to rvalue.
23533680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(matches("char c = 0, d = c;", castExpr()));
2354089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2355089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2356089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(CastExpression, DoesNotMatchNonCasts) {
23573680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(notMatches("char c = '0';", castExpr()));
23583680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(notMatches("char c, &q = c;", castExpr()));
23593680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(notMatches("int i = (0);", castExpr()));
23603680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
2361089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2362089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
23634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ReinterpretCast, MatchesSimpleCase) {
23644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("char* p = reinterpret_cast<char*>(&p);",
23653680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      reinterpretCastExpr()));
23664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ReinterpretCast, DoesNotMatchOtherCasts) {
23693680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(notMatches("char* p = (char*)(&p);", reinterpretCastExpr()));
23704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
23713680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                         reinterpretCastExpr()));
23724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void* p = static_cast<void*>(&p);",
23733680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                         reinterpretCastExpr()));
23744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
23754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                         "B b;"
23764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                         "D* p = dynamic_cast<D*>(&b);",
23773680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                         reinterpretCastExpr()));
23784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(FunctionalCast, MatchesSimpleCase) {
23814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  std::string foo_class = "class Foo { public: Foo(char*); };";
23824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",
23833680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      functionalCastExpr()));
23844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(FunctionalCast, DoesNotMatchOtherCasts) {
23874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  std::string FooClass = "class Foo { public: Foo(char*); };";
23884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
23894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",
23903680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                 functionalCastExpr()));
23914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(
23924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      notMatches(FooClass + "void r() { Foo f = \"hello world\"; }",
23933680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                 functionalCastExpr()));
23944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
23954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
23964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DynamicCast, MatchesSimpleCase) {
23974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("struct B { virtual ~B() {} }; struct D : B {};"
23984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "B b;"
23994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "D* p = dynamic_cast<D*>(&b);",
24003680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      dynamicCastExpr()));
24014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StaticCast, MatchesSimpleCase) {
24044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void* p(static_cast<void*>(&p));",
24053680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      staticCastExpr()));
24064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
24084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(StaticCast, DoesNotMatchOtherCasts) {
24093680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper  EXPECT_TRUE(notMatches("char* p = (char*)(&p);", staticCastExpr()));
24104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
24113680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                         staticCastExpr()));
24124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void* p = reinterpret_cast<char*>(&p);",
24133680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                         staticCastExpr()));
24144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
24154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                         "B b;"
24164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                         "D* p = dynamic_cast<D*>(&b);",
24173680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                         staticCastExpr()));
24184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2420e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel JasperTEST(CStyleCast, MatchesSimpleCase) {
2421e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper  EXPECT_TRUE(matches("int i = (int) 2.2f;", cStyleCastExpr()));
2422e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper}
2423e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper
2424e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel JasperTEST(CStyleCast, DoesNotMatchOtherCasts) {
2425e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper  EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);"
2426e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         "char q, *r = const_cast<char*>(&q);"
2427e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         "void* s = reinterpret_cast<char*>(&s);"
2428e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         "struct B { virtual ~B() {} }; struct D : B {};"
2429e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         "B b;"
2430e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         "D* t = dynamic_cast<D*>(&b);",
2431e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper                         cStyleCastExpr()));
2432e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper}
2433e6d2a96cc9689be584c3bfc09ac527a03a25b3bcDaniel Jasper
24344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasDestinationType, MatchesSimpleCase) {
24354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
24363680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      staticCastExpr(hasDestinationType(
24373680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          pointsTo(TypeMatcher(anything()))))));
24384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
24394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2440089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(HasImplicitDestinationType, MatchesSimpleCase) {
2441089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit const cast.
2442089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x; const int i = x;",
24433680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      implicitCastExpr(
24443680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          hasImplicitDestinationType(isInteger()))));
2445089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit array-to-pointer cast.
2446089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int arr[3]; int *p = arr;",
24473680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      implicitCastExpr(hasImplicitDestinationType(
24483680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          pointsTo(TypeMatcher(anything()))))));
2449089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2450089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2451089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(HasImplicitDestinationType, DoesNotMatchIncorrectly) {
2452089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from int to char.
2453089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char c = 0;",
24543680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      implicitCastExpr(hasImplicitDestinationType(
24553680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          unless(anything())))));
2456089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit array-to-pointer cast.
2457089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int arr[3]; int *p = arr;",
24583680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      implicitCastExpr(hasImplicitDestinationType(
24593680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          unless(anything())))));
2460089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2461089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2462089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(ImplicitCast, MatchesSimpleCase) {
2463089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit const cast.
2464089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0; const int y = x;",
24652dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(implicitCastExpr()))));
2466089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from int to char.
2467089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("char c = 0;",
24682dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(implicitCastExpr()))));
2469089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit array-to-pointer cast.
2470089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int arr[6]; int *p = arr;",
24712dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(implicitCastExpr()))));
2472089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2473089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2474089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(ImplicitCast, DoesNotMatchIncorrectly) {
24752dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  // This test verifies that implicitCastExpr() matches exactly when implicit casts
2476089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // are present, and that it ignores explicit and paren casts.
2477089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2478089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These two test cases have no casts.
2479089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x = 0;",
24802dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(implicitCastExpr()))));
2481089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x = 0, &y = x;",
24822dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(implicitCastExpr()))));
2483089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2484089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x = 0; double d = (double) x;",
24852dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(implicitCastExpr()))));
2486089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("const int *p; int *q = const_cast<int *>(p);",
24872dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(implicitCastExpr()))));
2488089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2489089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x = (0);",
24902dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(implicitCastExpr()))));
2491089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2492089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2493089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringImpCasts, MatchesImpCasts) {
2494089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test checks that ignoringImpCasts matches when implicit casts are
2495089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // present and its inner matcher alone does not match.
2496089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // Note that this test creates an implicit const cast.
2497089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0; const int y = x;",
24982dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringImpCasts(
24992dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          declRefExpr(to(varDecl(hasName("x")))))))));
2500089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implict cast from int to char.
2501089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("char x = 0;",
25022dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringImpCasts(
2503089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                          integerLiteral(equals(0)))))));
2504089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2505089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2506089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringImpCasts, DoesNotMatchIncorrectly) {
2507089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These tests verify that ignoringImpCasts does not match if the inner
2508089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // matcher does not match.
2509089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // Note that the first test creates an implicit const cast.
2510089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x; const int y = x;",
25112dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
2512089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
2513089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x; int y = x;",
25142dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
2515089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
2516089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2517089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These tests verify that ignoringImplictCasts does not look through explicit
2518089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // casts or parentheses.
2519089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
25202dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
25212dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
2522089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int i = (0);",
25232dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
25242dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
2525089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("float i = (float)0;",
25262dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
25272dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
2528089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("float i = float(0);",
25292dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringImpCasts(
25302dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
2531089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2532089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2533089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringImpCasts, MatchesWithoutImpCasts) {
2534089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test verifies that expressions that do not have implicit casts
2535089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // still match the inner matcher.
2536089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0; int &y = x;",
25372dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringImpCasts(
25382dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          declRefExpr(to(varDecl(hasName("x")))))))));
2539089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2540089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2541089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenCasts, MatchesParenCasts) {
2542089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test checks that ignoringParenCasts matches when parentheses and/or
2543089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // casts are present and its inner matcher alone does not match.
2544089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = (0);",
25452dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
25462dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
2547089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = (((((0)))));",
25482dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
25492dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
2550089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2551089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implict cast from int to char in addition to the
2552089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // parentheses.
2553089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("char x = (0);",
25542dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
25552dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
2556089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2557089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("char x = (char)0;",
25582dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
25592dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
2560089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
25612dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
2562089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                          integerLiteral(equals(0)))))));
2563089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2564089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2565089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenCasts, MatchesWithoutParenCasts) {
2566089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test verifies that expressions that do not have any casts still match.
2567089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0;",
25682dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenCasts(
25692dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
2570089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2571089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2572089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenCasts, DoesNotMatchIncorrectly) {
2573089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These tests verify that ignoringImpCasts does not match if the inner
2574089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // matcher does not match.
2575089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("int x = ((0));",
25762dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenCasts(
2577089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
2578089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2579089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from int to char in addition to the
2580089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // parentheses.
2581089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char x = ((0));",
25822dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenCasts(
2583089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
2584089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2585089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char *x = static_cast<char *>((0));",
25862dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenCasts(
2587089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
2588089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2589089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2590089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenAndImpCasts, MatchesParenImpCasts) {
2591089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test checks that ignoringParenAndImpCasts matches when
2592089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // parentheses and/or implicit casts are present and its inner matcher alone
2593089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // does not match.
2594089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // Note that this test creates an implicit const cast.
2595089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0; const int y = x;",
25962dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenImpCasts(
25972dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          declRefExpr(to(varDecl(hasName("x")))))))));
2598089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast from int to char.
2599089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("const char x = (0);",
26002dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenImpCasts(
26012dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
2602089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2603089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2604089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenAndImpCasts, MatchesWithoutParenImpCasts) {
2605089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test verifies that expressions that do not have parentheses or
2606089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // implicit casts still match.
2607089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0; int &y = x;",
26082dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenImpCasts(
26092dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          declRefExpr(to(varDecl(hasName("x")))))))));
2610089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(matches("int x = 0;",
26112dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      varDecl(hasInitializer(ignoringParenImpCasts(
26122dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          integerLiteral(equals(0)))))));
2613089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2614089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2615089e5b3bf2e57da0173b170ad501867b43395385Sam PanzerTEST(IgnoringParenAndImpCasts, DoesNotMatchIncorrectly) {
2616089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These tests verify that ignoringParenImpCasts does not match if
2617089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // the inner matcher does not match.
2618089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // This test creates an implicit cast.
2619089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char c = ((3));",
26202dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenImpCasts(
2621089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer                             unless(anything()))))));
2622089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // These tests verify that ignoringParenAndImplictCasts does not look
2623089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  // through explicit casts.
2624089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("float y = (float(0));",
26252dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenImpCasts(
26262dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
2627089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("float y = (float)0;",
26282dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenImpCasts(
26292dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
2630089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer  EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
26312dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         varDecl(hasInitializer(ignoringParenImpCasts(
26322dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             integerLiteral())))));
2633089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer}
2634089e5b3bf2e57da0173b170ad501867b43395385Sam Panzer
2635715c9568ee5d75f25dab98229c87bcec880daf5dManuel KlimekTEST(HasSourceExpression, MatchesImplicitCasts) {
26364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
26374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                      "void r() {string a_string; URL url = a_string; }",
26383680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      implicitCastExpr(
26393680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                          hasSourceExpression(constructExpr()))));
26404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
26414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2642715c9568ee5d75f25dab98229c87bcec880daf5dManuel KlimekTEST(HasSourceExpression, MatchesExplicitCasts) {
2643715c9568ee5d75f25dab98229c87bcec880daf5dManuel Klimek  EXPECT_TRUE(matches("float x = static_cast<float>(42);",
26443680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                      explicitCastExpr(
26452dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          hasSourceExpression(hasDescendant(
26463680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper                              expr(integerLiteral()))))));
2647715c9568ee5d75f25dab98229c87bcec880daf5dManuel Klimek}
2648715c9568ee5d75f25dab98229c87bcec880daf5dManuel Klimek
26494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Statement, DoesNotMatchDeclarations) {
26502dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("class X {};", stmt()));
26514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
26524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
26534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Statement, MatchesCompoundStatments) {
26542dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("void x() {}", stmt()));
26554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
26564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
26574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationStatement, DoesNotMatchCompoundStatements) {
26582dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(notMatches("void x() {}", declStmt()));
26594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
26604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
26614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(DeclarationStatement, MatchesVariableDeclarationStatements) {
26622dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  EXPECT_TRUE(matches("void x() { int a; }", declStmt()));
26634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
26644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2665e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(InitListExpression, MatchesInitListExpression) {
2666e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("int a[] = { 1, 2 };",
2667e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      initListExpr(hasType(asString("int [2]")))));
2668e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };",
26692dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      initListExpr(hasType(recordDecl(hasName("B"))))));
2670e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2671e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
2672e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UsingDeclaration, MatchesUsingDeclarations) {
2673e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("namespace X { int x; } using X::x;",
2674e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      usingDecl()));
2675e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2676e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
2677e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UsingDeclaration, MatchesShadowUsingDelcarations) {
2678e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("namespace f { int a; } using f::a;",
2679e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      usingDecl(hasAnyUsingShadowDecl(hasName("a")))));
2680e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2681e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
2682e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UsingDeclaration, MatchesSpecificTarget) {
2683e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
2684e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                      usingDecl(hasAnyUsingShadowDecl(
26852dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                          hasTargetDecl(functionDecl())))));
2686e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
2687e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper                         usingDecl(hasAnyUsingShadowDecl(
26882dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                             hasTargetDecl(functionDecl())))));
2689e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2690e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
2691e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel JasperTEST(UsingDeclaration, ThroughUsingDeclaration) {
2692e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(matches(
2693e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "namespace a { void f(); } using a::f; void g() { f(); }",
26942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      declRefExpr(throughUsingDecl(anything()))));
2695e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper  EXPECT_TRUE(notMatches(
2696e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper      "namespace a { void f(); } using a::f; void g() { a::f(); }",
26972dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      declRefExpr(throughUsingDecl(anything()))));
2698e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper}
2699e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper
2700425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam PanzerTEST(SingleDecl, IsSingleDecl) {
2701425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  StatementMatcher SingleDeclStmt =
27022dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      declStmt(hasSingleDecl(varDecl(hasInitializer(anything()))));
2703425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(matches("void f() {int a = 4;}", SingleDeclStmt));
2704425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(notMatches("void f() {int a;}", SingleDeclStmt));
2705425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
2706425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer                          SingleDeclStmt));
2707425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer}
2708425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer
2709425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam PanzerTEST(DeclStmt, ContainsDeclaration) {
27102dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper  DeclarationMatcher MatchesInit = varDecl(hasInitializer(anything()));
2711425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer
2712425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(matches("void f() {int a = 4;}",
27132dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      declStmt(containsDeclaration(0, MatchesInit))));
2714425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(matches("void f() {int a = 4, b = 3;}",
27152dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      declStmt(containsDeclaration(0, MatchesInit),
27162dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                               containsDeclaration(1, MatchesInit))));
2717425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  unsigned WrongIndex = 42;
2718425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
27192dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         declStmt(containsDeclaration(WrongIndex,
2720425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer                                                      MatchesInit))));
2721425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer}
2722425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer
2723425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam PanzerTEST(DeclCount, DeclCountIsCorrect) {
2724425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(matches("void f() {int i,j;}",
27252dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                      declStmt(declCountIs(2))));
2726425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(notMatches("void f() {int i,j; int k;}",
27272dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         declStmt(declCountIs(3))));
2728425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer  EXPECT_TRUE(notMatches("void f() {int i,j, k, l;}",
27292dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                         declStmt(declCountIs(3))));
2730425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer}
2731425f41b370a8795fbca9ffc3b35e9b0ccbb15d97Sam Panzer
27324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(While, MatchesWhileLoops) {
27334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() {}", whileStmt()));
27344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { while(true); }", whileStmt()));
27354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { do {} while(true); }", whileStmt()));
27364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Do, MatchesDoLoops) {
27394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { do {} while(true); }", doStmt()));
27404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { do ; while(false); }", doStmt()));
27414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(Do, DoesNotMatchWhileLoops) {
27444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { while(true) {} }", doStmt()));
27454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(SwitchCase, MatchesCase) {
27484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchCase()));
27494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchCase()));
27504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchCase()));
27514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches("void x() { switch(42) {} }", switchCase()));
27524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2754b54b7646b2d00a85d80e40adf7c49553f150c736Daniel JasperTEST(SwitchCase, MatchesSwitch) {
2755b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchStmt()));
2756b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchStmt()));
2757b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchStmt()));
2758b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(notMatches("void x() {}", switchStmt()));
2759b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper}
2760b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper
2761b54b7646b2d00a85d80e40adf7c49553f150c736Daniel JasperTEST(ExceptionHandling, SimpleCases) {
2762b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", catchStmt()));
2763b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", tryStmt()));
2764b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(notMatches("void foo() try { } catch(int X) { }", throwExpr()));
2765b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void foo() try { throw; } catch(int X) { }",
2766b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper                      throwExpr()));
2767b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void foo() try { throw 5;} catch(int X) { }",
2768b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper                      throwExpr()));
2769b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper}
2770b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper
27714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasConditionVariableStatement, DoesNotMatchCondition) {
27724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
27734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void x() { if(true) {} }",
27742dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      ifStmt(hasConditionVariableStatement(declStmt()))));
27754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
27764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void x() { int x; if((x = 42)) {} }",
27772dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      ifStmt(hasConditionVariableStatement(declStmt()))));
27784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(HasConditionVariableStatement, MatchesConditionVariables) {
27814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
27824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "void x() { if(int* a = 0) {} }",
27832dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      ifStmt(hasConditionVariableStatement(declStmt()))));
27844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEach, BindsOneNode) {
27874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
27882dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"), forEach(fieldDecl(hasName("x")).bind("x"))),
2789a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("x", 1)));
27904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEach, BindsMultipleNodes) {
27934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
27942dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"), forEach(fieldDecl().bind("f"))),
2795a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("f", 3)));
27964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
27974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
27984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEach, BindsRecursiveCombinations) {
27994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
28004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class C { class D { int x; int y; }; class E { int y; int z; }; };",
28012dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"),
28022dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 forEach(recordDecl(forEach(fieldDecl().bind("f"))))),
2803a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("f", 4)));
28044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEachDescendant, BindsOneNode) {
28074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
28082dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"),
28092dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper                 forEachDescendant(fieldDecl(hasName("x")).bind("x"))),
2810a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("x", 1)));
28114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28135f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel JasperTEST(ForEachDescendant, NestedForEachDescendant) {
28145f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper  DeclarationMatcher m = recordDecl(
28155f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper      isDefinition(), decl().bind("x"), hasName("C"));
28165f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
28175f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper    "class A { class B { class C {}; }; };",
28185f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper    recordDecl(hasName("A"), anyOf(m, forEachDescendant(m))),
28195f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper    new VerifyIdIsBoundTo<Decl>("x", "C")));
28205f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper
28215f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper  // FIXME: This is not really a useful matcher, but the result is still
28225f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper  // surprising (currently binds "A").
28235f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper  //EXPECT_TRUE(matchAndVerifyResultTrue(
28245f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper  //  "class A { class B { class C {}; }; };",
28255f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper  //  recordDecl(hasName("A"), allOf(hasDescendant(m), anyOf(m, anything()))),
28265f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper  //  new VerifyIdIsBoundTo<Decl>("x", "C")));
28275f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper}
28285f684e90c2f44eda979573a01c2ed063d9adc7a8Daniel Jasper
28294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEachDescendant, BindsMultipleNodes) {
28304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
28314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class C { class D { int x; int y; }; "
28324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "          class E { class F { int y; int z; }; }; };",
28332dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"), forEachDescendant(fieldDecl().bind("f"))),
2834a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("f", 4)));
28354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(ForEachDescendant, BindsRecursiveCombinations) {
28384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
28394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class C { class D { "
28404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "          class E { class F { class G { int y; int z; }; }; }; }; };",
28412dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("C"), forEachDescendant(recordDecl(
28422dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          forEachDescendant(fieldDecl().bind("f"))))),
2843a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("f", 8)));
28444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
284611c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel JasperTEST(ForEachDescendant, BindsCorrectNodes) {
284711c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
284811c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      "class C { void f(); int i; };",
284911c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
285011c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      new VerifyIdIsBoundTo<FieldDecl>("decl", 1)));
285111c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
285211c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      "class C { void f() {} int i; };",
285311c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
285411c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      new VerifyIdIsBoundTo<FunctionDecl>("decl", 1)));
285511c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper}
285611c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper
28577387673f83b8b37f660422947c9990778ba88193Manuel KlimekTEST(EachOf, TriggersForEachMatch) {
28587387673f83b8b37f660422947c9990778ba88193Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
28597387673f83b8b37f660422947c9990778ba88193Manuel Klimek      "class A { int a; int b; };",
28607387673f83b8b37f660422947c9990778ba88193Manuel Klimek      recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
28617387673f83b8b37f660422947c9990778ba88193Manuel Klimek                        has(fieldDecl(hasName("b")).bind("v")))),
28627387673f83b8b37f660422947c9990778ba88193Manuel Klimek      new VerifyIdIsBoundTo<FieldDecl>("v", 2)));
28637387673f83b8b37f660422947c9990778ba88193Manuel Klimek}
28647387673f83b8b37f660422947c9990778ba88193Manuel Klimek
28657387673f83b8b37f660422947c9990778ba88193Manuel KlimekTEST(EachOf, BehavesLikeAnyOfUnlessBothMatch) {
28667387673f83b8b37f660422947c9990778ba88193Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
28677387673f83b8b37f660422947c9990778ba88193Manuel Klimek      "class A { int a; int c; };",
28687387673f83b8b37f660422947c9990778ba88193Manuel Klimek      recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
28697387673f83b8b37f660422947c9990778ba88193Manuel Klimek                        has(fieldDecl(hasName("b")).bind("v")))),
28707387673f83b8b37f660422947c9990778ba88193Manuel Klimek      new VerifyIdIsBoundTo<FieldDecl>("v", 1)));
28717387673f83b8b37f660422947c9990778ba88193Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
28727387673f83b8b37f660422947c9990778ba88193Manuel Klimek      "class A { int c; int b; };",
28737387673f83b8b37f660422947c9990778ba88193Manuel Klimek      recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
28747387673f83b8b37f660422947c9990778ba88193Manuel Klimek                        has(fieldDecl(hasName("b")).bind("v")))),
28757387673f83b8b37f660422947c9990778ba88193Manuel Klimek      new VerifyIdIsBoundTo<FieldDecl>("v", 1)));
28767387673f83b8b37f660422947c9990778ba88193Manuel Klimek  EXPECT_TRUE(notMatches(
28777387673f83b8b37f660422947c9990778ba88193Manuel Klimek      "class A { int c; int d; };",
28787387673f83b8b37f660422947c9990778ba88193Manuel Klimek      recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
28797387673f83b8b37f660422947c9990778ba88193Manuel Klimek                        has(fieldDecl(hasName("b")).bind("v"))))));
28807387673f83b8b37f660422947c9990778ba88193Manuel Klimek}
28814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) {
28834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // Make sure that we can both match the class by name (::X) and by the type
28844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // the template was instantiated with (via a field).
28854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
28874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X {}; class A {}; X<A> x;",
28882dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("::X"), isTemplateInstantiation())));
28894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
28914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X { T t; }; class A {}; X<A> x;",
28922dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isTemplateInstantiation(), hasDescendant(
28932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          fieldDecl(hasType(recordDecl(hasName("A"))))))));
28944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
28954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
28964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) {
28974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
28984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
28992dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionDecl(hasParameter(0, hasType(recordDecl(hasName("A")))),
29004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek               isTemplateInstantiation())));
29014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
29034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) {
29044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
29054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X { T t; }; class A {};"
29064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template class X<A>;",
29072dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isTemplateInstantiation(), hasDescendant(
29082dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper          fieldDecl(hasType(recordDecl(hasName("A"))))))));
29094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
29114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation,
29124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek     MatchesInstantiationOfPartiallySpecializedClassTemplate) {
29134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
29144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X {};"
29154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
29162dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("::X"), isTemplateInstantiation())));
29174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
29194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation,
29204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek     MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
29214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
29224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class A {};"
29234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class X {"
29244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  template <typename U> class Y { U u; };"
29254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Y<A> y;"
29264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "};",
29272dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("::X::Y"), isTemplateInstantiation())));
29284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
29304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) {
29314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // FIXME: Figure out whether this makes sense. It doesn't affect the
29324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // normal use case as long as the uppermost instantiation always is marked
29334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  // as template instantiation, but it might be confusing as a predicate.
29344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(matches(
29354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class A {};"
29364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X {"
29374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  template <typename U> class Y { U u; };"
29384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "  Y<T> y;"
29394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "}; X<A> x;",
29402dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
29414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
29434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) {
29444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
29454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <typename T> class X {}; class A {};"
29464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "template <> class X<A> {}; X<A> x;",
29472dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(hasName("::X"), isTemplateInstantiation())));
29484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
29504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekTEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) {
29514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  EXPECT_TRUE(notMatches(
29524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      "class A {}; class Y { A a; };",
29532dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isTemplateInstantiation())));
29544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
29554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
29568456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(IsExplicitTemplateSpecialization,
29578456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko     DoesNotMatchPrimaryTemplate) {
29588456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
29598456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> class X {};",
29602dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isExplicitTemplateSpecialization())));
29618456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
29628456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> void f(T t);",
29632dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionDecl(isExplicitTemplateSpecialization())));
29648456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
29658456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
29668456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(IsExplicitTemplateSpecialization,
29678456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko     DoesNotMatchExplicitTemplateInstantiations) {
29688456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
29698456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> class X {};"
29708456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template class X<int>; extern template class X<long>;",
29712dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isExplicitTemplateSpecialization())));
29728456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
29738456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> void f(T t) {}"
29748456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template void f(int t); extern template void f(long t);",
29752dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionDecl(isExplicitTemplateSpecialization())));
29768456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
29778456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
29788456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(IsExplicitTemplateSpecialization,
29798456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko     DoesNotMatchImplicitTemplateInstantiations) {
29808456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
29818456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> class X {}; X<int> x;",
29822dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isExplicitTemplateSpecialization())));
29838456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(notMatches(
29848456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> void f(T t); void g() { f(10); }",
29852dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionDecl(isExplicitTemplateSpecialization())));
29868456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
29878456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
29888456ae602783b615019a42f7d5c6f0e71639b11bDmitri GribenkoTEST(IsExplicitTemplateSpecialization,
29898456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko     MatchesExplicitTemplateSpecializations) {
29908456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(matches(
29918456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> class X {};"
29928456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template<> class X<int> {};",
29932dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      recordDecl(isExplicitTemplateSpecialization())));
29948456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko  EXPECT_TRUE(matches(
29958456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template <typename T> void f(T t) {}"
29968456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko      "template<> void f(int t) {}",
29972dc75ed2ef2fa3cbfd8b2ed88eb2369f3fcd98a9Daniel Jasper      functionDecl(isExplicitTemplateSpecialization())));
29988456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko}
29998456ae602783b615019a42f7d5c6f0e71639b11bDmitri Gribenko
3000579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncenstor, MatchesDeclarationAncestors) {
3001579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
3002579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "class A { class B { class C {}; }; };",
3003579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("A"))))));
3004579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3005579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3006579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncenstor, FailsIfNoAncestorMatches) {
3007579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(notMatches(
3008579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "class A { class B { class C {}; }; };",
3009579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("X"))))));
3010579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3011579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3012579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, MatchesDeclarationsThatGetVisitedLater) {
3013579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
3014579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "class A { class B { void f() { C c; } class C {}; }; };",
3015579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      varDecl(hasName("c"), hasType(recordDecl(hasName("C"),
3016579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek          hasAncestor(recordDecl(hasName("A"))))))));
3017579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3018579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3019579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncenstor, MatchesStatementAncestors) {
3020579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
3021579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "void f() { if (true) { while (false) { 42; } } }",
30223680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      integerLiteral(equals(42), hasAncestor(ifStmt()))));
3023579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3024579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3025579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, DrillsThroughDifferentHierarchies) {
3026579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
3027579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "void f() { if (true) { int x = 42; } }",
30283680b4f7494b6744b9c5a25f83b63cd8b7e434fcDaniel Jasper      integerLiteral(equals(42), hasAncestor(functionDecl(hasName("f"))))));
3029579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3030579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3031579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, BindsRecursiveCombinations) {
3032579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3033579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "class C { class D { class E { class F { int y; }; }; }; };",
3034579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      fieldDecl(hasAncestor(recordDecl(hasAncestor(recordDecl().bind("r"))))),
3035a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<CXXRecordDecl>("r", 1)));
3036579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3037579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3038579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, BindsCombinationsWithHasDescendant) {
3039579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
3040579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "class C { class D { class E { class F { int y; }; }; }; };",
3041579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      fieldDecl(hasAncestor(
3042579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek          decl(
3043579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek            hasDescendant(recordDecl(isDefinition(),
3044579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek                                     hasAncestor(recordDecl())))
3045579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek          ).bind("d")
3046579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      )),
3047a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<CXXRecordDecl>("d", "E")));
3048579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3049579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3050579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, MatchesInTemplateInstantiations) {
3051579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
3052579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "template <typename T> struct A { struct B { struct C { T t; }; }; }; "
3053579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "A<int>::B::C a;",
3054579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      fieldDecl(hasType(asString("int")),
3055579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek                hasAncestor(recordDecl(hasName("A"))))));
3056579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3057579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3058579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel KlimekTEST(HasAncestor, MatchesInImplicitCode) {
3059579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek  EXPECT_TRUE(matches(
3060579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      "struct X {}; struct A { A() {} X x; };",
3061579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek      constructorDecl(
3062579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek          hasAnyConstructorInitializer(withInitializer(expr(
3063579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek              hasAncestor(recordDecl(hasName("A")))))))));
3064579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}
3065579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek
3066c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel JasperTEST(HasParent, MatchesOnlyParent) {
3067c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper  EXPECT_TRUE(matches(
3068c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      "void f() { if (true) { int x = 42; } }",
3069c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      compoundStmt(hasParent(ifStmt()))));
3070c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper  EXPECT_TRUE(notMatches(
3071c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      "void f() { for (;;) { int x = 42; } }",
3072c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      compoundStmt(hasParent(ifStmt()))));
3073c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper  EXPECT_TRUE(notMatches(
3074c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      "void f() { if (true) for (;;) { int x = 42; } }",
3075c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper      compoundStmt(hasParent(ifStmt()))));
3076c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper}
3077c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper
307830ace3715015b4a9bc5fa538a6515481abed40f9Manuel KlimekTEST(HasAncestor, MatchesAllAncestors) {
307930ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek  EXPECT_TRUE(matches(
308030ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "template <typename T> struct C { static void f() { 42; } };"
308130ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "void t() { C<int>::f(); }",
308230ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      integerLiteral(
308330ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek          equals(42),
308430ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek          allOf(hasAncestor(recordDecl(isTemplateInstantiation())),
308530ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek                hasAncestor(recordDecl(unless(isTemplateInstantiation())))))));
308630ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek}
308730ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek
308830ace3715015b4a9bc5fa538a6515481abed40f9Manuel KlimekTEST(HasParent, MatchesAllParents) {
308930ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek  EXPECT_TRUE(matches(
309030ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "template <typename T> struct C { static void f() { 42; } };"
309130ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "void t() { C<int>::f(); }",
309230ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      integerLiteral(
309330ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek          equals(42),
309430ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek          hasParent(compoundStmt(hasParent(functionDecl(
309530ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek              hasParent(recordDecl(isTemplateInstantiation())))))))));
309630ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek  EXPECT_TRUE(matches(
309730ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "template <typename T> struct C { static void f() { 42; } };"
309830ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "void t() { C<int>::f(); }",
309930ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      integerLiteral(
310030ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek          equals(42),
310130ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek          hasParent(compoundStmt(hasParent(functionDecl(
310230ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek              hasParent(recordDecl(unless(isTemplateInstantiation()))))))))));
310330ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek  EXPECT_TRUE(matches(
310430ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "template <typename T> struct C { static void f() { 42; } };"
310530ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      "void t() { C<int>::f(); }",
310630ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek      integerLiteral(equals(42),
310730ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek                     hasParent(compoundStmt(allOf(
310830ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek                         hasParent(functionDecl(
310930ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek                             hasParent(recordDecl(isTemplateInstantiation())))),
311030ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek                         hasParent(functionDecl(hasParent(recordDecl(
311130ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek                             unless(isTemplateInstantiation())))))))))));
311230ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek}
311330ace3715015b4a9bc5fa538a6515481abed40f9Manuel Klimek
3114ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesTypes) {
3115ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("struct S {};", qualType().bind("loc")));
3116ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3117ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3118ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesArrayTypes) {
3119ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[] = {2,3};", arrayType()));
3120ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[42];", arrayType()));
3121ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("void f(int b) { int a[b]; }", arrayType()));
3122ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3123ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches("struct A {}; A a[7];",
3124ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                         arrayType(hasElementType(builtinType()))));
3125ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3126ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3127ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int const a[] = { 2, 3 };",
3128ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(arrayType(hasElementType(builtinType())))));
3129ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3130ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int const a[] = { 2, 3 };",
3131ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
3132ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3133ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "typedef const int T; T x[] = { 1, 2 };",
3134ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(isConstQualified(), arrayType())));
3135ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3136ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
3137ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int a[] = { 2, 3 };",
3138ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
3139ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
3140ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int a[] = { 2, 3 };",
3141ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(arrayType(hasElementType(isConstQualified(), builtinType())))));
3142ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
3143ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int const a[] = { 2, 3 };",
3144ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      qualType(arrayType(hasElementType(builtinType())),
3145ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper               unless(isConstQualified()))));
3146ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3147ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[2];",
3148ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                      constantArrayType(hasElementType(builtinType()))));
3149ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("const int a = 0;", qualType(isInteger())));
3150ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3151ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3152ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesComplexTypes) {
3153ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("_Complex float f;", complexType()));
3154ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3155ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "_Complex float f;",
3156ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    complexType(hasElementType(builtinType()))));
3157ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
3158ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "_Complex float f;",
3159ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    complexType(hasElementType(isInteger()))));
3160ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3161ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3162ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesConstantArrayTypes) {
3163ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[2];", constantArrayType()));
3164ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
3165ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "void f() { int a[] = { 2, 3 }; int b[a[0]]; }",
3166ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    constantArrayType(hasElementType(builtinType()))));
3167ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3168ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[42];", constantArrayType(hasSize(42))));
3169ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int b[2*21];", constantArrayType(hasSize(42))));
3170ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches("int c[41], d[43];", constantArrayType(hasSize(42))));
3171ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3172ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3173ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesDependentSizedArrayTypes) {
3174ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3175ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "template <typename T, int Size> class array { T data[Size]; };",
3176ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    dependentSizedArrayType()));
3177ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
3178ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "int a[42]; int b[] = { 2, 3 }; void f() { int c[b[0]]; }",
3179ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    dependentSizedArrayType()));
3180ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3181ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3182ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesIncompleteArrayType) {
3183ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int a[] = { 2, 3 };", incompleteArrayType()));
3184ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("void f(int a[]) {}", incompleteArrayType()));
3185ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3186ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches("int a[42]; void f() { int b[a[0]]; }",
3187ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                         incompleteArrayType()));
3188ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3189ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3190ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesVariableArrayType) {
3191ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("void f(int b) { int a[b]; }", variableArrayType()));
3192ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches("int a[] = {2, 3}; int b[42];", variableArrayType()));
3193ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3194ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3195ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    "void f(int b) { int a[b]; }",
3196ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper    variableArrayType(hasSizeExpr(ignoringImpCasts(declRefExpr(to(
3197ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      varDecl(hasName("b")))))))));
3198ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3199ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3200ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesAtomicTypes) {
3201ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("_Atomic(int) i;", atomicType()));
3202ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3203ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("_Atomic(int) i;",
3204ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                      atomicType(hasValueType(isInteger()))));
3205ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches("_Atomic(float) f;",
3206ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                         atomicType(hasValueType(isInteger()))));
3207ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3208ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3209ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesAutoTypes) {
3210ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("auto i = 2;", autoType()));
3211ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int v[] = { 2, 3 }; void f() { for (int i : v) {} }",
3212ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                      autoType()));
3213ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3214ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("auto a = 1;",
3215ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                      autoType(hasDeducedType(isInteger()))));
3216ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches("auto b = 2.0;",
3217ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                         autoType(hasDeducedType(isInteger()))));
3218ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3219ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3220a267cf6f87dc695143d65fc61ec1744564f55932Daniel JasperTEST(TypeMatching, MatchesFunctionTypes) {
3221a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("int (*f)(int);", functionType()));
3222a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper  EXPECT_TRUE(matches("void f(int i) {}", functionType()));
3223a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper}
3224a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper
3225ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, PointerTypes) {
32261802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  // FIXME: Reactive when these tests can be more specific (not matching
32271802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  // implicit code on certain platforms), likely when we have hasDescendant for
32281802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  // Types/TypeLocs.
32291802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //EXPECT_TRUE(matchAndVerifyResultTrue(
32301802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    "int* a;",
32311802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    pointerTypeLoc(pointeeLoc(typeLoc().bind("loc"))),
32321802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    new VerifyIdIsBoundTo<TypeLoc>("loc", 1)));
32331802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //EXPECT_TRUE(matchAndVerifyResultTrue(
32341802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    "int* a;",
32351802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    pointerTypeLoc().bind("loc"),
32361802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  //    new VerifyIdIsBoundTo<TypeLoc>("loc", 1)));
3237ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3238ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int** a;",
3239ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      pointerTypeLoc(pointeeLoc(loc(qualType())))));
3240ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3241ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int** a;",
3242ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      loc(pointerType(pointee(pointerType())))));
3243ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3244ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int* b; int* * const a = &b;",
3245ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      loc(qualType(isConstQualified(), pointerType()))));
3246ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3247ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  std::string Fragment = "struct A { int i; }; int A::* ptr = &A::i;";
32481802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
32491802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(blockPointerType()))));
32501802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(matches(Fragment, varDecl(hasName("ptr"),
32511802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                        hasType(memberPointerType()))));
32521802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
32531802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(pointerType()))));
32541802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
32551802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(referenceType()))));
32561802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper
32571802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  Fragment = "int *ptr;";
32581802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
32591802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(blockPointerType()))));
32601802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
32611802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(memberPointerType()))));
32621802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(matches(Fragment, varDecl(hasName("ptr"),
32631802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                        hasType(pointerType()))));
32641802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
32651802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(referenceType()))));
32661802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper
32671802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  Fragment = "int a; int &ref = a;";
32681802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
32691802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(blockPointerType()))));
32701802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
32711802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(memberPointerType()))));
32721802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
32731802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                           hasType(pointerType()))));
32741802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
32751802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                        hasType(referenceType()))));
3276ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3277ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3278ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, PointeeTypes) {
3279ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int b; int &a = b;",
3280ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                      referenceType(pointee(builtinType()))));
3281ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int *a;", pointerType(pointee(builtinType()))));
3282ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3283ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int *a;",
3284ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                      pointerTypeLoc(pointeeLoc(loc(builtinType())))));
3285ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3286ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3287ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int const *A;",
3288ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      pointerType(pointee(isConstQualified(), builtinType()))));
3289ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(notMatches(
3290ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int *A;",
3291ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      pointerType(pointee(isConstQualified(), builtinType()))));
3292ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3293ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3294ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesPointersToConstTypes) {
3295ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int b; int * const a = &b;",
3296ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                      loc(pointerType())));
3297ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches("int b; int * const a = &b;",
3298ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper                      pointerTypeLoc()));
3299ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3300ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int b; const int * a = &b;",
3301ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      pointerTypeLoc(pointeeLoc(builtinTypeLoc()))));
3302ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  EXPECT_TRUE(matches(
3303ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      "int b; const int * a = &b;",
3304ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      pointerType(pointee(builtinType()))));
3305ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3306ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3307ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel JasperTEST(TypeMatching, MatchesTypedefTypes) {
33081802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(matches("typedef int X; X a;", varDecl(hasName("a"),
33091802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                                                     hasType(typedefType()))));
3310ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
33111802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper  EXPECT_TRUE(matches("typedef int X; X a;",
33121802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                      varDecl(hasName("a"),
33131802daf8539f3320c369e442d3c8471b10ffd3cbDaniel Jasper                              hasType(typedefType(hasDecl(decl()))))));
3314ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}
3315ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
3316a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, MatchesNestedNameSpecifiers) {
3317a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;",
3318a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper                      nestedNameSpecifier()));
3319a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("template <typename T> class A { typename T::B b; };",
3320a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper                      nestedNameSpecifier()));
3321a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("struct A { void f(); }; void A::f() {}",
3322a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper                      nestedNameSpecifier()));
3323a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
3324a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches(
3325a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    "struct A { static void f() {} }; void g() { A::f(); }",
3326a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    nestedNameSpecifier()));
3327a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(notMatches(
3328a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    "struct A { static void f() {} }; void g(A* a) { a->f(); }",
3329a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    nestedNameSpecifier()));
3330a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
3331a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
3332b54b7646b2d00a85d80e40adf7c49553f150c736Daniel JasperTEST(NullStatement, SimpleCases) {
3333b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(matches("void f() {int i;;}", nullStmt()));
3334b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper  EXPECT_TRUE(notMatches("void f() {int i;}", nullStmt()));
3335b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper}
3336b54b7646b2d00a85d80e40adf7c49553f150c736Daniel Jasper
3337a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, MatchesTypes) {
3338a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  NestedNameSpecifierMatcher Matcher = nestedNameSpecifier(
3339a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    specifiesType(hasDeclaration(recordDecl(hasName("A")))));
3340a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("struct A { struct B {}; }; A::B b;", Matcher));
3341a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("struct A { struct B { struct C {}; }; }; A::B::C c;",
3342a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper                      Matcher));
3343a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(notMatches("namespace A { struct B {}; } A::B b;", Matcher));
3344a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
3345a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
3346a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, MatchesNamespaceDecls) {
3347a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  NestedNameSpecifierMatcher Matcher = nestedNameSpecifier(
3348a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper    specifiesNamespace(hasName("ns")));
3349a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;", Matcher));
3350a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(notMatches("namespace xx { struct A {}; } xx::A a;", Matcher));
3351a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(notMatches("struct ns { struct A {}; }; ns::A a;", Matcher));
3352a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
3353a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
3354a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, BindsNestedNameSpecifiers) {
3355a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
3356a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      "namespace ns { struct E { struct B {}; }; } ns::E::B b;",
3357a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      nestedNameSpecifier(specifiesType(asString("struct ns::E"))).bind("nns"),
3358a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifier>("nns", "ns::struct E::")));
3359a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
3360a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
3361a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, BindsNestedNameSpecifierLocs) {
3362a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
3363a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      "namespace ns { struct B {}; } ns::B b;",
3364a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      loc(nestedNameSpecifier()).bind("loc"),
3365a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("loc", 1)));
3366a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
3367a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
3368a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperTEST(NNS, MatchesNestedNameSpecifierPrefixes) {
3369a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches(
3370a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      "struct A { struct B { struct C {}; }; }; A::B::C c;",
3371a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      nestedNameSpecifier(hasPrefix(specifiesType(asString("struct A"))))));
3372a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper  EXPECT_TRUE(matches(
3373a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper      "struct A { struct B { struct C {}; }; }; A::B::C c;",
3374ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper      nestedNameSpecifierLoc(hasPrefix(
3375ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper          specifiesTypeLoc(loc(qualType(asString("struct A"))))))));
3376a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}
3377a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
3378d1ce3c178b9c648687591b190e0d252124fc2459Daniel JasperTEST(NNS, DescendantsOfNestedNameSpecifiers) {
3379d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  std::string Fragment =
3380d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "namespace a { struct A { struct B { struct C {}; }; }; };"
3381d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "void f() { a::A::B::C c; }";
3382d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
3383d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3384d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
3385d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                          hasDescendant(nestedNameSpecifier(
3386d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                              specifiesNamespace(hasName("a")))))));
3387d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(notMatches(
3388d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3389d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
3390d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                          has(nestedNameSpecifier(
3391d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                              specifiesNamespace(hasName("a")))))));
3392d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
3393d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3394d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifier(specifiesType(asString("struct a::A")),
3395d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                          has(nestedNameSpecifier(
3396d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                              specifiesNamespace(hasName("a")))))));
3397d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
3398d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  // Not really useful because a NestedNameSpecifier can af at most one child,
3399d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  // but to complete the interface.
3400d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
3401d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3402d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
3403d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                          forEach(nestedNameSpecifier().bind("x"))),
3404d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifier>("x", 1)));
3405d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper}
3406d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
3407d1ce3c178b9c648687591b190e0d252124fc2459Daniel JasperTEST(NNS, NestedNameSpecifiersAsDescendants) {
3408d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  std::string Fragment =
3409d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "namespace a { struct A { struct B { struct C {}; }; }; };"
3410d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "void f() { a::A::B::C c; }";
3411d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
3412d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3413d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      decl(hasDescendant(nestedNameSpecifier(specifiesType(
3414d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper          asString("struct a::A")))))));
3415d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
3416d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3417d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      functionDecl(hasName("f"),
3418d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                   forEachDescendant(nestedNameSpecifier().bind("x"))),
3419d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      // Nested names: a, a::A and a::A::B.
3420d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifier>("x", 3)));
3421d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper}
3422d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
3423d1ce3c178b9c648687591b190e0d252124fc2459Daniel JasperTEST(NNSLoc, DescendantsOfNestedNameSpecifierLocs) {
3424d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  std::string Fragment =
3425d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "namespace a { struct A { struct B { struct C {}; }; }; };"
3426d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "void f() { a::A::B::C c; }";
3427d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
3428d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3429d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
3430d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                             hasDescendant(loc(nestedNameSpecifier(
3431d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                                 specifiesNamespace(hasName("a"))))))));
3432d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(notMatches(
3433d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3434d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
3435d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                             has(loc(nestedNameSpecifier(
3436d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                                 specifiesNamespace(hasName("a"))))))));
3437d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
3438d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3439d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A"))),
3440d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                             has(loc(nestedNameSpecifier(
3441d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                                 specifiesNamespace(hasName("a"))))))));
3442d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
3443d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
3444d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3445d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
3446d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                             forEach(nestedNameSpecifierLoc().bind("x"))),
3447d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("x", 1)));
3448d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper}
3449d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
3450d1ce3c178b9c648687591b190e0d252124fc2459Daniel JasperTEST(NNSLoc, NestedNameSpecifierLocsAsDescendants) {
3451d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  std::string Fragment =
3452d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "namespace a { struct A { struct B { struct C {}; }; }; };"
3453d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      "void f() { a::A::B::C c; }";
3454d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matches(
3455d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3456d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      decl(hasDescendant(loc(nestedNameSpecifier(specifiesType(
3457d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper          asString("struct a::A"))))))));
3458d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper  EXPECT_TRUE(matchAndVerifyResultTrue(
3459d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      Fragment,
3460d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      functionDecl(hasName("f"),
3461d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper                   forEachDescendant(nestedNameSpecifierLoc().bind("x"))),
3462d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      // Nested names: a, a::A and a::A::B.
3463d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper      new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("x", 3)));
3464d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper}
3465d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper
346660969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimektemplate <typename T> class VerifyMatchOnNode : public BoundNodesCallback {
34673e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimekpublic:
346860969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  VerifyMatchOnNode(StringRef Id, const internal::Matcher<T> &InnerMatcher)
346960969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      : Id(Id), InnerMatcher(InnerMatcher) {
3470452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper  }
3471452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper
347260969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  virtual bool run(const BoundNodes *Nodes) { return false; }
347360969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek
34743e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek  virtual bool run(const BoundNodes *Nodes, ASTContext *Context) {
34753e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek    const T *Node = Nodes->getNodeAs<T>(Id);
347660969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek    SmallVector<BoundNodes, 1> Result = match(InnerMatcher, *Node, *Context);
347760969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek    return !Result.empty();
34783e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek  }
34793e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimekprivate:
34803e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek  std::string Id;
34813e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek  internal::Matcher<T> InnerMatcher;
34823e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek};
34833e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek
34843e2aa99e992b89bd421ac2a6bf79307114d257fcManuel KlimekTEST(MatchFinder, CanMatchDeclarationsRecursively) {
348560969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
348660969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
348760969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      new VerifyMatchOnNode<clang::Decl>(
348860969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek          "X", decl(hasDescendant(recordDecl(hasName("X::Y")))))));
348960969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse(
349060969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
349160969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      new VerifyMatchOnNode<clang::Decl>(
349260969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek          "X", decl(hasDescendant(recordDecl(hasName("X::Z")))))));
34933e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek}
34943e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek
34953e2aa99e992b89bd421ac2a6bf79307114d257fcManuel KlimekTEST(MatchFinder, CanMatchStatementsRecursively) {
349660969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
349760969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
349860969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      new VerifyMatchOnNode<clang::Stmt>("if",
349960969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek                                         stmt(hasDescendant(forStmt())))));
350060969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse(
350160969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
350260969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      new VerifyMatchOnNode<clang::Stmt>("if",
350360969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek                                         stmt(hasDescendant(declStmt())))));
350460969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek}
350560969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek
350660969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel KlimekTEST(MatchFinder, CanMatchSingleNodesRecursively) {
350760969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultTrue(
350860969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
350960969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      new VerifyMatchOnNode<clang::Decl>(
351060969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek          "X", recordDecl(has(recordDecl(hasName("X::Y")))))));
351160969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek  EXPECT_TRUE(matchAndVerifyResultFalse(
351260969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
351360969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek      new VerifyMatchOnNode<clang::Decl>(
351460969f5f6be1cbf7ac2384cc5ad571d28adf6bf1Manuel Klimek          "X", recordDecl(has(recordDecl(hasName("X::Z")))))));
35153e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek}
35163e2aa99e992b89bd421ac2a6bf79307114d257fcManuel Klimek
3517e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimekclass VerifyStartOfTranslationUnit : public MatchFinder::MatchCallback {
3518e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimekpublic:
3519e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  VerifyStartOfTranslationUnit() : Called(false) {}
3520e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  virtual void run(const MatchFinder::MatchResult &Result) {
3521e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek    EXPECT_TRUE(Called);
3522e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  }
3523e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  virtual void onStartOfTranslationUnit() {
3524e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek    Called = true;
3525e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  }
3526e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  bool Called;
3527e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek};
3528e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek
3529e579328ec9a95acc7f181e04c58a747ba001d80fManuel KlimekTEST(MatchFinder, InterceptsStartOfTranslationUnit) {
3530e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  MatchFinder Finder;
3531e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  VerifyStartOfTranslationUnit VerifyCallback;
3532e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  Finder.addMatcher(decl(), &VerifyCallback);
3533e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  OwningPtr<FrontendActionFactory> Factory(newFrontendActionFactory(&Finder));
3534e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
3535e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek  EXPECT_TRUE(VerifyCallback.Called);
3536e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek}
3537e579328ec9a95acc7f181e04c58a747ba001d80fManuel Klimek
35384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek} // end namespace ast_matchers
35394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek} // end namespace clang
3540