//===--- ASTMatchers.h - Structural query framework -------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements matchers to be used together with the MatchFinder to
//  match AST nodes.
//
//  Matchers are created by generator functions, which can be combined in
//  a functional in-language DSL to express queries over the C++ AST.
//
//  For example, to match a class with a certain name, one would call:
//    record(hasName("MyClass"))
//  which returns a matcher that can be used to find all AST nodes that declare
//  a class named 'MyClass'.
//
//  For more complicated match expressions we're often interested in accessing
//  multiple parts of the matched AST nodes once a match is found. In that case,
//  use the id(...) matcher around the match expressions that match the nodes
//  you want to access.
//
//  For example, when we're interested in child classes of a certain class, we
//  would write:
//    record(hasName("MyClass"), hasChild(id("child", record())))
//  When the match is found via the MatchFinder, a user provided callback will
//  be called with a BoundNodes instance that contains a mapping from the
//  strings that we provided for the id(...) calls to the nodes that were
//  matched.
//  In the given example, each time our matcher finds a match we get a callback
//  where "child" is bound to the CXXRecordDecl node of the matching child
//  class declaration.
//
//  See ASTMatchersInternal.h for a more in-depth explanation of the
//  implementation details of the matcher framework.
//
//  See ASTMatchFinder.h for how to use the generated matchers to run over
//  an AST.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_H
#define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_H

#include "clang/AST/DeclTemplate.h"
#include "clang/ASTMatchers/ASTMatchersInternal.h"
#include "clang/ASTMatchers/ASTMatchersMacros.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Regex.h"

namespace clang {
namespace ast_matchers {

/// \brief Maps string IDs to AST nodes matched by parts of a matcher.
///
/// The bound nodes are generated by adding id(...) matchers into the
/// match expression around the matchers for the nodes we want to access later.
///
/// The instances of BoundNodes are created by MatchFinder when the user's
/// callbacks are executed every time a match is found.
class BoundNodes {
public:
  /// \brief Returns the AST node bound to 'ID'.
  /// Returns NULL if there was no node bound to 'ID' or if there is a node but
  /// it cannot be converted to the specified type.
  /// FIXME: We'll need one of those for every base type.
  /// @{
  template <typename T>
  const T *getDeclAs(StringRef ID) const {
    return getNodeAs<T>(DeclBindings, ID);
  }
  template <typename T>
  const T *getStmtAs(StringRef ID) const {
    return getNodeAs<T>(StmtBindings, ID);
  }
  /// @}

private:
  /// \brief Create BoundNodes from a pre-filled map of bindings.
  BoundNodes(const std::map<std::string, const Decl*> &DeclBindings,
             const std::map<std::string, const Stmt*> &StmtBindings)
      : DeclBindings(DeclBindings), StmtBindings(StmtBindings) {}

  template <typename T, typename MapT>
  const T *getNodeAs(const MapT &Bindings, StringRef ID) const {
    typename MapT::const_iterator It = Bindings.find(ID);
    if (It == Bindings.end()) {
      return NULL;
    }
    return llvm::dyn_cast<T>(It->second);
  }

  std::map<std::string, const Decl*> DeclBindings;
  std::map<std::string, const Stmt*> StmtBindings;

