//===--- 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:
//    cxxRecordDecl(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:
//    cxxRecordDecl(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 RecordDecl 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_ASTMATCHERS_ASTMATCHERS_H
#define LLVM_CLANG_ASTMATCHERS_ASTMATCHERS_H

#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/ASTMatchers/ASTMatchersInternal.h"
#include "clang/ASTMatchers/ASTMatchersMacros.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);
  }
  /// @}

  /// \brief Type of mapping from binding identifiers to bound nodes. This type
  /// is an associative container with a key type of \c std::string and a value
  /// type of \c clang::ast_type_traits::DynTypedNode
  typedef internal::BoundNodesMap::IDToNodeMap IDToNodeMap;

  /// \brief Retrieve mapping from binding identifiers to bound nodes.
  const IDToNodeMap &getMap() const {
    return MyBoundNodes.getMap();
  }

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

  internal::BoundNodesMap MyBoundNodes;

  friend class internal::BoundNodesTreeBuilder;
};

/// \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(StringRef 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::TrueMatcher anything() { return internal::TrueMatcher(); }

/// \brief Matches the top declaration context.
///
/// Given
/// \code
///   int X;
///   namespace NS {
///   int Y;
///   }  // namespace NS
/// \endcode
/// decl(hasDeclContext(translationUnitDecl()))
///   matches "int X", but not "int Y".
const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl>
    translationUnitDecl;

/// \brief Matches typedef declarations.
///
/// Given
/// \code
///   typedef int X;
///   using Y = int;
/// \endcode
/// typedefDecl()
///   matches "typedef int X", but not "using Y = int"
const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl> typedefDecl;

/// \brief Matches typedef name declarations.
///
/// Given
/// \code
///   typedef int X;
///   using Y = int;
/// \endcode
/// typedefNameDecl()
///   matches "typedef int X" and "using Y = int"
const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl>
    typedefNameDecl;

/// \brief Matches type alias declarations.
///
/// Given
/// \code
///   typedef int X;
///   using Y = int;
/// \endcode
/// typeAliasDecl()
///   matches "using Y = int", but not "typedef int X"
const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl> typeAliasDecl;

/// \brief Matches AST nodes that were expanded within the main-file.
///
/// Example matches X but not Y
///   (matcher = cxxRecordDecl(isExpansionInMainFile())
/// \code
///   #include <Y.h>
///   class X {};
/// \endcode
/// Y.h:
/// \code
///   class Y {};
/// \endcode
///
/// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
AST_POLYMORPHIC_MATCHER(isExpansionInMainFile,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc)) {
  auto &SourceManager = Finder->getASTContext().getSourceManager();
  return SourceManager.isInMainFile(
      SourceManager.getExpansionLoc(Node.getLocStart()));
}

/// \brief Matches AST nodes that were expanded within system-header-files.
///
/// Example matches Y but not X
///     (matcher = cxxRecordDecl(isExpansionInSystemHeader())
/// \code
///   #include <SystemHeader.h>
///   class X {};
/// \endcode
/// SystemHeader.h:
/// \code
///   class Y {};
/// \endcode
///
/// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
AST_POLYMORPHIC_MATCHER(isExpansionInSystemHeader,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc)) {
  auto &SourceManager = Finder->getASTContext().getSourceManager();
  auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getLocStart());
  if (ExpansionLoc.isInvalid()) {
    return false;
  }
  return SourceManager.isInSystemHeader(ExpansionLoc);
}

/// \brief Matches AST nodes that were expanded within files whose name is
/// partially matching a given regex.
///
/// Example matches Y but not X
///     (matcher = cxxRecordDecl(isExpansionInFileMatching("AST.*"))
/// \code
///   #include "ASTMatcher.h"
///   class X {};
/// \endcode
/// ASTMatcher.h:
/// \code
///   class Y {};
/// \endcode
///
/// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
AST_POLYMORPHIC_MATCHER_P(isExpansionInFileMatching,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc),
                          std::string, RegExp) {
  auto &SourceManager = Finder->getASTContext().getSourceManager();
  auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getLocStart());
  if (ExpansionLoc.isInvalid()) {
    return false;
  }
  auto FileEntry =
      SourceManager.getFileEntryForID(SourceManager.getFileID(ExpansionLoc));
  if (!FileEntry) {
    return false;
  }

  auto Filename = FileEntry->getName();
  llvm::Regex RE(RegExp);
  return RE.match(Filename);
}

/// \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::VariadicAllOfMatcher<Decl> decl;

/// \brief Matches a declaration of a linkage specification.
///
/// Given
/// \code
///   extern "C" {}
/// \endcode
/// linkageSpecDecl()
///   matches "extern "C" {}"
const internal::VariadicDynCastAllOfMatcher<Decl, LinkageSpecDecl>
    linkageSpecDecl;

/// \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 a declaration of label.
///
/// Given
/// \code
///   goto FOO;
///   FOO: bar();
/// \endcode
/// labelDecl()
///   matches 'FOO:'
const internal::VariadicDynCastAllOfMatcher<Decl, LabelDecl> labelDecl;

/// \brief Matches a declaration of a namespace.
///
/// Given
/// \code
///   namespace {}
///   namespace test {}
/// \endcode
/// namespaceDecl()
///   matches "namespace {}" and "namespace test {}"
const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceDecl> namespaceDecl;

/// \brief Matches a declaration of a namespace alias.
///
/// Given
/// \code
///   namespace test {}
///   namespace alias = ::test;
/// \endcode
/// namespaceAliasDecl()
///   matches "namespace alias" but not "namespace test"
const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceAliasDecl>
    namespaceAliasDecl;

/// \brief Matches class, struct, and union declarations.
///
/// Example matches \c X, \c Z, \c U, and \c S
/// \code
///   class X;
///   template<class T> class Z {};
///   struct S {};
///   union U {};
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Decl,
  RecordDecl> recordDecl;

/// \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> cxxRecordDecl;

/// \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 declarator declarations (field, variable, function
/// and non-type template parameter declarations).
///
/// Given
/// \code
///   class X { int y; };
/// \endcode
/// declaratorDecl()
///   matches \c int y.
const internal::VariadicDynCastAllOfMatcher<Decl, DeclaratorDecl>
    declaratorDecl;

/// \brief Matches parameter variable declarations.
///
/// Given
/// \code
///   void f(int x);
/// \endcode
/// parmVarDecl()
///   matches \c int x.
const internal::VariadicDynCastAllOfMatcher<Decl, ParmVarDecl> parmVarDecl;

/// \brief Matches C++ access specifier declarations.
///
/// Given
/// \code
///   class C {
///   public:
///     int a;
///   };
/// \endcode
/// accessSpecDecl()
///   matches 'public:'
const internal::VariadicDynCastAllOfMatcher<
  Decl,
  AccessSpecDecl> accessSpecDecl;

/// \brief Matches constructor initializers.
///
/// Examples matches \c i(42).
/// \code
///   class C {
///     C() : i(42) {}
///     int i;
///   };
/// \endcode
const internal::VariadicAllOfMatcher<CXXCtorInitializer> cxxCtorInitializer;

/// \brief Matches template arguments.
///
/// Given
/// \code
///   template <typename T> struct C {};
///   C<int> c;
/// \endcode
/// templateArgument()
///   matches 'int' in C<int>.
const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument;

/// \brief Matches template name.
///
/// Given
/// \code
///   template <typename T> class X { };
///   X<int> xi;
/// \endcode
/// templateName()
///   matches 'X' in X<int>.
const internal::VariadicAllOfMatcher<TemplateName> templateName;

/// \brief Matches non-type template parameter declarations.
///
/// Given
/// \code
///   template <typename T, int N> struct C {};
/// \endcode
/// nonTypeTemplateParmDecl()
///   matches 'N', but not 'T'.
const internal::VariadicDynCastAllOfMatcher<
  Decl,
  NonTypeTemplateParmDecl> nonTypeTemplateParmDecl;

/// \brief Matches template type parameter declarations.
///
/// Given
/// \code
///   template <typename T, int N> struct C {};
/// \endcode
/// templateTypeParmDecl()
///   matches 'T', but not 'N'.
const internal::VariadicDynCastAllOfMatcher<
  Decl,
  TemplateTypeParmDecl> templateTypeParmDecl;

/// \brief Matches public C++ declarations.
///
/// Given
/// \code
///   class C {
///   public:    int a;
///   protected: int b;
///   private:   int c;
///   };
/// \endcode
/// fieldDecl(isPublic())
///   matches 'int a;'
AST_MATCHER(Decl, isPublic) {
  return Node.getAccess() == AS_public;
}

/// \brief Matches protected C++ declarations.
///
/// Given
/// \code
///   class C {
///   public:    int a;
///   protected: int b;
///   private:   int c;
///   };
/// \endcode
/// fieldDecl(isProtected())
///   matches 'int b;'
AST_MATCHER(Decl, isProtected) {
  return Node.getAccess() == AS_protected;
}

/// \brief Matches private C++ declarations.
///
/// Given
/// \code
///   class C {
///   public:    int a;
///   protected: int b;
///   private:   int c;
///   };
/// \endcode
/// fieldDecl(isPrivate())
///   matches 'int c;'
AST_MATCHER(Decl, isPrivate) {
  return Node.getAccess() == AS_private;
}

/// \brief Matches non-static data members that are bit-fields.
///
/// Given
/// \code
///   class C {
///     int a : 2;
///     int b;
///   };
/// \endcode
/// fieldDecl(isBitField())
///   matches 'int a;' but not 'int b;'.
AST_MATCHER(FieldDecl, isBitField) {
  return Node.isBitField();
}

/// \brief Matches non-static data members that are bit-fields.
///
/// Given
/// \code
///   class C {
///     int a : 2;
///     int b : 4;
///     int c : 2;
///   };
/// \endcode
/// fieldDecl(isBitField())
///   matches 'int a;' and 'int c;' but not 'int b;'.
AST_MATCHER_P(FieldDecl, hasBitWidth, unsigned, Width) {
  return Node.isBitField() &&
         Node.getBitWidthValue(Finder->getASTContext()) == Width;
}

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

/// \brief Matches classTemplateSpecializations, templateSpecializationType and
/// functionDecl that have at least one TemplateArgument matching the given
/// InnerMatcher.
///
/// Given
/// \code
///   template<typename T> class A {};
///   template<> class A<double> {};
///   A<int> a;
///
///   template<typename T> f() {};
///   void func() { f<int>(); };
/// \endcode
///
/// \endcode
/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
///     refersToType(asString("int"))))
///   matches the specialization \c A<int>
///
/// functionDecl(hasAnyTemplateArgument(refersToType(asString("int"))))
///   matches the specialization \c f<int>
AST_POLYMORPHIC_MATCHER_P(
    hasAnyTemplateArgument,
    AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
                                    TemplateSpecializationType,
                                    FunctionDecl),
    internal::Matcher<TemplateArgument>, InnerMatcher) {
  ArrayRef<TemplateArgument> List =
      internal::getTemplateSpecializationArgs(Node);
  return matchesFirstInRange(InnerMatcher, List.begin(), List.end(), Finder,
                             Builder);
}

/// \brief Matches expressions that match InnerMatcher after any implicit AST
/// nodes are stripped off.
///
/// Parentheses and explicit casts are not discarded.
/// Given
/// \code
///   class C {};
///   C a = C();
///   C b;
///   C c = b;
/// \endcode
/// The matchers
/// \code
///    varDecl(hasInitializer(ignoringImplicit(cxxConstructExpr())))
/// \endcode
/// would match the declarations for a, b, and c.
/// While
/// \code
///    varDecl(hasInitializer(cxxConstructExpr()))
/// \endcode
/// only match the declarations for b and c.
AST_MATCHER_P(Expr, ignoringImplicit, ast_matchers::internal::Matcher<Expr>,
              InnerMatcher) {
  return InnerMatcher.matches(*Node.IgnoreImplicit(), Finder, Builder);
}

/// \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 types that match InnerMatcher after any parens are stripped.
///
/// Given
/// \code
///   void (*fp)(void);
/// \endcode
/// The matcher
/// \code
///   varDecl(hasType(pointerType(pointee(ignoringParens(functionType())))))
/// \endcode
/// would match the declaration for fp.
AST_MATCHER_P(QualType, ignoringParens,
              internal::Matcher<QualType>, InnerMatcher) {
  return InnerMatcher.matches(Node.IgnoreParens(), Finder, Builder);
}

/// \brief Matches classTemplateSpecializations, templateSpecializationType and
/// functionDecl 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;
///
///   template<typename T> f() {};
///   void func() { f<int>(); };
/// \endcode
/// classTemplateSpecializationDecl(hasTemplateArgument(
///     1, refersToType(asString("int"))))
///   matches the specialization \c A<bool, int>
///
/// functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))
///   matches the specialization \c f<int>
AST_POLYMORPHIC_MATCHER_P2(
    hasTemplateArgument,
    AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
                                    TemplateSpecializationType,
                                    FunctionDecl),
    unsigned, N, internal::Matcher<TemplateArgument>, InnerMatcher) {
  ArrayRef<TemplateArgument> List =
      internal::getTemplateSpecializationArgs(Node);
  if (List.size() <= N)
    return false;
  return InnerMatcher.matches(List[N], Finder, Builder);
}

