//===--- 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:
//    recordDecl(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:
//    recordDecl(hasName("MyClass"), hasChild(id("child", recordDecl())))
//  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"
#include <iterator>

namespace clang {
namespace ast_matchers {

/// \brief Maps string IDs to AST nodes matched by parts of a matcher.
///
/// The bound nodes are generated by calling \c bind("id") on the node matchers
/// of the nodes we want to access later.
///
/// The instances of BoundNodes are created by \c MatchFinder when the user's
/// callbacks are executed every time a match is found.
class BoundNodes {
public:
  /// \brief Returns the AST node bound to \c ID.
  ///
  /// Returns NULL if there was no node bound to \c ID or if there is a node but
  /// it cannot be converted to the specified type.
  template <typename T>
  const T *getNodeAs(StringRef ID) const {
    return MyBoundNodes.getNodeAs<T>(ID);
  }

  /// \brief Deprecated. Please use \c getNodeAs instead.
  /// @{
  template <typename T>
  const T *getDeclAs(StringRef ID) const {
    return getNodeAs<T>(ID);
  }
  template <typename T>
  const T *getStmtAs(StringRef ID) const {
    return getNodeAs<T>(ID);
  }
  /// @}

private:
  /// \brief Create BoundNodes from a pre-filled map of bindings.
  BoundNodes(internal::BoundNodesMap &MyBoundNodes)
      : MyBoundNodes(MyBoundNodes) {}

  internal::BoundNodesMap MyBoundNodes;