  friend class internal::BoundNodesTree;
};

/// \brief If the provided matcher matches a node, binds the node to 'ID'.
///
/// FIXME: Add example for accessing it.
template <typename T>
internal::Matcher<T> id(const std::string &ID,
                        const internal::Matcher<T> &InnerMatcher) {
  return internal::Matcher<T>(new internal::IdMatcher<T>(ID, InnerMatcher));
}

/// \brief Types of matchers for the top-level classes in the AST class
/// hierarchy.
/// @{
typedef internal::Matcher<Decl> DeclarationMatcher;
typedef internal::Matcher<QualType> TypeMatcher;
typedef internal::Matcher<Stmt> StatementMatcher;
/// @}

/// \brief Matches any node.
///
/// Useful when another matcher requires a child matcher, but there's no
/// additional constraint. This will often be used with an explicit conversion
/// to a internal::Matcher<> type such as TypeMatcher.
///
/// Example: DeclarationMatcher(anything()) matches all declarations, e.g.,
/// "int* p" and "void f()" in
///   int* p;
///   void f();
inline internal::PolymorphicMatcherWithParam0<internal::TrueMatcher> anything() {
  return internal::PolymorphicMatcherWithParam0<internal::TrueMatcher>();
}

/// \brief Matches a declaration of anything that could have a name.
///
/// Example matches X, S, the anonymous union type, i, and U;
///   typedef int X;
///   struct S {
///     union {
///       int i;
///     } U;
///   };
const internal::VariadicDynCastAllOfMatcher<
  Decl,
  NamedDecl> nameableDeclaration;

/// \brief Matches C++ class declarations.
///
/// Example matches X, Z
///   class X;
///   template<class T> class Z {};
const internal::VariadicDynCastAllOfMatcher<
  Decl,
  CXXRecordDecl> record;

/// \brief Matches C++ class template specializations.
///
/// Given
///   template<typename T> class A {};
///   template<> class A<double> {};
///   A<int> a;
/// classTemplateSpecialization()
///   matches the specializations \c A<int> and \c A<double>
const internal::VariadicDynCastAllOfMatcher<
  Decl,
  ClassTemplateSpecializationDecl> classTemplateSpecialization;

/// \brief Matches classTemplateSpecializations that have at least one
/// TemplateArgument matching the given Matcher.
///
/// Given
///   template<typename T> class A {};
///   template<> class A<double> {};
///   A<int> a;
/// classTemplateSpecialization(hasAnyTemplateArgument(
///     refersToType(asString("int"))))
///   matches the specialization \c A<int>
AST_MATCHER_P(ClassTemplateSpecializationDecl, hasAnyTemplateArgument,
              internal::Matcher<TemplateArgument>, Matcher) {
  const TemplateArgumentList &List = Node.getTemplateArgs();
  for (unsigned i = 0; i < List.size(); ++i) {
    if (Matcher.matches(List.get(i), Finder, Builder))
      return true;
  }
  return false;
}

/// \brief Matches classTemplateSpecializations where the n'th TemplateArgument
/// matches the given Matcher.
///
/// Given
///   template<typename T, typename U> class A {};
///   A<bool, int> b;
///   A<int, bool> c;
/// classTemplateSpecialization(hasTemplateArgument(
///     1, refersToType(asString("int"))))
///   matches the specialization \c A<bool, int>
AST_MATCHER_P2(ClassTemplateSpecializationDecl, hasTemplateArgument,
               unsigned, N, internal::Matcher<TemplateArgument>, Matcher) {
  const TemplateArgumentList &List = Node.getTemplateArgs();
  if (List.size() <= N)
    return false;
  return Matcher.matches(List.get(N), Finder, Builder);
}

/// \brief Matches a TemplateArgument that refers to a certain type.
///
/// Given
///   struct X {};
///   template<typename T> struct A {};
///   A<X> a;
/// classTemplateSpecialization(hasAnyTemplateArgument(
///     refersToType(class(hasName("X")))))
///   matches the specialization \c A<X>
AST_MATCHER_P(TemplateArgument, refersToType,
              internal::Matcher<QualType>, Matcher) {
  if (Node.getKind() != TemplateArgument::Type)
    return false;
  return Matcher.matches(Node.getAsType(), Finder, Builder);
}

/// \brief Matches a TemplateArgument that refers to a certain declaration.
///
/// Given
///   template<typename T> struct A {};
///   struct B { B* next; };
///   A<&B::next> a;
/// classTemplateSpecialization(hasAnyTemplateArgument(
///     refersToDeclaration(field(hasName("next"))))
///   matches the specialization \c A<&B::next> with \c field(...) matching
///     \c B::next
AST_MATCHER_P(TemplateArgument, refersToDeclaration,
              internal::Matcher<Decl>, Matcher) {
  if (const Decl *Declaration = Node.getAsDecl())
    return Matcher.matches(*Declaration, Finder, Builder);
  return false;
}

/// \brief Matches C++ constructor declarations.
///
/// Example matches Foo::Foo() and Foo::Foo(int)
///   class Foo {
///    public:
///     Foo();
///     Foo(int);
///     int DoSomething();
///   };
const internal::VariadicDynCastAllOfMatcher<
  Decl,
  CXXConstructorDecl> constructor;

/// \brief Matches explicit C++ destructor declarations.
///
/// Example matches Foo::~Foo()
///   class Foo {
///    public:
///     virtual ~Foo();
///   };
const internal::VariadicDynCastAllOfMatcher<Decl, CXXDestructorDecl> destructor;

/// \brief Matches enum declarations.
///
/// Example matches X
///   enum X {
///     A, B, C
///   };
const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;

/// \brief Matches enum constants.
///
/// Example matches A, B, C
///   enum X {
///     A, B, C
///   };
const internal::VariadicDynCastAllOfMatcher<
  Decl,
  EnumConstantDecl> enumConstant;

/// \brief Matches method declarations.
///
/// Example matches y
///   class X { void y() };
const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> method;

/// \brief Matches variable declarations.
///
/// Note: this does not match declarations of member variables, which are
/// "field" declarations in Clang parlance.
///
/// Example matches a
///   int a;
const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> variable;

/// \brief Matches field declarations.
///
/// Given
///   class X { int m; };
/// field()
///   matches 'm'.
const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> field;

/// \brief Matches function declarations.
///
/// Example matches f
///   void f();
const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl> function;


/// \brief Matches statements.
///
/// Given
///   { ++a; }
/// statement()
///   matches both the compound statement '{ ++a; }' and '++a'.
const internal::VariadicDynCastAllOfMatcher<Stmt, Stmt> statement;

/// \brief Matches declaration statements.
///
/// Given
///   int a;
/// declarationStatement()
///   matches 'int a'.
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  DeclStmt> declarationStatement;

/// \brief Matches member expressions.
///
/// Given
///   class Y {
///     void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
///     int a; static int b;
///   };
/// memberExpression()
///   matches this->x, x, y.x, a, this->b
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  MemberExpr> memberExpression;

/// \brief Matches call expressions.
///
/// Example matches x.y()
///   X x;
///   x.y();
const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> call;

/// \brief Matches init list expressions.
///
/// Given
///   int a[] = { 1, 2 };
///   struct B { int x, y; };
///   B b = { 5, 6 };
/// initList()
///   matches "{ 1, 2 }" and "{ 5, 6 }"
const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr;

/// \brief Matches using declarations.
///
/// Given
///   namespace X { int x; }
///   using X::x;
/// usingDecl()
///   matches \code using X::x \endcode
const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;

/// \brief Matches constructor call expressions (including implicit ones).
///
/// Example matches string(ptr, n) and ptr within arguments of f
///     (matcher = constructorCall())
///   void f(const string &a, const string &b);
///   char *ptr;
///   int n;
///   f(string(ptr, n), ptr);
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  CXXConstructExpr> constructorCall;

/// \brief Matches nodes where temporaries are created.
///
/// Example matches FunctionTakesString(GetStringByValue())
///     (matcher = bindTemporaryExpression())
///   FunctionTakesString(GetStringByValue());
///   FunctionTakesStringByPointer(GetStringPointer());
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  CXXBindTemporaryExpr> bindTemporaryExpression;

/// \brief Matches new expressions.
///
/// Given
///   new X;
/// newExpression()
///   matches 'new X'.
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  CXXNewExpr> newExpression;

/// \brief Matches delete expressions.
///
/// Given
///   delete X;
/// deleteExpression()
///   matches 'delete X'.
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  CXXDeleteExpr> deleteExpression;

/// \brief Matches array subscript expressions.
///
/// Given
///   int i = a[1];
/// arraySubscriptExpr()
///   matches "a[1]"
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  ArraySubscriptExpr> arraySubscriptExpr;

/// \brief Matches the value of a default argument at the call site.
///
/// Example matches the CXXDefaultArgExpr placeholder inserted for the
///     default value of the second parameter in the call expression f(42)
///     (matcher = defaultArgument())
///   void f(int x, int y = 0);
///   f(42);
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  CXXDefaultArgExpr> defaultArgument;

/// \brief Matches overloaded operator calls.
///
/// Note that if an operator isn't overloaded, it won't match. Instead, use
/// binaryOperator matcher.
/// Currently it does not match operators such as new delete.
/// FIXME: figure out why these do not match?
///
/// Example matches both operator<<((o << b), c) and operator<<(o, b)
///     (matcher = overloadedOperatorCall())
///   ostream &operator<< (ostream &out, int i) { };
///   ostream &o; int b = 1, c = 1;
///   o << b << c;
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  CXXOperatorCallExpr> overloadedOperatorCall;

/// \brief Matches expressions.
///
/// Example matches x()
///   void f() { x(); }
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  Expr> expression;

/// \brief Matches expressions that refer to declarations.
///
/// Example matches x in if (x)
///   bool x;
///   if (x) {}
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  DeclRefExpr> declarationReference;

/// \brief Matches if statements.
///
/// Example matches 'if (x) {}'
///   if (x) {}
const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt;

/// \brief Matches for statements.
///
/// Example matches 'for (;;) {}'
///   for (;;) {}
const internal::VariadicDynCastAllOfMatcher<
  Stmt, ForStmt> forStmt;

/// \brief Matches the increment statement of a for loop.
///
/// Example:
///     forStmt(hasIncrement(unaryOperator(hasOperatorName("++"))))
/// matches '++x' in
///     for (x; x < N; ++x) { }
AST_MATCHER_P(ForStmt, hasIncrement, internal::Matcher<Stmt>,
              InnerMatcher) {
  const Stmt *const Increment = Node.getInc();
  return (Increment != NULL &&
          InnerMatcher.matches(*Increment, Finder, Builder));
}

/// \brief Matches the initialization statement of a for loop.
///
/// Example:
///     forStmt(hasLoopInit(declarationStatement()))
/// matches 'int x = 0' in
///     for (int x = 0; x < N; ++x) { }
AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher<Stmt>,
              InnerMatcher) {
  const Stmt *const Init = Node.getInit();
  return (Init != NULL && InnerMatcher.matches(*Init, Finder, Builder));
}

/// \brief Matches while statements.
///
/// Given
///   while (true) {}
/// whileStmt()
///   matches 'while (true) {}'.
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  WhileStmt> whileStmt;

/// \brief Matches do statements.
///
/// Given
///   do {} while (true);
/// doStmt()
///   matches 'do {} while(true)'
const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt;

/// \brief Matches case and default statements inside switch statements.
///
/// Given
///   switch(a) { case 42: break; default: break; }
/// switchCase()
///   matches 'case 42: break;' and 'default: break;'.
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  SwitchCase> switchCase;

/// \brief Matches compound statements.
///
/// Example matches '{}' and '{{}}'in 'for (;;) {{}}'
///   for (;;) {{}}
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  CompoundStmt> compoundStatement;

/// \brief Matches bool literals.
///
/// Example matches true
///   true
const internal::VariadicDynCastAllOfMatcher<
  Expr,
  CXXBoolLiteralExpr> boolLiteral;

/// \brief Matches string literals (also matches wide string literals).
///
/// Example matches "abcd", L"abcd"
///   char *s = "abcd"; wchar_t *ws = L"abcd"
const internal::VariadicDynCastAllOfMatcher<
  Expr,
  StringLiteral> stringLiteral;

/// \brief Matches character literals (also matches wchar_t).
///
/// Not matching Hex-encoded chars (e.g. 0x1234, which is a IntegerLiteral),
/// though.
///
/// Example matches 'a', L'a'
///   char ch = 'a'; wchar_t chw = L'a';
const internal::VariadicDynCastAllOfMatcher<
  Expr,
  CharacterLiteral> characterLiteral;

/// \brief Matches integer literals of all sizes / encodings.
///
/// Not matching character-encoded integers such as L'a'.
///
/// Example matches 1, 1L, 0x1, 1U
const internal::VariadicDynCastAllOfMatcher<
  Expr,
  IntegerLiteral> integerLiteral;

/// \brief Matches binary operator expressions.
///
/// Example matches a || b
///   !(a || b)
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  BinaryOperator> binaryOperator;

/// \brief Matches unary operator expressions.
///
/// Example matches !a
///   !a || b
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  UnaryOperator> unaryOperator;

/// \brief Matches conditional operator expressions.
///
/// Example matches a ? b : c
///   (a ? b : c) + 42
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  ConditionalOperator> conditionalOperator;

/// \brief Matches a reinterpret_cast expression.
///
/// Either the source expression or the destination type can be matched
/// using has(), but hasDestinationType() is more specific and can be
/// more readable.
///
/// Example matches reinterpret_cast<char*>(&p) in
///   void* p = reinterpret_cast<char*>(&p);
const internal::VariadicDynCastAllOfMatcher<
  Expr,
  CXXReinterpretCastExpr> reinterpretCast;

/// \brief Matches a C++ static_cast expression.
///
/// \see hasDestinationType
/// \see reinterpretCast
///
/// Example:
///   staticCast()
/// matches
///   static_cast<long>(8)
/// in
///   long eight(static_cast<long>(8));
const internal::VariadicDynCastAllOfMatcher<
  Expr,
  CXXStaticCastExpr> staticCast;

/// \brief Matches a dynamic_cast expression.
///
/// Example:
///   dynamicCast()
/// matches
///   dynamic_cast<D*>(&b);
/// in
///   struct B { virtual ~B() {} }; struct D : B {};
///   B b;
///   D* p = dynamic_cast<D*>(&b);
const internal::VariadicDynCastAllOfMatcher<
  Expr,
  CXXDynamicCastExpr> dynamicCast;

/// \brief Matches a const_cast expression.
///
/// Example: Matches const_cast<int*>(&r) in
///   int n = 42;
///   const int& r(n);
///   int* p = const_cast<int*>(&r);
const internal::VariadicDynCastAllOfMatcher<
  Expr,
  CXXConstCastExpr> constCast;

/// \brief Matches explicit cast expressions.
///
/// Matches any cast expression written in user code, whether it be a
/// C-style cast, a functional-style cast, or a keyword cast.
///
/// Does not match implicit conversions.
///
/// Note: the name "explicitCast" is chosen to match Clang's terminology, as
/// Clang uses the term "cast" to apply to implicit conversions as well as to
/// actual cast expressions.
///
/// \see hasDestinationType.
///
/// Example: matches all five of the casts in
///   int((int)(reinterpret_cast<int>(static_cast<int>(const_cast<int>(42)))))
/// but does not match the implicit conversion in
///   long ell = 42;
const internal::VariadicDynCastAllOfMatcher<
  Expr,
  ExplicitCastExpr> explicitCast;

/// \brief Matches the implicit cast nodes of Clang's AST.
///
/// This matches many different places, including function call return value
/// eliding, as well as any type conversions.
const internal::VariadicDynCastAllOfMatcher<
  Expr,
  ImplicitCastExpr> implicitCast;

/// \brief Matches functional cast expressions
///
/// Example: Matches Foo(bar);
///   Foo f = bar;
///   Foo g = (Foo) bar;
///   Foo h = Foo(bar);
const internal::VariadicDynCastAllOfMatcher<
  Expr,
  CXXFunctionalCastExpr> functionalCast;

/// \brief Various overloads for the anyOf matcher.
/// @{
template<typename C1, typename C2>
internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C1, C2>
anyOf(const C1 &P1, const C2 &P2) {
  return internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher,
                                                C1, C2 >(P1, P2);
}
template<typename C1, typename C2, typename C3>
internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C1,
    internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C2, C3> >
anyOf(const C1 &P1, const C2 &P2, const C3 &P3) {
  return anyOf(P1, anyOf(P2, P3));
}
template<typename C1, typename C2, typename C3, typename C4>
internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C1,
    internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C2,
        internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher,
                                               C3, C4> > >
anyOf(const C1 &P1, const C2 &P2, const C3 &P3, const C4 &P4) {
  return AnyOf(P1, AnyOf(P2, AnyOf(P3, P4)));
}
template<typename C1, typename C2, typename C3, typename C4, typename C5>
internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C1,
    internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C2,
        internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C3,
            internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher,
                                                   C4, C5> > > >
anyOf(const C1& P1, const C2& P2, const C3& P3, const C4& P4, const C5& P5) {
  return anyOf(P1, anyOf(P2, anyOf(P3, anyOf(P4, P5))));
}
/// @}

/// \brief Various overloads for the allOf matcher.
/// @{
template<typename C1, typename C2>
internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, C1, C2>
allOf(const C1 &P1, const C2 &P2) {
  return internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher,
                                                C1, C2>(P1, P2);
}
template<typename C1, typename C2, typename C3>
internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, C1,
    internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, C2, C3> >
allOf(const C1& P1, const C2& P2, const C3& P3) {
  return allOf(P1, allOf(P2, P3));
}
/// @}

/// \brief Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL)
///
/// Given
///   Foo x = bar;
///   int y = sizeof(x) + alignof(x);
/// unaryExprOrTypeTraitExpr()
///   matches \c sizeof(x) and \c alignof(x)
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  UnaryExprOrTypeTraitExpr> unaryExprOrTypeTraitExpr;

/// \brief Matches unary expressions that have a specific type of argument.
///
/// Given
///   int a, c; float b; int s = sizeof(a) + sizeof(b) + alignof(c);
/// unaryExprOrTypeTraitExpr(hasArgumentOfType(asString("int"))
///   matches \c sizeof(a) and \c alignof(c)
AST_MATCHER_P(UnaryExprOrTypeTraitExpr, hasArgumentOfType,
              internal::Matcher<QualType>, Matcher) {
  const QualType ArgumentType = Node.getTypeOfArgument();
  return Matcher.matches(ArgumentType, Finder, Builder);
}

/// \brief Matches unary expressions of a certain kind.
///
/// Given
///   int x;
///   int s = sizeof(x) + alignof(x)
/// unaryExprOrTypeTraitExpr(ofKind(UETT_SizeOf))
///   matches \c sizeof(x)
AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind) {
  return Node.getKind() == Kind;
}