/// \brief Matches if the number of template arguments equals \p N.
///
/// Given
/// \code
///   template<typename T> struct C {};
///   C<int> c;
/// \endcode
/// classTemplateSpecializationDecl(templateArgumentCountIs(1))
///   matches C<int>.
AST_POLYMORPHIC_MATCHER_P(
    templateArgumentCountIs,
    AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
                                    TemplateSpecializationType),
    unsigned, N) {
  return internal::getTemplateSpecializationArgs(Node).size() == N;
}

/// \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 template.
///
/// Given
/// \code
///   template<template <typename> class S> class X {};
///   template<typename T> class Y {};"
///   X<Y> xi;
/// \endcode
/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
///     refersToTemplate(templateName())))
///   matches the specialization \c X<Y>
AST_MATCHER_P(TemplateArgument, refersToTemplate,
              internal::Matcher<TemplateName>, InnerMatcher) {
  if (Node.getKind() != TemplateArgument::Template)
    return false;
  return InnerMatcher.matches(Node.getAsTemplate(), Finder, Builder);
}

/// \brief Matches a canonical 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 a sugar TemplateArgument that refers to a certain expression.
///
/// Given
/// \code
///   template<typename T> struct A {};
///   struct B { B* next; };
///   A<&B::next> a;
/// \endcode
/// templateSpecializationType(hasAnyTemplateArgument(
///   isExpr(hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))
///   matches the specialization \c A<&B::next> with \c fieldDecl(...) matching
///     \c B::next
AST_MATCHER_P(TemplateArgument, isExpr, internal::Matcher<Expr>, InnerMatcher) {
  if (Node.getKind() == TemplateArgument::Expression)
    return InnerMatcher.matches(*Node.getAsExpr(), Finder, Builder);
  return false;
}

/// \brief Matches a TemplateArgument that is an integral value.
///
/// Given
/// \code
///   template<int T> struct A {};
///   C<42> c;
/// \endcode
/// classTemplateSpecializationDecl(
///   hasAnyTemplateArgument(isIntegral()))
///   matches the implicit instantiation of C in C<42>
///   with isIntegral() matching 42.
AST_MATCHER(TemplateArgument, isIntegral) {
  return Node.getKind() == TemplateArgument::Integral;
}

/// \brief Matches a TemplateArgument that referes to an integral type.
///
/// Given
/// \code
///   template<int T> struct A {};
///   C<42> c;
/// \endcode
/// classTemplateSpecializationDecl(
///   hasAnyTemplateArgument(refersToIntegralType(asString("int"))))
///   matches the implicit instantiation of C in C<42>.
AST_MATCHER_P(TemplateArgument, refersToIntegralType,
              internal::Matcher<QualType>, InnerMatcher) {
  if (Node.getKind() != TemplateArgument::Integral)
    return false;
  return InnerMatcher.matches(Node.getIntegralType(), Finder, Builder);
}

/// \brief Matches a TemplateArgument of integral type with a given value.
///
/// Note that 'Value' is a string as the template argument's value is
/// an arbitrary precision integer. 'Value' must be euqal to the canonical
/// representation of that integral value in base 10.
///
/// Given
/// \code
///   template<int T> struct A {};
///   C<42> c;
/// \endcode
/// classTemplateSpecializationDecl(
///   hasAnyTemplateArgument(equalsIntegralValue("42")))
///   matches the implicit instantiation of C in C<42>.
AST_MATCHER_P(TemplateArgument, equalsIntegralValue,
              std::string, Value) {
  if (Node.getKind() != TemplateArgument::Integral)
    return false;
  return Node.getAsIntegral().toString(10) == Value;
}

/// \brief Matches any value declaration.
///
/// Example matches A, B, C and F
/// \code
///   enum X { A, B, C };
///   void F();
/// \endcode
const internal::VariadicDynCastAllOfMatcher<Decl, ValueDecl> valueDecl;

/// \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> cxxConstructorDecl;

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

/// \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> cxxMethodDecl;

/// \brief Matches conversion operator declarations.
///
/// Example matches the operator.
/// \code
///   class X { operator int() const; };
/// \endcode
const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>
    cxxConversionDecl;

/// \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 friend declarations.
///
/// Given
/// \code
///   class X { friend void foo(); };
/// \endcode
/// friendDecl()
///   matches 'friend void foo()'.
const internal::VariadicDynCastAllOfMatcher<Decl, FriendDecl> friendDecl;

/// \brief Matches statements.
///
/// Given
/// \code
///   { ++a; }
/// \endcode
/// stmt()
///   matches both the compound statement '{ ++a; }' and '++a'.
const internal::VariadicAllOfMatcher<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> cxxMemberCallExpr;

/// \brief Matches ObjectiveC Message invocation expressions.
///
/// The innermost message send invokes the "alloc" class method on the
/// NSString class, while the outermost message send invokes the
/// "initWithString" instance method on the object returned from
/// NSString's "alloc". This matcher should match both message sends.
/// \code
///   [[NSString alloc] initWithString:@"Hello"]
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  ObjCMessageExpr> objcMessageExpr;

/// \brief Matches Objective-C interface declarations.
///
/// Example matches Foo
/// \code
///   @interface Foo
///   @end
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Decl,
  ObjCInterfaceDecl> objcInterfaceDecl;

/// \brief Matches expressions that introduce cleanups to be run at the end
/// of the sub-expression's evaluation.
///
/// Example matches std::string()
/// \code
///   const std::string str = std::string();
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  ExprWithCleanups> exprWithCleanups;

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

/// \brief Matches the syntactic form of init list expressions
/// (if expression have it).
AST_MATCHER_P(InitListExpr, hasSyntacticForm,
              internal::Matcher<Expr>, InnerMatcher) {
  const Expr *SyntForm = Node.getSyntacticForm();
  return (SyntForm != nullptr &&
          InnerMatcher.matches(*SyntForm, Finder, Builder));
}

/// \brief Matches implicit initializers of init list expressions.
///
/// Given
/// \code
///   point ptarray[10] = { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 };
/// \endcode
/// implicitValueInitExpr()
///   matches "[0].y" (implicitly)
const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitValueInitExpr>
implicitValueInitExpr;

/// \brief Matches paren list expressions.
/// ParenListExprs don't have a predefined type and are used for late parsing.
/// In the final AST, they can be met in template declarations.
///
/// Given
/// \code
///   template<typename T> class X {
///     void f() {
///       X x(*this);
///       int a = 0, b = 1; int i = (a, b);
///     }
///   };
/// \endcode
/// parenListExpr() matches "*this" but NOT matches (a, b) because (a, b)
/// has a predefined type and is a ParenExpr, not a ParenListExpr.
const internal::VariadicDynCastAllOfMatcher<Stmt, ParenListExpr> parenListExpr;

/// \brief Matches substitutions of non-type template parameters.
///
/// Given
/// \code
///   template <int N>
///   struct A { static const int n = N; };
///   struct B : public A<42> {};
/// \endcode
/// substNonTypeTemplateParmExpr()
///   matches "N" in the right-hand side of "static const int n = N;"
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  SubstNonTypeTemplateParmExpr> substNonTypeTemplateParmExpr;

/// \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 using namespace declarations.
///
/// Given
/// \code
///   namespace X { int x; }
///   using namespace X;
/// \endcode
/// usingDirectiveDecl()
///   matches \code using namespace X \endcode
const internal::VariadicDynCastAllOfMatcher<
  Decl,
  UsingDirectiveDecl> usingDirectiveDecl;

/// \brief Matches reference to a name that can be looked up during parsing
/// but could not be resolved to a specific declaration.
///
/// Given
/// \code
///   template<typename T>
///   T foo() { T a; return a; }
///   template<typename T>
///   void bar() {
///     foo<T>();
///   }
/// \endcode
/// unresolvedLookupExpr()
///   matches \code foo<T>() \endcode
const internal::VariadicDynCastAllOfMatcher<
   Stmt,
   UnresolvedLookupExpr> unresolvedLookupExpr;

/// \brief Matches unresolved using value declarations.
///
/// Given
/// \code
///   template<typename X>
///   class C : private X {
///     using X::x;
///   };
/// \endcode
/// unresolvedUsingValueDecl()
///   matches \code using X::x \endcode
const internal::VariadicDynCastAllOfMatcher<
  Decl,
  UnresolvedUsingValueDecl> unresolvedUsingValueDecl;

/// \brief Matches unresolved using value declarations that involve the
/// typename.
///
/// Given
/// \code
///   template <typename T>
///   struct Base { typedef T Foo; };
///
///   template<typename T>
///   struct S : private Base<T> {
///     using typename Base<T>::Foo;
///   };
/// \endcode
/// unresolvedUsingTypenameDecl()
///   matches \code using Base<T>::Foo \endcode
const internal::VariadicDynCastAllOfMatcher<
  Decl,
  UnresolvedUsingTypenameDecl> unresolvedUsingTypenameDecl;

/// \brief Matches parentheses used in expressions.
///
/// Example matches (foo() + 1)
/// \code
///   int foo() { return 1; }
///   int a = (foo() + 1);
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  ParenExpr> parenExpr;

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

/// \brief Matches unresolved constructor call expressions.
///
/// Example matches T(t) in return statement of f
///     (matcher = cxxUnresolvedConstructExpr())
/// \code
///   template <typename T>
///   void f(const T& t) { return T(t); }
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  CXXUnresolvedConstructExpr> cxxUnresolvedConstructExpr;

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

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

/// \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
/// cxxNewExpr()
///   matches 'new X'.
const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> cxxNewExpr;

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

/// \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 = cxxDefaultArgExpr())
/// \code
///   void f(int x, int y = 0);
///   f(42);
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  CXXDefaultArgExpr> cxxDefaultArgExpr;

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

/// \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 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 != nullptr &&
          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 != nullptr && InnerMatcher.matches(*Init, Finder, Builder));
}

/// \brief Matches range-based for statements.
///
/// cxxForRangeStmt() 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> cxxForRangeStmt;

/// \brief Matches the initialization statement of a for loop.
///
/// Example:
///     forStmt(hasLoopVariable(anything()))
/// matches 'int x' in
/// \code
///     for (int x : a) { }
/// \endcode
AST_MATCHER_P(CXXForRangeStmt, hasLoopVariable, internal::Matcher<VarDecl>,
              InnerMatcher) {
  const VarDecl *const Var = Node.getLoopVariable();
  return (Var != nullptr && InnerMatcher.matches(*Var, Finder, Builder));
}