  friend class internal::BoundNodesTree;
};

/// \brief If the provided matcher matches a node, binds the node to \c ID.
///
/// FIXME: Do we want to support this now that we have bind()?
template <typename T>
internal::Matcher<T> id(const std::string &ID,
                        const internal::BindableMatcher<T> &InnerMatcher) {
  return InnerMatcher.bind(ID);
}

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

/// \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 an \c internal::Matcher<> type such as \c TypeMatcher.
///
/// Example: \c DeclarationMatcher(anything()) matches all declarations, e.g.,
/// \code
/// "int* p" and "void f()" in
///   int* p;
///   void f();
/// \endcode
///
/// Usable as: Any Matcher
inline internal::PolymorphicMatcherWithParam0<internal::TrueMatcher> anything() {
  return internal::PolymorphicMatcherWithParam0<internal::TrueMatcher>();
}

/// \brief Matches declarations.
///
/// Examples matches \c X, \c C, and the friend declaration inside \c C;
/// \code
///   void X();
///   class C {
///     friend X;
///   };
/// \endcode
const internal::VariadicDynCastAllOfMatcher<Decl, Decl> decl;

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

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

/// \brief Matches C++ class template declarations.
///
/// Example matches \c Z
/// \code
///   template<class T> class Z {};
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Decl,
  ClassTemplateDecl> classTemplateDecl;

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

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

/// \brief Matches expressions that match InnerMatcher after any implicit casts
/// are stripped off.
///
/// Parentheses and explicit casts are not discarded.
/// Given
/// \code
///   int arr[5];
///   int a = 0;
///   char b = 0;
///   const int c = a;
///   int *d = arr;
///   long e = (long) 0l;
/// \endcode
/// The matchers
/// \code
///    varDecl(hasInitializer(ignoringImpCasts(integerLiteral())))
///    varDecl(hasInitializer(ignoringImpCasts(declRefExpr())))
/// \endcode
/// would match the declarations for a, b, c, and d, but not e.
/// While
/// \code
///    varDecl(hasInitializer(integerLiteral()))
///    varDecl(hasInitializer(declRefExpr()))
/// \endcode
/// only match the declarations for b, c, and d.
AST_MATCHER_P(Expr, ignoringImpCasts,
              internal::Matcher<Expr>, InnerMatcher) {
  return InnerMatcher.matches(*Node.IgnoreImpCasts(), Finder, Builder);
}

/// \brief Matches expressions that match InnerMatcher after parentheses and
/// casts are stripped off.
///
/// Implicit and non-C Style casts are also discarded.
/// Given
/// \code
///   int a = 0;
///   char b = (0);
///   void* c = reinterpret_cast<char*>(0);
///   char d = char(0);
/// \endcode
/// The matcher
///    varDecl(hasInitializer(ignoringParenCasts(integerLiteral())))
/// would match the declarations for a, b, c, and d.
/// while
///    varDecl(hasInitializer(integerLiteral()))
/// only match the declaration for a.
AST_MATCHER_P(Expr, ignoringParenCasts, internal::Matcher<Expr>, InnerMatcher) {
  return InnerMatcher.matches(*Node.IgnoreParenCasts(), Finder, Builder);
}

/// \brief Matches expressions that match InnerMatcher after implicit casts and
/// parentheses are stripped off.
///
/// Explicit casts are not discarded.
/// Given
/// \code
///   int arr[5];
///   int a = 0;
///   char b = (0);
///   const int c = a;
///   int *d = (arr);
///   long e = ((long) 0l);
/// \endcode
/// The matchers
///    varDecl(hasInitializer(ignoringParenImpCasts(integerLiteral())))
///    varDecl(hasInitializer(ignoringParenImpCasts(declRefExpr())))
/// would match the declarations for a, b, c, and d, but not e.
/// while
///    varDecl(hasInitializer(integerLiteral()))
///    varDecl(hasInitializer(declRefExpr()))
/// would only match the declaration for a.
AST_MATCHER_P(Expr, ignoringParenImpCasts,
              internal::Matcher<Expr>, InnerMatcher) {
  return InnerMatcher.matches(*Node.IgnoreParenImpCasts(), Finder, Builder);
}

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

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

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

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

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

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

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

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

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

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

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

/// \brief Matches C++ function template declarations.
///
/// Example matches f
/// \code
///   template<class T> void f(T t) {}
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Decl,
  FunctionTemplateDecl> functionTemplateDecl;

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

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

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

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

/// \brief Matches lambda expressions.
///
/// Example matches [&](){return 5;}
/// \code
///   [&](){return 5;}
/// \endcode
const internal::VariadicDynCastAllOfMatcher<Stmt, LambdaExpr> lambdaExpr;

/// \brief Matches member call expressions.
///
/// Example matches x.y()
/// \code
///   X x;
///   x.y();
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  CXXMemberCallExpr> memberCallExpr;

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

/// \brief Matches using declarations.
///
/// Given
/// \code
///   namespace X { int x; }
///   using X::x;
/// \endcode
/// 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 = constructExpr())
/// \code
///   void f(const string &a, const string &b);
///   char *ptr;
///   int n;
///   f(string(ptr, n), ptr);
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  CXXConstructExpr> constructExpr;

/// \brief Matches implicit and explicit this expressions.
///
/// Example matches the implicit this expression in "return i".
///     (matcher = thisExpr())
/// \code
/// struct foo {
///   int i;
///   int f() { return i; }
/// };
/// \endcode
const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr> thisExpr;

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

/// \brief Matches nodes where temporaries are materialized.
///
/// Example: Given
/// \code
///   struct T {void func()};
///   T f();
///   void g(T);
/// \endcode
/// materializeTemporaryExpr() matches 'f()' in these statements
/// \code
///   T u(f());
///   g(f());
/// \endcode
/// but does not match
/// \code
///   f();
///   f().func();
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  MaterializeTemporaryExpr> materializeTemporaryExpr;

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

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

/// \brief Matches array subscript expressions.
///
/// Given
/// \code
///   int i = a[1];
/// \endcode
/// 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 = defaultArgExpr())
/// \code
///   void f(int x, int y = 0);
///   f(42);
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  CXXDefaultArgExpr> defaultArgExpr;

/// \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 = operatorCallExpr())
/// \code
///   ostream &operator<< (ostream &out, int i) { };
///   ostream &o; int b = 1, c = 1;
///   o << b << c;
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  CXXOperatorCallExpr> operatorCallExpr;

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

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

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

/// \brief Matches for statements.
///
/// Example matches 'for (;;) {}'
/// \code
///   for (;;) {}
///   int i[] =  {1, 2, 3}; for (auto a : i);
/// \endcode
const internal::VariadicDynCastAllOfMatcher<Stmt, ForStmt> forStmt;

/// \brief Matches range-based for statements.
///
/// forRangeStmt() matches 'for (auto a : i)'
/// \code
///   int i[] =  {1, 2, 3}; for (auto a : i);
///   for(int j = 0; j < 5; ++j);
/// \endcode
const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt> forRangeStmt;

/// \brief Matches the increment statement of a for loop.
///
/// Example:
///     forStmt(hasIncrement(unaryOperator(hasOperatorName("++"))))
/// matches '++x' in
/// \code
///     for (x; x < N; ++x) { }
/// \endcode
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(declStmt()))
/// matches 'int x = 0' in
/// \code
///     for (int x = 0; x < N; ++x) { }
/// \endcode
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
/// \code
///   while (true) {}
/// \endcode
/// whileStmt()
///   matches 'while (true) {}'.
const internal::VariadicDynCastAllOfMatcher<Stmt, WhileStmt> whileStmt;

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

/// \brief Matches break statements.
///
/// Given
/// \code
///   while (true) { break; }
/// \endcode
/// breakStmt()
///   matches 'break'
const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt;

/// \brief Matches continue statements.
///
/// Given
/// \code
///   while (true) { continue; }
/// \endcode
/// continueStmt()
///   matches 'continue'
const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt> continueStmt;

/// \brief Matches return statements.
///
/// Given
/// \code
///   return 1;
/// \endcode
/// returnStmt()
///   matches 'return 1'
const internal::VariadicDynCastAllOfMatcher<Stmt, ReturnStmt> returnStmt;

/// \brief Matches goto statements.
///
/// Given
/// \code
///   goto FOO;
///   FOO: bar();
/// \endcode
/// gotoStmt()
///   matches 'goto FOO'
const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt;

/// \brief Matches label statements.
///
/// Given
/// \code
///   goto FOO;
///   FOO: bar();
/// \endcode
/// labelStmt()
///   matches 'FOO:'
const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt;

/// \brief Matches switch statements.
///
/// Given
/// \code
///   switch(a) { case 42: break; default: break; }
/// \endcode
/// switchStmt()
///   matches 'switch(a)'.
const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchStmt> switchStmt;

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

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

/// \brief Matches catch statements.
///
/// \code
///   try {} catch(int i) {}
/// \endcode
/// catchStmt()
///   matches 'catch(int i)'
const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt> catchStmt;

/// \brief Matches try statements.
///
/// \code
///   try {} catch(int i) {}
/// \endcode
/// tryStmt()
///   matches 'try {}'
const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> tryStmt;

/// \brief Matches throw expressions.
///
/// \code
///   try { throw 5; } catch(int i) {}
/// \endcode
/// throwExpr()
///   matches 'throw 5'
const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr> throwExpr;

/// \brief Matches null statements.
///
/// \code
///   foo();;
/// \endcode
/// nullStmt()
///   matches the second ';'
const internal::VariadicDynCastAllOfMatcher<Stmt, NullStmt> nullStmt;

/// \brief Matches asm statements.
///
/// \code
///  int i = 100;
///   __asm("mov al, 2");
/// \endcode
/// asmStmt()
///   matches '__asm("mov al, 2")'
const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt;

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

/// \brief Matches string literals (also matches wide string literals).
///
/// Example matches "abcd", L"abcd"
/// \code
///   char *s = "abcd"; wchar_t *ws = L"abcd"
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  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'
/// \code
///   char ch = 'a'; wchar_t chw = L'a';
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  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<
  Stmt,
  IntegerLiteral> integerLiteral;

/// \brief Matches user defined literal operator call.
///
/// Example match: "foo"_suffix
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  UserDefinedLiteral> userDefinedLiteral;

/// \brief Matches nullptr literal.
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  CXXNullPtrLiteralExpr> nullPtrLiteralExpr;

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

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

/// \brief Matches conditional operator expressions.
///
/// Example matches a ? b : c
/// \code
///   (a ? b : c) + 42
/// \endcode
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
/// \code
///   void* p = reinterpret_cast<char*>(&p);
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  CXXReinterpretCastExpr> reinterpretCastExpr;

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

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

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

/// \brief Matches a C-style cast expression.
///
/// Example: Matches (int*) 2.2f in
/// \code
///   int i = (int) 2.2f;
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  CStyleCastExpr> cStyleCastExpr;

/// \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
/// \code
///   int((int)(reinterpret_cast<int>(static_cast<int>(const_cast<int>(42)))))
/// \endcode
/// but does not match the implicit conversion in
/// \code
///   long ell = 42;
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  ExplicitCastExpr> explicitCastExpr;

/// \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<
  Stmt,
  ImplicitCastExpr> implicitCastExpr;

/// \brief Matches any cast nodes of Clang's AST.
///
/// Example: castExpr() matches each of the following:
/// \code
///   (int) 3;
///   const_cast<Expr *>(SubExpr);
///   char c = 0;
/// \endcode
/// but does not match
/// \code
///   int i = (0);
///   int k = 0;
/// \endcode
const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr;

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

/// \brief Matches \c QualTypes in the clang AST.
const internal::VariadicAllOfMatcher<QualType> qualType;

/// \brief Matches \c Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher<Type, Type> type;

/// \brief Matches \c TypeLocs in the clang AST.
const internal::VariadicDynCastAllOfMatcher<TypeLoc, TypeLoc> typeLoc;

/// \brief Various overloads for the anyOf matcher.
/// @{

/// \brief Matches if any of the given matchers matches.
///
/// Usable as: Any Matcher
template<typename M1, typename M2>
internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M1, M2>
anyOf(const M1 &P1, const M2 &P2) {
  return internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher,
                                                M1, M2 >(P1, P2);
}
template<typename M1, typename M2, typename M3>
internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M1,
    internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M2, M3> >
anyOf(const M1 &P1, const M2 &P2, const M3 &P3) {
  return anyOf(P1, anyOf(P2, P3));
}
template<typename M1, typename M2, typename M3, typename M4>
internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M1,
    internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M2,
        internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher,
                                               M3, M4> > >
anyOf(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4) {
  return anyOf(P1, anyOf(P2, anyOf(P3, P4)));
}
template<typename M1, typename M2, typename M3, typename M4, typename M5>
internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M1,
    internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M2,
        internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M3,
            internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher,
                                                   M4, M5> > > >
anyOf(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, const M5 &P5) {
  return anyOf(P1, anyOf(P2, anyOf(P3, anyOf(P4, P5))));
}

/// @}

/// \brief Various overloads for the allOf matcher.
/// @{

/// \brief Matches if all given matchers match.
///
/// Usable as: Any Matcher
template<typename M1, typename M2>
internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, M1, M2>
allOf(const M1 &P1, const M2 &P2) {
  return internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher,
                                                M1, M2>(P1, P2);
}
template<typename M1, typename M2, typename M3>
internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, M1,
    internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, M2, M3> >
allOf(const M1 &P1, const M2 &P2, const M3 &P3) {
  return allOf(P1, allOf(P2, P3));
}

/// @}

/// \brief Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL)
///
/// Given
/// \code
///   Foo x = bar;
///   int y = sizeof(x) + alignof(x);
/// \endcode
/// 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
/// \code
///   int a, c; float b; int s = sizeof(a) + sizeof(b) + alignof(c);
/// \endcode
/// unaryExprOrTypeTraitExpr(hasArgumentOfType(asString("int"))
///   matches \c sizeof(a) and \c alignof(c)
AST_MATCHER_P(UnaryExprOrTypeTraitExpr, hasArgumentOfType,
              internal::Matcher<QualType>, InnerMatcher) {
  const QualType ArgumentType = Node.getTypeOfArgument();
  return InnerMatcher.matches(ArgumentType, Finder, Builder);
}

/// \brief Matches unary expressions of a certain kind.
///
/// Given
/// \code
///   int x;
///   int s = sizeof(x) + alignof(x)
/// \endcode
/// 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> &InnerMatcher) {
  return internal::Matcher<Stmt>(unaryExprOrTypeTraitExpr(allOf(
      ofKind(UETT_AlignOf), InnerMatcher)));
}

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