/// \brief Same as unaryExprOrTypeTraitExpr, but only matching
/// alignof.
inline internal::Matcher<Stmt> alignOfExpr(
    const internal::Matcher<UnaryExprOrTypeTraitExpr> &Matcher) {
  return internal::Matcher<Stmt>(unaryExprOrTypeTraitExpr(allOf(
      ofKind(UETT_AlignOf), Matcher)));
}

/// \brief Same as unaryExprOrTypeTraitExpr, but only matching
/// sizeof.
inline internal::Matcher<Stmt> sizeOfExpr(
    const internal::Matcher<UnaryExprOrTypeTraitExpr> &Matcher) {
  return internal::Matcher<Stmt>(unaryExprOrTypeTraitExpr(allOf(
      ofKind(UETT_SizeOf), Matcher)));
}

/// \brief Matches NamedDecl nodes that have the specified name.
///
/// Supports specifying enclosing namespaces or classes by prefixing the name
/// with '<enclosing>::'.
/// Does not match typedefs of an underlying type with the given name.
///
/// Example matches X (Name == "X")
///   class X;
///
/// Example matches X (Name is one of "::a::b::X", "a::b::X", "b::X", "X")
/// namespace a { namespace b { class X; } }
AST_MATCHER_P(NamedDecl, hasName, std::string, Name) {
  assert(!Name.empty());
  const std::string FullNameString = "::" + Node.getQualifiedNameAsString();
  const llvm::StringRef FullName = FullNameString;
  const llvm::StringRef Pattern = Name;
  if (Pattern.startswith("::")) {
    return FullName == Pattern;
  } else {
    return FullName.endswith(("::" + Pattern).str());
  }
}