/// \brief Matches the range initialization statement of a for loop.
///
/// Example:
///     forStmt(hasRangeInit(anything()))
/// matches 'a' in
/// \code
///     for (int x : a) { }
/// \endcode
AST_MATCHER_P(CXXForRangeStmt, hasRangeInit, internal::Matcher<Expr>,
              InnerMatcher) {
  const Expr *const Init = Node.getRangeInit();
  return (Init != nullptr && 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 address of label statements (GNU extension).
///
/// Given
/// \code
///   FOO: bar();
///   void *ptr = &&FOO;
///   goto *bar;
/// \endcode
/// addrLabelExpr()
///   matches '&&FOO'
const internal::VariadicDynCastAllOfMatcher<Stmt, AddrLabelExpr> addrLabelExpr;

/// \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 case statements inside switch statements.
///
/// Given
/// \code
///   switch(a) { case 42: break; default: break; }
/// \endcode
/// caseStmt()
///   matches 'case 42: break;'.
const internal::VariadicDynCastAllOfMatcher<Stmt, CaseStmt> caseStmt;

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

/// \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
/// cxxCatchStmt()
///   matches 'catch(int i)'
const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt> cxxCatchStmt;

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

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

/// \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> cxxBoolLiteral;

/// \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, e.g.
/// 1, 1L, 0x1 and 1U.
///
/// Does not match character-encoded integers such as L'a'.
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  IntegerLiteral> integerLiteral;

/// \brief Matches float literals of all sizes / encodings, e.g.
/// 1.0, 1.0f, 1.0L and 1e10.
///
/// Does not match implicit conversions such as
/// \code
///   float a = 10;
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  FloatingLiteral> floatLiteral;

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

/// \brief Matches compound (i.e. non-scalar) literals
///
/// Example match: {1}, (1, 2)
/// \code
///   int array[4] = {1};
///   vector int myvec = (vector int)(1, 2);
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  CompoundLiteralExpr> compoundLiteralExpr;

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

/// \brief Matches GNU __null expression.
const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr> gnuNullExpr;

/// \brief Matches atomic builtins.
/// Example matches __atomic_load_n(ptr, 1)
/// \code
///   void foo() { int *ptr; __atomic_load_n(ptr, 1); }
/// \endcode
const internal::VariadicDynCastAllOfMatcher<Stmt, AtomicExpr> atomicExpr;

/// \brief Matches statement expression (GNU extension).
///
/// Example match: ({ int X = 4; X; })
/// \code
///   int C = ({ int X = 4; X; });
/// \endcode
const internal::VariadicDynCastAllOfMatcher<Stmt, StmtExpr> stmtExpr;

/// \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 binary conditional operator expressions (GNU extension).
///
/// Example matches a ?: b
/// \code
///   (a ?: b) + 42;
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  BinaryConditionalOperator> binaryConditionalOperator;

/// \brief Matches opaque value expressions. They are used as helpers
/// to reference another expressions and can be met
/// in BinaryConditionalOperators, for example.
///
/// Example matches 'a'
/// \code
///   (a ?: c) + 42;
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  OpaqueValueExpr> opaqueValueExpr;

/// \brief Matches a C++ static_assert declaration.
///
/// Example:
///   staticAssertExpr()
/// matches
///   static_assert(sizeof(S) == sizeof(int))
/// in
/// \code
///   struct S {
///     int x;
///   };
///   static_assert(sizeof(S) == sizeof(int));
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Decl,
  StaticAssertDecl> staticAssertDecl;

/// \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> cxxReinterpretCastExpr;

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

/// \brief Matches a dynamic_cast expression.
///
/// Example:
///   cxxDynamicCastExpr()
/// 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> cxxDynamicCastExpr;

/// \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> cxxConstCastExpr;

/// \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> cxxFunctionalCastExpr;

/// \brief Matches functional cast expressions having N != 1 arguments
///
/// Example: Matches Foo(bar, bar)
/// \code
///   Foo h = Foo(bar, bar);
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  CXXTemporaryObjectExpr> cxxTemporaryObjectExpr;

/// \brief Matches predefined identifier expressions [C99 6.4.2.2].
///
/// Example: Matches __func__
/// \code
///   printf("%s", __func__);
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  PredefinedExpr> predefinedExpr;

/// \brief Matches C99 designated initializer expressions [C99 6.7.8].
///
/// Example: Matches { [2].y = 1.0, [0].x = 1.0 }
/// \code
///   point ptarray[10] = { [2].y = 1.0, [0].x = 1.0 };
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  DesignatedInitExpr> designatedInitExpr;

/// \brief Matches designated initializer expressions that contain
/// a specific number of designators.
///
/// Example: Given
/// \code
///   point ptarray[10] = { [2].y = 1.0, [0].x = 1.0 };
///   point ptarray2[10] = { [2].y = 1.0, [2].x = 0.0, [0].x = 1.0 };
/// \endcode
/// designatorCountIs(2)
///   matches '{ [2].y = 1.0, [0].x = 1.0 }',
///   but not '{ [2].y = 1.0, [2].x = 0.0, [0].x = 1.0 }'.
AST_MATCHER_P(DesignatedInitExpr, designatorCountIs, unsigned, N) {
  return Node.size() == N;
}

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

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

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

/// \brief Matches if any of the given matchers matches.
///
/// Unlike \c anyOf, \c eachOf will generate a match result for each
/// matching submatcher.
///
/// For example, in:
/// \code
///   class A { int a; int b; };
/// \endcode
/// The matcher:
/// \code
///   cxxRecordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
///                        has(fieldDecl(hasName("b")).bind("v"))))
/// \endcode
/// will generate two results binding "v", the first of which binds
/// the field declaration of \c a, the second the field declaration of
/// \c b.
///
/// Usable as: Any Matcher
const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> eachOf = {
  internal::DynTypedMatcher::VO_EachOf
};

/// \brief Matches if any of the given matchers matches.
///
/// Usable as: Any Matcher
const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> anyOf = {
  internal::DynTypedMatcher::VO_AnyOf
};

/// \brief Matches if all given matchers match.
///
/// Usable as: Any Matcher
const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> allOf = {
  internal::DynTypedMatcher::VO_AllOf
};

/// \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 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 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
inline internal::Matcher<NamedDecl> hasName(const std::string &Name) {
  std::vector<std::string> Names;
  Names.push_back(Name);
  return internal::Matcher<NamedDecl>(new internal::HasNameMatcher(Names));
}

/// \brief Matches NamedDecl nodes that have any of the specified names.
///
/// This matcher is only provided as a performance optimization of hasName.
/// \code
///     hasAnyName(a, b, c)
/// \endcode
///  is equivalent to, but faster than
/// \code
///     anyOf(hasName(a), hasName(b), hasName(c))
/// \endcode
const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef,
                                 internal::hasAnyNameFunc>
    hasAnyName = {};

/// \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: e.g. "<<".
///
/// Given:
/// \code
///   class A { int operator*(); };
///   const A &operator<<(const A &a, const A &b);
///   A a;
///   a << a;   // <-- This matches
/// \endcode
///
/// \c cxxOperatorCallExpr(hasOverloadedOperatorName("<<"))) matches the
/// specified line and
/// \c cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*")))
/// matches the declaration of \c A.
///
/// Usable as: Matcher<CXXOperatorCallExpr>, Matcher<FunctionDecl>
inline internal::PolymorphicMatcherWithParam1<
    internal::HasOverloadedOperatorNameMatcher, StringRef,
    AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>
hasOverloadedOperatorName(StringRef Name) {
  return internal::PolymorphicMatcherWithParam1<
      internal::HasOverloadedOperatorNameMatcher, StringRef,
      AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>(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(...)).
AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isDerivedFrom, std::string, BaseName, 1) {
  assert(!BaseName.empty());
  return isDerivedFrom(hasName(BaseName)).matches(Node, Finder, Builder);
}

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

/// \brief Overloaded method as shortcut for
/// \c isSameOrDerivedFrom(hasName(...)).
AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isSameOrDerivedFrom, std::string,
                       BaseName, 1) {
  assert(!BaseName.empty());
  return isSameOrDerivedFrom(hasName(BaseName)).matches(Node, Finder, Builder);
}

/// \brief Matches the first method of a class or struct that satisfies \c
/// InnerMatcher.
///
/// Given:
/// \code
///   class A { void func(); };
///   class B { void member(); };
/// \endcode
///
/// \c cxxRecordDecl(hasMethod(hasName("func"))) matches the declaration of
/// \c A but not \c B.
AST_MATCHER_P(CXXRecordDecl, hasMethod, internal::Matcher<CXXMethodDecl>,
              InnerMatcher) {
  return matchesFirstInPointerRange(InnerMatcher, Node.method_begin(),
                                    Node.method_end(), Finder, Builder);
}

/// \brief Matches the generated class of lambda expressions.
///
/// Given:
/// \code
///   auto x = []{};
/// \endcode
///
/// \c cxxRecordDecl(isLambda()) matches the implicit class declaration of
/// \c decltype(x)
AST_MATCHER(CXXRecordDecl, isLambda) {
  return Node.isLambda();
}

/// \brief Matches AST nodes that have child AST nodes that match the
/// provided matcher.
///
/// Example matches X, Y
///   (matcher = cxxRecordDecl(has(cxxRecordDecl(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
/// Note that has is direct matcher, so it also matches things like implicit
/// casts and paren casts. If you are matching with expr then you should
/// probably consider using ignoringParenImpCasts like:
/// has(ignoringParenImpCasts(expr())).
const internal::ArgumentAdaptingMatcherFunc<internal::HasMatcher>
LLVM_ATTRIBUTE_UNUSED has = {};

/// \brief Matches AST nodes that have descendant AST nodes that match the
/// provided matcher.
///
/// Example matches X, Y, Z
///     (matcher = cxxRecordDecl(hasDescendant(cxxRecordDecl(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
const internal::ArgumentAdaptingMatcherFunc<internal::HasDescendantMatcher>
LLVM_ATTRIBUTE_UNUSED hasDescendant = {};

/// \brief Matches AST nodes that have child AST nodes that match the
/// provided matcher.
///
/// Example matches X, Y
///   (matcher = cxxRecordDecl(forEach(cxxRecordDecl(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
const internal::ArgumentAdaptingMatcherFunc<internal::ForEachMatcher>
LLVM_ATTRIBUTE_UNUSED forEach = {};

/// \brief Matches AST nodes that have descendant AST nodes that match the
/// provided matcher.
///
/// Example matches X, A, B, C
///   (matcher = cxxRecordDecl(forEachDescendant(cxxRecordDecl(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:
///   cxxRecordDecl(forEachDescendant(cxxRecordDecl(
///     forEachDescendant(cxxRecordDecl())
///   )))
/// 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
const internal::ArgumentAdaptingMatcherFunc<internal::ForEachDescendantMatcher>
LLVM_ATTRIBUTE_UNUSED forEachDescendant = {};

/// \brief Matches if the node or any descendant matches.
///
/// Generates results for each match.
///
/// For example, in:
/// \code
///   class A { class B {}; class C {}; };
/// \endcode
/// The matcher:
/// \code
///   cxxRecordDecl(hasName("::A"),
///                 findAll(cxxRecordDecl(isDefinition()).bind("m")))
/// \endcode
/// will generate results for \c A, \c B and \c C.
///
/// Usable as: Any Matcher
template <typename T>
internal::Matcher<T> findAll(const internal::Matcher<T> &Matcher) {
  return eachOf(Matcher, forEachDescendant(Matcher));
}

/// \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
const internal::ArgumentAdaptingMatcherFunc<
    internal::HasParentMatcher,
    internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>,
    internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
    LLVM_ATTRIBUTE_UNUSED hasParent = {};

/// \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
const internal::ArgumentAdaptingMatcherFunc<
    internal::HasAncestorMatcher,
    internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>,
    internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
    LLVM_ATTRIBUTE_UNUSED hasAncestor = {};

/// \brief Matches if the provided matcher does not match.
///
/// Example matches Y (matcher = cxxRecordDecl(unless(hasName("X"))))
/// \code
///   class X {};
///   class Y {};
/// \endcode
///
/// Usable as: Any Matcher
const internal::VariadicOperatorMatcherFunc<1, 1> unless = {
  internal::DynTypedMatcher::VO_UnaryNot
};

/// \brief Matches a node if the declaration associated with that node
/// matches the given matcher.
///
/// The associated declaration is:
/// - for type nodes, the declaration of the underlying type
/// - for CallExpr, the declaration of the callee
/// - for MemberExpr, the declaration of the referenced member
/// - for CXXConstructExpr, the declaration of the constructor
///
/// Also usable as Matcher<T> for any T supporting the getDecl() member
/// function. e.g. various subtypes of clang::Type and various expressions.
///
/// Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>,
///   Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>,
///   Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>,
///   Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>,
///   Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>,
///   Matcher<TypedefType>, Matcher<UnresolvedUsingType>
inline internal::PolymorphicMatcherWithParam1<
    internal::HasDeclarationMatcher, internal::Matcher<Decl>,
    void(internal::HasDeclarationSupportedTypes)>
hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) {
  return internal::PolymorphicMatcherWithParam1<
      internal::HasDeclarationMatcher, internal::Matcher<Decl>,
      void(internal::HasDeclarationSupportedTypes)>(InnerMatcher);
}

/// \brief Matches a \c NamedDecl whose underlying declaration matches the given
/// matcher.
///
/// Given
/// \code
///   namespace N { template<class T> void f(T t); }
///   template <class T> void g() { using N::f; f(T()); }
/// \endcode
/// \c unresolvedLookupExpr(hasAnyDeclaration(
///     namedDecl(hasUnderlyingDecl(hasName("::N::f")))))
///   matches the use of \c f in \c g() .
AST_MATCHER_P(NamedDecl, hasUnderlyingDecl, internal::Matcher<NamedDecl>,
              InnerMatcher) {
  const NamedDecl *UnderlyingDecl = Node.getUnderlyingDecl();

  return UnderlyingDecl != nullptr &&
         InnerMatcher.matches(*UnderlyingDecl, Finder, Builder);
}

/// \brief Matches on the implicit object argument of a member call expression.
///
/// Example matches y.x()
///   (matcher = cxxMemberCallExpr(on(hasType(cxxRecordDecl(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 = Node.getImplicitObjectArgument()
                            ->IgnoreParenImpCasts();
  return (ExprNode != nullptr &&
          InnerMatcher.matches(*ExprNode, Finder, Builder));
}


/// \brief Matches on the receiver of an ObjectiveC Message expression.
///
/// Example
/// matcher = objCMessageExpr(hasRecieverType(asString("UIWebView *")));
/// matches the [webView ...] message invocation.
/// \code
///   NSString *webViewJavaScript = ...
///   UIWebView *webView = ...
///   [webView stringByEvaluatingJavaScriptFromString:webViewJavascript];
/// \endcode
AST_MATCHER_P(ObjCMessageExpr, hasReceiverType, internal::Matcher<QualType>,
              InnerMatcher) {
  const QualType TypeDecl = Node.getReceiverType();
  return InnerMatcher.matches(TypeDecl, Finder, Builder);
}
  