/// \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")
/// \code
///   class X;
/// \endcode
///
/// Example matches X (Name is one of "::a::b::X", "a::b::X", "b::X", "X")
/// \code
///   namespace a { namespace b { class X; } }
/// \endcode
AST_MATCHER_P(NamedDecl, hasName, std::string, Name) {
  assert(!Name.empty());
  const std::string FullNameString = "::" + Node.getQualifiedNameAsString();
  const StringRef FullName = FullNameString;
  const StringRef Pattern = Name;
  if (Pattern.startswith("::")) {
    return FullName == Pattern;
  } else {
    return FullName.endswith(("::" + Pattern).str());
  }
}

/// \brief Matches NamedDecl nodes whose fully qualified names contain
/// a substring matched by 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")
/// \code
///   class X;
/// \endcode
///
/// Example matches X (regexp is one of "::X", "^foo::.*X", among others)
/// \code
///   namespace foo { namespace bar { class X; } }
/// \endcode
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 == operatorCallExpr(hasOverloadedOperatorName("<<")))
/// \code
///   a << b;
///   c && d;  // assuming both operator<<
///            // and operator&& are overloaded somewhere.
/// \endcode
AST_MATCHER_P(CXXOperatorCallExpr,
              hasOverloadedOperatorName, std::string, Name) {
  return getOperatorSpelling(Node.getOperator()) == Name;
}