/// \brief Matches NamedDecl nodes whose full names partially match the
/// given RegExp.
///
/// Supports specifying enclosing namespaces or classes by
/// prefixing the name with '<enclosing>::'.  Does not match typedefs
/// of an underlying type with the given name.
///
/// Example matches X (regexp == "::X")
///   class X;
///
/// Example matches X (regexp is one of "::X", "^foo::.*X", among others)
/// namespace foo { namespace bar { class X; } }
AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) {
  assert(!RegExp.empty());
  std::string FullNameString = "::" + Node.getQualifiedNameAsString();
  llvm::Regex RE(RegExp);
  return RE.match(FullNameString);
}

/// \brief Matches overloaded operator names.
///
/// Matches overloaded operator names specified in strings without the
/// "operator" prefix, such as "<<", for OverloadedOperatorCall's.
///
/// Example matches a << b
///     (matcher == overloadedOperatorCall(hasOverloadedOperatorName("<<")))
///   a << b;
///   c && d;  // assuming both operator<<
///            // and operator&& are overloaded somewhere.
AST_MATCHER_P(CXXOperatorCallExpr,
              hasOverloadedOperatorName, std::string, Name) {
  return getOperatorSpelling(Node.getOperator()) == Name;
}

/// \brief Matches C++ classes that are directly or indirectly derived from
/// the given base class.
///
/// Note that a class is considered to be also derived from itself.
/// The parameter specified the name of the base type (either a class or a
/// typedef), and does not allow structural matches for namespaces or template
/// type parameters.
///
/// Example matches X, Y, Z, C (Base == "X")
///   class X;                // A class is considered to be derived from itself
///   class Y : public X {};  // directly derived
///   class Z : public Y {};  // indirectly derived
///   typedef X A;
///   typedef A B;
///   class C : public B {};  // derived from a typedef of X
///
/// In the following example, Bar matches isDerivedFrom("X"):
///   class Foo;
///   typedef Foo X;
///   class Bar : public Foo {};  // derived from a type that X is a typedef of
AST_MATCHER_P(CXXRecordDecl, isDerivedFrom, std::string, Base) {
  assert(!Base.empty());
  return Finder->classIsDerivedFrom(&Node, Base);
}

/// \brief Matches AST nodes that have child AST nodes that match the
/// provided matcher.
///
/// Example matches X, Y (matcher = record(has(record(hasName("X")))
///   class X {};  // Matches X, because X::X is a class of name X inside X.
///   class Y { class X {}; };
///   class Z { class Y { class X {}; }; };  // Does not match Z.
///
/// ChildT must be an AST base type.
template <typename ChildT>
internal::ArgumentAdaptingMatcher<internal::HasMatcher, ChildT> has(
    const internal::Matcher<ChildT> &ChildMatcher) {
  return internal::ArgumentAdaptingMatcher<internal::HasMatcher,
                                           ChildT>(ChildMatcher);
}

/// \brief Matches AST nodes that have descendant AST nodes that match the
/// provided matcher.
///
/// Example matches X, Y, Z
///     (matcher = record(hasDescendant(record(hasName("X")))))
///   class X {};  // Matches X, because X::X is a class of name X inside X.
///   class Y { class X {}; };
///   class Z { class Y { class X {}; }; };
///
/// DescendantT must be an AST base type.
template <typename DescendantT>
internal::ArgumentAdaptingMatcher<internal::HasDescendantMatcher, DescendantT>
hasDescendant(const internal::Matcher<DescendantT> &DescendantMatcher) {
  return internal::ArgumentAdaptingMatcher<
    internal::HasDescendantMatcher,
    DescendantT>(DescendantMatcher);
}


/// \brief Matches AST nodes that have child AST nodes that match the
/// provided matcher.
///
/// Example matches X, Y (matcher = record(forEach(record(hasName("X")))
///   class X {};  // Matches X, because X::X is a class of name X inside X.
///   class Y { class X {}; };
///   class Z { class Y { class X {}; }; };  // Does not match Z.
///
/// ChildT must be an AST base type.
///
/// As opposed to 'has', 'forEach' will cause a match for each result that
/// matches instead of only on the first one.
template <typename ChildT>
internal::ArgumentAdaptingMatcher<internal::ForEachMatcher, ChildT> forEach(
    const internal::Matcher<ChildT>& ChildMatcher) {
  return internal::ArgumentAdaptingMatcher<
    internal::ForEachMatcher,
    ChildT>(ChildMatcher);
}

/// \brief Matches AST nodes that have descendant AST nodes that match the
/// provided matcher.
///
/// Example matches X, A, B, C
///     (matcher = record(forEachDescendant(record(hasName("X")))))
///   class X {};  // Matches X, because X::X is a class of name X inside X.
///   class A { class X {}; };
///   class B { class C { class X {}; }; };
///
/// DescendantT must be an AST base type.
///
/// As opposed to 'hasDescendant', 'forEachDescendant' will cause a match for
/// each result that matches instead of only on the first one.
///
/// Note: Recursively combined ForEachDescendant can cause many matches:
///   record(forEachDescendant(record(forEachDescendant(record()))))
/// will match 10 times (plus injected class name matches) on:
///   class A { class B { class C { class D { class E {}; }; }; }; };
template <typename DescendantT>
internal::ArgumentAdaptingMatcher<internal::ForEachDescendantMatcher, DescendantT>
forEachDescendant(
    const internal::Matcher<DescendantT>& DescendantMatcher) {
  return internal::ArgumentAdaptingMatcher<
    internal::ForEachDescendantMatcher,
    DescendantT>(DescendantMatcher);
}

/// \brief Matches if the provided matcher does not match.
///
/// Example matches Y (matcher = record(unless(hasName("X"))))
///   class X {};
///   class Y {};
template <typename M>
internal::PolymorphicMatcherWithParam1<internal::NotMatcher, M> unless(const M &InnerMatcher) {
  return internal::PolymorphicMatcherWithParam1<
    internal::NotMatcher, M>(InnerMatcher);
}