/// \brief Matches when BaseName == Selector.getAsString()
///
///  matcher = objCMessageExpr(hasSelector("loadHTMLString:baseURL:"));
///  matches the outer message expr in the code below, but NOT the message
///  invocation for self.bodyView.
/// \code
///     [self.bodyView loadHTMLString:html baseURL:NULL];
/// \endcode
AST_MATCHER_P(ObjCMessageExpr, hasSelector, std::string, BaseName) {
  Selector Sel = Node.getSelector();
  return BaseName.compare(Sel.getAsString()) == 0;
}

  
/// \brief Matches ObjC selectors whose name contains
/// a substring matched by the given RegExp.
///  matcher = objCMessageExpr(matchesSelector("loadHTMLString\:baseURL?"));
///  matches the outer message expr in the code below, but NOT the message
///  invocation for self.bodyView.
/// \code
///     [self.bodyView loadHTMLString:html baseURL:NULL];
/// \endcode
AST_MATCHER_P(ObjCMessageExpr, matchesSelector, std::string, RegExp) {
  assert(!RegExp.empty());
  std::string SelectorString = Node.getSelector().getAsString();
  llvm::Regex RE(RegExp);
  return RE.match(SelectorString);
}

/// \brief Matches when the selector is the empty selector
///
/// Matches only when the selector of the objCMessageExpr is NULL. This may
/// represent an error condition in the tree!
AST_MATCHER(ObjCMessageExpr, hasNullSelector) {
  return Node.getSelector().isNull();
}

/// \brief Matches when the selector is a Unary Selector
///
///  matcher = objCMessageExpr(matchesSelector(hasUnarySelector());
///  matches self.bodyView in the code below, but NOT the outer message
///  invocation of "loadHTMLString:baseURL:".
/// \code
///     [self.bodyView loadHTMLString:html baseURL:NULL];
/// \endcode
AST_MATCHER(ObjCMessageExpr, hasUnarySelector) {
  return Node.getSelector().isUnarySelector();
}

/// \brief Matches when the selector is a keyword selector
///
/// objCMessageExpr(hasKeywordSelector()) matches the generated setFrame
/// message expression in
///
/// \code
///   UIWebView *webView = ...;
///   CGRect bodyFrame = webView.frame;
///   bodyFrame.size.height = self.bodyContentHeight;
///   webView.frame = bodyFrame;
///   //     ^---- matches here
/// \endcode
AST_MATCHER(ObjCMessageExpr, hasKeywordSelector) {
  return Node.getSelector().isKeywordSelector();
}

/// \brief Matches when the selector has the specified number of arguments
///
///  matcher = objCMessageExpr(numSelectorArgs(0));
///  matches self.bodyView in the code below
///
///  matcher = objCMessageExpr(numSelectorArgs(2));
///  matches the invocation of "loadHTMLString:baseURL:" but not that
///  of self.bodyView
/// \code
///     [self.bodyView loadHTMLString:html baseURL:NULL];
/// \endcode
AST_MATCHER_P(ObjCMessageExpr, numSelectorArgs, unsigned, N) {
  return Node.getSelector().getNumArgs() == N;
}
   
/// \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 != nullptr &&
          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(
///                                    cxxMethodDecl(hasName("x")))))
/// \code
///   class Y { public: void x(); };
///   void z() { Y y; y.x(); }
/// \endcode
AST_MATCHER_P_OVERLOAD(CallExpr, callee, internal::Matcher<Decl>, InnerMatcher,
                       1) {
  return callExpr(hasDeclaration(InnerMatcher)).matches(Node, Finder, Builder);
}

/// \brief Matches if the expression's or declaration's type matches a type
/// matcher.
///
/// Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
///             and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
///             and U (matcher = typedefDecl(hasType(asString("int")))
/// \code
///  class X {};
///  void y(X &x) { x; X z; }
///  typedef int U;
/// \endcode
AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
    hasType, AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, TypedefNameDecl, ValueDecl),
    internal::Matcher<QualType>, InnerMatcher, 0) {
  return InnerMatcher.matches(internal::getUnderlyingType(Node),
                              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;", cxxRecordDecl(hasName("X")) matches the declaration of
/// X, while varDecl(hasType(cxxRecordDecl(hasName("X")))) matches the
/// declaration of x.
///
/// Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
///             and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
/// \code
///  class X {};
///  void y(X &x) { x; X z; }
/// \endcode
///
/// Usable as: Matcher<Expr>, Matcher<ValueDecl>
AST_POLYMORPHIC_MATCHER_P_OVERLOAD(hasType,
                                   AST_POLYMORPHIC_SUPPORTED_TYPES(Expr,
                                                                   ValueDecl),
                                   internal::Matcher<Decl>, InnerMatcher, 1) {
  return qualType(hasDeclaration(InnerMatcher))
      .matches(Node.getType(), Finder, Builder);
}

/// \brief Matches if the type location of the declarator decl's type matches
/// the inner matcher.
///
/// Given
/// \code
///   int x;
/// \endcode
/// declaratorDecl(hasTypeLoc(loc(asString("int"))))
///   matches int x
AST_MATCHER_P(DeclaratorDecl, hasTypeLoc, internal::Matcher<TypeLoc>, Inner) {
  if (!Node.getTypeSourceInfo())
    // This happens for example for implicit destructors.
    return false;
  return Inner.matches(Node.getTypeSourceInfo()->getTypeLoc(), Finder, Builder);
}

/// \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
/// cxxMemberCallExpr(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 = cxxMemberCallExpr(on(hasType(pointsTo
///      cxxRecordDecl(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->isAnyPointerType() &&
          InnerMatcher.matches(Node->getPointeeType(), Finder, Builder));
}

/// \brief Overloaded to match the pointee type's declaration.
AST_MATCHER_P_OVERLOAD(QualType, pointsTo, internal::Matcher<Decl>,
                       InnerMatcher, 1) {
  return pointsTo(qualType(hasDeclaration(InnerMatcher)))
      .matches(Node, Finder, Builder);
}

/// \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(cxxRecordDecl(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 Matches QualTypes whose canonical type matches InnerMatcher.
///
/// Given:
/// \code
///   typedef int &int_ref;
///   int a;
///   int_ref b = a;
/// \endcode
///
/// \c varDecl(hasType(qualType(referenceType()))))) will not match the
/// declaration of b but \c
/// varDecl(hasType(qualType(hasCanonicalType(referenceType())))))) does.
AST_MATCHER_P(QualType, hasCanonicalType, internal::Matcher<QualType>,
              InnerMatcher) {
  if (Node.isNull())
    return false;
  return InnerMatcher.matches(Node.getCanonicalType(), Finder, Builder);
}

/// \brief Overloaded to match the referenced type's declaration.
AST_MATCHER_P_OVERLOAD(QualType, references, internal::Matcher<Decl>,
                       InnerMatcher, 1) {
  return references(qualType(hasDeclaration(InnerMatcher)))
      .matches(Node, Finder, Builder);
}

AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument,
              internal::Matcher<Expr>, InnerMatcher) {
  const Expr *ExprNode = Node.getImplicitObjectArgument();
  return (ExprNode != nullptr &&
          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.
AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType,
                       internal::Matcher<QualType>, InnerMatcher, 0) {
  return onImplicitObjectArgument(
      anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher))))
      .matches(Node, Finder, Builder);
}

/// \brief Overloaded to match the type's declaration.
AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType,
                       internal::Matcher<Decl>, InnerMatcher, 1) {
  return onImplicitObjectArgument(
      anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher))))
      .matches(Node, Finder, Builder);
}

/// \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 != nullptr &&
          InnerMatcher.matches(*DeclNode, Finder, Builder));
}

/// \brief Matches a \c DeclRefExpr that refers to a declaration through a
/// specific using shadow declaration.
///
/// Given
/// \code
///   namespace a { void f() {} }
///   using a::f;
///   void g() {
///     f();     // Matches this ..
///     a::f();  // .. but not this.
///   }
/// \endcode
/// declRefExpr(throughUsingDecl(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 an \c OverloadExpr if any of the declarations in the set of
/// overloads matches the given matcher.
///
/// Given
/// \code
///   template <typename T> void foo(T);
///   template <typename T> void bar(T);
///   template <typename T> void baz(T t) {
///     foo(t);
///     bar(t);
///   }
/// \endcode
/// unresolvedLookupExpr(hasAnyDeclaration(
///     functionTemplateDecl(hasName("foo"))))
///   matches \c foo in \c foo(t); but not \c bar in \c bar(t);
AST_MATCHER_P(OverloadExpr, hasAnyDeclaration, internal::Matcher<Decl>,
              InnerMatcher) {
  return matchesFirstInPointerRange(InnerMatcher, Node.decls_begin(),
                                    Node.decls_end(), Finder, Builder);
}

/// \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 != nullptr &&
          InnerMatcher.matches(*Initializer, Finder, Builder));
}

/// \brief Matches a variable declaration that has function scope and is a
/// non-static local variable.
///
/// Example matches x (matcher = varDecl(hasLocalStorage())
/// \code
/// void f() {
///   int x;
///   static int y;
/// }
/// int z;
/// \endcode
AST_MATCHER(VarDecl, hasLocalStorage) {
  return Node.hasLocalStorage();
}

/// \brief Matches a variable declaration that does not have local storage.
///
/// Example matches y and z (matcher = varDecl(hasGlobalStorage())
/// \code
/// void f() {
///   int x;
///   static int y;
/// }
/// int z;
/// \endcode
AST_MATCHER(VarDecl, hasGlobalStorage) {
  return Node.hasGlobalStorage();
}

/// \brief Matches a variable declaration that has automatic storage duration.
///
/// Example matches x, but not y, z, or a.
/// (matcher = varDecl(hasAutomaticStorageDuration())
/// \code
/// void f() {
///   int x;
///   static int y;
///   thread_local int z;
/// }
/// int a;
/// \endcode
AST_MATCHER(VarDecl, hasAutomaticStorageDuration) {
  return Node.getStorageDuration() == SD_Automatic;
}

/// \brief Matches a variable declaration that has static storage duration.
///
/// Example matches y and a, but not x or z.
/// (matcher = varDecl(hasStaticStorageDuration())
/// \code
/// void f() {
///   int x;
///   static int y;
///   thread_local int z;
/// }
/// int a;
/// \endcode
AST_MATCHER(VarDecl, hasStaticStorageDuration) {
  return Node.getStorageDuration() == SD_Static;
}

/// \brief Matches a variable declaration that has thread storage duration.
///
/// Example matches z, but not x, z, or a.
/// (matcher = varDecl(hasThreadStorageDuration())
/// \code
/// void f() {
///   int x;
///   static int y;
///   thread_local int z;
/// }
/// int a;
/// \endcode
AST_MATCHER(VarDecl, hasThreadStorageDuration) {
  return Node.getStorageDuration() == SD_Thread;
}

/// \brief Matches a variable declaration that is an exception variable from
/// a C++ catch block, or an Objective-C \@catch statement.
///
/// Example matches x (matcher = varDecl(isExceptionVariable())
/// \code
/// void f(int y) {
///   try {
///   } catch (int x) {
///   }
/// }
/// \endcode
AST_MATCHER(VarDecl, isExceptionVariable) {
  return Node.isExceptionVariable();
}

/// \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,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
                                                          CXXConstructExpr,
                                                          ObjCMessageExpr),
                          unsigned, N) {
  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,
                           AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
                                                           CXXConstructExpr,
                                                           ObjCMessageExpr),
                           unsigned, N, internal::Matcher<Expr>, InnerMatcher) {
  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 C++ catch statement that has a catch-all handler.
///
/// Given
/// \code
///   try {
///     // ...
///   } catch (int) {
///     // ...
///   } catch (...) {
///     // ...
///   }
/// /endcode
/// cxxCatchStmt(isCatchAll()) matches catch(...) but not catch(int).
AST_MATCHER(CXXCatchStmt, isCatchAll) {
  return Node.getExceptionDecl() == nullptr;
}

/// \brief Matches a constructor initializer.
///
/// Given
/// \code
///   struct Foo {
///     Foo() : foo_(1) { }
///     int foo_;
///   };
/// \endcode
/// cxxRecordDecl(has(cxxConstructorDecl(
///   hasAnyConstructorInitializer(anything())
/// )))
///   record matches Foo, hasAnyConstructorInitializer matches foo_(1)
AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer,
              internal::Matcher<CXXCtorInitializer>, InnerMatcher) {
  return matchesFirstInPointerRange(InnerMatcher, Node.init_begin(),
                                    Node.init_end(), Finder, Builder);
}

/// \brief Matches the field declaration of a constructor initializer.
///
/// Given
/// \code
///   struct Foo {
///     Foo() : foo_(1) { }
///     int foo_;
///   };
/// \endcode
/// cxxRecordDecl(has(cxxConstructorDecl(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 != nullptr &&
      InnerMatcher.matches(*NodeAsDecl, Finder, Builder));
}

/// \brief Matches the initializer expression of a constructor initializer.
///
/// Given
/// \code
///   struct Foo {
///     Foo() : foo_(1) { }
///     int foo_;
///   };
/// \endcode
/// cxxRecordDecl(has(cxxConstructorDecl(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 != nullptr &&
      InnerMatcher.matches(*NodeAsExpr, Finder, Builder));
}