/// \brief Matches C++ classes that are directly or indirectly derived from
/// a class matching \c Base.
///
/// Note that a class is not considered to be derived from itself.
///
/// Example matches Y, Z, C (Base == hasName("X"))
/// \code
///   class X;
///   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
/// \endcode
///
/// In the following example, Bar matches isDerivedFrom(hasName("X")):
/// \code
///   class Foo;
///   typedef Foo X;
///   class Bar : public Foo {};  // derived from a type that X is a typedef of
/// \endcode
AST_MATCHER_P(CXXRecordDecl, isDerivedFrom,
              internal::Matcher<NamedDecl>, Base) {
  return Finder->classIsDerivedFrom(&Node, Base, Builder);
}

/// \brief Overloaded method as shortcut for \c isDerivedFrom(hasName(...)).
inline internal::Matcher<CXXRecordDecl> isDerivedFrom(StringRef BaseName) {
  assert(!BaseName.empty());
  return isDerivedFrom(hasName(BaseName));
}

/// \brief Similar to \c isDerivedFrom(), but also matches classes that directly
/// match \c Base.
inline internal::Matcher<CXXRecordDecl> isSameOrDerivedFrom(
    internal::Matcher<NamedDecl> Base) {
  return anyOf(Base, isDerivedFrom(Base));
}

/// \brief Overloaded method as shortcut for
/// \c isSameOrDerivedFrom(hasName(...)).
inline internal::Matcher<CXXRecordDecl> isSameOrDerivedFrom(
    StringRef BaseName) {
  assert(!BaseName.empty());
  return isSameOrDerivedFrom(hasName(BaseName));
}

/// \brief Matches AST nodes that have child AST nodes that match the
/// provided matcher.
///
/// Example matches X, Y (matcher = recordDecl(has(recordDecl(hasName("X")))
/// \code
///   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.
/// \endcode
///
/// ChildT must be an AST base type.
///
/// Usable as: Any Matcher
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 = recordDecl(hasDescendant(recordDecl(hasName("X")))))
/// \code
///   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 {}; }; };
/// \endcode
///
/// DescendantT must be an AST base type.
///
/// Usable as: Any Matcher
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 = recordDecl(forEach(recordDecl(hasName("X")))
/// \code
///   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.
/// \endcode
///
/// 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.
///
/// Usable as: Any Matcher
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 = recordDecl(forEachDescendant(recordDecl(hasName("X")))))
/// \code
///   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 {}; }; };
/// \endcode
///
/// 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:
///   recordDecl(forEachDescendant(recordDecl(forEachDescendant(recordDecl()))))
/// will match 10 times (plus injected class name matches) on:
/// \code
///   class A { class B { class C { class D { class E {}; }; }; }; };
/// \endcode
///
/// Usable as: Any Matcher
template <typename DescendantT>
internal::ArgumentAdaptingMatcher<internal::ForEachDescendantMatcher,
                                  DescendantT>
forEachDescendant(
    const internal::Matcher<DescendantT> &DescendantMatcher) {
  return internal::ArgumentAdaptingMatcher<
    internal::ForEachDescendantMatcher,
    DescendantT>(DescendantMatcher);
}

/// \brief Matches AST nodes that have a parent that matches the provided
/// matcher.
///
/// Given
/// \code
/// void f() { for (;;) { int x = 42; if (true) { int x = 43; } } }
/// \endcode
/// \c compoundStmt(hasParent(ifStmt())) matches "{ int x = 43; }".
///
/// Usable as: Any Matcher
template <typename ParentT>
internal::ArgumentAdaptingMatcher<internal::HasParentMatcher, ParentT>
hasParent(const internal::Matcher<ParentT> &ParentMatcher) {
  return internal::ArgumentAdaptingMatcher<
    internal::HasParentMatcher,
    ParentT>(ParentMatcher);
}

/// \brief Matches AST nodes that have an ancestor that matches the provided
/// matcher.
///
/// Given
/// \code
/// void f() { if (true) { int x = 42; } }
/// void g() { for (;;) { int x = 43; } }
/// \endcode
/// \c expr(integerLiteral(hasAncestor(ifStmt()))) matches \c 42, but not 43.
///
/// Usable as: Any Matcher
template <typename AncestorT>
internal::ArgumentAdaptingMatcher<internal::HasAncestorMatcher, AncestorT>
hasAncestor(const internal::Matcher<AncestorT> &AncestorMatcher) {
  return internal::ArgumentAdaptingMatcher<
    internal::HasAncestorMatcher,
    AncestorT>(AncestorMatcher);
}