/// \brief Matches a type if the declaration of the type matches the given
/// matcher.
inline internal::PolymorphicMatcherWithParam1< internal::HasDeclarationMatcher,
                                     internal::Matcher<Decl> >
    hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) {
  return internal::PolymorphicMatcherWithParam1<
    internal::HasDeclarationMatcher,
    internal::Matcher<Decl> >(InnerMatcher);
}

/// \brief Matches on the implicit object argument of a member call expression.
///
/// Example matches y.x() (matcher = call(on(hasType(record(hasName("Y"))))))
///   class Y { public: void x(); };
///   void z() { Y y; y.x(); }",
///
/// FIXME: Overload to allow directly matching types?
AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher<Expr>,
              InnerMatcher) {
  const Expr *ExprNode = const_cast<CXXMemberCallExpr&>(Node)
      .getImplicitObjectArgument()
      ->IgnoreParenImpCasts();
  return (ExprNode != NULL &&
          InnerMatcher.matches(*ExprNode, Finder, Builder));
}

/// \brief Matches if the call expression's callee expression matches.
///
/// Given
///   class Y { void x() { this->x(); x(); Y y; y.x(); } };
///   void f() { f(); }
/// call(callee(expression()))
///   matches this->x(), x(), y.x(), f()
/// with callee(...)
///   matching this->x, x, y.x, f respectively
///
/// Note: Callee cannot take the more general internal::Matcher<Expr>
/// because this introduces ambiguous overloads with calls to Callee taking a
/// internal::Matcher<Decl>, as the matcher hierarchy is purely
/// implemented in terms of implicit casts.
AST_MATCHER_P(CallExpr, callee, internal::Matcher<Stmt>,
              InnerMatcher) {
  const Expr *ExprNode = Node.getCallee();
  return (ExprNode != NULL &&
          InnerMatcher.matches(*ExprNode, Finder, Builder));
}

/// \brief Matches if the call expression's callee's declaration matches the
/// given matcher.
///
/// Example matches y.x() (matcher = call(callee(method(hasName("x")))))
///   class Y { public: void x(); };
///   void z() { Y y; y.x();
inline internal::Matcher<CallExpr> callee(
    const internal::Matcher<Decl> &InnerMatcher) {
  return internal::Matcher<CallExpr>(hasDeclaration(InnerMatcher));
}

/// \brief Matches if the expression's or declaration's type matches a type
/// matcher.
///
/// Example matches x (matcher = expression(hasType(
///                        hasDeclaration(record(hasName("X"))))))
///             and z (matcher = variable(hasType(
///                        hasDeclaration(record(hasName("X"))))))
///  class X {};
///  void y(X &x) { x; X z; }
AST_POLYMORPHIC_MATCHER_P(hasType, internal::Matcher<QualType>,
                          InnerMatcher) {
  TOOLING_COMPILE_ASSERT((llvm::is_base_of<Expr, NodeType>::value ||
                          llvm::is_base_of<ValueDecl, NodeType>::value),
                         instantiated_with_wrong_types);
  return InnerMatcher.matches(Node.getType(), Finder, Builder);
}

/// \brief Overloaded to match the declaration of the expression's or value
/// declaration's type.
///
/// In case of a value declaration (for example a variable declaration),
/// this resolves one layer of indirection. For example, in the value
/// declaration "X x;", record(hasName("X")) matches the declaration of X,
/// while variable(hasType(record(hasName("X")))) matches the declaration
/// of x."
///
/// Example matches x (matcher = expression(hasType(record(hasName("X")))))
///             and z (matcher = variable(hasType(record(hasName("X")))))
///  class X {};
///  void y(X &x) { x; X z; }
inline internal::PolymorphicMatcherWithParam1<
  internal::matcher_hasTypeMatcher,
  internal::Matcher<QualType> >
hasType(const internal::Matcher<Decl> &InnerMatcher) {
  return hasType(internal::Matcher<QualType>(
    hasDeclaration(InnerMatcher)));
}

/// \brief Matches if the matched type is represented by the given string.
///
/// Given
///   class Y { public: void x(); };
///   void z() { Y* y; y->x(); }
/// call(on(hasType(asString("class Y *"))))
///   matches y->x()
AST_MATCHER_P(QualType, asString, std::string, Name) {
  return Name == Node.getAsString();
}

/// \brief Matches if the matched type is a pointer type and the pointee type
/// matches the specified matcher.
///
/// Example matches y->x()
///     (matcher = call(on(hasType(pointsTo(record(hasName("Y")))))))
///   class Y { public: void x(); };
///   void z() { Y *y; y->x(); }
AST_MATCHER_P(
    QualType, pointsTo, internal::Matcher<QualType>,
    InnerMatcher) {
  return (!Node.isNull() && Node->isPointerType() &&
          InnerMatcher.matches(Node->getPointeeType(), Finder, Builder));
}

/// \brief Overloaded to match the pointee type's declaration.
inline internal::Matcher<QualType> pointsTo(
    const internal::Matcher<Decl> &InnerMatcher) {
  return pointsTo(internal::Matcher<QualType>(
    hasDeclaration(InnerMatcher)));
}

/// \brief Matches if the matched type is a reference type and the referenced
/// type matches the specified matcher.
///
/// Example matches X &x and const X &y
///     (matcher = variable(hasType(references(record(hasName("X"))))))
///   class X {
///     void a(X b) {
///       X &x = b;
///       const X &y = b;
///   };
AST_MATCHER_P(QualType, references, internal::Matcher<QualType>,
              InnerMatcher) {
  return (!Node.isNull() && Node->isReferenceType() &&
          InnerMatcher.matches(Node->getPointeeType(), Finder, Builder));
}

/// \brief Overloaded to match the referenced type's declaration.
inline internal::Matcher<QualType> references(
    const internal::Matcher<Decl> &InnerMatcher) {
  return references(internal::Matcher<QualType>(
    hasDeclaration(InnerMatcher)));
}

AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument,
              internal::Matcher<Expr>, InnerMatcher) {
  const Expr *ExprNode =
      const_cast<CXXMemberCallExpr&>(Node).getImplicitObjectArgument();
  return (ExprNode != NULL &&
          InnerMatcher.matches(*ExprNode, Finder, Builder));
}

/// \brief Matches if the expression's type either matches the specified
/// matcher, or is a pointer to a type that matches the InnerMatcher.
inline internal::Matcher<CallExpr> thisPointerType(
    const internal::Matcher<QualType> &InnerMatcher) {
  return onImplicitObjectArgument(
      anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher))));
}

/// \brief Overloaded to match the type's declaration.
inline internal::Matcher<CallExpr> thisPointerType(
    const internal::Matcher<Decl> &InnerMatcher) {
  return onImplicitObjectArgument(
      anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher))));
}

/// \brief Matches a DeclRefExpr that refers to a declaration that matches the
/// specified matcher.
///
/// Example matches x in if(x)
///     (matcher = declarationReference(to(variable(hasName("x")))))
///   bool x;
///   if (x) {}
AST_MATCHER_P(DeclRefExpr, to, internal::Matcher<Decl>,
              InnerMatcher) {
  const Decl *DeclNode = Node.getDecl();
  return (DeclNode != NULL &&
          InnerMatcher.matches(*DeclNode, Finder, Builder));
}