/// \brief Matches a constructor 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
/// cxxConstructorDecl(hasAnyConstructorInitializer(isWritten()))
///   will match Foo(int), but not Foo()
AST_MATCHER(CXXCtorInitializer, isWritten) {
  return Node.isWritten();
}

/// \brief Matches a constructor initializer if it is initializing a base, as
/// opposed to a member.
///
/// Given
/// \code
///   struct B {};
///   struct D : B {
///     int I;
///     D(int i) : I(i) {}
///   };
///   struct E : B {
///     E() : B() {}
///   };
/// \endcode
/// cxxConstructorDecl(hasAnyConstructorInitializer(isBaseInitializer()))
///   will match E(), but not match D(int).
AST_MATCHER(CXXCtorInitializer, isBaseInitializer) {
  return Node.isBaseInitializer();
}

/// \brief Matches a constructor initializer if it is initializing a member, as
/// opposed to a base.
///
/// Given
/// \code
///   struct B {};
///   struct D : B {
///     int I;
///     D(int i) : I(i) {}
///   };
///   struct E : B {
///     E() : B() {}
///   };
/// \endcode
/// cxxConstructorDecl(hasAnyConstructorInitializer(isMemberInitializer()))
///   will match D(int), but not match E().
AST_MATCHER(CXXCtorInitializer, isMemberInitializer) {
  return Node.isMemberInitializer();
}

/// \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,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
                                                          CXXConstructExpr),
                          internal::Matcher<Expr>, InnerMatcher) {
  for (const Expr *Arg : Node.arguments()) {
    BoundNodesTreeBuilder Result(*Builder);
    if (InnerMatcher.matches(*Arg, Finder, &Result)) {
      *Builder = std::move(Result);
      return true;
    }
  }
  return false;
}

/// \brief Matches a constructor call expression which uses list initialization.
AST_MATCHER(CXXConstructExpr, isListInitialization) {
  return Node.isListInitialization();
}

/// \brief Matches a constructor call expression which requires
/// zero initialization.
///
/// Given
/// \code
/// void foo() {
///   struct point { double x; double y; };
///   point pt[2] = { { 1.0, 2.0 } };
/// }
/// \endcode
/// initListExpr(has(cxxConstructExpr(requiresZeroInitialization()))
/// will match the implicit array filler for pt[1].
AST_MATCHER(CXXConstructExpr, requiresZeroInitialization) {
  return Node.requiresZeroInitialization();
}

/// \brief Matches the n'th parameter of a function declaration.
///
/// Given
/// \code
///   class X { void f(int x) {} };
/// \endcode
/// cxxMethodDecl(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 all arguments and their respective ParmVarDecl.
///
/// Given
/// \code
///   void f(int i);
///   int y;
///   f(y);
/// \endcode
/// callExpr(
///   forEachArgumentWithParam(
///     declRefExpr(to(varDecl(hasName("y")))),
///     parmVarDecl(hasType(isInteger()))
/// ))
///   matches f(y);
/// with declRefExpr(...)
///   matching int y
/// and parmVarDecl(...)
///   matching int i
AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParam,
                           AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
                                                           CXXConstructExpr),
                           internal::Matcher<Expr>, ArgMatcher,
                           internal::Matcher<ParmVarDecl>, ParamMatcher) {
  BoundNodesTreeBuilder Result;
  // The first argument of an overloaded member operator is the implicit object
  // argument of the method which should not be matched against a parameter, so
  // we skip over it here.
  BoundNodesTreeBuilder Matches;
  unsigned ArgIndex = cxxOperatorCallExpr(callee(cxxMethodDecl()))
                              .matches(Node, Finder, &Matches)
                          ? 1
                          : 0;
  int ParamIndex = 0;
  bool Matched = false;
  for (; ArgIndex < Node.getNumArgs(); ++ArgIndex) {
    BoundNodesTreeBuilder ArgMatches(*Builder);
    if (ArgMatcher.matches(*(Node.getArg(ArgIndex)->IgnoreParenCasts()),
                           Finder, &ArgMatches)) {
      BoundNodesTreeBuilder ParamMatches(ArgMatches);
      if (expr(anyOf(cxxConstructExpr(hasDeclaration(cxxConstructorDecl(
                         hasParameter(ParamIndex, ParamMatcher)))),
                     callExpr(callee(functionDecl(
                         hasParameter(ParamIndex, ParamMatcher))))))
              .matches(Node, Finder, &ParamMatches)) {
        Result.addMatch(ParamMatches);
        Matched = true;
      }
    }
    ++ParamIndex;
  }
  *Builder = std::move(Result);
  return Matched;
}

/// \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
/// cxxMethodDecl(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) {
  return matchesFirstInPointerRange(InnerMatcher, Node.param_begin(),
                                    Node.param_end(), Finder, Builder);
}

/// \brief Matches \c FunctionDecls and \c FunctionProtoTypes that have a
/// specific parameter count.
///
/// Given
/// \code
///   void f(int i) {}
///   void g(int i, int j) {}
///   void h(int i, int j);
///   void j(int i);
///   void k(int x, int y, int z, ...);
/// \endcode
/// functionDecl(parameterCountIs(2))
///   matches void g(int i, int j) {}
/// functionProtoType(parameterCountIs(2))
///   matches void h(int i, int j)
/// functionProtoType(parameterCountIs(3))
///   matches void k(int x, int y, int z, ...);
AST_POLYMORPHIC_MATCHER_P(parameterCountIs,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
                                                          FunctionProtoType),
                          unsigned, N) {
  return Node.getNumParams() == N;
}

/// \brief Matches the return type of a function declaration.
///
/// Given:
/// \code
///   class X { int f() { return 1; } };
/// \endcode
/// cxxMethodDecl(returns(asString("int")))
///   matches int f() { return 1; }
AST_MATCHER_P(FunctionDecl, returns,
              internal::Matcher<QualType>, InnerMatcher) {
  return InnerMatcher.matches(Node.getReturnType(), 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_POLYMORPHIC_MATCHER(isExternC, AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
                                                                   VarDecl)) {
  return Node.isExternC();
}

/// \brief Matches deleted function declarations.
///
/// Given:
/// \code
///   void Func();
///   void DeletedFunc() = delete;
/// \endcode
/// functionDecl(isDeleted())
///   matches the declaration of DeletedFunc, but not Func.
AST_MATCHER(FunctionDecl, isDeleted) {
  return Node.isDeleted();
}

/// \brief Matches defaulted function declarations.
///
/// Given:
/// \code
///   class A { ~A(); };
///   class B { ~B() = default; };
/// \endcode
/// functionDecl(isDefaulted())
///   matches the declaration of ~B, but not ~A.
AST_MATCHER(FunctionDecl, isDefaulted) {
  return Node.isDefaulted();
}

/// \brief Matches functions that have a dynamic exception specification.
///
/// Given:
/// \code
///   void f();
///   void g() noexcept;
///   void h() noexcept(true);
///   void i() noexcept(false);
///   void j() throw();
///   void k() throw(int);
///   void l() throw(...);
/// \endcode
/// functionDecl(hasDynamicExceptionSpec()) and
///   functionProtoType(hasDynamicExceptionSpec())
///   match the declarations of j, k, and l, but not f, g, h, or i.
AST_POLYMORPHIC_MATCHER(hasDynamicExceptionSpec,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
                                                        FunctionProtoType)) {
  if (const FunctionProtoType *FnTy = internal::getFunctionProtoType(Node))
    return FnTy->hasDynamicExceptionSpec();
  return false;
}

/// \brief Matches functions that have a non-throwing exception specification.
///
/// Given:
/// \code
///   void f();
///   void g() noexcept;
///   void h() throw();
///   void i() throw(int);
///   void j() noexcept(false);
/// \endcode
/// functionDecl(isNoThrow()) and functionProtoType(isNoThrow())
///   match the declarations of g, and h, but not f, i or j.
AST_POLYMORPHIC_MATCHER(isNoThrow,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
                                                        FunctionProtoType)) {
  const FunctionProtoType *FnTy = internal::getFunctionProtoType(Node);

  // If the function does not have a prototype, then it is assumed to be a
  // throwing function (as it would if the function did not have any exception
  // specification).
  if (!FnTy)
    return false;

  // Assume the best for any unresolved exception specification.
  if (isUnresolvedExceptionSpec(FnTy->getExceptionSpecType()))
    return true;

  return FnTy->isNothrow(Finder->getASTContext());
}

/// \brief Matches constexpr variable and function declarations.
///
/// Given:
/// \code
///   constexpr int foo = 42;
///   constexpr int bar();
/// \endcode
/// varDecl(isConstexpr())
///   matches the declaration of foo.
/// functionDecl(isConstexpr())
///   matches the declaration of bar.
AST_POLYMORPHIC_MATCHER(isConstexpr,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(VarDecl,
                                                        FunctionDecl)) {
  return Node.isConstexpr();
}

/// \brief Matches the condition expression of an if statement, for loop,
/// switch statement or conditional operator.
///
/// Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
/// \code
///   if (true) {}
/// \endcode
AST_POLYMORPHIC_MATCHER_P(
    hasCondition,
    AST_POLYMORPHIC_SUPPORTED_TYPES(IfStmt, ForStmt, WhileStmt, DoStmt,
                                    SwitchStmt, AbstractConditionalOperator),
    internal::Matcher<Expr>, InnerMatcher) {
  const Expr *const Condition = Node.getCond();
  return (Condition != nullptr &&
          InnerMatcher.matches(*Condition, Finder, Builder));
}

/// \brief Matches the then-statement of an if statement.
///
/// Examples matches the if statement
///   (matcher = ifStmt(hasThen(cxxBoolLiteral(equals(true)))))
/// \code
///   if (false) true; else false;
/// \endcode
AST_MATCHER_P(IfStmt, hasThen, internal::Matcher<Stmt>, InnerMatcher) {
  const Stmt *const Then = Node.getThen();
  return (Then != nullptr && InnerMatcher.matches(*Then, Finder, Builder));
}

/// \brief Matches the else-statement of an if statement.
///
/// Examples matches the if statement
///   (matcher = ifStmt(hasElse(cxxBoolLiteral(equals(true)))))
/// \code
///   if (false) false; else true;
/// \endcode
AST_MATCHER_P(IfStmt, hasElse, internal::Matcher<Stmt>, InnerMatcher) {
  const Stmt *const Else = Node.getElse();
  return (Else != nullptr && InnerMatcher.matches(*Else, Finder, Builder));
}

/// \brief Matches if a node equals a previously bound node.
///
/// Matches a node if it equals the node previously bound to \p ID.
///
/// Given
/// \code
///   class X { int a; int b; };
/// \endcode
/// cxxRecordDecl(
///     has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
///     has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))
///   matches the class \c X, as \c a and \c b have the same type.
///
/// Note that when multiple matches are involved via \c forEach* matchers,
/// \c equalsBoundNodes acts as a filter.
/// For example:
/// compoundStmt(
///     forEachDescendant(varDecl().bind("d")),
///     forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d"))))))
/// will trigger a match for each combination of variable declaration
/// and reference to that variable declaration within a compound statement.
AST_POLYMORPHIC_MATCHER_P(equalsBoundNode,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(Stmt, Decl, Type,
                                                          QualType),
                          std::string, ID) {
  // FIXME: Figure out whether it makes sense to allow this
  // on any other node types.
  // For *Loc it probably does not make sense, as those seem
  // unique. For NestedNameSepcifier it might make sense, as
  // those also have pointer identity, but I'm not sure whether
  // they're ever reused.
  internal::NotEqualsBoundNodePredicate Predicate;
  Predicate.ID = ID;
  Predicate.Node = ast_type_traits::DynTypedNode::create(Node);
  return Builder->removeBindings(Predicate);
}