/// \brief Matches if the provided matcher does not match.
///
/// Example matches Y (matcher = recordDecl(unless(hasName("X"))))
/// \code
///   class X {};
///   class Y {};
/// \endcode
///
/// Usable as: Any Matcher
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.
///
/// Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr>,
///   Matcher<MemberExpr>
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 = callExpr(on(hasType(recordDecl(hasName("Y"))))))
/// \code
///   class Y { public: void x(); };
///   void z() { Y y; y.x(); }",
/// \endcode
///
/// 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
/// \code
///   class Y { void x() { this->x(); x(); Y y; y.x(); } };
///   void f() { f(); }
/// \endcode
/// callExpr(callee(expr()))
///   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 = callExpr(callee(methodDecl(hasName("x")))))
/// \code
///   class Y { public: void x(); };
///   void z() { Y y; y.x();
/// \endcode
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 = expr(hasType(recordDecl(hasName("X")))))
///             and z (matcher = varDecl(hasType(recordDecl(hasName("X")))))
/// \code
///  class X {};
///  void y(X &x) { x; X z; }
/// \endcode
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;", recordDecl(hasName("X")) matches the declaration of X,
/// while varDecl(hasType(recordDecl(hasName("X")))) matches the declaration
/// of x."
///
/// Example matches x (matcher = expr(hasType(recordDecl(hasName("X")))))
///             and z (matcher = varDecl(hasType(recordDecl(hasName("X")))))
/// \code
///  class X {};
///  void y(X &x) { x; X z; }
/// \endcode
///
/// Usable as: Matcher<Expr>, Matcher<ValueDecl>
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
/// \code
///   class Y { public: void x(); };
///   void z() { Y* y; y->x(); }
/// \endcode
/// callExpr(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 = callExpr(on(hasType(pointsTo(recordDecl(hasName("Y")))))))
/// \code
///   class Y { public: void x(); };
///   void z() { Y *y; y->x(); }
/// \endcode
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 = varDecl(hasType(references(recordDecl(hasName("X"))))))
/// \code
///   class X {
///     void a(X b) {
///       X &x = b;
///       const X &y = b;
///   };
/// \endcode
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<CXXMemberCallExpr> 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<CXXMemberCallExpr> 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 = declRefExpr(to(varDecl(hasName("x")))))
/// \code
///   bool x;
///   if (x) {}
/// \endcode
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
/// \code
///   namespace a { void f() {} }
///   using a::f;
///   void g() {
///     f();     // Matches this ..
///     a::f();  // .. but not this.
///   }
/// \endcode
/// declRefExpr(throughUsingDeclaration(anything()))
///   matches \c f()
AST_MATCHER_P(DeclRefExpr, throughUsingDecl,
              internal::Matcher<UsingShadowDecl>, InnerMatcher) {
  const NamedDecl *FoundDecl = Node.getFoundDecl();
  if (const UsingShadowDecl *UsingDecl = dyn_cast<UsingShadowDecl>(FoundDecl))
    return InnerMatcher.matches(*UsingDecl, Finder, Builder);
  return false;
}

/// \brief Matches the Decl of a DeclStmt which has a single declaration.
///
/// Given
/// \code
///   int a, b;
///   int c;
/// \endcode
/// declStmt(hasSingleDecl(anything()))
///   matches 'int c;' but not 'int a, b;'.
AST_MATCHER_P(DeclStmt, hasSingleDecl, internal::Matcher<Decl>, InnerMatcher) {
  if (Node.isSingleDecl()) {
    const Decl *FoundDecl = Node.getSingleDecl();
    return InnerMatcher.matches(*FoundDecl, Finder, Builder);
  }
  return false;
}

/// \brief Matches a variable declaration that has an initializer expression
/// that matches the given matcher.
///
/// Example matches x (matcher = varDecl(hasInitializer(callExpr())))
/// \code
///   bool y() { return true; }
///   bool x = y();
/// \endcode
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 = callExpr(argumentCountIs(2)))
/// \code
///   void f(int x, int y);
///   f(0, 0);
/// \endcode
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 = callExpr(hasArgument(0, declRefExpr())))
/// \code
///   void x(int) { int y; x(y); }
/// \endcode
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 declaration statements that contain a specific number of
/// declarations.
///
/// Example: Given
/// \code
///   int a, b;
///   int c;
///   int d = 2, e;
/// \endcode
/// declCountIs(2)
///   matches 'int a, b;' and 'int d = 2, e;', but not 'int c;'.
AST_MATCHER_P(DeclStmt, declCountIs, unsigned, N) {
  return std::distance(Node.decl_begin(), Node.decl_end()) == (ptrdiff_t)N;
}

/// \brief Matches the n'th declaration of a declaration statement.
///
/// Note that this does not work for global declarations because the AST
/// breaks up multiple-declaration DeclStmt's into multiple single-declaration
/// DeclStmt's.
/// Example: Given non-global declarations
/// \code
///   int a, b = 0;
///   int c;
///   int d = 2, e;
/// \endcode
/// declStmt(containsDeclaration(
///       0, varDecl(hasInitializer(anything()))))
///   matches only 'int d = 2, e;', and
/// declStmt(containsDeclaration(1, varDecl()))
/// \code
///   matches 'int a, b = 0' as well as 'int d = 2, e;'
///   but 'int c;' is not matched.
/// \endcode
AST_MATCHER_P2(DeclStmt, containsDeclaration, unsigned, N,
               internal::Matcher<Decl>, InnerMatcher) {
  const unsigned NumDecls = std::distance(Node.decl_begin(), Node.decl_end());
  if (N >= NumDecls)
    return false;
  DeclStmt::const_decl_iterator Iterator = Node.decl_begin();
  std::advance(Iterator, N);
  return InnerMatcher.matches(**Iterator, Finder, Builder);
}

/// \brief Matches a constructor initializer.
///
/// Given
/// \code
///   struct Foo {
///     Foo() : foo_(1) { }
///     int foo_;
///   };
/// \endcode
/// recordDecl(has(constructorDecl(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
/// \code
///   struct Foo {
///     Foo() : foo_(1) { }
///     int foo_;
///   };
/// \endcode
/// recordDecl(has(constructorDecl(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
/// \code
///   struct Foo {
///     Foo() : foo_(1) { }
///     int foo_;
///   };
/// \endcode
/// recordDecl(has(constructorDecl(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
/// \code
///   struct Foo {
///     Foo() { }
///     Foo(int) : foo_("A") { }
///     string foo_;
///   };
/// \endcode
/// constructorDecl(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
/// \code
///   void x(int, int, int) { int y; x(1, y, 42); }
/// \endcode
/// callExpr(hasAnyArgument(declRefExpr()))
///   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
/// \code
///   class X { void f(int x) {} };
/// \endcode
/// methodDecl(hasParameter(0, hasType(varDecl())))
///   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
/// \code
///   class X { void f(int x, int y, int z) {} };
/// \endcode
/// methodDecl(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 \c FunctionDecls that have a specific parameter count.
///
/// Given
/// \code
///   void f(int i) {}
///   void g(int i, int j) {}
/// \endcode
/// functionDecl(parameterCountIs(2))
///   matches g(int i, int j) {}
AST_MATCHER_P(FunctionDecl, parameterCountIs, unsigned, N) {
  return Node.getNumParams() == N;
}

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