/// \brief Matches a \c DeclRefExpr that refers to a declaration through a
/// specific using shadow declaration.
///
/// FIXME: This currently only works for functions. Fix.
///
/// Given
///   namespace a { void f() {} }
///   using a::f;
///   void g() {
///     f();     // Matches this ..
///     a::f();  // .. but not this.
///   }
/// declarationReference(throughUsingDeclaration(anything()))
///   matches \c f()
AST_MATCHER_P(DeclRefExpr, throughUsingDecl,
              internal::Matcher<UsingShadowDecl>, Matcher) {
  const NamedDecl *FoundDecl = Node.getFoundDecl();
  if (const UsingShadowDecl *UsingDecl =
      llvm::dyn_cast<UsingShadowDecl>(FoundDecl))
    return Matcher.matches(*UsingDecl, Finder, Builder);
  return false;
}

/// \brief Matches a variable declaration that has an initializer expression
/// that matches the given matcher.
///
/// Example matches x (matcher = variable(hasInitializer(call())))
///   bool y() { return true; }
///   bool x = y();
AST_MATCHER_P(
    VarDecl, hasInitializer, internal::Matcher<Expr>,
    InnerMatcher) {
  const Expr *Initializer = Node.getAnyInitializer();
  return (Initializer != NULL &&
          InnerMatcher.matches(*Initializer, Finder, Builder));
}

/// \brief Checks that a call expression or a constructor call expression has
/// a specific number of arguments (including absent default arguments).
///
/// Example matches f(0, 0) (matcher = call(argumentCountIs(2)))
///   void f(int x, int y);
///   f(0, 0);
AST_POLYMORPHIC_MATCHER_P(argumentCountIs, unsigned, N) {
  TOOLING_COMPILE_ASSERT((llvm::is_base_of<CallExpr, NodeType>::value ||
                          llvm::is_base_of<CXXConstructExpr,
                                           NodeType>::value),
                         instantiated_with_wrong_types);
  return Node.getNumArgs() == N;
}

/// \brief Matches the n'th argument of a call expression or a constructor
/// call expression.
///
/// Example matches y in x(y)
///     (matcher = call(hasArgument(0, declarationReference())))
///   void x(int) { int y; x(y); }
AST_POLYMORPHIC_MATCHER_P2(
    hasArgument, unsigned, N, internal::Matcher<Expr>, InnerMatcher) {
  TOOLING_COMPILE_ASSERT((llvm::is_base_of<CallExpr, NodeType>::value ||
                         llvm::is_base_of<CXXConstructExpr,
                                          NodeType>::value),
                         instantiated_with_wrong_types);
  return (N < Node.getNumArgs() &&
          InnerMatcher.matches(
              *Node.getArg(N)->IgnoreParenImpCasts(), Finder, Builder));
}

/// \brief Matches a constructor initializer.
///
/// Given
///   struct Foo {
///     Foo() : foo_(1) { }
///     int foo_;
///   };
/// record(has(constructor(hasAnyConstructorInitializer(anything()))))
///   record matches Foo, hasAnyConstructorInitializer matches foo_(1)
AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer,
              internal::Matcher<CXXCtorInitializer>, InnerMatcher) {
  for (CXXConstructorDecl::init_const_iterator I = Node.init_begin();
       I != Node.init_end(); ++I) {
    if (InnerMatcher.matches(**I, Finder, Builder)) {
      return true;
    }
  }
  return false;
}

/// \brief Matches the field declaration of a constructor initializer.
///
/// Given
///   struct Foo {
///     Foo() : foo_(1) { }
///     int foo_;
///   };
/// record(has(constructor(hasAnyConstructorInitializer(
///     forField(hasName("foo_"))))))
///   matches Foo
/// with forField matching foo_
AST_MATCHER_P(CXXCtorInitializer, forField,
              internal::Matcher<FieldDecl>, InnerMatcher) {
  const FieldDecl *NodeAsDecl = Node.getMember();
  return (NodeAsDecl != NULL &&
      InnerMatcher.matches(*NodeAsDecl, Finder, Builder));
}

/// \brief Matches the initializer expression of a constructor initializer.
///
/// Given
///   struct Foo {
///     Foo() : foo_(1) { }
///     int foo_;
///   };
/// record(has(constructor(hasAnyConstructorInitializer(
///     withInitializer(integerLiteral(equals(1)))))))
///   matches Foo
/// with withInitializer matching (1)
AST_MATCHER_P(CXXCtorInitializer, withInitializer,
              internal::Matcher<Expr>, InnerMatcher) {
  const Expr* NodeAsExpr = Node.getInit();
  return (NodeAsExpr != NULL &&
      InnerMatcher.matches(*NodeAsExpr, Finder, Builder));
}

/// \brief Matches a contructor initializer if it is explicitly written in
/// code (as opposed to implicitly added by the compiler).
///
/// Given
///   struct Foo {
///     Foo() { }
///     Foo(int) : foo_("A") { }
///     string foo_;
///   };
/// constructor(hasAnyConstructorInitializer(isWritten()))
///   will match Foo(int), but not Foo()
AST_MATCHER(CXXCtorInitializer, isWritten) {
  return Node.isWritten();
}

/// \brief Matches a constructor declaration that has been implicitly added
/// by the compiler (eg. implicit default/copy constructors).
AST_MATCHER(CXXConstructorDecl, isImplicit) {
  return Node.isImplicit();
}

/// \brief Matches any argument of a call expression or a constructor call
/// expression.
///
/// Given
///   void x(int, int, int) { int y; x(1, y, 42); }
/// call(hasAnyArgument(declarationReference()))
///   matches x(1, y, 42)
/// with hasAnyArgument(...)
///   matching y
AST_POLYMORPHIC_MATCHER_P(hasAnyArgument, internal::Matcher<Expr>,
                          InnerMatcher) {
  TOOLING_COMPILE_ASSERT((llvm::is_base_of<CallExpr, NodeType>::value ||
                         llvm::is_base_of<CXXConstructExpr,
                                          NodeType>::value),
                         instantiated_with_wrong_types);
  for (unsigned I = 0; I < Node.getNumArgs(); ++I) {
    if (InnerMatcher.matches(*Node.getArg(I)->IgnoreParenImpCasts(),
                             Finder, Builder)) {
      return true;
    }
  }
  return false;
}

/// \brief Matches the n'th parameter of a function declaration.
///
/// Given
///   class X { void f(int x) {} };
/// method(hasParameter(0, hasType(variable())))
///   matches f(int x) {}
/// with hasParameter(...)
///   matching int x
AST_MATCHER_P2(FunctionDecl, hasParameter,
               unsigned, N, internal::Matcher<ParmVarDecl>,
               InnerMatcher) {
  return (N < Node.getNumParams() &&
          InnerMatcher.matches(
              *Node.getParamDecl(N), Finder, Builder));
}

/// \brief Matches any parameter of a function declaration.
///
/// Does not match the 'this' parameter of a method.
///
/// Given
///   class X { void f(int x, int y, int z) {} };
/// method(hasAnyParameter(hasName("y")))
///   matches f(int x, int y, int z) {}
/// with hasAnyParameter(...)
///   matching int y
AST_MATCHER_P(FunctionDecl, hasAnyParameter,
              internal::Matcher<ParmVarDecl>, InnerMatcher) {
  for (unsigned I = 0; I < Node.getNumParams(); ++I) {
    if (InnerMatcher.matches(*Node.getParamDecl(I), Finder, Builder)) {
      return true;
    }
  }
  return false;
}