/// \brief Matches the condition variable statement in an if statement.
///
/// Given
/// \code
///   if (A* a = GetAPointer()) {}
/// \endcode
/// hasConditionVariableStatement(...)
///   matches 'A* a = GetAPointer()'.
AST_MATCHER_P(IfStmt, hasConditionVariableStatement,
              internal::Matcher<DeclStmt>, InnerMatcher) {
  const DeclStmt* const DeclarationStatement =
    Node.getConditionVariableDeclStmt();
  return DeclarationStatement != nullptr &&
         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', 'do while' statement or a function
/// definition that has a given body.
///
/// Given
/// \code
///   for (;;) {}
/// \endcode
/// hasBody(compoundStmt())
///   matches 'for (;;) {}'
/// with compoundStmt()
///   matching '{}'
AST_POLYMORPHIC_MATCHER_P(hasBody,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(DoStmt, ForStmt,
                                                          WhileStmt,
                                                          CXXForRangeStmt,
                                                          FunctionDecl),
                          internal::Matcher<Stmt>, InnerMatcher) {
  const Stmt *const Statement = internal::GetBodyMatcher<NodeType>::get(Node);
  return (Statement != nullptr &&
          InnerMatcher.matches(*Statement, Finder, Builder));
}

/// \brief Matches compound statements where at least one substatement matches
/// a given matcher. Also matches StmtExprs that have CompoundStmt as children.
///
/// Given
/// \code
///   { {}; 1+2; }
/// \endcode
/// hasAnySubstatement(compoundStmt())
///   matches '{ {}; 1+2; }'
/// with compoundStmt()
///   matching '{}'
AST_POLYMORPHIC_MATCHER_P(hasAnySubstatement,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(CompoundStmt,
                                                          StmtExpr),
                          internal::Matcher<Stmt>, InnerMatcher) {
  const CompoundStmt *CS = CompoundStmtMatcher<NodeType>::get(Node);
  return CS && matchesFirstInPointerRange(InnerMatcher, CS->body_begin(),
                                          CS->body_end(), Finder, Builder);
}

/// \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 = cxxBoolLiteral(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,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator,
                                                          UnaryOperator),
                          std::string, Name) {
  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_POLYMORPHIC_MATCHER_P(hasLHS,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator,
                                                          ArraySubscriptExpr),
                          internal::Matcher<Expr>, InnerMatcher) {
  const Expr *LeftHandSide = Node.getLHS();
  return (LeftHandSide != nullptr &&
          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_POLYMORPHIC_MATCHER_P(hasRHS,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator,
                                                          ArraySubscriptExpr),
                          internal::Matcher<Expr>, InnerMatcher) {
  const Expr *RightHandSide = Node.getRHS();
  return (RightHandSide != nullptr &&
          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(
///                                   cxxBoolLiteral(equals(true))))
/// \code
///   !true
/// \endcode
AST_MATCHER_P(UnaryOperator, hasUnaryOperand,
              internal::Matcher<Expr>, InnerMatcher) {
  const Expr * const Operand = Node.getSubExpr();
  return (Operand != nullptr &&
          InnerMatcher.matches(*Operand, Finder, Builder));
}

/// \brief Matches if the cast's source expression
/// or opaque value's source expression matches the given matcher.
///
/// Example 1: matches "a string"
/// (matcher = castExpr(hasSourceExpression(cxxConstructExpr())))
/// \code
/// class URL { URL(string); };
/// URL url = "a string";
/// \endcode
///
/// Example 2: matches 'b' (matcher =
/// opaqueValueExpr(hasSourceExpression(implicitCastExpr(declRefExpr())))
/// \code
/// int a = b ?: 1;
/// \endcode

AST_POLYMORPHIC_MATCHER_P(hasSourceExpression,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(CastExpr,
                                                          OpaqueValueExpr),
                          internal::Matcher<Expr>, InnerMatcher) {
  const Expr *const SubExpression =
      internal::GetSourceExpressionMatcher<NodeType>::get(Node);
  return (SubExpression != nullptr &&
          InnerMatcher.matches(*SubExpression, Finder, Builder));
}

/// \brief Matches casts that has a given cast kind.
///
/// Example: matches the implicit cast around \c 0
/// (matcher = castExpr(hasCastKind(CK_NullToPointer)))
/// \code
///   int *p = 0;
/// \endcode
AST_MATCHER_P(CastExpr, hasCastKind, CastKind, Kind) {
  return Node.getCastKind() == Kind;
}

/// \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 RecordDecl object that are spelled with "struct."
///
/// Example matches S, but not C or U.
/// \code
///   struct S {};
///   class C {};
///   union U {};
/// \endcode
AST_MATCHER(RecordDecl, isStruct) {
  return Node.isStruct();
}

/// \brief Matches RecordDecl object that are spelled with "union."
///
/// Example matches U, but not C or S.
/// \code
///   struct S {};
///   class C {};
///   union U {};
/// \endcode
AST_MATCHER(RecordDecl, isUnion) {
  return Node.isUnion();
}

/// \brief Matches RecordDecl object that are spelled with "class."
///
/// Example matches C, but not S or U.
/// \code
///   struct S {};
///   class C {};
///   union U {};
/// \endcode
AST_MATCHER(RecordDecl, isClass) {
  return Node.isClass();
}

/// \brief Matches the true branch expression of a conditional operator.
///
/// Example 1 (conditional ternary operator): matches a
/// \code
///   condition ? a : b
/// \endcode
///
/// Example 2 (conditional binary operator): matches opaqueValueExpr(condition)
/// \code
///   condition ?: b
/// \endcode
AST_MATCHER_P(AbstractConditionalOperator, hasTrueExpression,
              internal::Matcher<Expr>, InnerMatcher) {
  const Expr *Expression = Node.getTrueExpr();
  return (Expression != nullptr &&
          InnerMatcher.matches(*Expression, Finder, Builder));
}

/// \brief Matches the false branch expression of a conditional operator
/// (binary or ternary).
///
/// Example matches b
/// \code
///   condition ? a : b
///   condition ?: b
/// \endcode
AST_MATCHER_P(AbstractConditionalOperator, hasFalseExpression,
              internal::Matcher<Expr>, InnerMatcher) {
  const Expr *Expression = Node.getFalseExpr();
  return (Expression != nullptr &&
          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>
AST_POLYMORPHIC_MATCHER(isDefinition,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(TagDecl, VarDecl,
                                                        FunctionDecl)) {
  return Node.isThisDeclarationADefinition();
}

/// \brief Matches if a function declaration is variadic.
///
/// Example matches f, but not g or h. The function i will not match, even when
/// compiled in C mode.
/// \code
///   void f(...);
///   void g(int);
///   template <typename... Ts> void h(Ts...);
///   void i();
/// \endcode
AST_MATCHER(FunctionDecl, isVariadic) {
  return Node.isVariadic();
}

/// \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 = cxxConstructExpr(hasDeclaration(cxxMethodDecl(
///         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 != nullptr &&
          InnerMatcher.matches(*Parent, Finder, Builder));
}

/// \brief Matches each method overriden by the given method. This matcher may
/// produce multiple matches.
///
/// Given
/// \code
///   class A { virtual void f(); };
///   class B : public A { void f(); };
///   class C : public B { void f(); };
/// \endcode
/// cxxMethodDecl(ofClass(hasName("C")),
///               forEachOverridden(cxxMethodDecl().bind("b"))).bind("d")
///   matches once, with "b" binding "A::f" and "d" binding "C::f" (Note
///   that B::f is not overridden by C::f).
///
/// The check can produce multiple matches in case of multiple inheritance, e.g.
/// \code
///   class A1 { virtual void f(); };
///   class A2 { virtual void f(); };
///   class C : public A1, public A2 { void f(); };
/// \endcode
/// cxxMethodDecl(ofClass(hasName("C")),
///               forEachOverridden(cxxMethodDecl().bind("b"))).bind("d")
///   matches twice, once with "b" binding "A1::f" and "d" binding "C::f", and
///   once with "b" binding "A2::f" and "d" binding "C::f".
AST_MATCHER_P(CXXMethodDecl, forEachOverridden,
              internal::Matcher<CXXMethodDecl>, InnerMatcher) {
  BoundNodesTreeBuilder Result;
  bool Matched = false;
  for (const auto *Overridden : Node.overridden_methods()) {
    BoundNodesTreeBuilder OverriddenBuilder(*Builder);
    const bool OverriddenMatched =
        InnerMatcher.matches(*Overridden, Finder, &OverriddenBuilder);
    if (OverriddenMatched) {
      Matched = true;
      Result.addMatch(OverriddenBuilder);
    }
  }
  *Builder = std::move(Result);
  return Matched;
}

/// \brief Matches if the given method declaration is virtual.
///
/// Given
/// \code
///   class A {
///    public:
///     virtual void x();
///   };
/// \endcode
///   matches A::x
AST_MATCHER(CXXMethodDecl, isVirtual) {
  return Node.isVirtual();
}

/// \brief Matches if the given method declaration has an explicit "virtual".
///
/// Given
/// \code
///   class A {
///    public:
///     virtual void x();
///   };
///   class B : public A {
///    public:
///     void x();
///   };
/// \endcode
///   matches A::x but not B::x
AST_MATCHER(CXXMethodDecl, isVirtualAsWritten) {
  return Node.isVirtualAsWritten();
}

/// \brief Matches if the given method or class declaration is final.
///
/// Given:
/// \code
///   class A final {};
///
///   struct B {
///     virtual void f();
///   };
///
///   struct C : B {
///     void f() final;
///   };
/// \endcode
/// matches A and C::f, but not B, C, or B::f
AST_POLYMORPHIC_MATCHER(isFinal,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(CXXRecordDecl,
                                                        CXXMethodDecl)) {
  return Node.template hasAttr<FinalAttr>();
}

/// \brief Matches if the given method declaration is pure.
///
/// Given
/// \code
///   class A {
///    public:
///     virtual void x() = 0;
///   };
/// \endcode
///   matches A::x
AST_MATCHER(CXXMethodDecl, isPure) {
  return Node.isPure();
}

/// \brief Matches if the given method declaration is const.
///
/// Given
/// \code
/// struct A {
///   void foo() const;
///   void bar();
/// };
/// \endcode
///
/// cxxMethodDecl(isConst()) matches A::foo() but not A::bar()
AST_MATCHER(CXXMethodDecl, isConst) {
  return Node.isConst();
}

/// \brief Matches if the given method declaration declares a copy assignment
/// operator.
///
/// Given
/// \code
/// struct A {
///   A &operator=(const A &);
///   A &operator=(A &&);
/// };
/// \endcode
///
/// cxxMethodDecl(isCopyAssignmentOperator()) matches the first method but not
/// the second one.
AST_MATCHER(CXXMethodDecl, isCopyAssignmentOperator) {
  return Node.isCopyAssignmentOperator();
}

/// \brief Matches if the given method declaration declares a move assignment
/// operator.
///
/// Given
/// \code
/// struct A {
///   A &operator=(const A &);
///   A &operator=(A &&);
/// };
/// \endcode
///
/// cxxMethodDecl(isMoveAssignmentOperator()) matches the second method but not
/// the first one.
AST_MATCHER(CXXMethodDecl, isMoveAssignmentOperator) {
  return Node.isMoveAssignmentOperator();
}

/// \brief Matches if the given method declaration overrides another method.
///
/// Given
/// \code
///   class A {
///    public:
///     virtual void x();
///   };
///   class B : public A {
///    public:
///     virtual void x();
///   };
/// \endcode
///   matches B::x
AST_MATCHER(CXXMethodDecl, isOverride) {
  return Node.size_overridden_methods() > 0 || Node.hasAttr<OverrideAttr>();
}

/// \brief Matches method declarations that are user-provided.
///
/// Given
/// \code
///   struct S {
///     S(); // #1
///     S(const S &) = default; // #2
///     S(S &&) = delete; // #3
///   };
/// \endcode
/// cxxConstructorDecl(isUserProvided()) will match #1, but not #2 or #3.
AST_MATCHER(CXXMethodDecl, isUserProvided) {
  return Node.isUserProvided();
}

/// \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
AST_MATCHER(MemberExpr, isArrow) {
  return Node.isArrow();
}

/// \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 of unsigned integer type.
///
/// Given
/// \code
///   void a(int);
///   void b(unsigned long);
///   void c(double);
/// \endcode
/// functionDecl(hasAnyParameter(hasType(isUnsignedInteger())))
/// matches "b(unsigned long)", but not "a(int)" and "c(double)".
AST_MATCHER(QualType, isUnsignedInteger) {
    return Node->isUnsignedIntegerType();
}

/// \brief Matches QualType nodes that are of signed integer type.
///
/// Given
/// \code
///   void a(int);
///   void b(unsigned long);
///   void c(double);
/// \endcode
/// functionDecl(hasAnyParameter(hasType(isSignedInteger())))
/// matches "a(int)", but not "b(unsigned long)" and "c(double)".
AST_MATCHER(QualType, isSignedInteger) {
    return Node->isSignedIntegerType();
}

/// \brief Matches QualType nodes that are of character type.
///
/// Given
/// \code
///   void a(char);
///   void b(wchar_t);
///   void c(double);
/// \endcode
/// functionDecl(hasAnyParameter(hasType(isAnyCharacter())))
/// matches "a(char)", "b(wchar_t)", but not "c(double)".
AST_MATCHER(QualType, isAnyCharacter) {
    return Node->isAnyCharacterType();
}

/// \brief Matches QualType nodes that are of any pointer type; this includes
/// the Objective-C object pointer type, which is different despite being
/// syntactically similar.
///
/// Given
/// \code
///   int *i = nullptr;
///
///   @interface Foo
///   @end
///   Foo *f;
///
///   int j;
/// \endcode
/// varDecl(hasType(isAnyPointer()))
///   matches "int *i" and "Foo *f", but not "int j".
AST_MATCHER(QualType, isAnyPointer) {
  return Node->isAnyPointerType();
}

/// \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 *".
AST_MATCHER(QualType, isConstQualified) {
  return Node.isConstQualified();
}

/// \brief Matches QualType nodes that are volatile-qualified, i.e., that
/// include "top-level" volatile.
///
/// Given
/// \code
///   void a(int);
///   void b(int volatile);
///   void c(volatile int);
///   void d(volatile int*);
///   void e(int volatile) {};
/// \endcode
/// functionDecl(hasAnyParameter(hasType(isVolatileQualified())))
///   matches "void b(int volatile)", "void c(volatile int)" and
///   "void e(int volatile) {}". It does not match d as there
///   is no top-level volatile on the parameter type "volatile int *".
AST_MATCHER(QualType, isVolatileQualified) {
  return Node.isVolatileQualified();
}

/// \brief Matches QualType nodes that have local CV-qualifiers attached to
/// the node, not hidden within a typedef.
///
/// Given
/// \code
///   typedef const int const_int;
///   const_int i;
///   int *const j;
///   int *volatile k;
///   int m;
/// \endcode
/// \c varDecl(hasType(hasLocalQualifiers())) matches only \c j and \c k.
/// \c i is const-qualified but the qualifier is not local.
AST_MATCHER(QualType, hasLocalQualifiers) {
  return Node.hasLocalQualifiers();
}

/// \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(cxxRecordDecl(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) {
  return matchesFirstInPointerRange(InnerMatcher, Node.shadow_begin(),
                                    Node.shadow_end(), Finder, Builder);
}

/// \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
/// cxxRecordDecl(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
/// cxxRecordDecl(hasName("::X"), isTemplateInstantiation())
///   does not match, as X<A> is an explicit template specialization.
///
/// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
AST_POLYMORPHIC_MATCHER(isTemplateInstantiation,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, VarDecl,
                                                        CXXRecordDecl)) {
  return (Node.getTemplateSpecializationKind() == TSK_ImplicitInstantiation ||
          Node.getTemplateSpecializationKind() ==
          TSK_ExplicitInstantiationDefinition);
}

/// \brief Matches declarations that are template instantiations or are inside
/// template instantiations.
///
/// Given
/// \code
///   template<typename T> void A(T t) { T i; }
///   A(0);
///   A(0U);
/// \endcode
/// functionDecl(isInstantiated())
///   matches 'A(int) {...};' and 'A(unsigned) {...}'.
AST_MATCHER_FUNCTION(internal::Matcher<Decl>, isInstantiated) {
  auto IsInstantiation = decl(anyOf(cxxRecordDecl(isTemplateInstantiation()),
                                    functionDecl(isTemplateInstantiation())));
  return decl(anyOf(IsInstantiation, hasAncestor(IsInstantiation)));
}

/// \brief Matches statements inside of a template instantiation.
///
/// Given
/// \code
///   int j;
///   template<typename T> void A(T t) { T i; j += 42;}
///   A(0);
///   A(0U);
/// \endcode
/// declStmt(isInTemplateInstantiation())
///   matches 'int i;' and 'unsigned i'.
/// unless(stmt(isInTemplateInstantiation()))
///   will NOT match j += 42; as it's shared between the template definition and
///   instantiation.
AST_MATCHER_FUNCTION(internal::Matcher<Stmt>, isInTemplateInstantiation) {
  return stmt(
      hasAncestor(decl(anyOf(cxxRecordDecl(isTemplateInstantiation()),
                             functionDecl(isTemplateInstantiation())))));
}

/// \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>
AST_POLYMORPHIC_MATCHER(isExplicitTemplateSpecialization,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, VarDecl,
                                                        CXXRecordDecl)) {
  return (Node.getTemplateSpecializationKind() == TSK_ExplicitSpecialization);
}

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

/// \brief Matches type \c bool.
///
/// Given
/// \code
///  struct S { bool func(); };
/// \endcode
/// functionDecl(returns(booleanType()))
///   matches "bool func();"
AST_MATCHER(Type, booleanType) {
  return Node.isBooleanType();
}

/// \brief Matches type \c void.
///
/// Given
/// \code
///  struct S { void func(); };
/// \endcode
/// functionDecl(returns(voidType()))
///   matches "void func();"
AST_MATCHER(Type, voidType) {
  return Node.isVoidType();
}

/// \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 any real floating-point type (float, double, long double).
///
/// Given
/// \code
///   int i;
///   float f;
/// \endcode
/// realFloatingPointType()
///   matches "float f" but not "int i"
AST_MATCHER(Type, realFloatingPointType) {
  return Node.isRealFloatingType();
}

/// \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,
                             AST_POLYMORPHIC_SUPPORTED_TYPES(ArrayType,
                                                             ComplexType));