/// \brief Matches extern "C" function declarations.
///
/// Given:
/// \code
///   extern "C" void f() {}
///   extern "C" { void g() {} }
///   void h() {}
/// \endcode
/// functionDecl(isExternC())
///   matches the declaration of f and g, but not the declaration h
AST_MATCHER(FunctionDecl, isExternC) {
  return Node.isExternC();
}

/// \brief Matches the condition expression of an if statement, for loop,
/// or conditional operator.
///
/// Example matches true (matcher = hasCondition(boolLiteral(equals(true))))
/// \code
///   if (true) {}
/// \endcode
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
/// \code
///   if (A* a = GetAPointer()) {}
/// \endcode
/// 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
/// \code
///   int i[5];
///   void f() { i[1] = 42; }
/// \endcode
/// arraySubscriptExpression(hasIndex(integerLiteral()))
///   matches \c i[1] with the \c integerLiteral() matching \c 1
AST_MATCHER_P(ArraySubscriptExpr, hasIndex,
              internal::Matcher<Expr>, InnerMatcher) {
  if (const Expr* Expression = Node.getIdx())
    return InnerMatcher.matches(*Expression, Finder, Builder);
  return false;
}

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

/// \brief Matches a 'for', 'while', or 'do while' statement that has
/// a given body.
///
/// Given
/// \code
///   for (;;) {}
/// \endcode
/// hasBody(compoundStmt())
///   matches 'for (;;) {}'
/// with compoundStmt()
///   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
/// \code
///   { {}; 1+2; }
/// \endcode
/// hasAnySubstatement(compoundStmt())
///   matches '{ {}; 1+2; }'
/// with compoundStmt()
///   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
/// \code
///   { for (;;) {} }
/// \endcode
/// compoundStmt(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)))
/// \code
///   true
/// \endcode
///
/// Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteral>,
///            Matcher<FloatingLiteral>, Matcher<IntegerLiteral>
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("||")))
/// \code
///   !(a || b)
/// \endcode
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()))
/// \code
///   a || b
/// \endcode
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()))
/// \code
///   a || b
/// \endcode
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 = hasUnaryOperand(boolLiteral(equals(true))))
/// \code
///   !true
/// \endcode
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 cast's source expression matches the given matcher.
///
/// Example: matches "a string" (matcher =
///                                  hasSourceExpression(constructExpr()))
/// \code
/// class URL { URL(string); };
/// URL url = "a string";
AST_MATCHER_P(CastExpr, 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
/// \code
///   condition ? a : b
/// \endcode
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
/// \code
///   condition ? a : b
/// \endcode
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
/// \code
///   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.
/// \endcode
///
/// Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>
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 = constructExpr(hasDeclaration(methodDecl(
///         ofClass(hasName("A"))))))
/// \code
///   class A {
///    public:
///     A();
///   };
///   A a = A();
/// \endcode
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
/// \code
///   class Y {
///     void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
///     int a;
///     static int b;
///   };
/// \endcode
/// memberExpr(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
/// \code
///   void a(int);
///   void b(long);
///   void c(double);
/// \endcode
/// functionDecl(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
/// \code
///   void a(int);
///   void b(int const);
///   void c(const int);
///   void d(const int*);
///   void e(int const) {};
/// \endcode
/// functionDecl(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
/// \code
///   struct { int first, second; } first, second;
///   int i(second.first);
///   int j(first.second);
/// \endcode
/// memberExpr(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
/// \code
///   struct X { int m; };
///   void f(X x) { x.m; m; }
/// \endcode
/// memberExpr(hasObjectExpression(hasType(recordDecl(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
/// \code
///   namespace X { void b(); }
///   using X::b;
/// \endcode
/// usingDecl(hasAnyUsingShadowDecl(hasName("b"))))
///   matches \code using X::b \endcode
AST_MATCHER_P(UsingDecl, hasAnyUsingShadowDecl,
              internal::Matcher<UsingShadowDecl>, InnerMatcher) {
  for (UsingDecl::shadow_iterator II = Node.shadow_begin();
       II != Node.shadow_end(); ++II) {
    if (InnerMatcher.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
/// \code
///   namespace X { int a; void b(); }
///   using X::a;
///   using X::b;
/// \endcode
/// usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(functionDecl())))
///   matches \code using X::b \endcode
///   but not \code using X::a \endcode
AST_MATCHER_P(UsingShadowDecl, hasTargetDecl,
              internal::Matcher<NamedDecl>, InnerMatcher) {
  return InnerMatcher.matches(*Node.getTargetDecl(), Finder, Builder);
}

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

/// \brief Matches explicit template specializations of function, class, or
/// static member variable template instantiations.
///
/// Given
/// \code
///   template<typename T> void A(T t) { }
///   template<> void A(int N) { }
/// \endcode
/// functionDecl(isExplicitTemplateSpecialization())
///   matches the specialization A<int>().
///
/// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
inline internal::PolymorphicMatcherWithParam0<
  internal::IsExplicitTemplateSpecializationMatcher>
isExplicitTemplateSpecialization() {
  return internal::PolymorphicMatcherWithParam0<
    internal::IsExplicitTemplateSpecializationMatcher>();
}

/// \brief Matches \c TypeLocs for which the given inner
/// QualType-matcher matches.
inline internal::BindableMatcher<TypeLoc> loc(
    const internal::Matcher<QualType> &InnerMatcher) {
  return internal::BindableMatcher<TypeLoc>(
      new internal::TypeLocTypeMatcher(InnerMatcher));
}

/// \brief Matches builtin Types.
///
/// Given
/// \code
///   struct A {};
///   A a;
///   int b;
///   float c;
///   bool d;
/// \endcode
/// builtinType()
///   matches "int b", "float c" and "bool d"
AST_TYPE_MATCHER(BuiltinType, builtinType);

/// \brief Matches all kinds of arrays.
///
/// Given
/// \code
///   int a[] = { 2, 3 };
///   int b[4];
///   void f() { int c[a[0]]; }
/// \endcode
/// arrayType()
///   matches "int a[]", "int b[4]" and "int c[a[0]]";
AST_TYPE_MATCHER(ArrayType, arrayType);

/// \brief Matches C99 complex types.
///
/// Given
/// \code
///   _Complex float f;
/// \endcode
/// complexType()
///   matches "_Complex float f"
AST_TYPE_MATCHER(ComplexType, complexType);

/// \brief Matches arrays and C99 complex types that have a specific element
/// type.
///
/// Given
/// \code
///   struct A {};
///   A a[7];
///   int b[7];
/// \endcode
/// arrayType(hasElementType(builtinType()))
///   matches "int b[7]"
///
/// Usable as: Matcher<ArrayType>, Matcher<ComplexType>
AST_TYPELOC_TRAVERSE_MATCHER(hasElementType, getElement);

/// \brief Matches C arrays with a specified constant size.
///
/// Given
/// \code
///   void() {
///     int a[2];
///     int b[] = { 2, 3 };
///     int c[b[0]];
///   }
/// \endcode
/// constantArrayType()
///   matches "int a[2]"
AST_TYPE_MATCHER(ConstantArrayType, constantArrayType);

/// \brief Matches \c ConstantArrayType nodes that have the specified size.
///
/// Given
/// \code
///   int a[42];
///   int b[2 * 21];
///   int c[41], d[43];
/// \endcode
/// constantArrayType(hasSize(42))
///   matches "int a[42]" and "int b[2 * 21]"
AST_MATCHER_P(ConstantArrayType, hasSize, unsigned, N) {
  return Node.getSize() == N;
}

/// \brief Matches C++ arrays whose size is a value-dependent expression.
///
/// Given
/// \code
///   template<typename T, int Size>
///   class array {
///     T data[Size];
///   };
/// \endcode
/// dependentSizedArrayType
///   matches "T data[Size]"
AST_TYPE_MATCHER(DependentSizedArrayType, dependentSizedArrayType);

/// \brief Matches C arrays with unspecified size.
///
/// Given
/// \code
///   int a[] = { 2, 3 };
///   int b[42];
///   void f(int c[]) { int d[a[0]]; };
/// \endcode
/// incompleteArrayType()
///   matches "int a[]" and "int c[]"
AST_TYPE_MATCHER(IncompleteArrayType, incompleteArrayType);

/// \brief Matches C arrays with a specified size that is not an
/// integer-constant-expression.
///
/// Given
/// \code
///   void f() {
///     int a[] = { 2, 3 }
///     int b[42];
///     int c[a[0]];
/// \endcode
/// variableArrayType()
///   matches "int c[a[0]]"
AST_TYPE_MATCHER(VariableArrayType, variableArrayType);

/// \brief Matches \c VariableArrayType nodes that have a specific size
/// expression.
///
/// Given
/// \code
///   void f(int b) {
///     int a[b];
///   }
/// \endcode
/// variableArrayType(hasSizeExpr(ignoringImpCasts(declRefExpr(to(
///   varDecl(hasName("b")))))))
///   matches "int a[b]"
AST_MATCHER_P(VariableArrayType, hasSizeExpr,
              internal::Matcher<Expr>, InnerMatcher) {
  return InnerMatcher.matches(*Node.getSizeExpr(), Finder, Builder);
}

/// \brief Matches atomic types.
///
/// Given
/// \code
///   _Atomic(int) i;
/// \endcode
/// atomicType()
///   matches "_Atomic(int) i"
AST_TYPE_MATCHER(AtomicType, atomicType);

/// \brief Matches atomic types with a specific value type.
///
/// Given
/// \code
///   _Atomic(int) i;
///   _Atomic(float) f;
/// \endcode
/// atomicType(hasValueType(isInteger()))
///  matches "_Atomic(int) i"
///
/// Usable as: Matcher<AtomicType>
AST_TYPELOC_TRAVERSE_MATCHER(hasValueType, getValue);

/// \brief Matches types nodes representing C++11 auto types.
///
/// Given:
/// \code
///   auto n = 4;
///   int v[] = { 2, 3 }
///   for (auto i : v) { }
/// \endcode
/// autoType()
///   matches "auto n" and "auto i"
AST_TYPE_MATCHER(AutoType, autoType);

/// \brief Matches \c AutoType nodes where the deduced type is a specific type.
///
/// Note: There is no \c TypeLoc for the deduced type and thus no
/// \c getDeducedLoc() matcher.
///
/// Given
/// \code
///   auto a = 1;
///   auto b = 2.0;
/// \endcode
/// autoType(hasDeducedType(isInteger()))
///   matches "auto a"
///
/// Usable as: Matcher<AutoType>
AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType);

/// \brief Matches \c FunctionType nodes.
///
/// Given
/// \code
///   int (*f)(int);
///   void g();
/// \endcode
/// functionType()
///   matches "int (*f)(int)" and the type of "g".
AST_TYPE_MATCHER(FunctionType, functionType);

/// \brief Matches block pointer types, i.e. types syntactically represented as
/// "void (^)(int)".
///
/// The \c pointee is always required to be a \c FunctionType.
AST_TYPE_MATCHER(BlockPointerType, blockPointerType);

/// \brief Matches member pointer types.
/// Given
/// \code
///   struct A { int i; }
///   A::* ptr = A::i;
/// \endcode
/// memberPointerType()
///   matches "A::* ptr"
AST_TYPE_MATCHER(MemberPointerType, memberPointerType);

/// \brief Matches pointer types.
///
/// Given
/// \code
///   int *a;
///   int &b = *a;
///   int c = 5;
/// \endcode
/// pointerType()
///   matches "int *a"
AST_TYPE_MATCHER(PointerType, pointerType);

/// \brief Matches reference types.
///
/// Given
/// \code
///   int *a;
///   int &b = *a;
///   int c = 5;
/// \endcode
/// pointerType()
///   matches "int &b"
AST_TYPE_MATCHER(ReferenceType, referenceType);

/// \brief Narrows PointerType (and similar) matchers to those where the
/// \c pointee matches a given matcher.
///
/// Given
/// \code
///   int *a;
///   int const *b;
///   float const *f;
/// \endcode
/// pointerType(pointee(isConstQualified(), isInteger()))
///   matches "int const *b"
///
/// Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>,
///   Matcher<PointerType>, Matcher<ReferenceType>
AST_TYPELOC_TRAVERSE_MATCHER(pointee, getPointee);

/// \brief Matches typedef types.
///
/// Given
/// \code
///   typedef int X;
/// \endcode
/// typedefType()
///   matches "typedef int X"
AST_TYPE_MATCHER(TypedefType, typedefType);

/// \brief Matches \c TypedefTypes referring to a specific
/// \c TypedefNameDecl.
AST_MATCHER_P(TypedefType, hasDecl,
              internal::Matcher<TypedefNameDecl>, InnerMatcher) {
  return InnerMatcher.matches(*Node.getDecl(), Finder, Builder);
}

/// \brief Matches nested name specifiers.
///
/// Given
/// \code
///   namespace ns {
///     struct A { static void f(); };
///     void A::f() {}
///     void g() { A::f(); }
///   }
///   ns::A a;
/// \endcode
/// nestedNameSpecifier()
///   matches "ns::" and both "A::"
const internal::VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier;

/// \brief Same as \c nestedNameSpecifier but matches \c NestedNameSpecifierLoc.
const internal::VariadicAllOfMatcher<
  NestedNameSpecifierLoc> nestedNameSpecifierLoc;

/// \brief Matches \c NestedNameSpecifierLocs for which the given inner
/// NestedNameSpecifier-matcher matches.
inline internal::BindableMatcher<NestedNameSpecifierLoc> loc(
    const internal::Matcher<NestedNameSpecifier> &InnerMatcher) {
  return internal::BindableMatcher<NestedNameSpecifierLoc>(
      new internal::LocMatcher<NestedNameSpecifierLoc, NestedNameSpecifier>(
          InnerMatcher));
}

/// \brief Matches nested name specifiers that specify a type matching the
/// given \c QualType matcher without qualifiers.
///
/// Given
/// \code
///   struct A { struct B { struct C {}; }; };
///   A::B::C c;
/// \endcode
/// nestedNameSpecifier(specifiesType(hasDeclaration(recordDecl(hasName("A")))))
///   matches "A::"
AST_MATCHER_P(NestedNameSpecifier, specifiesType,
              internal::Matcher<QualType>, InnerMatcher) {
  if (Node.getAsType() == NULL)
    return false;
  return InnerMatcher.matches(QualType(Node.getAsType(), 0), Finder, Builder);
}

/// \brief Matches nested name specifier locs that specify a type matching the
/// given \c TypeLoc.
///
/// Given
/// \code
///   struct A { struct B { struct C {}; }; };
///   A::B::C c;
/// \endcode
/// nestedNameSpecifierLoc(specifiesTypeLoc(loc(type(
///   hasDeclaration(recordDecl(hasName("A")))))))
///   matches "A::"
AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc,
              internal::Matcher<TypeLoc>, InnerMatcher) {
  return InnerMatcher.matches(Node.getTypeLoc(), Finder, Builder);
}

/// \brief Matches on the prefix of a \c NestedNameSpecifier.
///
/// Given
/// \code
///   struct A { struct B { struct C {}; }; };
///   A::B::C c;
/// \endcode
/// nestedNameSpecifier(hasPrefix(specifiesType(asString("struct A")))) and
///   matches "A::"
inline internal::Matcher<NestedNameSpecifier> hasPrefix(
    const internal::Matcher<NestedNameSpecifier> &InnerMatcher) {
  return internal::makeMatcher(
    new internal::NestedNameSpecifierPrefixMatcher(InnerMatcher));
}

/// \brief Matches on the prefix of a \c NestedNameSpecifierLoc.
///
/// Given
/// \code
///   struct A { struct B { struct C {}; }; };
///   A::B::C c;
/// \endcode
/// nestedNameSpecifierLoc(hasPrefix(loc(specifiesType(asString("struct A")))))
///   matches "A::"
inline internal::Matcher<NestedNameSpecifierLoc> hasPrefix(
    const internal::Matcher<NestedNameSpecifierLoc> &InnerMatcher) {
  return internal::makeMatcher(
    new internal::NestedNameSpecifierLocPrefixMatcher(InnerMatcher));
}

/// \brief Matches nested name specifiers that specify a namespace matching the
/// given namespace matcher.
///
/// Given
/// \code
///   namespace ns { struct A {}; }
///   ns::A a;
/// \endcode
/// nestedNameSpecifier(specifiesNamespace(hasName("ns")))
///   matches "ns::"
AST_MATCHER_P(NestedNameSpecifier, specifiesNamespace,
              internal::Matcher<NamespaceDecl>, InnerMatcher) {
  if (Node.getAsNamespace() == NULL)
    return false;
  return InnerMatcher.matches(*Node.getAsNamespace(), Finder, Builder);
}

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

#endif // LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_H