/// \brief Matches the return type of a function declaration.
///
/// Given:
///   class X { int f() { return 1; } };
/// method(returns(asString("int")))
///   matches int f() { return 1; }
AST_MATCHER_P(FunctionDecl, returns, internal::Matcher<QualType>, Matcher) {
  return Matcher.matches(Node.getResultType(), Finder, Builder);
}

/// \brief Matches the condition expression of an if statement, for loop,
/// or conditional operator.
///
/// Example matches true (matcher = hasCondition(boolLiteral(equals(true))))
///   if (true) {}
AST_POLYMORPHIC_MATCHER_P(hasCondition, internal::Matcher<Expr>,
                          InnerMatcher) {
  TOOLING_COMPILE_ASSERT(
    (llvm::is_base_of<IfStmt, NodeType>::value) ||
    (llvm::is_base_of<ForStmt, NodeType>::value) ||
    (llvm::is_base_of<WhileStmt, NodeType>::value) ||
    (llvm::is_base_of<DoStmt, NodeType>::value) ||
    (llvm::is_base_of<ConditionalOperator, NodeType>::value),
    has_condition_requires_if_statement_conditional_operator_or_loop);
  const Expr *const Condition = Node.getCond();
  return (Condition != NULL &&
          InnerMatcher.matches(*Condition, Finder, Builder));
}

/// \brief Matches the condition variable statement in an if statement.
///
/// Given
///   if (A* a = GetAPointer()) {}
/// hasConditionVariableStatment(...)
///   matches 'A* a = GetAPointer()'.
AST_MATCHER_P(IfStmt, hasConditionVariableStatement,
              internal::Matcher<DeclStmt>, InnerMatcher) {
  const DeclStmt* const DeclarationStatement =
    Node.getConditionVariableDeclStmt();
  return DeclarationStatement != NULL &&
         InnerMatcher.matches(*DeclarationStatement, Finder, Builder);
}

/// \brief Matches the index expression of an array subscript expression.
///
/// Given
///   int i[5];
///   void f() { i[1] = 42; }
/// arraySubscriptExpression(hasIndex(integerLiteral()))
///   matches \c i[1] with the \c integerLiteral() matching \c 1
AST_MATCHER_P(ArraySubscriptExpr, hasIndex,
              internal::Matcher<Expr>, matcher) {
  if (const Expr* Expression = Node.getIdx())
    return matcher.matches(*Expression, Finder, Builder);
  return false;
}

/// \brief Matches the base expression of an array subscript expression.
///
/// Given
///   int i[5];
///   void f() { i[1] = 42; }
/// arraySubscriptExpression(hasBase(implicitCast(
///     hasSourceExpression(declarationReference()))))
///   matches \c i[1] with the \c declarationReference() matching \c i
AST_MATCHER_P(ArraySubscriptExpr, hasBase,
              internal::Matcher<Expr>, matcher) {
  if (const Expr* Expression = Node.getBase())
    return matcher.matches(*Expression, Finder, Builder);
  return false;
}

/// \brief Matches a 'for', 'while', or 'do while' statement that has
/// a given body.
///
/// Given
///   for (;;) {}
/// hasBody(compoundStatement())
///   matches 'for (;;) {}'
/// with compoundStatement()
///   matching '{}'
AST_POLYMORPHIC_MATCHER_P(hasBody, internal::Matcher<Stmt>,
                          InnerMatcher) {
  TOOLING_COMPILE_ASSERT(
      (llvm::is_base_of<DoStmt, NodeType>::value) ||
      (llvm::is_base_of<ForStmt, NodeType>::value) ||
      (llvm::is_base_of<WhileStmt, NodeType>::value),
      has_body_requires_for_while_or_do_statement);
  const Stmt *const Statement = Node.getBody();
  return (Statement != NULL &&
          InnerMatcher.matches(*Statement, Finder, Builder));
}

/// \brief Matches compound statements where at least one substatement matches
/// a given matcher.
///
/// Given
///   { {}; 1+2; }
/// hasAnySubstatement(compoundStatement())
///   matches '{ {}; 1+2; }'
/// with compoundStatement()
///   matching '{}'
AST_MATCHER_P(CompoundStmt, hasAnySubstatement,
              internal::Matcher<Stmt>, InnerMatcher) {
  for (CompoundStmt::const_body_iterator It = Node.body_begin();
       It != Node.body_end();
       ++It) {
    if (InnerMatcher.matches(**It, Finder, Builder)) return true;
  }
  return false;
}

/// \brief Checks that a compound statement contains a specific number of
/// child statements.
///
/// Example: Given
///   { for (;;) {} }
/// compoundStatement(statementCountIs(0)))
///   matches '{}'
///   but does not match the outer compound statement.
AST_MATCHER_P(CompoundStmt, statementCountIs, unsigned, N) {
  return Node.size() == N;
}

/// \brief Matches literals that are equal to the given value.
///
/// Example matches true (matcher = boolLiteral(equals(true)))
///   true
template <typename ValueT>
internal::PolymorphicMatcherWithParam1<internal::ValueEqualsMatcher, ValueT>
equals(const ValueT &Value) {
  return internal::PolymorphicMatcherWithParam1<
    internal::ValueEqualsMatcher,
    ValueT>(Value);
}

/// \brief Matches the operator Name of operator expressions (binary or
/// unary).
///
/// Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
///   !(a || b)
AST_POLYMORPHIC_MATCHER_P(hasOperatorName, std::string, Name) {
  TOOLING_COMPILE_ASSERT(
    (llvm::is_base_of<BinaryOperator, NodeType>::value) ||
    (llvm::is_base_of<UnaryOperator, NodeType>::value),
    has_condition_requires_if_statement_or_conditional_operator);
  return Name == Node.getOpcodeStr(Node.getOpcode());
}

/// \brief Matches the left hand side of binary operator expressions.
///
/// Example matches a (matcher = binaryOperator(hasLHS()))
///   a || b
AST_MATCHER_P(BinaryOperator, hasLHS,
              internal::Matcher<Expr>, InnerMatcher) {
  Expr *LeftHandSide = Node.getLHS();
  return (LeftHandSide != NULL &&
          InnerMatcher.matches(*LeftHandSide, Finder, Builder));
}

/// \brief Matches the right hand side of binary operator expressions.
///
/// Example matches b (matcher = binaryOperator(hasRHS()))
///   a || b
AST_MATCHER_P(BinaryOperator, hasRHS,
              internal::Matcher<Expr>, InnerMatcher) {
  Expr *RightHandSide = Node.getRHS();
  return (RightHandSide != NULL &&
          InnerMatcher.matches(*RightHandSide, Finder, Builder));
}

/// \brief Matches if either the left hand side or the right hand side of a
/// binary operator matches.
inline internal::Matcher<BinaryOperator> hasEitherOperand(
    const internal::Matcher<Expr> &InnerMatcher) {
  return anyOf(hasLHS(InnerMatcher), hasRHS(InnerMatcher));
}

/// \brief Matches if the operand of a unary operator matches.
///
/// Example matches true (matcher = hasOperand(boolLiteral(equals(true))))
///   !true
AST_MATCHER_P(UnaryOperator, hasUnaryOperand,
              internal::Matcher<Expr>, InnerMatcher) {
  const Expr * const Operand = Node.getSubExpr();
  return (Operand != NULL &&
          InnerMatcher.matches(*Operand, Finder, Builder));
}

/// \brief Matches if the implicit cast's source expression matches the given
/// matcher.
///
/// Example: matches "a string" (matcher =
///                                  hasSourceExpression(constructorCall()))
///
/// class URL { URL(string); };
/// URL url = "a string";
AST_MATCHER_P(ImplicitCastExpr, hasSourceExpression,
              internal::Matcher<Expr>, InnerMatcher) {
  const Expr* const SubExpression = Node.getSubExpr();
  return (SubExpression != NULL &&
          InnerMatcher.matches(*SubExpression, Finder, Builder));
}