/// \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 nodes that have the specified size.
///
/// Given
/// \code
///   int a[42];
///   int b[2 * 21];
///   int c[41], d[43];
///   char *s = "abcd";
///   wchar_t *ws = L"abcd";
///   char *w = "a";
/// \endcode
/// constantArrayType(hasSize(42))
///   matches "int a[42]" and "int b[2 * 21]"
/// stringLiteral(hasSize(4))
///   matches "abcd", L"abcd"
AST_POLYMORPHIC_MATCHER_P(hasSize,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(ConstantArrayType,
                                                          StringLiteral),
                          unsigned, N) {
  return internal::HasSizeMatcher<NodeType>::hasSize(Node, 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,
                             AST_POLYMORPHIC_SUPPORTED_TYPES(AtomicType));

/// \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,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(AutoType));

/// \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 \c FunctionProtoType nodes.
///
/// Given
/// \code
///   int (*f)(int);
///   void g();
/// \endcode
/// functionProtoType()
///   matches "int (*f)(int)" and the type of "g" in C++ mode.
///   In C mode, "g" is not matched because it does not contain a prototype.
AST_TYPE_MATCHER(FunctionProtoType, functionProtoType);

/// \brief Matches \c ParenType nodes.
///
/// Given
/// \code
///   int (*ptr_to_array)[4];
///   int *array_of_ptrs[4];
/// \endcode
///
/// \c varDecl(hasType(pointsTo(parenType()))) matches \c ptr_to_array but not
/// \c array_of_ptrs.
AST_TYPE_MATCHER(ParenType, parenType);

/// \brief Matches \c ParenType nodes where the inner type is a specific type.
///
/// Given
/// \code
///   int (*ptr_to_array)[4];
///   int (*ptr_to_func)(int);
/// \endcode
///
/// \c varDecl(hasType(pointsTo(parenType(innerType(functionType()))))) matches
/// \c ptr_to_func but not \c ptr_to_array.
///
/// Usable as: Matcher<ParenType>
AST_TYPE_TRAVERSE_MATCHER(innerType, getInnerType,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(ParenType));

/// \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, but does not match Objective-C object pointer
/// types.
///
/// Given
/// \code
///   int *a;
///   int &b = *a;
///   int c = 5;
///
///   @interface Foo
///   @end
///   Foo *f;
/// \endcode
/// pointerType()
///   matches "int *a", but does not match "Foo *f".
AST_TYPE_MATCHER(PointerType, pointerType);

/// \brief Matches an Objective-C object pointer type, which is different from
/// a pointer type, despite being syntactically similar.
///
/// Given
/// \code
///   int *a;
///
///   @interface Foo
///   @end
///   Foo *f;
/// \endcode
/// pointerType()
///   matches "Foo *f", but does not match "int *a".
AST_TYPE_MATCHER(ObjCObjectPointerType, objcObjectPointerType);

/// \brief Matches both lvalue and rvalue reference types.
///
/// Given
/// \code
///   int *a;
///   int &b = *a;
///   int &&c = 1;
///   auto &d = b;
///   auto &&e = c;
///   auto &&f = 2;
///   int g = 5;
/// \endcode
///
/// \c referenceType() matches the types of \c b, \c c, \c d, \c e, and \c f.
AST_TYPE_MATCHER(ReferenceType, referenceType);

/// \brief Matches lvalue reference types.
///
/// Given:
/// \code
///   int *a;
///   int &b = *a;
///   int &&c = 1;
///   auto &d = b;
///   auto &&e = c;
///   auto &&f = 2;
///   int g = 5;
/// \endcode
///
/// \c lValueReferenceType() matches the types of \c b, \c d, and \c e. \c e is
/// matched since the type is deduced as int& by reference collapsing rules.
AST_TYPE_MATCHER(LValueReferenceType, lValueReferenceType);

/// \brief Matches rvalue reference types.
///
/// Given:
/// \code
///   int *a;
///   int &b = *a;
///   int &&c = 1;
///   auto &d = b;
///   auto &&e = c;
///   auto &&f = 2;
///   int g = 5;
/// \endcode
///
/// \c rValueReferenceType() matches the types of \c c and \c f. \c e is not
/// matched as it is deduced to int& by reference collapsing rules.
AST_TYPE_MATCHER(RValueReferenceType, rValueReferenceType);

/// \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,
                             AST_POLYMORPHIC_SUPPORTED_TYPES(BlockPointerType,
                                                             MemberPointerType,
                                                             PointerType,
                                                             ReferenceType));

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

/// \brief Matches enum types.
///
/// Given
/// \code
///   enum C { Green };
///   enum class S { Red };
///
///   C c;
///   S s;
/// \endcode
//
/// \c enumType() matches the type of the variable declarations of both \c c and
/// \c s.
AST_TYPE_MATCHER(EnumType, enumType);

/// \brief Matches template specialization types.
///
/// Given
/// \code
///   template <typename T>
///   class C { };
///
///   template class C<int>;  // A
///   C<char> var;            // B
/// \endcode
///
/// \c templateSpecializationType() matches the type of the explicit
/// instantiation in \c A and the type of the variable declaration in \c B.
AST_TYPE_MATCHER(TemplateSpecializationType, templateSpecializationType);

/// \brief Matches types nodes representing unary type transformations.
///
/// Given:
/// \code
///   typedef __underlying_type(T) type;
/// \endcode
/// unaryTransformType()
///   matches "__underlying_type(T)"
AST_TYPE_MATCHER(UnaryTransformType, unaryTransformType);

/// \brief Matches record types (e.g. structs, classes).
///
/// Given
/// \code
///   class C {};
///   struct S {};
///
///   C c;
///   S s;
/// \endcode
///
/// \c recordType() matches the type of the variable declarations of both \c c
/// and \c s.
AST_TYPE_MATCHER(RecordType, recordType);

/// \brief Matches types specified with an elaborated type keyword or with a
/// qualified name.
///
/// Given
/// \code
///   namespace N {
///     namespace M {
///       class D {};
///     }
///   }
///   class C {};
///
///   class C c;
///   N::M::D d;
/// \endcode
///
/// \c elaboratedType() matches the type of the variable declarations of both
/// \c c and \c d.
AST_TYPE_MATCHER(ElaboratedType, elaboratedType);

/// \brief Matches ElaboratedTypes whose qualifier, a NestedNameSpecifier,
/// matches \c InnerMatcher if the qualifier exists.
///
/// Given
/// \code
///   namespace N {
///     namespace M {
///       class D {};
///     }
///   }
///   N::M::D d;
/// \endcode
///
/// \c elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N"))))
/// matches the type of the variable declaration of \c d.
AST_MATCHER_P(ElaboratedType, hasQualifier,
              internal::Matcher<NestedNameSpecifier>, InnerMatcher) {
  if (const NestedNameSpecifier *Qualifier = Node.getQualifier())
    return InnerMatcher.matches(*Qualifier, Finder, Builder);

  return false;
}

/// \brief Matches ElaboratedTypes whose named type matches \c InnerMatcher.
///
/// Given
/// \code
///   namespace N {
///     namespace M {
///       class D {};
///     }
///   }
///   N::M::D d;
/// \endcode
///
/// \c elaboratedType(namesType(recordType(
/// hasDeclaration(namedDecl(hasName("D")))))) matches the type of the variable
/// declaration of \c d.
AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>,
              InnerMatcher) {
  return InnerMatcher.matches(Node.getNamedType(), Finder, Builder);
}

/// \brief Matches types that represent the result of substituting a type for a
/// template type parameter.
///
/// Given
/// \code
///   template <typename T>
///   void F(T t) {
///     int i = 1 + t;
///   }
/// \endcode
///
/// \c substTemplateTypeParmType() matches the type of 't' but not '1'
AST_TYPE_MATCHER(SubstTemplateTypeParmType, substTemplateTypeParmType);

/// \brief Matches template type parameter types.
///
/// Example matches T, but not int.
///     (matcher = templateTypeParmType())
/// \code
///   template <typename T> void f(int i);
/// \endcode
AST_TYPE_MATCHER(TemplateTypeParmType, templateTypeParmType);

/// \brief Matches injected class name types.
///
/// Example matches S s, but not S<T> s.
///     (matcher = parmVarDecl(hasType(injectedClassNameType())))
/// \code
///   template <typename T> struct S {
///     void f(S s);
///     void g(S<T> s);
///   };
/// \endcode
AST_TYPE_MATCHER(InjectedClassNameType, injectedClassNameType);

/// \brief Matches decayed type
/// Example matches i[] in declaration of f.
///     (matcher = valueDecl(hasType(decayedType(hasDecayedType(pointerType())))))
/// Example matches i[1].
///     (matcher = expr(hasType(decayedType(hasDecayedType(pointerType())))))
/// \code
///   void f(int i[]) {
///     i[1] = 0;
///   }
/// \endcode
AST_TYPE_MATCHER(DecayedType, decayedType);

/// \brief Matches the decayed type, whos decayed type matches \c InnerMatcher
AST_MATCHER_P(DecayedType, hasDecayedType, internal::Matcher<QualType>,
              InnerType) {
  return InnerType.matches(Node.getDecayedType(), Finder, Builder);
}