/// \brief Matches casts whose destination type matches a given matcher.
///
/// (Note: Clang's AST refers to other conversions as "casts" too, and calls
/// actual casts "explicit" casts.)
AST_MATCHER_P(ExplicitCastExpr, hasDestinationType,
              internal::Matcher<QualType>, InnerMatcher) {
  const QualType NodeType = Node.getTypeAsWritten();
  return InnerMatcher.matches(NodeType, Finder, Builder);
}

/// \brief Matches implicit casts whose destination type matches a given
/// matcher.
///
/// FIXME: Unit test this matcher
AST_MATCHER_P(ImplicitCastExpr, hasImplicitDestinationType,
              internal::Matcher<QualType>, InnerMatcher) {
  return InnerMatcher.matches(Node.getType(), Finder, Builder);
}

/// \brief Matches the true branch expression of a conditional operator.
///
/// Example matches a
///   condition ? a : b
AST_MATCHER_P(ConditionalOperator, hasTrueExpression,
              internal::Matcher<Expr>, InnerMatcher) {
  Expr *Expression = Node.getTrueExpr();
  return (Expression != NULL &&
          InnerMatcher.matches(*Expression, Finder, Builder));
}

/// \brief Matches the false branch expression of a conditional operator.
///
/// Example matches b
///   condition ? a : b
AST_MATCHER_P(ConditionalOperator, hasFalseExpression,
              internal::Matcher<Expr>, InnerMatcher) {
  Expr *Expression = Node.getFalseExpr();
  return (Expression != NULL &&
          InnerMatcher.matches(*Expression, Finder, Builder));
}

/// \brief Matches if a declaration has a body attached.
///
/// Example matches A, va, fa
///   class A {};
///   class B;  // Doesn't match, as it has no body.
///   int va;
///   extern int vb;  // Doesn't match, as it doesn't define the variable.
///   void fa() {}
///   void fb();  // Doesn't match, as it has no body.
inline internal::PolymorphicMatcherWithParam0<internal::IsDefinitionMatcher>
isDefinition() {
  return internal::PolymorphicMatcherWithParam0<
    internal::IsDefinitionMatcher>();
}

/// \brief Matches the class declaration that the given method declaration
/// belongs to.
///
/// FIXME: Generalize this for other kinds of declarations.
/// FIXME: What other kind of declarations would we need to generalize
/// this to?
///
/// Example matches A() in the last line
///     (matcher = constructorCall(hasDeclaration(method(
///         ofClass(hasName("A"))))))
///   class A {
///    public:
///     A();
///   };
///   A a = A();
AST_MATCHER_P(CXXMethodDecl, ofClass,
              internal::Matcher<CXXRecordDecl>, InnerMatcher) {
  const CXXRecordDecl *Parent = Node.getParent();
  return (Parent != NULL &&
          InnerMatcher.matches(*Parent, Finder, Builder));
}

/// \brief Matches member expressions that are called with '->' as opposed
/// to '.'.
///
/// Member calls on the implicit this pointer match as called with '->'.
///
/// Given
///   class Y {
///     void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
///     int a;
///     static int b;
///   };
/// memberExpression(isArrow())
///   matches this->x, x, y.x, a, this->b
inline internal::Matcher<MemberExpr> isArrow() {
  return makeMatcher(new internal::IsArrowMatcher());
}

/// \brief Matches QualType nodes that are of integer type.
///
/// Given
///   void a(int);
///   void b(long);
///   void c(double);
/// function(hasAnyParameter(hasType(isInteger())))
/// matches "a(int)", "b(long)", but not "c(double)".
AST_MATCHER(QualType, isInteger) {
    return Node->isIntegerType();
}

/// \brief Matches QualType nodes that are const-qualified, i.e., that
/// include "top-level" const.
///
/// Given
///   void a(int);
///   void b(int const);
///   void c(const int);
///   void d(const int*);
///   void e(int const) {};
/// function(hasAnyParameter(hasType(isConstQualified())))
///   matches "void b(int const)", "void c(const int)" and
///   "void e(int const) {}". It does not match d as there
///   is no top-level const on the parameter type "const int *".
inline internal::Matcher<QualType> isConstQualified() {
  return makeMatcher(new internal::IsConstQualifiedMatcher());
}

/// \brief Matches a member expression where the member is matched by a
/// given matcher.
///
/// Given
///   struct { int first, second; } first, second;
///   int i(second.first);
///   int j(first.second);
/// memberExpression(member(hasName("first")))
///   matches second.first
///   but not first.second (because the member name there is "second").
AST_MATCHER_P(MemberExpr, member,
              internal::Matcher<ValueDecl>, InnerMatcher) {
  return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
}

/// \brief Matches a member expression where the object expression is
/// matched by a given matcher.
///
/// Given
///   struct X { int m; };
///   void f(X x) { x.m; m; }
/// memberExpression(hasObjectExpression(hasType(record(hasName("X")))))))
///   matches "x.m" and "m"
/// with hasObjectExpression(...)
///   matching "x" and the implicit object expression of "m" which has type X*.
AST_MATCHER_P(MemberExpr, hasObjectExpression,
              internal::Matcher<Expr>, InnerMatcher) {
  return InnerMatcher.matches(*Node.getBase(), Finder, Builder);
}

/// \brief Matches any using shadow declaration.
///
/// Given
///   namespace X { void b(); }
///   using X::b;
/// usingDecl(hasAnyUsingShadowDecl(hasName("b"))))
///   matches \code using X::b \endcode
AST_MATCHER_P(UsingDecl, hasAnyUsingShadowDecl,
              internal::Matcher<UsingShadowDecl>, Matcher) {
  for (UsingDecl::shadow_iterator II = Node.shadow_begin();
       II != Node.shadow_end(); ++II) {
    if (Matcher.matches(**II, Finder, Builder))
      return true;
  }
  return false;
}

/// \brief Matches a using shadow declaration where the target declaration is
/// matched by the given matcher.
///
/// Given
///   namespace X { int a; void b(); }
///   using X::a;
///   using X::b;
/// usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(function())))
///   matches \code using X::b \endcode
///   but not \code using X::a \endcode
AST_MATCHER_P(UsingShadowDecl, hasTargetDecl,
              internal::Matcher<NamedDecl>, Matcher) {
  return Matcher.matches(*Node.getTargetDecl(), Finder, Builder);
}

/// \brief Matches template instantiations of function, class, or static
/// member variable template instantiations.
///
/// Given
///   template <typename T> class X {}; class A {}; X<A> x;
/// or
///   template <typename T> class X {}; class A {}; template class X<A>;
/// record(hasName("::X"), isTemplateInstantiation())
///   matches the template instantiation of X<A>.
///
/// But given
///   template <typename T> class X {}; class A {};
///   template <> class X<A> {}; X<A> x;
/// record(hasName("::X"), isTemplateInstantiation())
///   does not match, as X<A> is an explicit template specialization.
inline internal::PolymorphicMatcherWithParam0<
  internal::IsTemplateInstantiationMatcher>
isTemplateInstantiation() {
  return internal::PolymorphicMatcherWithParam0<
    internal::IsTemplateInstantiationMatcher>();
}

} // end namespace ast_matchers
} // end namespace clang

#endif // LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_H