/// \brief Matches declarations whose declaration context, interpreted as a
/// Decl, matches \c InnerMatcher.
///
/// Given
/// \code
///   namespace N {
///     namespace M {
///       class D {};
///     }
///   }
/// \endcode
///
/// \c cxxRcordDecl(hasDeclContext(namedDecl(hasName("M")))) matches the
/// declaration of \c class \c D.
AST_MATCHER_P(Decl, hasDeclContext, internal::Matcher<Decl>, InnerMatcher) {
  const DeclContext *DC = Node.getDeclContext();
  if (!DC) return false;
  return InnerMatcher.matches(*Decl::castFromDeclContext(DC), 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.
AST_MATCHER_FUNCTION_P_OVERLOAD(
    internal::BindableMatcher<NestedNameSpecifierLoc>, loc,
    internal::Matcher<NestedNameSpecifier>, InnerMatcher, 1) {
  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(cxxRecordDecl(hasName("A")))
/// ))
///   matches "A::"
AST_MATCHER_P(NestedNameSpecifier, specifiesType,
              internal::Matcher<QualType>, InnerMatcher) {
  if (!Node.getAsType())
    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(cxxRecordDecl(hasName("A")))))))
///   matches "A::"
AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc,
              internal::Matcher<TypeLoc>, InnerMatcher) {
  return Node && 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::"
AST_MATCHER_P_OVERLOAD(NestedNameSpecifier, hasPrefix,
                       internal::Matcher<NestedNameSpecifier>, InnerMatcher,
                       0) {
  const NestedNameSpecifier *NextNode = Node.getPrefix();
  if (!NextNode)
    return false;
  return InnerMatcher.matches(*NextNode, Finder, Builder);
}

/// \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::"
AST_MATCHER_P_OVERLOAD(NestedNameSpecifierLoc, hasPrefix,
                       internal::Matcher<NestedNameSpecifierLoc>, InnerMatcher,
                       1) {
  NestedNameSpecifierLoc NextNode = Node.getPrefix();
  if (!NextNode)
    return false;
  return InnerMatcher.matches(NextNode, Finder, Builder);
}

/// \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())
    return false;
  return InnerMatcher.matches(*Node.getAsNamespace(), Finder, Builder);
}

/// \brief Overloads for the \c equalsNode matcher.
/// FIXME: Implement for other node types.
/// @{

/// \brief Matches if a node equals another node.
///
/// \c Decl has pointer identity in the AST.
AST_MATCHER_P_OVERLOAD(Decl, equalsNode, const Decl*, Other, 0) {
  return &Node == Other;
}
/// \brief Matches if a node equals another node.
///
/// \c Stmt has pointer identity in the AST.
AST_MATCHER_P_OVERLOAD(Stmt, equalsNode, const Stmt*, Other, 1) {
  return &Node == Other;
}
/// \brief Matches if a node equals another node.
///
/// \c Type has pointer identity in the AST.
AST_MATCHER_P_OVERLOAD(Type, equalsNode, const Type*, Other, 2) {
    return &Node == Other;
}

/// @}

/// \brief Matches each case or default statement belonging to the given switch
/// statement. This matcher may produce multiple matches.
///
/// Given
/// \code
///   switch (1) { case 1: case 2: default: switch (2) { case 3: case 4: ; } }
/// \endcode
/// switchStmt(forEachSwitchCase(caseStmt().bind("c"))).bind("s")
///   matches four times, with "c" binding each of "case 1:", "case 2:",
/// "case 3:" and "case 4:", and "s" respectively binding "switch (1)",
/// "switch (1)", "switch (2)" and "switch (2)".
AST_MATCHER_P(SwitchStmt, forEachSwitchCase, internal::Matcher<SwitchCase>,
              InnerMatcher) {
  BoundNodesTreeBuilder Result;
  // FIXME: getSwitchCaseList() does not necessarily guarantee a stable
  // iteration order. We should use the more general iterating matchers once
  // they are capable of expressing this matcher (for example, it should ignore
  // case statements belonging to nested switch statements).
  bool Matched = false;
  for (const SwitchCase *SC = Node.getSwitchCaseList(); SC;
       SC = SC->getNextSwitchCase()) {
    BoundNodesTreeBuilder CaseBuilder(*Builder);
    bool CaseMatched = InnerMatcher.matches(*SC, Finder, &CaseBuilder);
    if (CaseMatched) {
      Matched = true;
      Result.addMatch(CaseBuilder);
    }
  }
  *Builder = std::move(Result);
  return Matched;
}

/// \brief Matches each constructor initializer in a constructor definition.
///
/// Given
/// \code
///   class A { A() : i(42), j(42) {} int i; int j; };
/// \endcode
/// cxxConstructorDecl(forEachConstructorInitializer(
///   forField(decl().bind("x"))
/// ))
///   will trigger two matches, binding for 'i' and 'j' respectively.
AST_MATCHER_P(CXXConstructorDecl, forEachConstructorInitializer,
              internal::Matcher<CXXCtorInitializer>, InnerMatcher) {
  BoundNodesTreeBuilder Result;
  bool Matched = false;
  for (const auto *I : Node.inits()) {
    BoundNodesTreeBuilder InitBuilder(*Builder);
    if (InnerMatcher.matches(*I, Finder, &InitBuilder)) {
      Matched = true;
      Result.addMatch(InitBuilder);
    }
  }
  *Builder = std::move(Result);
  return Matched;
}

/// \brief Matches constructor declarations that are copy constructors.
///
/// Given
/// \code
///   struct S {
///     S(); // #1
///     S(const S &); // #2
///     S(S &&); // #3
///   };
/// \endcode
/// cxxConstructorDecl(isCopyConstructor()) will match #2, but not #1 or #3.
AST_MATCHER(CXXConstructorDecl, isCopyConstructor) {
  return Node.isCopyConstructor();
}

/// \brief Matches constructor declarations that are move constructors.
///
/// Given
/// \code
///   struct S {
///     S(); // #1
///     S(const S &); // #2
///     S(S &&); // #3
///   };
/// \endcode
/// cxxConstructorDecl(isMoveConstructor()) will match #3, but not #1 or #2.
AST_MATCHER(CXXConstructorDecl, isMoveConstructor) {
  return Node.isMoveConstructor();
}

/// \brief Matches constructor declarations that are default constructors.
///
/// Given
/// \code
///   struct S {
///     S(); // #1
///     S(const S &); // #2
///     S(S &&); // #3
///   };
/// \endcode
/// cxxConstructorDecl(isDefaultConstructor()) will match #1, but not #2 or #3.
AST_MATCHER(CXXConstructorDecl, isDefaultConstructor) {
  return Node.isDefaultConstructor();
}

/// \brief Matches constructors that delegate to another constructor.
///
/// Given
/// \code
///   struct S {
///     S(); // #1
///     S(int) {} // #2
///     S(S &&) : S() {} // #3
///   };
///   S::S() : S(0) {} // #4
/// \endcode
/// cxxConstructorDecl(isDelegatingConstructor()) will match #3 and #4, but not
/// #1 or #2.
AST_MATCHER(CXXConstructorDecl, isDelegatingConstructor) {
  return Node.isDelegatingConstructor();
}

/// \brief Matches constructor and conversion declarations that are marked with
/// the explicit keyword.
///
/// Given
/// \code
///   struct S {
///     S(int); // #1
///     explicit S(double); // #2
///     operator int(); // #3
///     explicit operator bool(); // #4
///   };
/// \endcode
/// cxxConstructorDecl(isExplicit()) will match #2, but not #1.
/// cxxConversionDecl(isExplicit()) will match #4, but not #3.
AST_POLYMORPHIC_MATCHER(isExplicit,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(CXXConstructorDecl,
                                                        CXXConversionDecl)) {
  return Node.isExplicit();
}

/// \brief Matches function and namespace declarations that are marked with
/// the inline keyword.
///
/// Given
/// \code
///   inline void f();
///   void g();
///   namespace n {
///   inline namespace m {}
///   }
/// \endcode
/// functionDecl(isInline()) will match ::f().
/// namespaceDecl(isInline()) will match n::m.
AST_POLYMORPHIC_MATCHER(isInline,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(NamespaceDecl,
                                                        FunctionDecl)) {
  // This is required because the spelling of the function used to determine
  // whether inline is specified or not differs between the polymorphic types.
  if (const auto *FD = dyn_cast<FunctionDecl>(&Node))
    return FD->isInlineSpecified();
  else if (const auto *NSD = dyn_cast<NamespaceDecl>(&Node))
    return NSD->isInline();
  llvm_unreachable("Not a valid polymorphic type");
}

/// \brief Matches anonymous namespace declarations.
///
/// Given
/// \code
///   namespace n {
///   namespace {} // #1
///   }
/// \endcode
/// namespaceDecl(isAnonymous()) will match #1 but not ::n.
AST_MATCHER(NamespaceDecl, isAnonymous) {
  return Node.isAnonymousNamespace();
}

/// \brief If the given case statement does not use the GNU case range
/// extension, matches the constant given in the statement.
///
/// Given
/// \code
///   switch (1) { case 1: case 1+1: case 3 ... 4: ; }
/// \endcode
/// caseStmt(hasCaseConstant(integerLiteral()))
///   matches "case 1:"
AST_MATCHER_P(CaseStmt, hasCaseConstant, internal::Matcher<Expr>,
              InnerMatcher) {
  if (Node.getRHS())
    return false;

  return InnerMatcher.matches(*Node.getLHS(), Finder, Builder);
}

/// \brief Matches declaration that has a given attribute.
///
/// Given
/// \code
///   __attribute__((device)) void f() { ... }
/// \endcode
/// decl(hasAttr(clang::attr::CUDADevice)) matches the function declaration of
/// f. If the matcher is use from clang-query, attr::Kind parameter should be
/// passed as a quoted string. e.g., hasAttr("attr::CUDADevice").
AST_MATCHER_P(Decl, hasAttr, attr::Kind, AttrKind) {
  for (const auto *Attr : Node.attrs()) {
    if (Attr->getKind() == AttrKind)
      return true;
  }
  return false;
}

/// \brief Matches the return value expression of a return statement
///
/// Given
/// \code
///   return a + b;
/// \endcode
/// hasReturnValue(binaryOperator())
///   matches 'return a + b'
/// with binaryOperator()
///   matching 'a + b'
AST_MATCHER_P(ReturnStmt, hasReturnValue, internal::Matcher<Expr>,
              InnerMatcher) {
  if (const auto *RetValue = Node.getRetValue())
    return InnerMatcher.matches(*RetValue, Finder, Builder);
  return false;
}


/// \brief Matches CUDA kernel call expression.
///
/// Example matches,
/// \code
///   kernel<<<i,j>>>();
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
  Stmt,
  CUDAKernelCallExpr> cudaKernelCallExpr;


/// \brief Matches expressions that resolve to a null pointer constant, such as
/// GNU's __null, C++11's nullptr, or C's NULL macro.
///
/// Given:
/// \code
///   void *v1 = NULL;
///   void *v2 = nullptr;
///   void *v3 = __null; // GNU extension
///   char *cp = (char *)0;
///   int *ip = 0;
///   int i = 0;
/// \endcode
/// expr(nullPointerConstant())
///   matches the initializer for v1, v2, v3, cp, and ip. Does not match the
///   initializer for i.
AST_MATCHER_FUNCTION(internal::Matcher<Expr>, nullPointerConstant) {
  return anyOf(
      gnuNullExpr(), cxxNullPtrLiteralExpr(),
      integerLiteral(equals(0), hasParent(expr(hasType(pointerType())))));
}

/// \brief Matches declaration of the function the statemenet belongs to
///
/// Given:
/// \code
/// F& operator=(const F& o) {
///   std::copy_if(o.begin(), o.end(), begin(), [](V v) { return v > 0; });
///   return *this;
/// }
/// \endcode
/// returnStmt(forFunction(hasName("operator=")))
///   matches 'return *this'
///   but does match 'return > 0'
AST_MATCHER_P(Stmt, forFunction, internal::Matcher<FunctionDecl>,
              InnerMatcher) {
  const auto &Parents = Finder->getASTContext().getParents(Node);

  llvm::SmallVector<ast_type_traits::DynTypedNode, 8> Stack(Parents.begin(),
                                                            Parents.end());
  while(!Stack.empty()) {
    const auto &CurNode = Stack.back();
    Stack.pop_back();
    if(const auto *FuncDeclNode = CurNode.get<FunctionDecl>()) {
      if(InnerMatcher.matches(*FuncDeclNode, Finder, Builder)) {
        return true;
      }
    } else if(const auto *LambdaExprNode = CurNode.get<LambdaExpr>()) {
      if(InnerMatcher.matches(*LambdaExprNode->getCallOperator(),
                              Finder, Builder)) {
        return true;
      }
    } else {
      for(const auto &Parent: Finder->getASTContext().getParents(CurNode))
        Stack.push_back(Parent);
    }
  }
  return false;
}

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

#endif
